Free up some SSTs
From Sonic Retro
First Part Of The Guide By Alriightyman
This Guide Is For The Xerowhirl Disassembly
"invulnerable invincibility and speedshoes_time"
Go to Touch_ChkHurt2: and change
Touch_ChkHurt2:
btst #1,status_secondary(a1)
bne.s return_15AC4
tst.w invulnerable_time(a1)
to
Touch_ChkHurt2:
btst #1,status_secondary(a1)
bne.s return_15AC4
tst.b invulnerable_time(a1); change here
Next go to loc_170D0: and scroll down until you see
+
cmpi.w #$5A,invulnerable_time(a0)
bcc.w return_17166
and change that to
+
cmpi.b #$5A,invulnerable_time(a0); Change this
bcc.w return_17166
Next stop, Sonic_Display. Now there is quite a bit we are going to change here.
Start with whats below
Sonic_Display:
move.w invulnerable_time(a0),d0
beq.s Obj01_Display
subq.w #1,invulnerable_time(a0)
lsr.w #3,d0
bcc.s Obj01_ChkInvin
and change it to
move.b invulnerable_time(a0),d0; here
beq.s Obj01_Display
subq.b #1,invulnerable_time(a0);here
lsr.w #3,d0
bcc.s Obj01_ChkInvin
Next scroll down a bit, to Obj01_ChkInvin:
Obj01_ChkInvin:; Checks if invincibility has expired and disables it if it has.
btst #1,status_secondary(a0)
beq.s Obj01_ChkShoes
tst.w invincibility_time(a0)
beq.s Obj01_ChkShoes; If there wasn't any time left, that means we're in Super Sonic mode.
subq.w #1,invincibility_time(a0)
bne.s Obj01_ChkShoes
tst.b (Current_Boss_ID).w; Don't change music if in a boss fight
bne.s Obj01_RmvInvin
cmpi.b #$C,air_left(a0); Don't change music if drowning
bcs.s Obj01_RmvInvin
move.w (Level_Music).w,d0
jsr (PlayMusic).l
and change it to
btst #1,status_secondary(a0)
beq.s Obj01_ChkShoes
tst.b invincibility_time(a0);here
beq.s Obj01_ChkShoes; If there wasn't any time left, that means we're in Super Sonic mode.
move.b ($FFFFFE05).w,d0; add this
andi.b #7,d0 ; add this
bne.s Obj01_ChkShoes; add this
subq.b #1,invincibility_time(a0); here
bne.s Obj01_ChkShoes
tst.b (Current_Boss_ID).w; Don't change music if in a boss fight
bne.s Obj01_RmvInvin
cmpi.b #$C,air_left(a0); Don't change music if drowning
bcs.s Obj01_RmvInvin
move.w (Level_Music).w,d0
jsr (PlayMusic).l
Now scroll down to Obj01_ChkShoes: and change it from
Obj01_ChkShoes:; Checks if Speed Shoes have expired and disables them if they have.
btst #2,status_secondary(a0)
beq.s Obj01_ExitChk
tst.w speedshoes_time(a0)
beq.s Obj01_ExitChk
subq.w #1,speedshoes_time(a0)
bne.s Obj01_ExitChk
move.w #$600,(Sonic_top_speed).w
move.w #$C,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
tst.b (Super_Sonic_flag).w
beq.s Obj01_RmvSpeed
move.w #$A00,(Sonic_top_speed).w
move.w #$30,(Sonic_acceleration).w
move.w #$100,(Sonic_deceleration).w
to
btst #2,status_secondary(a0)
beq.s Obj01_ExitChk
tst.b speedshoes_time(a0); here
beq.s Obj01_ExitChk
move.b ($FFFFFE05).w,d0; add
andi.b #7,d0 ; add
bne.s Obj01_ExitChk; add
subq.b #1,speedshoes_time(a0); here
bne.s Obj01_ExitChk
move.w #$600,(Sonic_top_speed).w
move.w #$C,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
tst.b (Super_Sonic_flag).w
beq.s Obj01_RmvSpeed
move.w #$A00,(Sonic_top_speed).w
move.w #$30,(Sonic_acceleration).w
move.w #$100,(Sonic_deceleration).w
Now what these lines do
move.b ($FFFFFE05).w,d0
andi.b #7,d0
bne.s Obj01_ExitChk
is instead of counting down every frame subtract 1 from invincibility time
or speed shoes time, it counts down every 8 frames instead
Ok, go to Sonic_HurtStop, change this
move.w (Camera_Max_Y_pos_now).w,d0
addi.w #$E0,d0
cmp.w y_pos(a0),d0
blt.w JmpTo_KillCharacter
bsr.w Sonic_DoLevelCollision
btst #1,status(a0)
bne.s return_1B1C8
moveq #0,d0
move.w d0,y_vel(a0)
move.w d0,x_vel(a0)
move.w d0,inertia(a0)
move.b d0,obj_control(a0)
move.b #0,anim(a0)
subq.b #2,routine(a0); => Obj01_Control
move.w #$78,invulnerable_time(a0)
move.b #0,spindash_flag(a0)
to
move.w (Camera_Max_Y_pos_now).w,d0
addi.w #$E0,d0
cmp.w y_pos(a0),d0
blt.w JmpTo_KillCharacter
bsr.w Sonic_DoLevelCollision
btst #1,status(a0)
bne.s return_1B1C8
moveq #0,d0
move.w d0,y_vel(a0)
move.w d0,x_vel(a0)
move.w d0,inertia(a0)
move.b d0,obj_control(a0)
move.b #0,anim(a0)
subq.b #2,routine(a0); => Obj01_Control
move.b #$78,invulnerable_time(a0);here
move.b #0,spindash_flag(a0)
Now go do the same thing but for Tails.
Now go to Touch_ChkValue and change this
move.b collision_flags(a1),d1; load touch response number
andi.b #$C0,d1 ; is touch response $40 or higher?
beq.w Touch_Enemy; if not, branch
cmpi.b #$C0,d1 ; is touch response $C0 or higher?
beq.w loc_3F976; if yes, branch
tst.b d1 ; is touch response $80-$BF ?
bmi.w Touch_ChkHurt; if yes, branch
; touch response is $40-$7F
move.b collision_flags(a1),d0
andi.b #$3F,d0
cmpi.b #6,d0 ; is touch response $46 ?
beq.s Touch_Monitor; if yes, branch
move.w (MainCharacter+invulnerable_time).w,d0
tst.w (Two_player_mode).w
beq.s loc_3F728
move.w invulnerable_time(a0),d0
loc_3F728:
cmpi.w #$5A,d0
bcc.w return_3F73A
move.b #4,routine(a1); set the object's routine counter
move.w a0,parent(a1)
return_3F73A:
rts
to
Touch_ChkValue:
move.b collision_flags(a1),d1; load touch response number
andi.b #$C0,d1 ; is touch response $40 or higher?
beq.w Touch_Enemy; if not, branch
cmpi.b #$C0,d1 ; is touch response $C0 or higher?
beq.w loc_3F976; if yes, branch
tst.b d1 ; is touch response $80-$BF ?
bmi.w Touch_ChkHurt; if yes, branch
; touch response is $40-$7F
move.b collision_flags(a1),d0
andi.b #$3F,d0
cmpi.b #6,d0 ; is touch response $46 ?
beq.s Touch_Monitor; if yes, branch
move.b (MainCharacter+invulnerable_time).w,d0;here
tst.w (Two_player_mode).w
beq.s loc_3F728
move.b invulnerable_time(a0),d0;here
loc_3F728:
cmpi.b #$5A,d0 ; here
and to Touch_Hurt: change it to
Touch_Hurt:
nop
tst.b invulnerable_time(a0);here
bne.s Touch_NoHurt
movea.l a1,a2
Go to Hurt_ChkSpikes, change it to
move.w #0,inertia(a0)
move.b #$1A,anim(a0)
move.b #$78,invulnerable_time(a0); here
move.w #$23+$80,d0; load normal damage sound
cmpi.b #$36,(a2); was damage caused by spikes?
bne.s Hurt_Sound; if not, branch
move.w #$26+$80,d0; load spikes damage sound
and loc_3FB28 change this
loc_3FB28:
move.l #$40004,d1
bsr.w loc_3FC4C
move.w (sp)+,d7
move.b collision_flags(a1),d0
cmpi.w #$78,invulnerable_time(a0)
bne.s return_3FB44
st objoff_38(a1)
to
loc_3FB28:
move.l #$40004,d1
bsr.w loc_3FC4C
move.w (sp)+,d7
move.b collision_flags(a1),d0
cmpi.b #$78,invulnerable_time(a0);here
bne.s return_3FB44
st objoff_38(a1)
And loc_3FB50 change from
loc_3FB50:
move.w x_pos(a1),d0
move.w y_pos(a1),d7
subi.w #$20,d7
add.w a5,d0
move.l #$100004,d1
bsr.w loc_3FC4C
movea.w #-$14,a5
adda.w #1,a4
cmpa.w #1,a4
beq.s loc_3FB50
move.w (sp)+,d7
move.b collision_flags(a1),d0
cmpi.w #$78,invulnerable_time(a0)
bne.s return_3FB88
st objoff_38(a1)
to
move.w x_pos(a1),d0
move.w y_pos(a1),d7
subi.w #$20,d7
add.w a5,d0
move.l #$100004,d1
bsr.w loc_3FC4C
movea.w #-$14,a5
adda.w #1,a4
cmpa.w #1,a4
beq.s loc_3FB50
move.w (sp)+,d7
move.b collision_flags(a1),d0
cmpi.b #$78,invulnerable_time(a0);here
bne.s return_3FB88
st objoff_38(a1)
Ok, now find this lable super_shoes: Change it from
super_shoes:
addq.w #1,(a2)
bset #2,status_secondary(a1)
move.w #$4B0,speedshoes_time(a1)
cmpa.w #MainCharacter,a1
bne.s loc_12A10
cmpi.w #2,(Player_mode).w; Maybe set if the char is Tails?
beq.s loc_12A10
move.w #$C00,(Sonic_top_speed).w
move.w #$18,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
bra.s loc_12A22
to
super_shoes:
addq.w #1,(a2)
bset #2,status_secondary(a1)
move.b #$96,speedshoes_time(a1);here
cmpa.w #MainCharacter,a1
bne.s loc_12A10
cmpi.w #2,(Player_mode).w; Maybe set if the char is Tails?
beq.s loc_12A10
move.w #$C00,(Sonic_top_speed).w
move.w #$18,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
bra.s loc_12A22
Go to invincible_monitor,
invincible_monitor:
addq.w #1,(a2)
tst.b (Super_Sonic_flag).w
bne.s return_12AA4
bset #1,status_secondary(a1)
move.w #$4B0,invincibility_time(a1)
tst.b (Current_Boss_ID).w
bne.s loc_12A88
cmpi.b #$C,air_left(a1)
bls.s loc_12A88
move.w #$97,d0
jsr (PlayMusic).l
change it to
invincible_monitor:
addq.w #1,(a2)
tst.b (Super_Sonic_flag).w
bne.s return_12AA4
bset #1,status_secondary(a1)
move.b #$96,invincibility_time(a1);here
tst.b (Current_Boss_ID).w
bne.s loc_12A88
cmpi.b #$C,air_left(a1)
bls.s loc_12A88
move.w #$97,d0
jsr (PlayMusic).l
Now go to Sonic_CheckGoSuper and change
Sonic_CheckGoSuper:
tst.b (Super_Sonic_flag).w; is Sonic already Super?
bne.s return_1ABA4; if yes, branch
cmpi.b #7,(Emerald_count).w; does Sonic have exactly 7 emeralds?
bne.s return_1ABA4; if not, branch
cmpi.w #50,(Ring_count).w; does Sonic have at least 50 rings?
bcs.s return_1ABA4; if not, branch
move.b #1,(Super_Sonic_palette).w
move.b #$F,(Palette_frame_count).w
move.b #1,(Super_Sonic_flag).w
move.b #$81,obj_control(a0)
move.b #$1F,anim(a0) ; use transformation animation
move.b #$7E,(Object_RAM+$2040).w; load Obj7E (super sonic stars object) at $FFFFD040
move.w #$A00,(Sonic_top_speed).w
move.w #$30,(Sonic_acceleration).w
move.w #$100,(Sonic_deceleration).w
move.w #0,invincibility_time(a0)
bset #1,status_secondary(a0); make Sonic invincible
move.w #$5F+$80,d0
jsr (PlaySound).l; Play transformation sound effect.
move.w #$16+$80,d0
jmp (PlayMusic).l; load the Super Sonic song and return
to
Sonic_CheckGoSuper:
tst.b (Super_Sonic_flag).w; is Sonic already Super?
bne.s return_1ABA4; if yes, branch
cmpi.b #7,(Emerald_count).w; does Sonic have exactly 7 emeralds?
bne.s return_1ABA4; if not, branch
cmpi.w #50,(Ring_count).w; does Sonic have at least 50 rings?
bcs.s return_1ABA4; if not, branch
move.b #1,(Super_Sonic_palette).w
move.b #$F,(Palette_frame_count).w
move.b #1,(Super_Sonic_flag).w
move.b #$81,obj_control(a0)
move.b #$1F,anim(a0) ; use transformation animation
move.b #$7E,(Object_RAM+$2040).w; load Obj7E (super sonic stars object) at $FFFFD040
move.w #$A00,(Sonic_top_speed).w
move.w #$30,(Sonic_acceleration).w
move.w #$100,(Sonic_deceleration).w
move.b #0,invincibility_time(a0) ; here
bset #1,status_secondary(a0); make Sonic invincible
move.w #$5F+$80,d0
jsr (PlaySound).l; Play transformation sound effect.
move.w #$16+$80,d0
jmp (PlayMusic).l; load the Super Sonic song and return
Go to Sonic_RevertToNormal change it from
Sonic_RevertToNormal:
move.b #2,(Super_Sonic_palette).w; Remove rotating palette
move.w #$28,($FFFFF65C).w; Unknown
move.b #0,(Super_Sonic_flag).w
move.b #1,next_anim(a0); Change animation back to normal ?
move.w #1,invincibility_time(a0); Remove invincibility
move.w #$600,(Sonic_top_speed).w
move.w #$C,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
btst #6,status(a0); Check if underwater, return if not
beq.s return_1AC3C
move.w #$300,(Sonic_top_speed).w
move.w #6,(Sonic_acceleration).w
move.w #$40,(Sonic_deceleration).w
to
Sonic_RevertToNormal:
move.b #2,(Super_Sonic_palette).w; Remove rotating palette
move.w #$28,($FFFFF65C).w; Unknown
move.b #0,(Super_Sonic_flag).w
move.b #1,next_anim(a0); Change animation back to normal ?
move.b #1,invincibility_time(a0); Remove invincibility;here
move.w #$600,(Sonic_top_speed).w
move.w #$C,(Sonic_acceleration).w
move.w #$80,(Sonic_deceleration).w
btst #6,status(a0); Check if underwater, return if not
beq.s return_1AC3C
move.w #$300,(Sonic_top_speed).w
move.w #6,(Sonic_acceleration).w
move.w #$40,(Sonic_deceleration).w
Now the last thing that is optional, is go the Equates section Find
invulnerable_time = $34
invincibility_time = $35
speedshoes_time = $36
change it to
invulnerable_time = $30
invincibility_time = $31
speedshoes_time = $32