Sonic and Sega Retro Message Board: Some changes and fixes for Sonic 2 - Sonic and Sega Retro Message Board

Jump to content

Hey there, Guest!  (Log In · Register) Help
  • 16 Pages +
  • ◄ First
  • 12
  • 13
  • 14
  • 15
  • 16
    Locked
    Locked Forum

Some changes and fixes for Sonic 2

#196 User is offline Clownacy 

Posted 12 June 2016 - 09:49 AM

  • Posts: 718
  • Joined: 06-July 13
  • Gender:Not Telling
In HTZ, the stakes that the ziplines are attached to are taller than 32 pixels, yet don't have their 'accurate y-height check' render_flags bit, or y_radius, set, so they disappear while still onscreen. To fix this, go to Obj1C_Radii, and change this

	dc.b   0	; 4
	dc.b   0	; 5


to this

	dc.b $28	; 4
	dc.b $28	; 5


Also, another pair of bugfixes: the bug detailed in the post above also exists in DEZ and MCZ's background-scrolling code. I just never noticed.

We'll start with the hardest one - DEZ. Unlike ARZ and MCZ, SwScrl_DEZ handles the screen-shaking at the end of its code, instead of the start. We have to change that. Find something that looks like this:

	moveq	#0,d2
	tst.b	(Screen_Shaking_Flag).w
	beq.s	++	; rts
	subq.w	#1,(DEZ_Shake_Timer).w
	bpl.s	+
	clr.b	(Screen_Shaking_Flag).w
+
	move.w	(Timer_frames).w,d0
	andi.w	#$3F,d0
	lea_	SwScrl_RippleData,a1
	lea	(a1,d0.w),a1
	moveq	#0,d0
	move.b	(a1)+,d0
	add.w	d0,(Vscroll_Factor_FG).w
	add.w	d0,(Vscroll_Factor_BG).w
	add.w	d0,(Camera_Y_pos_copy).w
	move.b	(a1)+,d2
	add.w	d2,(Camera_X_pos_copy).w
+


and move it all so it's just after the 'move.w (Camera_BG_Y_pos).w,(Vscroll_Factor_BG).w' instruction.

Now we just do like we did for ARZ's background, and insert a 'moveq #0,d3' after the 'moveq #0,d2', a 'move.w d0,d3' after the 'add.w d0,(Camera_Y_pos_copy).w', and a 'add.w d3,d1' after 'move.w (Camera_BG_Y_pos).w,d1'. Do the same for SwScrl_MCZ.

#197 User is offline redhotsonic 

Posted 13 June 2016 - 07:52 AM

  • Also known as RHS
  • Posts: 1582
  • Joined: 31-January 05
  • Gender:Male
  • Location:United Kingdom
  • Project:Sonic Bash!
  • Wiki edits:24
Is there a reason why DEZ put it's shaking at the end instead of the beginning?

#198 User is offline Clownacy 

Posted 13 June 2016 - 09:37 AM

  • Posts: 718
  • Joined: 06-July 13
  • Gender:Not Telling
Not that I can tell. There's actually a trick to how the shake code works: Before the check for if the screen is set to shake, d2 is cleared. This is strange, because d2 is only used if the screen is shaking, so the clear should only be done if the screen is shaking, too. Furthermore, d2 is used to hold the x-shake value, but y-shake uses d0. x-shake has no reason to not use d0, too, and save a register clear. This turns out to be a leftover from SwScrl_HTZ, which does not suffer from the bugs ARZ, DEZ, and MCZ have. This is because d2 is never overwritten, and is used in the SwScrl's calculations, much like d3 is in my fixes. It's because of this requirement for d2 to hold the 'current x-shake value' that the screen-shaking code usually goes at the beginning. It's possible DEZ didn't receive its shake-feature until late in development, and the programmer just tacked the code onto the end for a quick result.
This post has been edited by Clownacy: 13 June 2016 - 09:38 AM

#199 User is offline Knucklez 

Posted 13 June 2016 - 12:51 PM

  • Posts: 578
  • Joined: 10-May 11
  • Gender:Male
  • Location:Florida
Random question... I was wondering whether anyone has thought of or intends to make an official ReadySonic/S3Complete-esque hack of Sonic 2 with as many listed bugs fixed as possible so that we also have a "perfected" version of Sonic 2 available? You know, rather than only just the fixes being posted. Just wondering.

#200 User is offline MrMaestro 

Posted 07 July 2016 - 10:41 PM

  • Not your average member of a forum
  • Posts: 20
  • Joined: 19-June 16
  • Gender:Male
  • Location:Singapore
  • Project:Solving a Rubik's cube
I agree, that would be very nice to have a sequel of ReadySonic, But we do already have "Saxman's Sonic-Boom Engine" to our disassembly collection, maybe something like that in a ReadySonic style fashion with the Elective fixes and the Permanent fixes and what not.

#201 User is offline Clownacy 

Posted 08 July 2016 - 10:45 AM

  • Posts: 718
  • Joined: 06-July 13
  • Gender:Not Telling
Keep in mind that, despite being based on the then-current Hg disasm, ReadySonic became woefully outdated as Hg evolved into the Git disasm. Guides can be interpreted, and used on any disasm. As for BOOM, I don't wanna use something that's ultimately a disasm from 2007, even if it comes with some extra features.
This post has been edited by Clownacy: 08 July 2016 - 10:50 AM

#202 User is offline Colton 

Posted 28 September 2016 - 08:41 PM

  • Posts: 9
  • Joined: 17-February 15
Is it possible that someone, somewhere, could at least make a ROM (or make a custom disassembly or something) with all these bugfixes you guys have been making? I just can't seem to find SSHG to find it for the life of me & these bugs frustrate me now that I know about them... :argh:

#203 User is offline Clownacy 

Posted 29 September 2016 - 02:53 AM

  • Posts: 718
  • Joined: 06-July 13
  • Gender:Not Telling
A lot of these fixes aren't in the SCHG. Also, wasn't this brought up like two posts ago?

#204 User is offline Colton 

Posted 03 October 2016 - 05:51 PM

  • Posts: 9
  • Joined: 17-February 15
4 to be exact. Blame it on Knucklez.

#205 User is offline Clownacy 

Posted 12 October 2016 - 11:25 AM

  • Posts: 718
  • Joined: 06-July 13
  • Gender:Not Telling


Thanks to this guy, I learned of another bug: starting the game through the options menu doesn't clear your emerald count, meaning you can soft-reset and replay EHZ over and over, and collect all the emeralds within the first act. If I remember right, I once read of a similar bug, involving emeralds not being cleared in 2-player mode, allowing Sonic to go Super.

Here's the problematic code:
; loc_909A:
OptionScreen_Select:
	move.b	(Options_menu_box).w,d0
	bne.s	OptionScreen_Select_Not1P
	; Start a single player game
	moveq	#0,d0
	move.w	d0,(Two_player_mode).w
	move.w	d0,(Two_player_mode_copy).w
	move.w	d0,(Current_ZoneAndAct).w	; emerald_hill_zone_act_1
	move.b	#GameModeID_Level,(Game_Mode).w ; => Level (Zone play mode)
	rts



And here's the code that does the same thing, only on the Title Screen:
TitleScreen_Loop:
	; ...
	moveq	#0,d0
	move.b	(Title_screen_option).w,d0
	bne.s	TitleScreen_CheckIfChose2P	; branch if not a 1-player game

	moveq	#0,d0
	move.w	d0,(Two_player_mode_copy).w
	move.w	d0,(Two_player_mode).w
    if emerald_hill_zone_act_1=0
	move.w	d0,(Current_ZoneAndAct).w ; emerald_hill_zone_act_1
    else
	move.w #emerald_hill_zone_act_1,(Current_ZoneAndAct).w
    endif
	tst.b	(Level_select_flag).w	; has level select cheat been entered?
	beq.s	+			; if not, branch
	btst	#button_A,(Ctrl_1_Held).w ; is A held down?
	beq.s	+	 		; if not, branch
	move.b	#GameModeID_LevelSelect,(Game_Mode).w ; => LevelSelectMenu
	rts


Look similar? I imagine Sonic Team copied directly from this code while working on the Options menu. But what's that underneath it?

	tst.b	(Level_select_flag).w	; has level select cheat been entered?
	beq.s	+			; if not, branch
	btst	#button_A,(Ctrl_1_Held).w ; is A held down?
	beq.s	+	 		; if not, branch
	move.b	#GameModeID_LevelSelect,(Game_Mode).w ; => LevelSelectMenu
	rts
; ---------------------------------------------------------------------------
+
	move.w	d0,(Current_Special_StageAndAct).w
	move.w	d0,(Got_Emerald).w
	move.l	d0,(Got_Emeralds_array).w
	move.l	d0,(Got_Emeralds_array+4).w
	rts


Uh oh...

So, as you can see, it looks like Sonic Team just missed this bit off the end. This also seems to be case with the Level Select, though it's debatable whether that was intentional or not, being a debugging menu, and all.

The fix is simple: just append those last clears to the Options code, for both 1 Player and 2 Player mode.

#206 User is offline TheLastWhiteFlame 

Posted 14 October 2016 - 05:21 AM

  • Posts: 13
  • Joined: 29-August 16
  • Gender:Male
  • Location:Earth
  • Project:S1 & S2 Restored
Time for another bug-fix. In sonic 2, if you get invincibility then turn super, you will have stars around you while super. I agree it may look good but it's not intended. It's a simple fix, just add checks for super sonic around obj35, so in "loc_1DA0C" change this
	movea.w	parent(a0),a1 ; a1=character
	btst	#status_sec_isInvincible,status_secondary(a1)
	beq.w	DeleteObject


to this

	movea.w	parent(a0),a1 ; a1=character
	btst	#status_sec_isInvincible,status_secondary(a1)
	beq.w	DeleteObject
	tst.b	(Super_Sonic_flag).w
	beq.s	+
	jmp	DeleteObject
+


and then at "loc_1DA80" change this

	movea.w	parent(a0),a1 ; a1=character
	btst	#status_sec_isInvincible,status_secondary(a1)
	beq.w	DeleteObject


to this

	movea.w	parent(a0),a1 ; a1=character
	btst	#status_sec_isInvincible,status_secondary(a1)
	beq.w	DeleteObject
	tst.b	(Super_Sonic_flag).w
	beq.s	+
	jmp	DeleteObject
+


And now when you get invincibility, it checks for super sonic thus ridding the bug.

#207 User is offline Clownacy 

Posted 14 October 2016 - 10:40 AM

  • Posts: 718
  • Joined: 06-July 13
  • Gender:Not Telling
Since the code above your checks can reach DeleteObject with a word-sized branch, your checks probably can too. Just invert the conditions and branch to DeleteObject instead. Also, S3K places the checks above the code you posted.

#208 User is offline Clownacy 

Posted 16 November 2016 - 05:24 PM

  • Posts: 718
  • Joined: 06-July 13
  • Gender:Not Telling
Thanks to a heads-up from djohe, I learned that the multisprite feature is broken in 2-Player mode: X- and Y-flipping don't work. You can see this in MCZ, by looking at a Crawlton's body segments. They should be X-flipped, much like its head, if Sonic is facing its opposite side, but they only do so in single-player.

To fix this, look at ChkDrawSprite, to see how single-player does it:

; sub_1680A:
ChkDrawSprite:
	cmpi.b	#80,d5		; has the sprite limit been reached?
	blo.s	DrawSprite_Cont	; if it hasn't, branch
	rts	; otherwise, return
; End of function ChkDrawSprite


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

; sub_16812:
DrawSprite:
	movea.w	art_tile(a0),a3
	cmpi.b	#80,d5
	bhs.s	DrawSprite_Done
; loc_1681C:
DrawSprite_Cont:
	btst	#0,d4	; is the sprite to be X-flipped?
	bne.s	DrawSprite_FlipX	; if it is, branch
	btst	#1,d4	; is the sprite to be Y-flipped?
	bne.w	DrawSprite_FlipY	; if it is, branch
; loc__1682A:
DrawSprite_Loop:


As you can see, when ChkDrawSprite is called, it branches to DrawSprite_Cont, where the X/Y-flip checks are performed.

Now let's see how 2P does it:

; sub_16DA6:
ChkDrawSprite_2P:
	cmpi.b	#80,d5
	blo.s	DrawSprite_2P_Loop
	rts
; End of function ChkDrawSprite_2P


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

; copy sprite art to VRAM, in 2-player mode

; sub_16DAE:
DrawSprite_2P:
	movea.w	art_tile(a0),a3
	cmpi.b	#80,d5
	bhs.s	DrawSprite_2P_Done
	btst	#0,d4
	bne.s	DrawSprite_2P_FlipX
	btst	#1,d4
	bne.w	DrawSprite_2P_FlipY
; loc_16DC6:
DrawSprite_2P_Loop:


Oh dear.

The issue's pretty obvious: the wrong label is called, skipping the checks. Just add a DrawSprite_2P_Cont before the checks, and make ChkDrawSprite_2P use that instead.
This post has been edited by Clownacy: 16 November 2016 - 05:25 PM

#209 User is offline Clownacy 

Posted 22 November 2016 - 06:27 PM

  • Posts: 718
  • Joined: 06-July 13
  • Gender:Not Telling
Don't you hate it when you Spin Dash next to a moving object, and it takes you out of your Spin Dash animation, and into your walking one?

Posted Image

Well, S3K has the fix just for you! The code responsible for this issue is SolidObject_TestClearPush (loc_19AC4 in old disasms). The S3K version, loc_1E0A2, checks for if the Spin Dash animation is playing, and if so, it doesn't interrupt it. Simple, huh?

S2:
SolidObject_TestClearPush:
	move.l	d6,d4
	addq.b	#pushing_bit_delta,d4
	btst	d4,status(a0)
	beq.s	loc_19AEA
	cmpi.b	#AniIDSonAni_Roll,anim(a1)
	beq.s	loc_19ADC
	move.w	#AniIDSonAni_Run,anim(a1)


S3K:
loc_1E0A2:
		move.l	d6,d4
		addq.b	#2,d4
		btst	d4,$2A(a0)
		beq.s	loc_1E0D0
		cmpi.b	#2,$20(a1)
		beq.s	sub_1E0C2
		cmpi.b	#9,$20(a1)
		beq.s	sub_1E0C2
		move.w	#1,$20(a1)


Spoiler


How about another bug?

Posted Image

This is silly. As it turns out, S3K fixes this as well. The cause is... a little harder to grasp than the last one, especially since the code in question was largely rewritten in S3K.

TAnim_WalkRunZoom: ; a0=character
	; note: for some reason SAnim_WalkRun doesn't need to do this here...
	subq.b	#1,anim_frame_duration(a0)	; subtract 1 from Tails' frame duration
	bpl.s	TAnim_Delay			; if time remains, branch


The comment was right to be suspicious: this is the cause. It simply occurs too early.

You see, if you look at Sonic's animation code, you can see that check multiple times. It occurs way later in SAnim_WalkRun than it does in TAnim_WalkRunZoom, and it appears in SAnim_Roll and SAnim_Push. What's significant about these subroutines? The animations they control - walking, running, rolling, and pushing - are all dependant on the player's Inertia value.

So what's the problem? Tails' code, by placing the check early into TAnim_WalkRunZoom, 'kills two birds with one stone', so to say: instead of having multiple checks for each piece of code, this does it with one. The problem with this is that the 'tumbling' animation also runs this code, even though that particular animation isn't Inertia-dependant.

So what do we do? Simple, do what Sonic's code does: move the check at TAnim_WalkRunZoom down to under TAnim_SpeedSelected, then add the same check to the start of TAnim_Roll, TAnim_Push, and TAnim_GetTailFrame.

And with that, the bug is fixed. Hoora- wait what's that?

Posted Image

Oh great, now Tails' tails are messing up.

Once again, S3K provides a fix:

Obj_Tails_Tail_Main:
		moveq	#0,d0
		move.b	anim(a2),d0
		btst	#5,status(a2)
		beq.s	loc_1612C
		tst.b	($FFFFF7C9).w
		bne.s	loc_1612C
		; This is checking if parent (Tails) is in its pushing animation
		cmpi.b	#$A9,mapping_frame(a2)
		blo.s	loc_1612C
		cmpi.b	#$AC,mapping_frame(a2)
		bhi.s	loc_1612C
		moveq	#4,d0
loc_1612C:


The game technically lacks a 'pushing' animation ID, so the Tails' tails object (Obj05) relies on the 'this object is pushing something' status bit to determine if it should use its own 'pushing' animation. That flag doesn't necessarily mean Tails is in his pushing animation, however. To counter this, the S3K version of the object manually checks Tails' mapping frames. This eliminates all chance of the object acting funny if the 'pushing' bit and 'pushing' animation are not set at the same time. The S2 equivalent of this code would be:

Obj05_Main:
	moveq	#0,d0
	move.b	anim(a2),d0
	btst	#5,status(a2)
	beq.s	+
	; This is checking if parent (Tails) is in its pushing animation
	cmpi.b	#$63,mapping_frame(a2)
	blo.s	+
	cmpi.b	#$66,mapping_frame(a2)
	bhi.s	+
	moveq	#4,d0
+

This post has been edited by Clownacy: 22 November 2016 - 07:44 PM

#210 User is offline Clownacy 

Posted 06 December 2016 - 05:40 PM

  • Posts: 718
  • Joined: 06-July 13
  • Gender:Not Telling
Okay, another fix for Tails... kinda. The fix in the above post isn't complete, causing Tails' sprite to visibly glitch when walking around CPZ's tubes. As mentioned before, Tails' animation code in TAnim_WalkRunZoom is very different to Sonic's SAnim_WalkRun. I'm still not sure why that is, but S3K wound up reverting a lot of it anyway, and managed to fix some bugs in the process. So, for the (hopefully) last fix in this little series, we'll be replacing some of Tails' code with Sonic's.

Find SAnim_WalkRun, and find this block of code (the Git disasm is always changing, so be sure to find your own copy):

	moveq	#0,d1
	move.b	anim_frame(a0),d1
	move.b	1(a1,d1.w),d0
	cmpi.b	#-1,d0
	bne.s	+
	move.b	#0,anim_frame(a0)
	move.b	1(a1),d0
+
	move.b	d0,mapping_frame(a0)
	add.b	d3,mapping_frame(a0)
	subq.b	#1,anim_frame_duration(a0)
	bpl.s	return_1B4AC
	neg.w	d2
	addi.w	#$800,d2
	bpl.s	+
	moveq	#0,d2
+
	lsr.w	#8,d2
	move.b	d2,anim_frame_duration(a0)	; modify frame duration
	addq.b	#1,anim_frame(a0)		; modify frame number


Copy that, then go to your TAnim_SpeedSelected, and replace everything after the label up until the 'rts' instruction with the code you just copied.

  • 16 Pages +
  • ◄ First
  • 12
  • 13
  • 14
  • 15
  • 16
    Locked
    Locked Forum

2 User(s) are reading this topic
0 members, 2 guests, 0 anonymous users