Sonic S‐Tunnel Flicker Fix - RetroKoH/S1Fixed GitHub Wiki

(Original guide by Mercury)
Source: ReadySonic
Commit: 58c2f59

In Sonic 1, Sonic is programmed to automatically enter the rolling state when inside the chunk of an S-Tunnel (See Sonic Loops.asm for more on how that works). There is a rarely seen bug that can be seen if the player enters the tunnel slowly, and holds left to force Sonic to come to a stop. Sonic's sprite will flicker, briefly showing a frame from his idle animation. This is because the rolling code only sets his next animation to be run, not his current sprite frame, which means he doesn't turn into a ball immediately, resulting in an annoying flicker if he were to come to a stop while still inside the tunnel. Such a bug can become even more apparent if users decide to add more rolling sections akin to Sonic 2. Let's fix this:

In _incObj\Sonic Roll.asm, under .roll, add this line:

.roll:
	bset	#staSpin,obStatus(a0)
	move.b	#$E,obHeight(a0)
	move.b	#7,obWidth(a0)
	move.b	#aniID_Roll,obAnim(a0)	; use "rolling" animation
+	move.b	#fr_Roll1,obFrame(a0)	; hard sets frame so no flicker when roll in tunnels
	addq.w	#5,obY(a0)

This will resolve the flickering issue. NOTE: This is only a simple workaround for Sonic 1, and is not how Sonic 2 handles the animation while forced rolling, as that instead checks for a "pinball mode" flag in Sonic's RAM before setting Sonic to his idle animation. You can see that code from Sonic 2 below:

; loc_1A81E:
Sonic_CheckRollStop:
	tst.w	inertia(a0)
	bne.s	Obj01_Roll_ResetScr
	tst.b	pinball_mode(a0) ; this is used to tell the game that Sonic's not allowed to stop rolling
	bne.s	Sonic_KeepRolling

; this is where Sonic unrolls, ONLY if not in a forced rolling state
	bclr	#2,status(a0)
	move.b	#$13,y_radius(a0)
	move.b	#9,x_radius(a0)
	move.b	#AniIDSonAni_Wait,anim(a0)
	subq.w	#5,y_pos(a0)
	bra.s	Obj01_Roll_ResetScr