Release 2026-11-04-r2 · SHA256 fd932214dca5f2f1ba772b71f3c5063bd2e0467b6b6e528261b122d1c3187dee · Click a line number for a direct link.
1 .ifndef WITH_MANUAL_KEEPER_PASS2 .equ WITH_MANUAL_KEEPER_PASS,13 .endif4| B changes to another eligible skater on press; Y remains explicit goalie selection.5| Input D1=new presses, D3=held buttons, D4=pad offset 0/2, A3=old object.6 .equ Q,0xFFFFF048 | words at +pad: pending switch countdown (30 calls)7 .equ QOBJ,0xFFFFF04C | object that requested the switch8 .equ HELD,0xFFFFF050 | consume B until physical release after a successful switch9 .equ MAGIC,0xFFFFF05410 .text11 .globl _start12_start:13 bra.w early14 bra.w legacy15eligible:16 tst.w 0xFFFFD046 | native multitap behavior retained17 bne.s no18 cmpi.w #2,%d419 bhi.s no20 btst #0,0xFFFFC2FA | shootout21 bne.s no22 tst.w 0xFFFFD412 | penalty-shot state23 bne.s no24 btst #2,0xFFFFC2F2 | whistle/faceoff state25 bne.s no26 btst #3,0x62(%a3) | only a human-controlled object27 beq.s no28 btst #0,0x63(%a3) | fighting29 bne.s no30 moveq #0,%d031 rts32no: moveq #-1,%d033 rts34early:35 movem.l %d0-%d7/%a0-%a6,-(%sp)36 cmpi.w #0x5357,MAGIC37 beq.s initialized38 move.w #0x5357,MAGIC39 clr.l Q40 clr.l HELD41initialized:42 bsr.s eligible43 tst.w %d044 bne.w reset_original45 lea 0xFFFFF0E0,%a0 | explicit Y wins over B and clears an old switch latch46 tst.b (%a0,%d4.w)47 bne.w reset_original48 jsr 0x2FDC0C | possession can change while an earlier switch consumed B49 tst.w %d050 beq.s check_consumed51 .if WITH_IMMEDIATE_B52 cmpi.w #2,%d053 beq.w fresh_switch54 .endif55 lea Q,%a056 clr.w (%a0,%d4.w)57 move.w #1,8(%a0,%d4.w) | consume this press/hold/release; keep the requesting skater58 bra.w consume59check_consumed:60 lea HELD,%a061 tst.w (%a0,%d4.w)62 beq.s ordinary_switch63 btst #4,%d364 bne.w consume65 clr.w (%a0,%d4.w)66 bra.w consume67 .if WITH_IMMEDIATE_B68fresh_switch:69 move.w 0x52(%a3),%d070 cmp.w 0xFFFFB7AA,%d071 .if WITH_MANUAL_KEEPER_PASS72 beq.w reset_original | owned manual keeper B is a native pass, like an owned skater73 .else74 bne.s fresh_without_puck75 tst.w 0x34(%a3)76 bne.w reset_original77 .endif78fresh_without_puck:79 lea Q,%a280 move.w #1,(%a2,%d4.w)81 move.w %d0,4(%a2,%d4.w)82 bra.w choose_nearest83 .endif84ordinary_switch:85 jsr 0x2E1008 | jdc r22: a pass from your own goalie on its way (onetimer.s +8,86 beq.w consume | clears Q): B does not switch skaters (spammed B jumped the cursor)87 move.w 0x52(%a3),%d088 cmp.w 0xFFFFB7AA,%d089 beq.w reset_original | current puck carrier: native passing90 lea Q,%a291 btst #4,%d192 beq.s pending93 move.w #30,(%a2,%d4.w)94 move.w %d0,4(%a2,%d4.w)95pending:96 tst.w (%a2,%d4.w)97 beq.w original98 cmp.w 4(%a2,%d4.w),%d099 bne.w reset_original | automatic selection already changed the controlled object100 subq.w #1,(%a2,%d4.w)101 btst #3,0x63(%a3) | finish an in-progress pass before assigning another player102 bne.w original103choose_nearest:104 .if WITH_IMMEDIATE_B105 move.w 0xFFFFB74A,%d2106 move.w 0xFFFFB75E,%d3107 .else108 move.w 0xFFFFB772,%d2109 asr.w #8,%d2110 add.w 0xFFFFB74A,%d2111 move.w 0xFFFFB774,%d3112 asr.w #8,%d3113 add.w 0xFFFFB75E,%d3114 .endif115 lea 0xFFFFB04A,%a0116 lea 0xFFFFC328,%a1117 cmpi.w #1,(%a1,%d4.w)118 beq.s team_ready119 cmpi.w #2,(%a1,%d4.w)120 bne.w reset_original121 adda.w #0x300,%a0122team_ready:123 moveq #-1,%d5 | best object124 moveq #-1,%d6 | best squared distance125 moveq #5,%d7126candidate:127 tst.w 0x34(%a0)128 ble.s next | goalie/injured/unavailable slot129 move.w 0x52(%a0),%d0130 cmp.w 4(%a2,%d4.w),%d0131 beq.s next | actually change player, rather than selecting the same one132 btst #2,0x63(%a0)133 bne.s next134 btst #3,0x62(%a0)135 bne.s next | never take the other human's player136 btst #5,0x62(%a0)137 bne.s next | unavailable action/knockdown138 move.w %d2,%d0139 sub.w (%a0),%d0140 muls.w %d0,%d0141 move.w %d3,%d1142 sub.w 0x14(%a0),%d1143 muls.w %d1,%d1144 add.l %d1,%d0145 cmp.l %d6,%d0146 bhi.s next147 move.l %d0,%d6148 move.w 0x52(%a0),%d5149next:150 adda.w #0x80,%a0151 dbra %d7,candidate152 tst.w %d5153 .if WITH_IMMEDIATE_B154 bmi.w original155 .else156 bmi.s original157 .endif158 .if WITH_IMMEDIATE_B159 move.w %sr,-(%sp)160 ori.w #0x700,%sr161 move.b 0x63(%a3),-(%sp)162 bclr #3,0x63(%a3) | Native assignment otherwise refuses the released pass animation163 .endif164 move.w %d5,%d0165 tst.w %d4166 bne.s assign_p2167 jsr 0xC0BC168 bra.s assigned169assign_p2:170 jsr 0xC0DA171assigned:172 .if WITH_IMMEDIATE_B173 move.b (%sp)+,0x63(%a3) | preserve the actual in-flight pass/animation state174 move.w (%sp)+,%sr175 | A brief B tap must also publish the outlet for the newly selected skater.176 | Use the original physical press, even if the hold ends before its next tick.177 move.l 4(%sp),%d1178 move.l 12(%sp),%d3179 bclr #4,%d1180 ori.w #16,%d3181 move.l %a3,-(%sp)182 move.w %d5,%d0183 lsl.w #7,%d0184 lea 0xFFFFB04A,%a3185 adda.w %d0,%a3186 jsr 0x2FDC0C187 movea.l (%sp)+,%a3188 .endif189 lea Q,%a2190 clr.w (%a2,%d4.w)191 move.w #1,8(%a2,%d4.w)192 movem.l (%sp)+,%d0-%d7/%a0-%a6193 rts | the old object's input handler ends after selection194consume:195 movem.l (%sp)+,%d0-%d7/%a0-%a6196 bclr #4,%d1197 bclr #4,%d2198 bclr #4,%d3199 bra.s original_flags200reset_original:201 cmpi.w #2,%d4202 bhi.s original203 lea Q,%a0204 clr.w (%a0,%d4.w)205 clr.w 8(%a0,%d4.w)206original:207 movem.l (%sp)+,%d0-%d7/%a0-%a6208original_flags:209 btst #3,0x63(%a3) | replaced pass-lock check at B1B6210 bne.s original_pass211 jmp 0xB1C0212original_pass:213 jmp 0xBA88214legacy:215 move.l %d0,-(%sp)216 bsr.w eligible217 tst.w %d0218 movem.l (%sp)+,%d0219 bne.s original_b220 jmp 0xB42E | native delayed/release B switch and B-hold goalie disabled221original_b:222 btst #4,%d3223 beq.s released224 jmp 0xB2E2225released:226 jmp 0xB35C227