; --------------------------------------------------------------------------- ; Subroutine to make Sonic perform a spindash ; --------------------------------------------------------------------------- ; ||||||||||||||| S U B R O U T I N E ||||||||||||||||||||||||||||||||||||||| Sonic_SpinDash: tst.b $39(a0) ; already Spin Dashing? bne.s Spindash_CheckRelease ; if set, branch cmpi.b #8,$1C(a0) ; is anim duck bne.s Spindash_Return ; if not, return move.b ($FFFFF603).w,d0 ; read controller andi.b #$70,d0 ; pressing A/B/C ? beq.s Spindash_Return ; if not, return move.b #9,$1C(a0) ; set Spin Dash anim (9 in s2) move.w #$D1,d0 ; spin sound ($E0 in s2) jsr (PlaySound_Special).l ; play spin sound addq.l #4,sp ; increment stack ptr move.b #1,$39(a0) ; set Spin Dash flag move.b #0,$3A(a0) ; set charge count to 0 cmpi.b #$C,$28(a0) ; ??? oxygen remaining? bcs.s Spindash_CallNecessaryRoutines ; ??? branch if carry move.b #2,($FFFFD11C).w ; ??? $D11C is used for ; the smoke/dust object Spindash_CallNecessaryRoutines: bsr.w Sonic_LevelBoundaries bsr.w Sonic_AnglePos Spindash_Return: rts ; --------------------------------------------------------------------------- Spindash_CheckRelease: ; move.b #9,$1C(a0) move.b ($FFFFF602).w,d0 ; read controller btst #1,d0 ; check down button bne.w Spindash_StillCharging ; if set, branch move.b #$E,$16(a0) ; $16(a0) is height/2 move.b #7,$17(a0) ; $17(a0) is width/2 move.b #2,$1C(a0) ; set animation to roll addq.w #5,$C(a0) ; $C(a0) is Y coordinate move.b #0,$39(a0) ; clear Spin Dash flag moveq #0,d0 move.b $3A(a0),d0 ; copy charge count add.w d0,d0 ; double it move.w Dash_Speeds(pc,d0.w),$14(a0) ; get normal speed move.w $14(a0),d0 ; get inertia subi.w #$800,d0 ; subtract $800 add.w d0,d0 ; double it andi.w #$1F00,d0 ; mask it against $1F00 neg.w d0 ; negate it addi.w #$2000,d0 ; add $2000 move.w d0,($FFFFEED0).w ; move to $EED0 btst #0,$22(a0) ; is sonic facing right? beq.s Spindash_Release2 ; if not, branch neg.w $14(a0) ; negate inertia Spindash_Release2: bset #2,$22(a0) ; set rolling flag move.b #0,($FFFFD11C).w ; clear $D11C (smoke) move.w #$BC,d0 ; spin release sound jsr (PlaySound_Special).l ; play it! move.b angle(a0),d0 ; Load Sonic's angle to d0. jsr (CalcSine).l ; Calculate Sonic's sine and cosine based on his angle. muls.w inertia(a0),d1 ; Multiply d1 by Sonic's inertia. asr.l #8,d1 ; Divide the longword in d1 by 2*2*2*2*2*2*2*2 = 256 (also read as 2^8 = 256). move.w d1,x_vel(a0) ; Give Sonic horizontal velocity. This has no effect when Sonic is on flat ground at a 0- or 180-degree angle. muls.w inertia(a0),d0 ; Multiply d0 by Sonic's inertia. asr.l #8,d0 ; Divide the longword in d0 by 2*2*2*2*2*2*2*2 = 256 (also read as 2^8 = 256). move.w d0,y_vel(a0) ; Give Sonic vertical velocity. This has no effect when Sonic is on flat ground that is at a 90- or 270-degree angle. bra.s Spindash_ResetScr ; =========================================================================== Dash_Speeds: dc.w $800 ; 0 dc.w $880 ; 1 dc.w $900 ; 2 dc.w $980 ; 3 dc.w $A00 ; 4 dc.w $A80 ; 5 dc.w $B00 ; 6 dc.w $B80 ; 7 dc.w $C00 ; 8 ; =========================================================================== Spindash_StillCharging: ; If still charging the dash... tst.b $3A(a0) ; check charge count beq.s Spindash_Recharge ; if zero, branch move.b $3A(a0),d0 ; otherwise put it in d0 lsr.b #5,d0 ; shift right 5 (divide it by 32) sub.b d0,$3A(a0) ; subtract from charge count bcc.s Spindash_Recharge ; ??? branch if carry clear move.b #0,$3A(a0) ; set charge count to 0 Spindash_Recharge: move.b ($FFFFF603).w,d0 ; read controller andi.b #$70,d0 ; pressing A/B/C? beq.w Spindash_ResetScr ; if not, branch move.w #$900,$1C(a0) ; reset spdsh animation move.w #$D1,d0 ; was $E0 in sonic 2 jsr (PlaySound_Special).l ; play charge sound addi.b #$1,spindash_counter(a0) cmpi.b #$8,spindash_counter(a0) bcs.s Spindash_ResetScr move.b #$8,spindash_counter(a0) bra.s Spindash_ResetScr move.b #$8,spindash_counter(a0) Spindash_ResetScr: addq.l #4,sp ; increase stack ptr cmpi.w #$60,($FFFFEED8).w ; $EED8 only ever seems beq.s Spindash_CallNecessaryRoutines2 ; to be used in Spin Dash bcc.s Spindash_ResetScr_Part2 addq.w #4,($FFFFEED8).w Spindash_ResetScr_Part2: subq.w #2,($FFFFEED8).w Spindash_CallNecessaryRoutines2: bsr.w Sonic_LevelBoundaries bsr.w Sonic_AnglePos ; move.w #$60,($FFFFF73E).w ; reset looking up/down rts ; End of subroutine Sonic_SpinDash ; =========================================================================== align 4