; ---------------------------------------------------------------------------
; 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
Comments
0 B
|0 👍
/0 👎
0 B
|👍
/👎