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
  • 13
  • 14
  • 15
  • 16
    Locked
    Locked Forum

Some changes and fixes for Sonic 2

#211 User is offline Caverns 4 

Posted 26 December 2016 - 02:20 PM

  • Posts: 324
  • Joined: 07-December 12
  • Gender:Male
  • Project:Sanik Quest: Journey To The Right

View PostClownacy, on 12 October 2016 - 11:25 AM, said:

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.


If my memory serves me, this isn't a "bug", but was intended behavior. I don't really have the place where that was said on hand though, and it would take me a while to find it.
It's also not really worth debating over, since it also could be considered a design preference depending on the scope of your hack.

#212 User is online Clownacy 

Posted 26 December 2016 - 02:46 PM

  • Layin' the Wax and Spinnin' the Sounds
  • Posts: 662
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
...then why bring it up? It seems obvious that Sonic Team were duplicating code (which is considered bad practice for leading to bugs just like this), and simply stopped at the checks, not noticing the additional clears after it. What reason would this be intentional?
This post has been edited by Clownacy: 26 December 2016 - 02:58 PM

#213 User is offline Neo 

Posted 26 December 2016 - 03:36 PM

  • Clackerjack
  • Posts: 1288
  • Joined: 10-December 04
  • Gender:Male
  • Location:Portugal
  • Project:Sonic 3 Unlocked
  • Wiki edits:1
It's weird inconsistent behavior to be sure, but it's also the only way to play EHZ1 as Super Sonic without using cheats.

I'd rather have the emerald count clear when you reset the game or run out of continues, though.

#214 User is online Clownacy 

Posted 09 January 2017 - 02:53 PM

  • Layin' the Wax and Spinnin' the Sounds
  • Posts: 662
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
So, apparently the DEZ music was meant to resume between the Silver Sonic and Final Boss fights.

loc_39BA4:
	move.w	#$1000,(Camera_Max_X_pos).w
	addq.b	#2,(Dynamic_Resize_Routine).w
	move.b	(Level_Music).w,d0
	jsrto	(PlayMusic).l, JmpTo5_PlayMusic
	bra.w	JmpTo65_DeleteObject


The problem here is that Level_Music is actually a word long, meaning all that 'move.b' does is try to play Sound 0, which doesn't do anything, thus the Boss music just continues until the Final Boss music interrupts it. To fix this, just change the 'move.b' to 'move.w'

#215 User is offline Overlord 

Posted 09 January 2017 - 03:18 PM

  • Substitute Meerkovo IT Chief
  • Posts: 16581
  • Joined: 12-January 03
  • Gender:Male
  • Location:Berkshire, England
  • Project:VGDB
  • Wiki edits:3,204
That track is still underused though. Even in a scenario where it'd be working, you'd hear it again while playing normally for what, 5 seconds? 10 at most?

#216 User is online DigitalDuck 

Posted 09 January 2017 - 03:44 PM

  • Arriving four years late.
  • Posts: 4608
  • Joined: 23-June 08
  • Gender:Male
  • Location:Lincs, UK
  • Project:TurBoa, S1RL

View PostOverlord, on 09 January 2017 - 03:18 PM, said:

That track is still underused though. Even in a scenario where it'd be working, you'd hear it again while playing normally for what, 5 seconds? 10 at most?


Yeah, you wouldn't even get to the melody in normal gameplay. There are people who've completed the game lots of times that don't even know it has a melody.

#217 User is online Dark Sonic 

Posted 09 January 2017 - 04:20 PM

  • Posts: 10931
  • Joined: 21-April 06
  • Gender:Male
  • Project:Working on my art!
  • Wiki edits:10
I always thought it would have been better if you fought Mecha Sonic to the Death Egg melody rather than the boss music. Actually give the song a chance to be heard.

#218 User is offline Mercury 

Posted 22 March 2017 - 12:19 AM

  • His Name Is Sonic
  • Posts: 1725
  • Joined: 13-November 08
  • Gender:Not Telling
  • Location:Location Location
  • Project:AeStHete
  • Wiki edits:130
Was having a conversation about the minutiae of how 1-ups are awarded in the classic games and discovered this:

Flags are set when you get a life at 100 and 200 rings, so you can't re-get those lives when your rings count down from being Super Sonic (they didn't want you to e.g. collect 100 rings, wait a second for them to count down to 99, grab one more ring and get a free life, rinse and repeat).

However, these flags are not cleared when you revert to normal (by dropping to 0 rings). They are only cleared when Sonic is hit and loses his rings, or when the level is loaded. (Search "Sonic_RevertToNormal" and "Extra_life_flags" in the github disasm for the relevant stuff.)

#219 User is online DigitalDuck 

Posted 22 March 2017 - 11:42 AM

  • Arriving four years late.
  • Posts: 4608
  • Joined: 23-June 08
  • Gender:Male
  • Location:Lincs, UK
  • Project:TurBoa, S1RL

View PostMercury, on 22 March 2017 - 12:19 AM, said:

However, these flags are not cleared when you revert to normal (by dropping to 0 rings). They are only cleared when Sonic is hit and loses his rings, or when the level is loaded. (Search "Sonic_RevertToNormal" and "Extra_life_flags" in the github disasm for the relevant stuff.)


Design pondering:

Should they even be cleared when Sonic is hit? If you wanted to farm lives from rings, you could collect 100, get hit, and then start afresh with up to 32 (meaning you only need to hunt for another 68 rings instead of another 100). Doesn't make that much of a difference, but it's food for thought.

#220 User is offline Ralakimus 

Posted 12 June 2017 - 06:20 PM

  • All I wish is gone away...
  • Posts: 188
  • Joined: 16-April 13
  • Gender:Male
  • Project:sekrit
So, notice how bridges in Sonic 2 can only have an even amount of segments? Well, here's how you can allow for odd number of segments.

In "Obj11_Init", there's this little segment of code:

	lsr.w    #1,d0
	lsl.w    #4,d0    ; (d0 div 2) * 16


This basically forces the number of segments to be even and then shifts it to what it needs to be. What you need to do is just change that to:

	lsl.w	#3,d0	; d0 * 8


But, we aren't done yet. There's a little segment of code that appears to be an incorrect calculation for calculating the X position of the second set of bridge segments (for when it's needed) (although, this could be intentional, but I'm not quite sure). Take a look at this in the same routine:

	move.w	d4,d0
	add.w	d0,d0
	add.w	d4,d0	; d0*3
	move.w	sub2_x_pos(a1,d0.w),d0


For one thing, it's mutliplying the offset used to get the X position value in the sub sprite data by 3, which is wrong. Sub sprite data each take up 6 bytes, not 3. So, what we need to do is just make it:

	move.w	d4,d0
	add.w	d0,d0
	add.w	d4,d0
	add.w	d0,d0	; d0*6
	move.w	sub2_x_pos(a1,d0.w),d0


But there's still one more thing: because the segment count is based on 1 instead of 0 (meaning 1 = 1 segment, instead of 0 = 1 segment), it's getting the wrong data. For example, with 1 segment, it will multiply 1 by 6, and get the data from sub3_x_pos, since sub2_x_pos+6 = sub3_x_pos, which isn't used with only 1 segment. So, all we need to do is this, so that it will point to the correct data:

	move.w	d4,d0
	add.w	d0,d0
	add.w	d4,d0
	add.w	d0,d0	; d0*6
	move.w	sub2_x_pos-next_subspr(a1,d0.w),d0


And that's it! I can't seem to find any issues with doing this, but if any of you find any, let me know.
This post has been edited by Ralakimus: 12 June 2017 - 06:29 PM

#221 User is offline flamewing 

Posted 13 June 2017 - 12:55 AM

  • Emerald Hunter
  • Posts: 1113
  • Joined: 11-October 10
  • Gender:Male
  • Location:🇫🇷 France
  • Project:Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
  • Wiki edits:12
The second bit of code did its job correctly in the case of even logs only: subtype would be always even, so multiplying by 3 would be enough to get the correct offset. When you edited to allow an odd number of logs you broke that assumption.

The low bit of subtype does not seem to be used anywhere, so there should not be any issues.

#222 User is offline Ralakimus 

Posted 13 June 2017 - 01:42 AM

  • All I wish is gone away...
  • Posts: 188
  • Joined: 16-April 13
  • Gender:Male
  • Project:sekrit
So, a small update. So, with the new calculation I added is actually incorrect. The multiplication by 3 is intentional, since 2 segments is supposed to use sub3_x_pos and 4 segments use sub4_x_pos, etc, rather than 2 using sub4_x_pos, 4 using sub6_x_pos, etc. Here's a fixed version of it that handles odd numbered segments, by rounding down the offset:
	move.w  d4,d0
        add.w   d0,d0
        add.w   d4,d0	; d0*3
        btst	#0,d0	; align the offset for odd numbered segments
        beq.s	.getX
        subq.w	#3,d0
.getX:
        move.w  sub2_x_pos(a1,d0.w),d0


This post has been edited by Ralakimus: 13 June 2017 - 01:51 AM

#223 User is online Clownacy 

Posted 25 September 2017 - 07:02 PM

  • Layin' the Wax and Spinnin' the Sounds
  • Posts: 662
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
MCZ boss fix
This is a correction of sorts for this guide.

In particular, I found the actual cause for Eggman not laughing unless he hits AI Tails... but even that bit's not correct. He doesn't only laugh if he hits AI Tails, he only laughs if he hits a character, and they don't drop any rings. This means in Sonic Alone or Tails Alone, if you have a shield, getting hit by Eggman will actually make him laugh.

That's not just it though, I also found what causes it, which should make a chunk of that above guide pointless:

Eggman detects when he's hit Sonic or Tails based on the boss_hurt_sonic SST flag. So why does this not get set most of the time? Well, as BossCollision_MCZ would tell you, the pointer to boss_hurt_sonic is stored in a1... which gets overwritten by Boss_DoCollision, but only if the player drops rings. This is because, long down the chain of code, Boss_DoCollision eventually reaches HurtCharacter, where the 'dropped rings' object is loaded in a1.

So how should that be fixed? Well, BossCollision_MCZ already saves d7 on the stack, so just do the same with a1, preferably with a 'movem'.

End-of-level fix
I've known about this bug for a long time, but because I like it so much I never actually tried fixing it. When you hit the signpost, you have a few seconds to run around before the game locks your controls and makes you run off to the right. However, if you jump while at the right edge of the screen, just as the controls are about to lock, the lock won't happen, and you're free to walk around during the score tally. It sure made it easier to get the hidden bonus points in S1.

The code you want to look for is Obj0D_Main_State3. Here, you can see the code that locks Sonic's controls... which is skipped over if the character is in the air. No, I don't mean the function returns, I mean just that bit of code is skipped. The game still checks if Sonic has reached the right side of the screen, and, if so, triggers the score tally. Thus, if you're in the air, and also on the right side of the screen, you can avoid having your controls lock.

I'd say the reason the code is a weird mess like this is because of Sonic 1, where you had to take the Big Ring into account: Sonic disappears when he goes into the big ring, so of course he'll never touch the ground, and it makes sense to just keep going... but still, this edgecase creeps through. I believe the correct way for this code to work would have been this:

; loc_19418:
Obj0D_Main_State3:
	tst.w	(Debug_placement_mode).w
	bne.w	return_194D0
	; This check here is for S1's Big Ring, which would set Sonic's Object ID to 0
	tst.b	(MainCharacter+id).w
	beq.s	loc_1944C
	btst	#1,(MainCharacter+status).w
	bne.w	return_194D0
	move.b	#1,(Control_Locked).w
	move.w	#(button_right_mask<<8)|0,(Ctrl_1_Logical).w
	move.w	(MainCharacter+x_pos).w,d0
	move.w	(Camera_Max_X_pos).w,d1
	addi.w	#$128,d1
	cmp.w	d1,d0
	blo.w	return_194D0

loc_1944C:


Here, the in-air check causes the function to terminate, and it's been moved to after the check for if Sonic entered the big ring. This should solve this issue.

Super Sonic transformation fix
I've noticed that if you transform into Super Sonic by performing a roll-jump, Sonic's controls will be locked until he lands. To me, this doesn't make any sense since Sonic is in his walking animation, not his rolling one, so the roll-jump logic shouldn't apply anymore.

Anyway, looking around the transformation code, I noticed that it doesn't look like anything is done to take Sonic out of his 'curled up into a ball' state, even though his sprite clearly shows him walking. Here are a few things that shouldn't be:
  • Sonic's controls remain locked if he roll-jumped
  • Sonic's 'in ball' status bit won't be cleared
  • Sonic will still be using his smaller hitbox


These all suck, so let's fix them.

The solution is simple enough: just stick this blob of code above Sonic_CheckGoSuper's write to Super_Sonic_palette.

	bclr	#2,status(a0)
	bclr	#4,status(a0)
	move.b	#$13,y_radius(a0)
	move.b	#9,x_radius(a0)


#224 User is online Clownacy 

Posted 26 September 2017 - 05:16 PM

  • Layin' the Wax and Spinnin' the Sounds
  • Posts: 662
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
Another day, another stupid bug...

The limit on Blocks in Sonic 2 is 0x300... but ARZ has 0x320. Those last 0x20 are completely unused, so go ahead and delete them.

The problem with the level having too many blocks is that, when it gets decompressed to RAM, it overwrites whatever comes after the buffer. In the vanilla game, this is TempArray_LayerDef. Another big problem with this is that it causes SonLVL to make 'ARZ primary 16x16 collision index.bin' and 'ARZ secondary 16x16 collision index.bin' larger than they should be - 0x320 bytes intead of 0x300 - because it's trying to account for every block. This one's slightly more dangerous, as Secondary_Collision will overflow into VDP_Command_Buffer, which can have disasterous results when using the likes of flamewing's DMA queue, causing the game to explode into a garbled mess upon trying to load the level.

#225 User is online Clownacy 

Posted 27 September 2017 - 05:49 PM

  • Layin' the Wax and Spinnin' the Sounds
  • Posts: 662
  • Joined: 06-July 13
  • Gender:Male
  • Location:Englandland
I know for a fact flamewing posted a fix for this before, but it's nowhere in this thread. It must have been the Q&A thread, I guess.

In the Level Select, when you go from highlighting one zone to another, the new icon briefly shows the wrong colours. The issue here is that the icon itself is loaded right after V-Int, but the palette only updates on the *next* V-Int. This gives the VDP time to draw the new icon before the palette gets a chance to load.

If I remember right, flamewing suggested two fixes: transfer the icon data (actually its mappings) via DMA, or update the palette manually, instead of waiting for V-Int to do it. Transferring the mappings via DMA will sync it with V-Int, just like the palette, and manually transferring the palette with sync it with the code, just like the icon. I think the latter option is a simpler change to make, so that's the one I'll be using.

In 'LevelSelect_DrawIcon', add this line before the loop at the end:

move.l	#vdpComm(2*16*2,CRAM,WRITE),VDP_control_port-VDP_data_port(a6)


Also, before the 'move.l (a1)+,(a2)+' instruction (but after the loop's label), add this:

move.l	(a1),(a6)


And that's it.

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

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