-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathBank $94.asm
7155 lines (6389 loc) · 374 KB
/
Bank $94.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
;;; $8000..84D5: Post grapple collision detection ;;;
{
;;; $8000: Post grapple collision detection - horizontal - slope - non-square ;;;
{
;; Parameters:
;; X: Block index
;; $20: Samus left/right boundary
;; Returns:
;; Carry: Set if Samus collides with slope, clear otherwise
;; A: If carry set, X depth into slope in pixels
$94:8000 AD 02 0B LDA $0B02 [$7E:0B02] ;\
$94:8003 4A LSR A ;} If collision direction is right:
$94:8004 90 03 BCC $03 [$8009] ;/
$94:8006 4C 73 80 JMP $8073 [$94:8073] ; Go to BRANCH_RIGHT
; BRANCH_LEFT
$94:8009 AD C4 0D LDA $0DC4 [$7E:0DC4] ;\
$94:800C 8D 04 42 STA $4204 ;|
$94:800F E2 20 SEP #$20 ;|
$94:8011 AD A5 07 LDA $07A5 [$7E:07A5] ;|
$94:8014 8D 06 42 STA $4206 ;|
$94:8017 C2 20 REP #$20 ;|
$94:8019 AD F6 0A LDA $0AF6 [$7E:0AF6] ;} If [current block index] % [room width in blocks] != [Samus X position] / 10h (Samus' centre isn't in block):
$94:801C 4A LSR A ;|
$94:801D 4A LSR A ;|
$94:801E 4A LSR A ;|
$94:801F 4A LSR A ;|
$94:8020 CD 16 42 CMP $4216 ;|
$94:8023 F0 02 BEQ $02 [$8027] ;/
$94:8025 18 CLC ;\
$94:8026 60 RTS ;} Return carry clear
$94:8027 A5 20 LDA $20 [$7E:0020] ;\
$94:8029 29 0F 00 AND #$000F ;} $0DD4 = [Samus left boundary] % 10h (Samus left X offset)
$94:802C 8D D4 0D STA $0DD4 [$7E:0DD4] ;/
$94:802F BF 02 64 7F LDA $7F6402,x ;\
$94:8033 29 1F 00 AND #$001F ;|
$94:8036 0A ASL A ;|
$94:8037 0A ASL A ;} $0DD6 = ([block BTS] & 1Fh) * 10h (slope definition table base index)
$94:8038 0A ASL A ;|
$94:8039 0A ASL A ;|
$94:803A 8D D6 0D STA $0DD6 [$7E:0DD6] ;/
$94:803D BF 01 64 7F LDA $7F6401,x ;\
$94:8041 0A ASL A ;} If [block BTS] & 40h = 0: go to post grapple collision detection - horizontal - solid
$94:8042 10 2C BPL $2C [$8070] ;/
$94:8044 BF 01 64 7F LDA $7F6401,x ;\
$94:8048 30 05 BMI $05 [$804F] ;} If [block BTS] & 80h = 0:
$94:804A AD FA 0A LDA $0AFA [$7E:0AFA] ; A = [Samus Y position] % 10h
$94:804D 80 06 BRA $06 [$8055]
$94:804F AD FA 0A LDA $0AFA [$7E:0AFA] ;\ Else ([block BTS] & 80h != 0):
$94:8052 49 0F 00 EOR #$000F ;} A = Fh - [Samus Y position] % 10h
$94:8055 29 0F 00 AND #$000F
$94:8058 18 CLC ;\
$94:8059 6D D6 0D ADC $0DD6 [$7E:0DD6] ;|
$94:805C AA TAX ;} A = [$892B + [$0DD6] + [A]] (slope left X offset)
$94:805D BD 2B 89 LDA $892B,x ;/
$94:8060 29 1F 00 AND #$001F
$94:8063 38 SEC ;\
$94:8064 ED D4 0D SBC $0DD4 [$7E:0DD4] ;} A -= (Samus left X offset) + 1
$94:8067 3A DEC A ;/
$94:8068 F0 02 BEQ $02 [$806C]
$94:806A 30 02 BMI $02 [$806E] ; If [A] < 0: return carry clear
$94:806C 38 SEC ;\
$94:806D 60 RTS ;} Return carry set
$94:806E 18 CLC
$94:806F 60 RTS
$94:8070 4C BE 82 JMP $82BE [$94:82BE]
; BRANCH_RIGHT
$94:8073 AD C4 0D LDA $0DC4 [$7E:0DC4] ;\
$94:8076 8D 04 42 STA $4204 ;|
$94:8079 E2 20 SEP #$20 ;|
$94:807B AD A5 07 LDA $07A5 [$7E:07A5] ;|
$94:807E 8D 06 42 STA $4206 ;|
$94:8081 C2 20 REP #$20 ;|
$94:8083 AD F6 0A LDA $0AF6 [$7E:0AF6] ;} If [current block index] % [room width in blocks] != [Samus X position] / 10h (Samus' centre isn't in block):
$94:8086 4A LSR A ;|
$94:8087 4A LSR A ;|
$94:8088 4A LSR A ;|
$94:8089 4A LSR A ;|
$94:808A CD 16 42 CMP $4216 ;|
$94:808D F0 02 BEQ $02 [$8091] ;/
$94:808F 18 CLC ;\
$94:8090 60 RTS ;} Return carry clear
$94:8091 A5 20 LDA $20 [$7E:0020] ;\
$94:8093 29 0F 00 AND #$000F ;} $0DD4 = [Samus right boundary] % 10h (Samus right X offset)
$94:8096 8D D4 0D STA $0DD4 [$7E:0DD4] ;/
$94:8099 BF 02 64 7F LDA $7F6402,x ;\
$94:809D 29 1F 00 AND #$001F ;|
$94:80A0 0A ASL A ;|
$94:80A1 0A ASL A ;} $0DD6 = ([block BTS] & 1Fh) * 10h (slope definition table base index)
$94:80A2 0A ASL A ;|
$94:80A3 0A ASL A ;|
$94:80A4 8D D6 0D STA $0DD6 [$7E:0DD6] ;/
$94:80A7 BF 01 64 7F LDA $7F6401,x ;\
$94:80AB 0A ASL A ;} If [block BTS] & 40h != 0: go to post grapple collision detection - horizontal - solid
$94:80AC 30 2F BMI $2F [$80DD] ;/
$94:80AE BF 01 64 7F LDA $7F6401,x ;\
$94:80B2 30 05 BMI $05 [$80B9] ;} If [block BTS] & 80h = 0:
$94:80B4 AD FA 0A LDA $0AFA [$7E:0AFA] ; A = [Samus Y position] % 10h
$94:80B7 80 06 BRA $06 [$80BF]
$94:80B9 AD FA 0A LDA $0AFA [$7E:0AFA] ;\ Else ([block BTS] & 80h != 0):
$94:80BC 49 0F 00 EOR #$000F ;} A = Fh - [Samus Y position] % 10h
$94:80BF 29 0F 00 AND #$000F
$94:80C2 18 CLC ;\
$94:80C3 6D D6 0D ADC $0DD6 [$7E:0DD6] ;|
$94:80C6 AA TAX ;} A = [$892B + [$0DD6] + [A]] (slope left X offset)
$94:80C7 BD 2B 89 LDA $892B,x ;/
$94:80CA 29 1F 00 AND #$001F
$94:80CD 38 SEC ;\
$94:80CE ED D4 0D SBC $0DD4 [$7E:0DD4] ;} A -= (Samus right X offset) + 1
$94:80D1 3A DEC A ;/
$94:80D2 F0 02 BEQ $02 [$80D6] ;\
$94:80D4 10 05 BPL $05 [$80DB] ;} If [A] > 0: return carry clear
$94:80D6 49 FF FF EOR #$FFFF ; A = -1 - [A]
$94:80D9 38 SEC ;\
$94:80DA 60 RTS ;} Return carry set
$94:80DB 18 CLC
$94:80DC 60 RTS
$94:80DD 4C BE 82 JMP $82BE [$94:82BE]
}
;;; $80E0: Post grapple collision detection - vertical - slope - non-square ;;;
{
;; Parameters:
;; X: Block index
;; $20: Samus bottom/top boundary
;; Returns:
;; Carry: Set if Samus collides with slope, clear otherwise
;; A: If carry set, Y depth into slope in pixels
$94:80E0 AD 02 0B LDA $0B02 [$7E:0B02] ;\
$94:80E3 4A LSR A ;} If collision direction is down:
$94:80E4 90 03 BCC $03 [$80E9] ;/
$94:80E6 4C 4F 81 JMP $814F [$94:814F] ; Go to BRANCH_DOWN
$94:80E9 AD C4 0D LDA $0DC4 [$7E:0DC4] ;\
$94:80EC 8D 04 42 STA $4204 ;|
$94:80EF E2 20 SEP #$20 ;|
$94:80F1 AD A5 07 LDA $07A5 [$7E:07A5] ;|
$94:80F4 8D 06 42 STA $4206 ;|
$94:80F7 C2 20 REP #$20 ;|
$94:80F9 AD F6 0A LDA $0AF6 [$7E:0AF6] ;} If [current block index] % [room width in blocks] != [Samus X position] / 10h:
$94:80FC 4A LSR A ;|
$94:80FD 4A LSR A ;|
$94:80FE 4A LSR A ;|
$94:80FF 4A LSR A ;|
$94:8100 CD 16 42 CMP $4216 ;|
$94:8103 F0 02 BEQ $02 [$8107] ;/
$94:8105 18 CLC ;\
$94:8106 60 RTS ;} Return carry clear
$94:8107 A5 20 LDA $20 [$7E:0020] ;\
$94:8109 29 0F 00 AND #$000F ;} $0DD4 = [Samus top boundary] % 10h (Samus top Y offset)
$94:810C 8D D4 0D STA $0DD4 [$7E:0DD4] ;/
$94:810F BF 02 64 7F LDA $7F6402,x ;\
$94:8113 29 1F 00 AND #$001F ;|
$94:8116 0A ASL A ;|
$94:8117 0A ASL A ;} $0DD6 = ([block BTS] & 1Fh) * 10h (slope definition table base index)
$94:8118 0A ASL A ;|
$94:8119 0A ASL A ;|
$94:811A 8D D6 0D STA $0DD6 [$7E:0DD6] ;/
$94:811D BF 01 64 7F LDA $7F6401,x ;\
$94:8121 10 29 BPL $29 [$814C] ;} If [block BTS] & 80h = 0: go to post grapple collision detection - vertical - solid
$94:8123 0A ASL A ;\
$94:8124 30 05 BMI $05 [$812B] ;} If [block BTS] & 40h = 0:
$94:8126 AD F6 0A LDA $0AF6 [$7E:0AF6] ; A = [Samus X position] % 10h
$94:8129 80 06 BRA $06 [$8131]
$94:812B AD F6 0A LDA $0AF6 [$7E:0AF6] ;\ Else ([block BTS] & 40h != 0):
$94:812E 49 0F 00 EOR #$000F ;} A = Fh - [Samus X position] % 10h
$94:8131 29 0F 00 AND #$000F
$94:8134 18 CLC ;\
$94:8135 6D D6 0D ADC $0DD6 [$7E:0DD6] ;|
$94:8138 AA TAX ;} A = [$8B2B + [$0DD6] + [A]] (slope top Y offset)
$94:8139 BD 2B 8B LDA $8B2B,x ;/
$94:813C 29 1F 00 AND #$001F
$94:813F 38 SEC ;\
$94:8140 ED D4 0D SBC $0DD4 [$7E:0DD4] ;} A -= (Samus top Y offset) + 1
$94:8143 3A DEC A ;/
$94:8144 F0 02 BEQ $02 [$8148]
$94:8146 30 02 BMI $02 [$814A] ; If [A] < 0: return carry clear
$94:8148 38 SEC ;\
$94:8149 60 RTS ;} Return carry set
$94:814A 18 CLC
$94:814B 60 RTS
$94:814C 4C DA 82 JMP $82DA [$94:82DA]
; BRANCH_DOWN
$94:814F AD C4 0D LDA $0DC4 [$7E:0DC4] ;\
$94:8152 8D 04 42 STA $4204 ;|
$94:8155 E2 20 SEP #$20 ;|
$94:8157 AD A5 07 LDA $07A5 [$7E:07A5] ;|
$94:815A 8D 06 42 STA $4206 ;|
$94:815D C2 20 REP #$20 ;|
$94:815F AD F6 0A LDA $0AF6 [$7E:0AF6] ;} If [current block index] % [room width in blocks] != [Samus X position] / 10h:
$94:8162 4A LSR A ;|
$94:8163 4A LSR A ;|
$94:8164 4A LSR A ;|
$94:8165 4A LSR A ;|
$94:8166 CD 16 42 CMP $4216 ;|
$94:8169 F0 02 BEQ $02 [$816D] ;/
$94:816B 18 CLC ;\
$94:816C 60 RTS ;} Return carry clear
$94:816D A5 20 LDA $20 [$7E:0020] ;\
$94:816F 29 0F 00 AND #$000F ;} $0DD4 = [Samus bottom boundary] % 10h (Samus bottom Y offset)
$94:8172 8D D4 0D STA $0DD4 [$7E:0DD4] ;/
$94:8175 BF 02 64 7F LDA $7F6402,x ;\
$94:8179 29 1F 00 AND #$001F ;|
$94:817C 0A ASL A ;|
$94:817D 0A ASL A ;} $0DD6 = ([block BTS] & 1Fh) * 10h (slope definition table base index)
$94:817E 0A ASL A ;|
$94:817F 0A ASL A ;|
$94:8180 8D D6 0D STA $0DD6 [$7E:0DD6] ;/
$94:8183 BF 01 64 7F LDA $7F6401,x ;\
$94:8187 30 2C BMI $2C [$81B5] ;} If [block BTS] & 80h != 0: go to post grapple collision detection - vertical - solid
$94:8189 0A ASL A ;\
$94:818A 30 05 BMI $05 [$8191] ;} If [block BTS] & 40h = 0:
$94:818C AD F6 0A LDA $0AF6 [$7E:0AF6] ; A = [Samus X position] % 10h
$94:818F 80 06 BRA $06 [$8197]
$94:8191 AD F6 0A LDA $0AF6 [$7E:0AF6] ;\ Else ([block BTS] & 40h != 0):
$94:8194 49 0F 00 EOR #$000F ;} A = Fh - [Samus X position] % 10h
$94:8197 29 0F 00 AND #$000F
$94:819A 18 CLC ;\
$94:819B 6D D6 0D ADC $0DD6 [$7E:0DD6] ;|
$94:819E AA TAX ;} A = [$8B2B + [$0DD6] + [A]] (slope top Y offset)
$94:819F BD 2B 8B LDA $8B2B,x ;/
$94:81A2 29 1F 00 AND #$001F
$94:81A5 38 SEC ;\
$94:81A6 ED D4 0D SBC $0DD4 [$7E:0DD4] ;} A -= (Samus bottom Y offset) + 1
$94:81A9 3A DEC A ;/
$94:81AA F0 02 BEQ $02 [$81AE] ;\
$94:81AC 10 05 BPL $05 [$81B3] ;} If [A] > 0: return carry clear
$94:81AE 49 FF FF EOR #$FFFF ; A = -1 - [A]
$94:81B1 38 SEC ;\
$94:81B2 60 RTS ;} Return carry set
$94:81B3 18 CLC
$94:81B4 60 RTS
$94:81B5 4C DA 82 JMP $82DA [$94:82DA]
}
;;; $81B8: Post grapple collision detection - horizontal - slope - square ;;;
{
;; Parameters:
;; X: Block index
;; $1A: Number of blocks left to check (0 if final (bottom) block)
;; $1C: Samus' Y block span
;; $20: Samus left/right boundary
;; Returns:
;; Carry: Set if Samus collides with solid slope, clear otherwise
;; A: If carry set, X depth into slope in pixels
$94:81B8 BF 02 64 7F LDA $7F6402,x ;\
$94:81BC 29 1F 00 AND #$001F ;|
$94:81BF 0A ASL A ;} $0DD4 = ([block BTS] & 1Fh) * 4 (solid slope definition table base index)
$94:81C0 0A ASL A ;|
$94:81C1 8D D4 0D STA $0DD4 [$7E:0DD4] ;/
$94:81C4 BF 01 64 7F LDA $7F6401,x ;\
$94:81C8 2A ROL A ;|
$94:81C9 2A ROL A ;|
$94:81CA 2A ROL A ;} $0DD6 = [block BTS] >> 6 & 3 (slope flip flags)
$94:81CB 29 03 00 AND #$0003 ;|
$94:81CE 8D D6 0D STA $0DD6 [$7E:0DD6] ;/
$94:81D1 A5 20 LDA $20 [$7E:0020] ;\
$94:81D3 29 08 00 AND #$0008 ;} A = [$20] & 8 (is Samus boundary in right half of block)
$94:81D6 4A LSR A ;\
$94:81D7 4A LSR A ;|
$94:81D8 4A LSR A ;} A = [$0DD6] ^ [A] >> 3 (toggle X flip flag if Samus is in right half of block)
$94:81D9 4D D6 0D EOR $0DD6 [$7E:0DD6] ;/
$94:81DC 6D D4 0D ADC $0DD4 [$7E:0DD4] ;\
$94:81DF AA TAX ;} X = [$0DD4] + [A] (solid slope definition table index)
$94:81E0 A5 1A LDA $1A [$7E:001A] ;\
$94:81E2 D0 14 BNE $14 [$81F8] ;} If [$1A] = 0 (bottom block check):
$94:81E4 AD FA 0A LDA $0AFA [$7E:0AFA] ;\
$94:81E7 18 CLC ;|
$94:81E8 6D 00 0B ADC $0B00 [$7E:0B00] ;|
$94:81EB 3A DEC A ;} If Samus bottom boundary is in bottom half: go to BRANCH_CHECK_BOTH_HALVES
$94:81EC 29 08 00 AND #$0008 ;|
$94:81EF D0 17 BNE $17 [$8208] ;/
$94:81F1 BD 53 8E LDA $8E53,x ;\
$94:81F4 30 23 BMI $23 [$8219] ;} If [$8E54 + [X]] & 80h != 0 (top half is solid): go to BRANCH_SOLID
$94:81F6 80 1F BRA $1F [$8217] ; Return carry clear
$94:81F8 C5 1C CMP $1C [$7E:001C] ;\
$94:81FA D0 0C BNE $0C [$8208] ;} If [$1A] = [$1C] (top block check):
$94:81FC AD FA 0A LDA $0AFA [$7E:0AFA] ;\
$94:81FF 38 SEC ;|
$94:8200 ED 00 0B SBC $0B00 [$7E:0B00] ;} If Samus top boundary is in bottom half: go to BRANCH_CHECK_BOTTOM_HALF
$94:8203 29 08 00 AND #$0008 ;|
$94:8206 D0 05 BNE $05 [$820D] ;/
; BRANCH_CHECK_BOTH_HALVES
$94:8208 BD 53 8E LDA $8E53,x ;\
$94:820B 30 0C BMI $0C [$8219] ;} If [$8E54 + [X]] & 80h != 0 (top half is solid): go to BRANCH_SOLID
; BRANCH_CHECK_BOTTOM_HALF
$94:820D 8A TXA ;\
$94:820E 49 02 00 EOR #$0002 ;|
$94:8211 AA TAX ;} If [$8E54 + ([X] ^ 2)] & 80h != 0 (bottom half is solid): go to BRANCH_SOLID
$94:8212 BD 53 8E LDA $8E53,x ;|
$94:8215 30 02 BMI $02 [$8219] ;/
$94:8217 18 CLC ;\
$94:8218 60 RTS ;} Return carry clear
; BRANCH_SOLID
$94:8219 AD 02 0B LDA $0B02 [$7E:0B02] ;\
$94:821C 4A LSR A ;} If collision direction is right:
$94:821D 90 07 BCC $07 [$8226] ;/
$94:821F A5 20 LDA $20 [$7E:0020] ;\
$94:8221 29 07 00 AND #$0007 ;} A = [$20] % 8
$94:8224 38 SEC ;\
$94:8225 60 RTS ;} Return carry set
$94:8226 A5 20 LDA $20 [$7E:0020] ;\
$94:8228 29 07 00 AND #$0007 ;} A = 7 - [$20] % 8
$94:822B 49 07 00 EOR #$0007 ;/
$94:822E 38 SEC ;\
$94:822F 60 RTS ;} Return carry set
}
;;; $8230: Post grapple collision detection - vertical - slope - square ;;;
{
;; Parameters:
;; X: Block index
;; $1A: Number of blocks left to check (0 if final (rightmost) block)
;; $1C: Samus' X block span
;; $20: Samus bottom/top boundary
;; Returns:
;; Carry: Set if Samus collides with solid slope, clear otherwise
;; A: If carry set, Y depth into slope in pixels
$94:8230 BF 02 64 7F LDA $7F6402,x ;\
$94:8234 29 1F 00 AND #$001F ;|
$94:8237 0A ASL A ;} $0DD4 = ([block BTS] & 1Fh) * 4 (solid slope definition table base index)
$94:8238 0A ASL A ;|
$94:8239 8D D4 0D STA $0DD4 [$7E:0DD4] ;/
$94:823C BF 01 64 7F LDA $7F6401,x ;\
$94:8240 2A ROL A ;|
$94:8241 2A ROL A ;|
$94:8242 2A ROL A ;} $0DD6 = [block BTS] >> 6 & 3 (slope flip flags)
$94:8243 29 03 00 AND #$0003 ;|
$94:8246 8D D6 0D STA $0DD6 [$7E:0DD6] ;/
$94:8249 A5 20 LDA $20 [$7E:0020] ;\
$94:824B 29 08 00 AND #$0008 ;} A = [$20] & 8 (is Samus boundary in lower half of block)
$94:824E 4A LSR A ;\
$94:824F 4A LSR A ;} A = [$0DD6] ^ [A] >> 2 (toggle Y flip flag if Samus is in lower half of block)
$94:8250 4D D6 0D EOR $0DD6 [$7E:0DD6] ;/
$94:8253 6D D4 0D ADC $0DD4 [$7E:0DD4] ;\
$94:8256 AA TAX ;} X = [$0DD4] + [A] (solid slope definition table index)
$94:8257 A5 1A LDA $1A [$7E:001A] ;\
$94:8259 D0 14 BNE $14 [$826F] ;} If [$1A] = 0 (rightmost block check):
$94:825B AD F6 0A LDA $0AF6 [$7E:0AF6] ;\
$94:825E 18 CLC ;|
$94:825F 6D FE 0A ADC $0AFE [$7E:0AFE] ;|
$94:8262 3A DEC A ;} If Samus right boundary is in right half: go to BRANCH_CHECK_BOTH_HALVES
$94:8263 29 08 00 AND #$0008 ;|
$94:8266 D0 17 BNE $17 [$827F] ;/
$94:8268 BD 53 8E LDA $8E53,x ;\
$94:826B 30 23 BMI $23 [$8290] ;} If [$8E54 + [X]] & 80h != 0 (left half is solid): go to BRANCH_SOLID
$94:826D 80 1F BRA $1F [$828E] ; Return carry clear
$94:826F C5 1C CMP $1C [$7E:001C] ;\
$94:8271 D0 0C BNE $0C [$827F] ;} If [$1A] = [$1C] (leftmost block check):
$94:8273 AD F6 0A LDA $0AF6 [$7E:0AF6] ;\
$94:8276 38 SEC ;|
$94:8277 ED FE 0A SBC $0AFE [$7E:0AFE] ;} If Samus left boundary is in right half: go to BRANCH_CHECK_RIGHT_HALF
$94:827A 29 08 00 AND #$0008 ;|
$94:827D D0 05 BNE $05 [$8284] ;/
; BRANCH_CHECK_BOTH_HALVES
$94:827F BD 53 8E LDA $8E53,x ;\
$94:8282 30 0C BMI $0C [$8290] ;} If [$8E54 + [X]] & 80h != 0 (left half is solid): go to BRANCH_SOLID
; BRANCH_CHECK_RIGHT_HALF
$94:8284 8A TXA ;\
$94:8285 49 01 00 EOR #$0001 ;|
$94:8288 AA TAX ;} If [$8E54 + ([X] ^ 1)] & 80h != 0 (right half is solid): go to BRANCH_SOLID
$94:8289 BD 53 8E LDA $8E53,x ;|
$94:828C 30 02 BMI $02 [$8290] ;/
$94:828E 18 CLC ;\
$94:828F 60 RTS ;} Return carry clear
; BRANCH_SOLID
$94:8290 AD 02 0B LDA $0B02 [$7E:0B02] ;\
$94:8293 4A LSR A ;} If collision direction is down:
$94:8294 90 07 BCC $07 [$829D] ;/
$94:8296 A5 20 LDA $20 [$7E:0020] ;\
$94:8298 29 07 00 AND #$0007 ;} A = [$20] % 8
$94:829B 38 SEC ;\
$94:829C 60 RTS ;} Return carry set
$94:829D A5 20 LDA $20 [$7E:0020] ;\
$94:829F 29 07 00 AND #$0007 ;} A = 7 - [$20] % 8
$94:82A2 49 07 00 EOR #$0007 ;/
$94:82A5 38 SEC ;\
$94:82A6 60 RTS ;} Return carry set
}
;;; $82A7: Clear carry ;;;
{
$94:82A7 18 CLC
$94:82A8 60 RTS
}
;;; $82A9: Post grapple collision detection - horizontal - slope ;;;
{
;; Parameters:
;; $1A: Number of blocks left to check (0 if final (bottom) block)
;; $1C: Samus' Y block span
;; $20: Samus left/right boundary
;; Returns:
;; Carry: Set if Samus collides with slope, clear otherwise
;; A: If carry set, X depth into slope in pixels
$94:82A9 AE C4 0D LDX $0DC4 [$7E:0DC4] ;\
$94:82AC BF 02 64 7F LDA $7F6402,x ;|
$94:82B0 29 1F 00 AND #$001F ;} If [block BTS] & 1Fh >= 5:
$94:82B3 C9 05 00 CMP #$0005 ;|
$94:82B6 90 03 BCC $03 [$82BB] ;/
$94:82B8 4C 00 80 JMP $8000 [$94:8000] ; Go to post grapple collision detection - horizontal - slope - non-square
$94:82BB 4C B8 81 JMP $81B8 [$94:81B8] ; Go to post grapple collision detection - horizontal - slope - square
}
;;; $82BE: Post grapple collision detection - horizontal - solid ;;;
{
;; Parameters:
;; $20: Samus left/right boundary
;; Returns:
;; Carry: Set (Samus collides with block)
;; A: X depth into block in pixels
$94:82BE A5 20 LDA $20 [$7E:0020]
$94:82C0 29 0F 00 AND #$000F
$94:82C3 38 SEC
$94:82C4 60 RTS
}
;;; $82C5: Post grapple collision detection - vertical - slope ;;;
{
;; Parameters:
;; $1A: Number of blocks left to check (0 if final (rightmost) block)
;; $1C: Samus' X block span
;; $20: Samus bottom/top boundary
;; Returns:
;; Carry: Set if Samus collides with slope, clear otherwise
;; A: If carry set, Y depth into slope in pixels
$94:82C5 AE C4 0D LDX $0DC4 [$7E:0DC4] ;\
$94:82C8 BF 02 64 7F LDA $7F6402,x ;|
$94:82CC 29 1F 00 AND #$001F ;} If [block BTS] & 1Fh >= 5:
$94:82CF C9 05 00 CMP #$0005 ;|
$94:82D2 90 03 BCC $03 [$82D7] ;/
$94:82D4 4C E0 80 JMP $80E0 [$94:80E0] ; Go to post grapple collision detection - vertical - slope - non-square
$94:82D7 4C 30 82 JMP $8230 [$94:8230] ; Go to post grapple collision detection - vertical - slope - square
}
;;; $82DA: Post grapple collision detection - vertical - solid ;;;
{
;; Parameters:
;; $20: Samus bottom/top boundary
;; Returns:
;; Carry: Set (Samus collides with block)
;; A: Y depth into block in pixels
$94:82DA A5 20 LDA $20 [$7E:0020]
$94:82DC 29 0F 00 AND #$000F
$94:82DF 38 SEC
$94:82E0 60 RTS
}
;;; $82E1: Post grapple collision detection - horizontal - jump table ;;;
{
$94:82E1 dw 82A7, ; 0: Air
82A9, ; *1: Slope
82A7, ; 2: Spike air
82A7, ; 3: Special air
82A7, ; 4: Shootable air
82A7, ; 5: Horizontal extension
82A7, ; 6: Unused air
82A7, ; 7: Bombable air
82BE, ; 8: Solid block
82BE, ; 9: Door block
82BE, ; Ah: Spike block
82BE, ; Bh: Special block
82BE, ; Ch: Shootable block
82BE, ; Dh: Vertical extension
82BE, ; Eh: Grapple block
82BE ; Fh: Bombable block
}
;;; $8301: Post grapple collision detection - vertical - jump table ;;;
{
$94:8301 dw 82A7, ; 0: Air
82C5, ; *1: Slope
82A7, ; 2: Spike air
82A7, ; 3: Special air
82A7, ; 4: Shootable air
82A7, ; 5: Horizontal extension
82A7, ; 6: Unused air
82A7, ; 7: Bombable air
82DA, ; 8: Solid block
82DA, ; 9: Door block
82DA, ; Ah: Spike block
82DA, ; Bh: Special block
82DA, ; Ch: Shootable block
82DA, ; Dh: Vertical extension
82DA, ; Eh: Grapple block
82DA ; Fh: Bombable block
}
;;; $8321: Post grapple collision detection - horizontal - single block ;;;
{
;; Parameters:
;; X: Block index
;; $1A: Number of blocks left to check (0 if final (bottom) block)
;; $1C: Samus Y block span
;; $20: Samus left/right boundary
;; Returns:
;; Carry: Set if Samus collides with block, clear otherwise
;; A: If carry set, X depth into block in pixels
$94:8321 DA PHX
$94:8322 8A TXA ;\
$94:8323 4A LSR A ;} Current block index = [X] / 2
$94:8324 8D C4 0D STA $0DC4 [$7E:0DC4] ;/
$94:8327 BF 02 00 7F LDA $7F0002,x[$7F:0262];\
$94:832B 29 00 F0 AND #$F000 ;|
$94:832E EB XBA ;|
$94:832F 4A LSR A ;|
$94:8330 4A LSR A ;} Execute [$82E1 + (block type) * 2]
$94:8331 4A LSR A ;|
$94:8332 AA TAX ;|
$94:8333 FC E1 82 JSR ($82E1,x)[$94:82A7];/
$94:8336 FA PLX
$94:8337 60 RTS
}
;;; $8338: Post grapple collision detection - vertical - single block ;;;
{
;; Parameters:
;; X: Block index
;; $1A: Number of blocks left to check (0 if final (rightmost) block)
;; $1C: Samus' X block span
;; $20: Samus bottom/top boundary
;; Returns:
;; Carry: Set if Samus collides with block, clear otherwise
;; A: If carry set, Y depth into block in pixels
$94:8338 DA PHX
$94:8339 8A TXA ;\
$94:833A 4A LSR A ;} Current block index = [X] / 2
$94:833B 8D C4 0D STA $0DC4 [$7E:0DC4] ;/
$94:833E BF 02 00 7F LDA $7F0002,x[$7F:0320];\
$94:8342 29 00 F0 AND #$F000 ;|
$94:8345 EB XBA ;|
$94:8346 4A LSR A ;|
$94:8347 4A LSR A ;} Execute [$8301 + (block type) * 2]
$94:8348 4A LSR A ;|
$94:8349 AA TAX ;|
$94:834A FC 01 83 JSR ($8301,x)[$94:82A7];/
$94:834D FA PLX
$94:834E 60 RTS
}
;;; $834F: Post grapple collision detection - rightwards ;;;
{
$94:834F 8B PHB
$94:8350 4B PHK ;\
$94:8351 AB PLB ;} DB = $94
$94:8352 A9 01 00 LDA #$0001 ;\
$94:8355 8D 02 0B STA $0B02 [$7E:0B02] ;} Collision direction = right
$94:8358 9C 04 0E STZ $0E04 [$7E:0E04] ; $0E04 = 0 (distance to eject Samus left)
$94:835B 20 95 94 JSR $9495 [$94:9495] ; $1A = $1C = Samus Y block span
$94:835E AD FA 0A LDA $0AFA [$7E:0AFA] ;\
$94:8361 38 SEC ;|
$94:8362 ED 00 0B SBC $0B00 [$7E:0B00] ;|
$94:8365 4A LSR A ;|
$94:8366 4A LSR A ;|
$94:8367 4A LSR A ;} Calculate block index of the row of Samus top boundary
$94:8368 4A LSR A ;|
$94:8369 E2 20 SEP #$20 ;|
$94:836B 8D 02 42 STA $4202 ;|
$94:836E AD A5 07 LDA $07A5 [$7E:07A5] ;|
$94:8371 8D 03 42 STA $4203 ;/
$94:8374 C2 20 REP #$20
$94:8376 AD F8 0A LDA $0AF8 [$7E:0AF8] ;\
$94:8379 85 16 STA $16 [$7E:0016] ;|
$94:837B AD F6 0A LDA $0AF6 [$7E:0AF6] ;} $18.$16 = [Samus X position] <-- never read
$94:837E 85 18 STA $18 [$7E:0018] ;/
$94:8380 18 CLC ;\
$94:8381 6D FE 0A ADC $0AFE [$7E:0AFE] ;|
$94:8384 3A DEC A ;} $20 = (Samus right boundary)
$94:8385 85 20 STA $20 [$7E:0020] ;/
$94:8387 4A LSR A ;\
$94:8388 4A LSR A ;|
$94:8389 4A LSR A ;|
$94:838A 4A LSR A ;} Current block index = (Samus top-right corner)
$94:838B 18 CLC ;|
$94:838C 6D 16 42 ADC $4216 ;|
$94:838F 8D C4 0D STA $0DC4 [$7E:0DC4] ;/
$94:8392 0A ASL A ;\
$94:8393 AA TAX ;} X = [current block index] * 2
; LOOP
$94:8394 20 21 83 JSR $8321 [$94:8321] ; Post grapple collision detection - horizontal
$94:8397 90 09 BCC $09 [$83A2] ; If collision:
$94:8399 1A INC A ;\
$94:839A CD 04 0E CMP $0E04 [$7E:0E04] ;|
$94:839D 90 03 BCC $03 [$83A2] ;} $0E04 = max([$0E04], [A] + 1) (distance to eject Samus left)
$94:839F 8D 04 0E STA $0E04 [$7E:0E04] ;/
$94:83A2 8A TXA ;\
$94:83A3 18 CLC ;|
$94:83A4 6D A5 07 ADC $07A5 [$7E:07A5] ;} X += [room width in blocks] * 2 (next row)
$94:83A7 6D A5 07 ADC $07A5 [$7E:07A5] ;|
$94:83AA AA TAX ;/
$94:83AB C6 1A DEC $1A [$7E:001A] ; Decrement $1A
$94:83AD 10 E5 BPL $E5 [$8394] ; If [$1A] >= 0: go to LOOP
$94:83AF AB PLB
$94:83B0 60 RTS
}
;;; $83B1: Post grapple collision detection - leftwards ;;;
{
$94:83B1 8B PHB
$94:83B2 4B PHK ;\
$94:83B3 AB PLB ;} DB = $94
$94:83B4 9C 02 0B STZ $0B02 [$7E:0B02] ; Collision direction = left
$94:83B7 9C 06 0E STZ $0E06 [$7E:0E06] ; $0E06 = 0 (distance to eject Samus right)
$94:83BA 20 95 94 JSR $9495 [$94:9495] ; $1A = $1C = Samus Y block span
$94:83BD AD FA 0A LDA $0AFA [$7E:0AFA] ;\
$94:83C0 38 SEC ;|
$94:83C1 ED 00 0B SBC $0B00 [$7E:0B00] ;|
$94:83C4 4A LSR A ;|
$94:83C5 4A LSR A ;|
$94:83C6 4A LSR A ;} Calculate block index of the row of Samus top boundary
$94:83C7 4A LSR A ;|
$94:83C8 E2 20 SEP #$20 ;|
$94:83CA 8D 02 42 STA $4202 ;|
$94:83CD AD A5 07 LDA $07A5 [$7E:07A5] ;|
$94:83D0 8D 03 42 STA $4203 ;/
$94:83D3 C2 20 REP #$20
$94:83D5 AD F8 0A LDA $0AF8 [$7E:0AF8] ;\
$94:83D8 85 16 STA $16 [$7E:0016] ;|
$94:83DA AD F6 0A LDA $0AF6 [$7E:0AF6] ;} $18.$16 = [Samus X position] <-- never read
$94:83DD 85 18 STA $18 [$7E:0018] ;/
$94:83DF 38 SEC ;\
$94:83E0 ED FE 0A SBC $0AFE [$7E:0AFE] ;} $20 = (Samus left boundary)
$94:83E3 85 20 STA $20 [$7E:0020] ;/
$94:83E5 4A LSR A ;\
$94:83E6 4A LSR A ;|
$94:83E7 4A LSR A ;|
$94:83E8 4A LSR A ;} Current block index = Samus top-left corner
$94:83E9 18 CLC ;|
$94:83EA 6D 16 42 ADC $4216 ;|
$94:83ED 8D C4 0D STA $0DC4 [$7E:0DC4] ;/
$94:83F0 0A ASL A ;\
$94:83F1 AA TAX ;} X = [current block index] * 2
; LOOP
$94:83F2 20 21 83 JSR $8321 [$94:8321] ; Post grapple collision detection - horizontal
$94:83F5 90 09 BCC $09 [$8400] ; If collision:
$94:83F7 1A INC A ;\
$94:83F8 CD 06 0E CMP $0E06 [$7E:0E06] ;|
$94:83FB 90 03 BCC $03 [$8400] ;} $0E06 = max([$0E06], [A] + 1) (distance to eject Samus right)
$94:83FD 8D 06 0E STA $0E06 [$7E:0E06] ;/
$94:8400 8A TXA ;\
$94:8401 18 CLC ;|
$94:8402 6D A5 07 ADC $07A5 [$7E:07A5] ;} X += [room width in blocks] * 2 (next row)
$94:8405 6D A5 07 ADC $07A5 [$7E:07A5] ;|
$94:8408 AA TAX ;/
$94:8409 C6 1A DEC $1A [$7E:001A] ; Decrement $1A
$94:840B 10 E5 BPL $E5 [$83F2] ; If [$1A] >= 0: go to LOOP
$94:840D AB PLB
$94:840E 60 RTS
}
;;; $840F: Post grapple collision detection - downwards ;;;
{
$94:840F 8B PHB
$94:8410 4B PHK ;\
$94:8411 AB PLB ;} DB = $94
$94:8412 A9 03 00 LDA #$0003 ;\
$94:8415 8D 02 0B STA $0B02 [$7E:0B02] ;} Collision direction = down
$94:8418 9C 08 0E STZ $0E08 [$7E:0E08] ; $0E08 = 0 (distance to eject Samus up)
$94:841B 20 B5 94 JSR $94B5 [$94:94B5] ; $1A = $1C = Samus X block span
$94:841E AD FC 0A LDA $0AFC [$7E:0AFC] ;\
$94:8421 85 16 STA $16 [$7E:0016] ;|
$94:8423 AD FA 0A LDA $0AFA [$7E:0AFA] ;} $18.$16 = [Samus Y position] <-- never read
$94:8426 85 18 STA $18 [$7E:0018] ;/
$94:8428 18 CLC ;\
$94:8429 6D 00 0B ADC $0B00 [$7E:0B00] ;|
$94:842C 3A DEC A ;} $20 = (Samus bottom boundary)
$94:842D 85 20 STA $20 [$7E:0020] ;/
$94:842F 4A LSR A ;\
$94:8430 4A LSR A ;|
$94:8431 4A LSR A ;|
$94:8432 4A LSR A ;|
$94:8433 E2 20 SEP #$20 ;|
$94:8435 8D 02 42 STA $4202 ;|
$94:8438 AD A5 07 LDA $07A5 [$7E:07A5] ;} Calculate Samus left boundary column block index
$94:843B 8D 03 42 STA $4203 ;|
$94:843E C2 20 REP #$20 ;|
$94:8440 AD F6 0A LDA $0AF6 [$7E:0AF6] ;|
$94:8443 38 SEC ;|
$94:8444 ED FE 0A SBC $0AFE [$7E:0AFE] ;/
$94:8447 4A LSR A ;\
$94:8448 4A LSR A ;|
$94:8449 4A LSR A ;|
$94:844A 4A LSR A ;} Current block index = (Samus bottom-left corner)
$94:844B 18 CLC ;|
$94:844C 6D 16 42 ADC $4216 ;|
$94:844F 8D C4 0D STA $0DC4 [$7E:0DC4] ;/
$94:8452 0A ASL A ;\
$94:8453 AA TAX ;} X = [current block index] * 2
; LOOP
$94:8454 20 38 83 JSR $8338 [$94:8338] ; Post grapple collision detection - vertical
$94:8457 90 09 BCC $09 [$8462] ; If collision:
$94:8459 1A INC A ;\
$94:845A CD 08 0E CMP $0E08 [$7E:0E08] ;|
$94:845D 90 03 BCC $03 [$8462] ;} $0E08 = max([$0E08], [A] + 1) (distance to eject Samus up)
$94:845F 8D 08 0E STA $0E08 [$7E:0E08] ;/
$94:8462 E8 INX ;\
$94:8463 E8 INX ;} X += 2 (next block)
$94:8464 C6 1A DEC $1A [$7E:001A] ; Decrement $1A
$94:8466 10 EC BPL $EC [$8454] ; If [$1A] >= 0: go to LOOP
$94:8468 AB PLB
$94:8469 60 RTS
}
;;; $846A: Post grapple collision detection - upwards ;;;
{
$94:846A 8B PHB
$94:846B 4B PHK ;\
$94:846C AB PLB ;} DB = $94
$94:846D A9 02 00 LDA #$0002 ;\
$94:8470 8D 02 0B STA $0B02 [$7E:0B02] ;} Collision direction = up
$94:8473 9C 0A 0E STZ $0E0A [$7E:0E0A] ; $0E0A = 0 (distance to eject Samus down)
$94:8476 20 B5 94 JSR $94B5 [$94:94B5] ; $1A = $1C = Samus X block span
$94:8479 AD FC 0A LDA $0AFC [$7E:0AFC] ;\
$94:847C 85 16 STA $16 [$7E:0016] ;|
$94:847E AD FA 0A LDA $0AFA [$7E:0AFA] ;} $18.$16 = [Samus Y position] <-- never read
$94:8481 85 18 STA $18 [$7E:0018] ;/
$94:8483 38 SEC ;\
$94:8484 ED 00 0B SBC $0B00 [$7E:0B00] ;} $20 = (Samus top boundary)
$94:8487 85 20 STA $20 [$7E:0020] ;/
$94:8489 4A LSR A ;\
$94:848A 4A LSR A ;|
$94:848B 4A LSR A ;|
$94:848C 4A LSR A ;|
$94:848D E2 20 SEP #$20 ;|
$94:848F 8D 02 42 STA $4202 ;|
$94:8492 AD A5 07 LDA $07A5 [$7E:07A5] ;} Calculate Samus left boundary column block index
$94:8495 8D 03 42 STA $4203 ;|
$94:8498 C2 20 REP #$20 ;|
$94:849A AD F6 0A LDA $0AF6 [$7E:0AF6] ;|
$94:849D 38 SEC ;|
$94:849E ED FE 0A SBC $0AFE [$7E:0AFE] ;/
$94:84A1 4A LSR A ;\
$94:84A2 4A LSR A ;|
$94:84A3 4A LSR A ;|
$94:84A4 4A LSR A ;} Current block index = (Samus top-left corner)
$94:84A5 18 CLC ;|
$94:84A6 6D 16 42 ADC $4216 ;|
$94:84A9 8D C4 0D STA $0DC4 [$7E:0DC4] ;/
$94:84AC 0A ASL A ;\
$94:84AD AA TAX ;} X = [current block index] * 2
; LOOP
$94:84AE 20 38 83 JSR $8338 [$94:8338] ; Post grapple collision detection - vertical
$94:84B1 90 09 BCC $09 [$84BC] ; If collision:
$94:84B3 1A INC A ;\
$94:84B4 CD 0A 0E CMP $0E0A [$7E:0E0A] ;|
$94:84B7 90 03 BCC $03 [$84BC] ;} $0E0A = max([$0E0A], [A] + 1) (distance to eject Samus down)
$94:84B9 8D 0A 0E STA $0E0A [$7E:0E0A] ;/
$94:84BC E8 INX ;\
$94:84BD E8 INX ;} X += 2 (next block)
$94:84BE C6 1A DEC $1A [$7E:001A] ; Decrement $1A
$94:84C0 10 EC BPL $EC [$84AE] ; If [$1A] >= 0: go to LOOP
$94:84C2 AB PLB
$94:84C3 60 RTS
}
;;; $84C4: Post grapple collision detection - horizontal ;;;
{
; Called by $90:EF25 (post grapple collision detection)
; This routine is used to calculate $0E04/06 (distance to eject Samus left/right), which is never read,
; making this routine and all its subroutines entirely pointless
$94:84C4 08 PHP
$94:84C5 20 4F 83 JSR $834F [$94:834F] ; Post grapple collision handling - rightwards
$94:84C8 20 B1 83 JSR $83B1 [$94:83B1] ; Post grapple collision handling - leftwards
$94:84CB 28 PLP
$94:84CC 6B RTL
}
;;; $84CD: Post grapple collision detection - vertical ;;;
{
; Called by $90:EF25 (post grapple collision detection), sometimes twice (if Samus was ejected up and her hitbox is >= 10h pixels tall)
$94:84CD 08 PHP
$94:84CE 20 0F 84 JSR $840F [$94:840F] ; Post grapple collision handling - downwards
$94:84D1 20 6A 84 JSR $846A [$94:846A] ; Post grapple collision handling - upwards
$94:84D4 28 PLP
$94:84D5 6B RTL
}
}
;;; $84D6..97BE: Samus block collision detection ;;;
{
;;; $84D6: Samus block collision reaction - horizontal - slope - non-square ;;;
{
;; Parameters:
;; $12.$14: Distance to check for collision
;; Returns:
;; Carry: Clear (no collision)
;; $12.$14: Adjusted distance to move Samus
$94:84D6 AD 77 1E LDA $1E77 [$7E:1E77] ;\
$94:84D9 89 80 00 BIT #$0080 ;} If [current slope BTS] & 80h = 0 (not Y flipped):
$94:84DC D0 08 BNE $08 [$84E6] ;/
$94:84DE AD 2C 0B LDA $0B2C [$7E:0B2C] ;\
$94:84E1 0D 2E 0B ORA $0B2E [$7E:0B2E] ;} If [Samus Y speed] = 0.0: go to BRANCH_SAMUS_ON_SLOPE_SURFACE
$94:84E4 F0 02 BEQ $02 [$84E8] ;/
$94:84E6 18 CLC ;\
$94:84E7 60 RTS ;} Return carry clear
; BRANCH_SAMUS_ON_SLOPE_SURFACE
$94:84E8 AD 77 1E LDA $1E77 [$7E:1E77] ;\
$94:84EB 29 1F 00 AND #$001F ;|
$94:84EE 0A ASL A ;} X = ([current slope BTS] & 1Fh) * 4
$94:84EF 0A ASL A ;|
$94:84F0 AA TAX ;/
$94:84F1 A5 12 LDA $12 [$7E:0012] ;\
$94:84F3 10 51 BPL $51 [$8546] ;} If [$12] >= 0: go to BRANCH_RIGHT
$94:84F5 AD 48 0B LDA $0B48 [$7E:0B48] ;\
$94:84F8 0D 46 0B ORA $0B46 [$7E:0B46] ;|
$94:84FB F0 1C BEQ $1C [$8519] ;|
$94:84FD AD 77 1E LDA $1E77 [$7E:1E77] ;|
$94:8500 89 40 00 BIT #$0040 ;|
$94:8503 D0 0B BNE $0B [$8510] ;|
$94:8505 AD 48 0B LDA $0B48 [$7E:0B48] ;|
$94:8508 18 CLC ;|
$94:8509 7D 86 85 ADC $8586,x[$94:85D6] ;} >_<;
$94:850C 90 0B BCC $0B [$8519] ;|
$94:850E 80 09 BRA $09 [$8519] ;|
;|
$94:8510 AD 48 0B LDA $0B48 [$7E:0B48] ;|
$94:8513 38 SEC ;|
$94:8514 FD 86 85 SBC $8586,x[$94:85D6] ;|
$94:8517 B0 00 BCS $00 [$8519] ;/
$94:8519 E2 20 SEP #$20 ;\
$94:851B A5 12 LDA $12 [$7E:0012] ;|
$94:851D EB XBA ;|
$94:851E A5 15 LDA $15 [$7E:0015] ;|
$94:8520 C2 20 REP #$20 ;|
$94:8522 49 FF FF EOR #$FFFF ;|
$94:8525 1A INC A ;|
$94:8526 BC 88 85 LDY $8588,x[$94:85D8] ;|
$94:8529 22 D6 82 80 JSL $8082D6[$80:82D6] ;|
$94:852D AD F1 05 LDA $05F1 [$7E:05F1] ;} $12.$14 = [$12].[$14] * [$8588 + [X]] / 100h
$94:8530 49 FF FF EOR #$FFFF ;|
$94:8533 18 CLC ;|
$94:8534 69 01 00 ADC #$0001 ;|
$94:8537 85 14 STA $14 [$7E:0014] ;|
$94:8539 AD F3 05 LDA $05F3 [$7E:05F3] ;|
$94:853C 49 FF FF EOR #$FFFF ;|
$94:853F 69 00 00 ADC #$0000 ;|
$94:8542 85 12 STA $12 [$7E:0012] ;/
$94:8544 18 CLC ;\
$94:8545 60 RTS ;} Return carry clear
; BRANCH_RIGHT
$94:8546 AD 48 0B LDA $0B48 [$7E:0B48] ;\
$94:8549 0D 46 0B ORA $0B46 [$7E:0B46] ;|
$94:854C F0 1C BEQ $1C [$856A] ;|
$94:854E AD 77 1E LDA $1E77 [$7E:1E77] ;|
$94:8551 89 40 00 BIT #$0040 ;|
$94:8554 F0 0B BEQ $0B [$8561] ;|
$94:8556 AD 48 0B LDA $0B48 [$7E:0B48] ;|
$94:8559 18 CLC ;|
$94:855A 7D 86 85 ADC $8586,x[$94:85D6] ;} >_<;
$94:855D 90 0B BCC $0B [$856A] ;|
$94:855F 80 09 BRA $09 [$856A] ;|
;|
$94:8561 AD 48 0B LDA $0B48 [$7E:0B48] ;|
$94:8564 38 SEC ;|
$94:8565 FD 86 85 SBC $8586,x[$94:85D6] ;|
$94:8568 B0 00 BCS $00 [$856A] ;/
$94:856A E2 20 SEP #$20 ;\
$94:856C A5 12 LDA $12 [$7E:0012] ;|
$94:856E EB XBA ;|
$94:856F A5 15 LDA $15 [$7E:0015] ;|
$94:8571 C2 20 REP #$20 ;|
$94:8573 BC 88 85 LDY $8588,x[$94:85D8] ;} $12.$14 = [$12].[$14] * [$8588 + [X]] / 100h
$94:8576 22 D6 82 80 JSL $8082D6[$80:82D6] ;|
$94:857A AD F1 05 LDA $05F1 [$7E:05F1] ;|
$94:857D 85 14 STA $14 [$7E:0014] ;|
$94:857F AD F3 05 LDA $05F3 [$7E:05F3] ;|
$94:8582 85 12 STA $12 [$7E:0012] ;/
$94:8584 18 CLC ;\
$94:8585 60 RTS ;} Return carry clear
; ________ Unused. Seem to be speed modifiers, added to or subtracted from Samus X base subspeed when moving down or up the slope respectively
; | ___ Adjusted distance multiplier * 100h
; | |
$94:8586 dw 0000,0100,
0000,0100,
0000,0100,
0000,0100,
0000,0100,
0000,0100, ; 5: Unused. Half height isosceles triangle
0000,0100, ; 6: Unused. Isosceles triangle
0000,0100, ; 7: Half height rectangle
0000,0100, ; 8: Unused. Rectangle
0000,0100, ; 9: Unused. Rectangle
0000,0100, ; Ah: Unused. Rectangle
0000,0100, ; Bh: Unused. Rectangle
0000,0100, ; Ch: Unused. Rectangle
0000,0100, ; Dh: Unused. Rectangle
1000,00B0, ; Eh: Unused. Very bumpy triangle
1000,00B0, ; Fh: Bumpy triangle
0000,0100, ; 10h: Unused
0000,0100, ; 11h: Unused
1000,00C0, ; 12h: Triangle
0000,0100, ; 13h: Rectangle
1000,00C0, ; 14h: Quarter triangle
1000,00C0, ; 15h: Three quarter triangle
0800,00D8, ; 16h: Lower half-height triangle
0800,00D8, ; 17h: Upper half-height triangle
0600,00F0, ; 18h: Unused. Lower third-height triangle
0600,00F0, ; 19h: Unused. Middle third-height triangle
0600,00F0, ; 1Ah: Unused. Upper third-height triangle
4000,0080, ; 1Bh: Upper half-width triangle
4000,0080, ; 1Ch: Lower half-width triangle
6000,0050, ; 1Dh: Unused. Upper third-width triangle
6000,0050, ; 1Eh: Unused. Middle third-width triangle
6000,0050 ; 1Fh: Unused. Lower third-width triangle
}
;;; $8606: Unused ;;;
{
;; Parameters:
;; X: Block index
;; $12: Distance to check for collision
;; $18: Target X position
;; Returns:
;; Carry: Set if Samus collides with solid slope, clear otherwise
;; $12.$14: Adjusted distance to move Samus or distance to collision
; This resembles $8000 adapted for block collision, or $86FE adapted for horizontal collision
; I guess this was written before it was decided that non-square slopes shouldn't have solid horizontal collision
; Looking at $86FE, I assume there's supposed to be a collision direction check here to branch to BRANCH_RIGHT
$94:8606 AD C4 0D LDA $0DC4 [$7E:0DC4] ;\
$94:8609 8D 04 42 STA $4204 ;|
$94:860C E2 20 SEP #$20 ;|