Actions

SCHG How-to

Restore Surfboard Intro to Sonic 3 Alone

From Sonic Retro

Revision as of 12:57, 26 February 2019 by Inferno Gear (talk | contribs) (Created page with "''(Guide by Inferno Gear, based on: https://s3unlocked.blogspot.com/2018/01/the-unused-surfboard-intro.html, by Fred Bronze for his blog Sonic 3 Unlocked)...")
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

(Guide by Inferno Gear, based on: https://s3unlocked.blogspot.com/2018/01/the-unused-surfboard-intro.html, by Fred Bronze for his blog Sonic 3 Unlocked)

So, say you want to restore the surfboard intro to Sonic 3 Alone. You would have to manually hex edit an intact ROM of Sonic 3 Alone, which could be quite the pain! That is, until now! With Fred Bronze's new Sonic 3 Alone disassembly as part of the Sonic & Knuckles GitHub disassembly, you can now edit Sonic 3 Alone in regular ASM!

However, where would you begin to start modifying back in the Surfboard intro to be almost fully perfect? Well, that's what this guide is for!

If you search Obj_AIZSurfboardIntro:, you'll find this piece of code:

Obj_AIZSurfboardIntro:
		move.l	#Map_SurfboardIntro,$C(a0)
		move.w	#$100,8(a0)
		move.b	#$20,7(a0)
		move.b	#4,4(a0)
		move.w	#$680,$A(a0)
		move.b	#-1,(Player_prev_frame).w
		move.l	#Obj_AIZSurfboardIntro_Main,(a0)
		move.w	(Player_1+x_pos).w,$10(a0)
		move.w	(Player_1+y_pos).w,$14(a0)
		subi.w	#$20,$10(a0)
		subi.w	#$10,$14(a0)
		move.w	#0,$18(a0)
		move.w	#0,$1A(a0)
		clr.w	($FFFFEEB6).w
		tst.b	$2C(a0)
		bne.s	loc_20B78
		lea	(Player_1).w,a1
		move.b	#0,$22(a1)
		move.b	#3,$2E(a1)

loc_20B78:
		jsr	(Create_New_Sprite3).l
		bne.w	Obj_AIZSurfboardIntro_Main
		move.l	#Obj_SurfboardSplash,(a1)
		move.w	a0,$30(a1)

Obj_AIZSurfboardIntro_Main:
		tst.b	$2C(a0)
		bne.s	loc_20BFC
		lea	(Player_1).w,a1
		addi.w	#8,$10(a1)
		addi.w	#8,$10(a0)
		cmpi.w	#$900,$10(a1)
		bcs.s	loc_20BFC
		jsr	(Create_New_Sprite3).l
		bne.w	loc_20BD0
		move.l	#Obj_Surfboard,(a1)
		move.w	$10(a0),$10(a1)
		move.w	$14(a0),$14(a1)
		addi.w	#$C,$14(a1)
		move.w	a0,$30(a1)

loc_20BD0:
		move.w	#$800,$18(a0)
		move.w	#-$400,$1A(a0)
		move.l	#Obj_AIZSurfboardIntro_Jump,(a0)
		move.w	#1,$20(a0)
		subi.w	#5,$10(a0)
		move.b	#7,$22(a0)
		jsr	(SurfboardIntro_LoadPLC).l
		bra.s	loc_20C00
; ---------------------------------------------------------------------------

loc_20BFC:
		bsr.w	SurfboardIntro_Move

loc_20C00:
		jmp	(Sprite_OnScreen_Test).l
; ---------------------------------------------------------------------------

Obj_AIZSurfboardIntro_Jump:
		lea	(Player_1).w,a1
		addi.w	#8,$10(a1)
		jsr	(MoveSprite2).l
		addi.w	#$20,$1A(a0)
		moveq	#1,d2
		move.w	$10(a0),d0
		cmp.w	$10(a1),d0
		beq.s	loc_20C30
		blt.s	loc_20C2C
		neg.w	d2

loc_20C2C:
		add.w	d2,$10(a0)

loc_20C30:
		tst.w	$1A(a0)
		bmi.s	loc_20C74
		cmpi.w	#$440,$14(a0)
		bcs.s	loc_20C74
		move.w	#$440,$14(a0)
		move.w	#0,$1A(a0)
		move.w	$10(a0),$10(a1)
		move.w	$14(a0),$14(a1)
		move.w	#1,$20(a1)
		move.w	#$800,$1C(a1)
		move.w	#$800,$18(a1)
		move.w	#0,$1A(a1)
		move.l	#Obj_AIZSurfboardIntro_Run,(a0)

loc_20C74:
		lea	(Ani_SurfboardIntro).l,a1
		jsr	(Animate_Sprite).l
		jsr	(SurfboardIntro_LoadPLC).l
		jmp	(Sprite_OnScreen_Test).l
; ---------------------------------------------------------------------------
Ani_SurfboardIntro:
		include "General/Sprites/Sonic/Anim - Sonic Surfboard.asm"
; ---------------------------------------------------------------------------

Obj_AIZSurfboardIntro_Run:
		movea.l	a0,a3
		lea	(Player_1).w,a0
		move.w	#0,$1A(a0)
		cmpi.w	#$1170,$10(a0)
		bcs.s	loc_20CB6
		cmpi.w	#$1270,$10(a0)
		bcc.s	loc_20CB6
		move.w	#-$138,$1A(a0)

loc_20CB6:
		jsr	(MoveSprite2).l
		cmpi.w	#$13C0,$10(a0)
		bcs.s	loc_20CE2
		move.b	#0,$2E(a0)
		move.l	#Obj_AIZSurfboardIntro_Stop,(a3)
		move.b	#1,(Ctrl_1_locked).w
		move.w	#$400,(Ctrl_1_logical).w
		move.w	#$E,$2E(a3)

loc_20CE2:
		jsr	(Animate_Sonic).l
		move.l	a3,-(sp)
		jsr	(Sonic_Load_PLC).l
		movea.l	(sp)+,a0
		addi.w	#8,$10(a0)
		move.b	#0,$22(a0)
		jmp	(Sprite_OnScreen_Test).l
; ---------------------------------------------------------------------------

Obj_AIZSurfboardIntro_Stop:
		subq.w	#1,$2E(a0)
		bpl.s	loc_20D32
		lea	(Player_1).w,a1
		move.w	#0,$1C(a1)
		move.w	#0,$18(a1)
		move.w	#0,$1A(a1)
		move.b	#0,(Ctrl_1_locked).w
		move.w	#0,(Ctrl_1_logical).w
		move.l	#Obj_AIZSurfboardIntro_CheckDelete,(a0)

loc_20D32:
		jmp	(Sprite_OnScreen_Test).l
; ---------------------------------------------------------------------------

Obj_AIZSurfboardIntro_CheckDelete:
		jmp	(Sprite_OnScreen_Test).l

; =============== S U B R O U T I N E =======================================


SurfboardIntro_Move:
		move.w	#2,d1
		move.w	(Player_1+x_pos).w,d0
		cmp.w	$10(a0),d0
		bcc.s	loc_20D4E
		neg.w	d1

loc_20D4E:
		add.w	d1,$18(a0)
		moveq	#0,d2
		lea	(SurfboardIntro_DownFrames).l,a1
		move.w	#3,d1
		move.w	(Player_1+y_pos).w,d0
		cmp.w	$14(a0),d0
		bcc.s	loc_20D76
		moveq	#1,d2
		lea	(SurfboardIntro_UpFrames).l,a1
		move.w	#4,d1
		neg.w	d1

loc_20D76:
		add.w	d1,$1A(a0)
		jsr	(MoveSprite2).l
		move.w	$1A(a0),d0
		tst.w	d2
		bne.s	loc_20D8A
		neg.w	d0

loc_20D8A:
		addi.w	#$80,d0
		cmpi.w	#$100,d0
		bcs.s	loc_20D98
		move.w	#$100,d0

loc_20D98:
		lsr.w	#5,d0
		move.b	(a1,d0.w),d0
		addq.b	#1,d0
		move.b	d0,$22(a0)
		jsr	(SurfboardIntro_LoadPLC).l
		subq.w	#1,$2E(a0)
		bpl.s	locret_20DCA
		move.w	#5,$2E(a0)
		jsr	(Create_New_Sprite3).l
		bne.w	locret_20DCA
		move.l	#Obj_SurfboardWaves,(a1)
		move.w	a0,$30(a1)

locret_20DCA:
		rts
; ---------------------------------------------------------------------------
SurfboardIntro_DownFrames:
		dc.b    2,   1,   1,   0,   0,   0,   0,   1,   2,   2
SurfboardIntro_UpFrames:
		dc.b    3,   4,   4,   4,   5,   5,   5,   4,   3,   3
; End of function SurfboardIntro_Move


; =============== S U B R O U T I N E =======================================


SurfboardIntro_LoadPLC:
		moveq	#0,d0
		move.b	$22(a0),d0
		cmp.b	(Player_prev_frame).w,d0
		beq.s	locret_20E32
		move.b	d0,(Player_prev_frame).w
		lea	(DPLC_SurfboardIntro).l,a2
		add.w	d0,d0
		adda.w	(a2,d0.w),a2
		move.w	(a2)+,d5
		subq.w	#1,d5
		bmi.s	locret_20E32
		move.w	#-$3000,d4

loc_20E06:
		moveq	#0,d1
		move.w	(a2)+,d1
		move.w	d1,d3
		lsr.w	#8,d3
		andi.w	#$F0,d3
		addi.w	#$10,d3
		andi.w	#$FFF,d1
		lsl.l	#5,d1
		addi.l	#ArtUnc_SurfboardIntro,d1
		move.w	d4,d2
		add.w	d3,d4
		add.w	d3,d4
		jsr	(Add_To_DMA_Queue).l
		dbf	d5,loc_20E06

locret_20E32:
		rts
; End of function SurfboardIntro_LoadPLC

; ---------------------------------------------------------------------------
Map_SurfboardIntro:
		include "General/Sprites/Sonic/Map - Sonic Surfboarding.asm"
DPLC_SurfboardIntro:
		include "General/Sprites/Sonic/DPLC - Sonic Surfboarding.asm"
; ---------------------------------------------------------------------------

This is the main code for the Surfboard intro object, which is referenced in the debug list for Angel Island Zone. Let's rememeber Obj_AIZSurfboardIntro, it will be needed.

Now to add back in the surfboard as the object that loads for the intro. Go to SpawnLevelMainSprites, you should see this code:

SpawnLevelMainSprites:
		move.l	#Obj_Level_50B2,(Reserved_object_3).w
		bsr.w	SpawnLevelMainSprites_SpawnPlayers
		bsr.w	SpawnLevelMainSprites_SpawnPowerup
		tst.b	(Last_star_post_hit).w
		bne.w	locret_4EC6
		tst.b	(Special_bonus_entry_flag).w

loc_4DD2:
		bne.w	locret_4EC6
		lea	(Player_1).w,a1
		lea	(Player_2).w,a2
		cmpi.w	#0,(Current_zone_and_act).w
		bne.s	loc_4DFE
		cmpi.w	#2,(Player_mode).w
		beq.s	locret_4DFC
		move.l	#Obj_AIZPlaneIntro,($FFFFB172).w
		clr.b	(Level_started_flag).w
		rts

I want you to look at this fragment.

		cmpi.w	#0,(Current_zone_and_act).w
		bne.s	loc_4DFE
		cmpi.w	#2,(Player_mode).w
		beq.s	locret_4DFC
		move.l	#Obj_AIZPlaneIntro,($FFFFB172).w

What this does is if the current Zone and Act ID isn't Angel Island, branch to loc_$4DFE. After that, it checks for Player Mode ID 2, which means it's checking if the player is Tails. If it is, it branches to locret_$4DFC. Finally, it adds Obj_AIZPlaneIntro to RAM Address $FFFFB172, which is used for reserved Object SSTs. It spawns the plane intro right there. Change the instance of #Obj_AIZPlaneIntro to Obj_AIZSurfboardIntro.

(WIP)