Actions

SCHG How-to

Add SuperPeelOut to Sonic 1

From Sonic Retro

Revision as of 10:11, 10 July 2020 by Pmowery (talk | contribs)

What you'll need:

  • Sonic 1 Hivebrain disassembly
  • Sonic 1 STH OpenSource project (ROM Hack) (Link here: [1])

Step 1: Port it to Sonic 1 directly

First, open your Sonic 1 .ASM file and use your text editor (if you're using one, which you should. I use Windows Notepad, but you can use any one you like) to go to Obj01 (the Sonic Object)_MdNormal. There, make a branch to a subroutine that we're going to be using. It's going to be called Sonic_SuperPeelout.

Sonic 1 REV02 (ROM Hack) and all other hacks with the SpinDash:

Obj01_MdNormal:				; XREF: Obj01_Modes
		bsr.w	Sonic_SuperPeelout
		bsr.w	Sonic_Spindash
		bsr.w	Sonic_Jump
		bsr.w	Sonic_SlopeResist
		bsr.w	Sonic_Move
		bsr.w	Sonic_Roll
		bsr.w	Sonic_LevelBound
		jsr	SpeedToPos
		bsr.w	Sonic_AnglePos
		bsr.w	Sonic_SlopeRepel
		rts

All other S1 disassemblys:

Obj01_MdNormal:				; XREF: Obj01_Modes
		bsr.w	Sonic_SuperPeelout
		bsr.w	Sonic_Jump
		bsr.w	Sonic_SlopeResist
		bsr.w	Sonic_Move
		bsr.w	Sonic_Roll
		bsr.w	Sonic_LevelBound
		jsr	SpeedToPos
		bsr.w	Sonic_AnglePos
		bsr.w	Sonic_SlopeRepel
		rts

Next, we need to port the actual SuperPeelOut. To do that, go to ; End of function Sonic JumpHeight and paste this block of code right below it:

; ---------------------------------------------------------------------------
; Subroutine Sonic Super Peelout
; ---------------------------------------------------------------------------

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

Sonic_SuperPeelout:
		cmpi.b	#$21,$1C(a0)		; already peelouting?
		beq.s	loc4_1AC8E			; if set, branch
		cmpi.b	#7,$1C(a0)			; is anim looking up?
		bne.s	locret4_1AC8C		; if not, return
		move.b	($FFFFF603).w,d0	; read controller
		andi.b	#$10,d0				; pressing B?
		beq.s	locret4_1AC8C		; if not, return
		move.b	#$21,$1C(a0)		; set Super Peelout anim
		move.w	#$D1,d0				; Super Peelout sound
		jsr	(PlaySound_Special).l	; play Super Peelout sound
		addq.l	#4,sp				; increment stack ptr
		cmpi.b	#$C,$28(a0)			; ??? oxygen remaining?
		bsr.w	Sonic_LevelBound
		bsr.w	Sonic_AnglePos
		
locret4_1AC8C:
		rts	

; ---------------------------------------------------------------------------
loc4_1AC8E:
		addq.w	#1,($FFFFFFD4).w	; add 1 of peelout time
		move.b	#$21,$1C(a0)		; set Super Peelout anim
		move.b	($FFFFF602).w,d0	; read controller
		btst	#0,d0				; check up button
		bne.s	loc4_1AD78			; if set, branch
		tst.b	($FFFFFE19).w		; is sonic super?
		bne.s	loc4_1AC8ECont		; if yes, branch
		cmpi.w	#28,($FFFFFFD4).w	; passed 28 frames? (peelout time)
		bgt.s	loc4_1AC8ECont		; if yes, branch
		move.w	#0,($FFFFFFD4).w	; clear peelout time
		move.w	#$D1,d0				; stop Super Peelout sound
		jsr	(PlaySound_Special).l	; play it!
		rts

loc4_1AC8ECont:
		clr.b	$1C(a0)				; clear anim peelout
		moveq	#0,d0
		move.w	#$EF0,$14(a0)	; get normal speed
		tst.b	($FFFFFE19).w		; is sonic super?
		beq.s	loc4_1ACD0			; if not, branch
		move.w	#$EF0,$14(a0)	; get normal speed

loc4_1ACD0:
		move.w	($FFFFFFD4).w,d2	; set peelout time to d2
		cmpi.w	#$C5,d2				; passed $C5 frames? (peelout time)
		ble.s	loc4_1ACD0_Cont		; if not, branch
		move.w	#$110,d2			; set max speed of waiting

loc4_1ACD0_Cont:
		add.w	d2,$14(a0)			; add peelout time to speed, how much more you wait (until $C5 frames), greater is the speed added
		move.w	#0,($FFFFFFD4).w	; clear peelout time
		btst	#0,$22(a0)			; is sonic facing right?
		beq.s	loc4_1ACF4			; if not, branch
		neg.w	$14(a0)				; negate inertia

loc4_1ACF4:
		move.w	#$BC,d0				; Super Peelout release sound
		jsr	(PlaySound_Special).l	; play it!

loc4_1AD78:
		addq.l	#4,sp			; increase stack ptr
		cmpi.w	#$60,($FFFFF73E).w
		beq.s	loc4_1AD8C
		rts

loc4_1AD8C:
		bsr.w	Sonic_LevelBound
		bsr.w	Sonic_AnglePos
		rts

; End of function Sonic_SuperPeelout

For those who have no spindash, go to Part 2 of How to Add SpinDash to Sonic 1 by Puto to get the spindash sound.

Step 2: Porting the PeelOut animation from STHOSP

(Quick note: if you don't want to add the PeelOut animation, skip to Step 3)

Next step is to go to the \artunc folder of your disassembly and also go to the \artunc folder of STHOSP's disassembly. Once you're there, copy the art file sonic.bin from STHOSP's disasm and replace the one in your disasm with that.

Next step? Replace '\maps\Sonic.asm', '\inc\Sonic dynamic pattern load cues.asm', and '\anim\Sonic.asm' with their STHOSP equivalents.

Finally, open the main Sonic 1 .ASM file once again, and go to Sonic_Animate: Then go to this:

loc_13A9C:
		lea	(SonAni_Run).l,a1 ; use	running	animation
		cmpi.w	#$600,d2	; is Sonic at running speed?
		bcc.s	loc_13AB4	; if yes, branch
		lea	(SonAni_Walk).l,a1 ; use walking animation
		move.b	d0,d1
		lsr.b	#1,d1
		add.b	d1,d0

and change to this:

loc_13A9C:
		lea	(SonAni_SuperPeelout).l,a1
		cmpi.w	#$D00,d2	; is Sonic at running speed?
		bcc.s	loc_13AB4	; if yes, branch
		lea	(SonAni_Run).l,a1 ; use	running	animation
		cmpi.w	#$600,d2	; is Sonic at running speed?
		bcc.s	loc_13AB4	; if yes, branch
		lea	(SonAni_Walk).l,a1 ; use walking animation
		move.b	d0,d1
		lsr.b	#1,d1
		add.b	d1,d0

Step 3: Not porting peelout animations (Optional)

Okay, here's the part where you don't add the peelout animation. First, open \anim\Sonic.asm in your disasm. Then, go to the spot just before SonAni_Walk: dc.b $FF, 8, 9, $A, $B, 6, 7, $FF, and add:

		dc.w SonAni_SuperPeelout-SonicAniData	;20

Then at the very bottom of the file, but just before the even, add:

SonAni_SuperPeelout:	dc.b 0, 5, $8, $8, $8, $8, $8, $8, $8, $8, $9, $9, $9, $9, $9, $A, $A, $A, $21, $21, $1E, $1F, $20, $21, $1E, $1F, $20, $61, $5E, $5F, $60, $FE, 4, 0

Next, go back to the main ASM file and change all instances of #$21,$1C to #$20,$1C.

Step 4: Fix a minor bug where it doesn't clear the time you stay in peelout mode

Finally, go to Hurt_ChkSpikes: and before this:

		move.w	#0,$14(a0)

add this:

		move.w	#0,($FFFFFFD4).w	; clear peelout time

That's it! You're done.

{S1Howtos}