    .ifndef WITH_CONTACT_ATOMIC
    .equ WITH_CONTACT_ATOMIC,0
    .endif
    .ifndef WITH_HUMAN_CONTACT
    .equ WITH_HUMAN_CONTACT,1
    .endif
| Buffered one-timer for a human pass receiver (jdc 2026-10-25): while a pass is on
| its way to you, C (pressed, held or mashed) no longer queues the one-timer at once
| (that stops you and the lead pass slides by). The press is remembered and the
| native one-timer request (action $23) is made when the puck is close, so you keep
| skating into the pass.
| Hook $B6C8 (btst #5,d1 / beq.w $10750) = receiver input with a pass in flight;
| exits: $B6D0 (native one-timer checks and request) or $10750 (normal skating).
    .equ PEND,0xFFF736                 | word: receiver object + 1 with a remembered C
    .equ NEAR,NEAR_PX                  | |dx|+|dy| puck -> receiver that releases it (0 = on reception)
    .ifndef WITH_AI_PLAYBOOK
    .equ WITH_AI_PLAYBOOK,1
    .endif
    .text
    .globl _start
_start:
    bra.w input
    bra.w frame
    bra.w gkflight
    .if WITH_HUMAN_CONTACT
    bra.w owned_shoot
    .endif

| gkflight (switch.s, jdc r22): a3 = your skater, d4 = pad offset -> Z set (and switch.s Q cleared) when a pass from your own goalie is
| on its way (puck loose, last passer a goalie of your team). Keeps all registers.
gkflight:
    movem.l %d0-%d2/%a0,-(%sp)
    moveq #1,%d1                       | 1 = no
    tst.w 0xFFFFB7AA
    bpl.s 9f
    move.w 0xFFFFBEDA,%d0
    bmi.s 9f
    lsl.w #7,%d0
    movea.w #0xB04A,%a0
    adda.w %d0,%a0
    tst.w 0x34(%a0)                    | the passer is a goalie
    bne.s 9f
    move.b 0x62(%a0),%d0               | of your team
    move.b 0x62(%a3),%d2
    eor.b %d2,%d0
    btst #6,%d0
    bne.s 9f
    moveq #0,%d1
    lea 0xFFFFF048,%a0                 | switch.s Q: no pending switch for this pad (d4 = 0/2)
    clr.w (%a0,%d4.w)
9:  tst.w %d1
    movem.l (%sp)+,%d0-%d2/%a0          | (movem keeps the flags)
    rts

| Once per frame (sprite builder, after $FD78A): the receiver with a remembered press
| has the puck now -> immediate full-power forehand one-timer (native shot $C2F2).
frame:
    jsr 0xFD78A
    .if WITH_AI_PLAYBOOK
    jsr 0x2DD010
    .endif
    move.w PEND,%d0
    beq.s 9f
    subq.w #1,%d0
    cmp.w 0xFFFFB7AA,%d0
    beq.s 1f
    cmp.w 0xFFFFBEE0,%d0               | no longer the pass target and not caught:
    beq.s 9f                           | the pass was cut off, forget the press
    clr.w PEND
    bra.s 9f
1:
    .if !WITH_HUMAN_CONTACT
    clr.w PEND
    .endif
    movem.l %d0-%d7/%a0-%a6,-(%sp)
    lsl.w #7,%d0
    movea.w #0xB04A,%a3
    adda.w %d0,%a3
    .if WITH_CONTACT_ATOMIC
    move.w %sr,-(%sp)
    ori.w #0x700,%sr                   | keep contact sprite/flip coherent until native shot returns
    .endif
    .if WITH_HUMAN_CONTACT
    bsr.w stick_contact
    tst.w %d0
    beq.s wait_contact
    clr.w PEND
    .endif
    bset #3,0x64(%a3)                  | native one-timer: release power 31 ($C35E)
    move.w #0x7FC,%d1                  | forehand slapshot animation (crit-eligible)
    jsr 0x1073A
    .if WITH_HUMAN_CONTACT
    move.w #0x18,0x5A(%a3)             | native one-timer contact/follow-through, not a new windup
    move.w #-1,0x5C(%a3)
    clr.b 0x65(%a3)                    | allow the contact sprite on the next native animation update
    .endif
    jsr 0xC2F2                         | native shot
    bclr #3,0x64(%a3)
    .if WITH_CONTACT_ATOMIC
    move.w %sr,%d7
    move.b %d7,1(%sp)                 | retain native post-shot/wait CCR; restore only prior upper SR
    move.w (%sp)+,%sr
    .endif
    movem.l (%sp)+,%d0-%d7/%a0-%a6
9:  rts
    .if WITH_HUMAN_CONTACT
wait_contact:
    .if WITH_CONTACT_ATOMIC
    move.w %sr,%d7
    move.b %d7,1(%sp)                 | retain native post-shot/wait CCR; restore only prior upper SR
    move.w (%sp)+,%sr
    .endif
    movem.l (%sp)+,%d0-%d7/%a0-%a6
    rts
    .endif

input:
    movem.l %d0/%d2,-(%sp)
    move.w 0x52(%a3),%d2
    addq.w #1,%d2                      | this object's PEND value
    btst #5,%d1
    bne.s 1f
    cmp.w PEND,%d2
    bne.s skate                        | no press now, nothing remembered
1:  move.w 0x52(%a3),%d0               | still the pass target, puck still loose?
    cmp.w 0xFFFFBEE0,%d0
    bne.s gone
    tst.w 0xFFFFB7AA
    bpl.s gone
    move.w 0xFFFFB74A,%d0              | |dx| + |dy| puck -> us
    sub.w (%a3),%d0
    bpl.s 2f
    neg.w %d0
2:  move.w 0xFFFFB75E,%d2
    sub.w 0x14(%a3),%d2
    bpl.s 3f
    neg.w %d2
3:  add.w %d2,%d0
    cmpi.w #NEAR,%d0
    bcs.s now
    move.w 0x52(%a3),%d0
    addq.w #1,%d0
    move.w %d0,PEND                    | far: remember and keep skating
    bra.s skate
now:
    clr.w PEND
    movem.l (%sp)+,%d0/%d2
    jmp 0xB6D0                         | native one-timer request
gone:
    move.w 0x52(%a3),%d0
    cmp.w 0xFFFFB7AA,%d0
    beq.s skate                        | we caught it: the frame hook fires
    .if WITH_HUMAN_CONTACT
    addq.w #1,%d0
    cmp.w PEND,%d0                    | another pad cannot cancel the actual receiver's request
    bne.s keep_other_request
    clr.w PEND
keep_other_request:
    .else
    clr.w PEND
    .endif
    btst #5,%d1
    beq.s skate
    movem.l (%sp)+,%d0/%d2
    jmp 0xB6D0                         | an ordinary new press: native path
skate:
    movem.l (%sp)+,%d0/%d2
    jmp 0x10750

    .if WITH_HUMAN_CONTACT
| The native owner flag can precede the owned puck's quarter-distance follow.
| Retain the request until it reaches the current rendered stick hotspot.
| GetHot consumes the pushed object pointer and preserves a0/a1.
stick_contact:
    move.l %a3,-(%sp)
    jsr 0x106E0
    add.w (%a3),%d0
    sub.w 0xFFFFB74A,%d0
    cmpi.w #4,%d0
    bgt.s not_contact
    cmpi.w #-4,%d0
    blt.s not_contact
    add.w 0x14(%a3),%d1
    sub.w 0xFFFFB75E,%d1
    cmpi.w #4,%d1
    bgt.s not_contact
    cmpi.w #-4,%d1
    blt.s not_contact
    muls.w %d0,%d0
    muls.w %d1,%d1
    add.l %d1,%d0
    cmpi.l #16,%d0
    bhi.s not_contact
    moveq #1,%d0
    rts
not_contact:
    moveq #0,%d0
    rts
    .endif

    .if WITH_HUMAN_CONTACT
| B810 is reached only for a newly pressed human C while owning the puck.
| An already remembered pass shot waits for contact rather than starting a
| competing ordinary windup. Outside that request, replay the exact native call.
owned_shoot:
    move.w %sr,-(%sp)
    move.l %d0,-(%sp)
    move.w 0x52(%a3),%d0
    addq.w #1,%d0
    cmp.w PEND,%d0
    bne.s ordinary_owned
    subq.w #1,%d0
    cmp.w 0xFFFFB7AA,%d0
    bne.s ordinary_owned
    move.l (%sp)+,%d0
    move.w (%sp)+,%sr
    jmp 0x10750
ordinary_owned:
    move.l (%sp)+,%d0
    move.w (%sp)+,%sr
    jsr 0xFEE60
    jmp 0xB816
    .endif
