Actions

SCHG How-to

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