don't click here

Some changes and fixes for Sonic 2

Discussion in 'Engineering & Reverse Engineering' started by Esrael, Jun 7, 2012.

  1. Esrael

    Esrael

    Neto Tech Member
    306
    262
    63
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto MD-DOS
    Did someone noticed that Bottom part of Background in CNz in 2 Player Mode don't scroll for Tails?
    How To fix this:

    Find This
    Code (ASM):
    1.  
    2. ; ===========================================================================
    3. byte_D270:
    4.     dc.b   4
    5.     dc.b   4    ; 1
    6.     dc.b   8    ; 2
    7.     dc.b   8    ; 3
    8.     dc.b   8    ; 4
    9.     dc.b   8    ; 5
    10.     dc.b   8    ; 6
    11.     dc.b   8    ; 7
    12.     dc.b   8    ; 8
    13.     dc.b   8    ; 9
    14.     dc.b   0    ; 10
    15.     dc.b $78    ; 11
    16. ; ===========================================================================
    17.  
    and add the following data:

    Code (ASM):
    1.  
    2. Bg_Scroll_CNz_Data_Player_2:
    3.        dc.b    $08, $08, $08, $08, $08, $08, $08, $0C, $00, $78, $00, $00  
    4.  
    and find:
    Code (ASM):
    1.  
    2.         move.w   #bytesToLcnt($1D0),d2
    3.     lea  (byte_D270+1).l,a3
    4.  
    5. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
    6.  
    7.  
    8. sub_D216:
    9.  

    and change to:
    Code (ASM):
    1.  
    2.         move.w   #bytesToLcnt($1D0),d2
    3.     lea (Bg_Scroll_CNz_Data_Player_2).l,a3
    4.  
    5. ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||
    6.  
    7.  
    8. sub_D216:
    9.  
     
  2. Alriightyman

    Alriightyman

    I am back... from the dead! Tech Member
    357
    11
    18
    Somewhere in hot, death Florida
    0101001101101111011011100110100101100011 00000010: 0101001100000011 01000101011001000110100101110100011010010110111101101110
    How the hell do all of you notice these things?!?!?!? I love all these previously unknown fixes!
     
  3. Jayextee

    Jayextee

    Unpopular Opinions™ Member
    3,253
    67
    28
    Atro City
    I DONE MAKED GAMES.
    I don't recall, has anyone ever fixed the collision? -- when Sonic (or Tails) is colliding with two objects at once, only one registers? This is why Sonic walks through certain badniks in ARZ when he's scattering leaves, and why he can't collect dropped rings in lava without jumping.
     
  4. MoDule

    MoDule

    Tech Member
    328
    32
    28
    Procrastinating from writing bug-fix guides
    Cool. I never managed to fix this one in a way I was satisfied with. What the hell was the original code trying to do, anyway?


    For me, it's observing the games obsessively.

    Not a very difficult fix, I think, but it probably wouldn't be feasible without s3k's faster collision checking.
     
  5. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    I normally find bugs with my hack "Sonic 2 Recreation". When I notice these bugs, I look to see if it's in the original game, which 95% of the time, it is. Because I fix it for S2R, I might as well tell people how to fix it for the originals, otherwise everyone will have the same bugs.



    eh? This shouldn't happen. I've tried this many times, and it works okay to me. In both HTZ and MTZ.






    Anyway, seeming as we've moved on from bosses, I have another bug to show:




    How to fix Spindash's height collision




    [​IMG]

    Here's Sonic standing with an arrow heading towards him. Obviously, the arrow is going to hurt him.



    [​IMG]

    Here's Sonic ducking with an arrow heading towards him. Obviously, the arrow is going to miss him.



    [​IMG]

    Here's Sonic spindashing with an arrow heading towards him. This should miss him. But in Sonic 2, it doesn't! Bug? I think so! Here's how to fix. (again, I'm using Xenowhirl's 2007 disassembly)




    Go to "TouchResponse:" and find this bit of coding:

    Code (ASM):
    1.     cmpi.b  #$4D,mapping_frame(a0)  ; is Sonic ducking?
    2.     bne.s   Touch_NoDuck        ; if not, branch
    3.     addi.w  #$C,d3
    4.     moveq   #$A,d5
    5. ; loc_3F592:
    6. Touch_NoDuck:

    What it's doing here, is comparing if Sonic is ducking. If so, do NOT branch, and shorten his y_radius (to $A) and edits his y_pos before carrying on with the routine. It only does this with the ducking though. Because of this, when you spindash, it's still branching to continue with the routine without making any edits to his y_radius, so Sonic's y_radius is still the same as Sonic's standing y_radius ($13). When Sonic rolls, his y_radius is changed, but that's set elsewhere. Anyway, change the coding you see above, to this below:

    Code (ASM):
    1.     cmpi.b  #9,anim(a0)     ; is Sonic spindashing?
    2.     beq.s   Duckinganddashing   ; if so, branch
    3.     cmpi.b  #$4D,mapping_frame(a0)  ; is Sonic ducking?
    4.     bne.s   Touch_NoDuck        ; if not, branch
    5. Duckinganddashing:      ; So, Sonic is spindashing or ducking
    6.     addi.w  #$C,d3
    7.     moveq   #$A,d5
    8. ; loc_3F592:
    9. Touch_NoDuck:

    Now, it's doing an extra check to see if Sonic is spindashing, and if so, it will branch to a new label and shorten his y_radius. If not, it will then ask if you're ducking and if so, it won't branch and shorten the y_radius. If you're not ducking either, it will branch to "Touch_NoDuck" and carry on with the routine.

    The codes above run the majority of the time of the game, so this affects most of the objects.




    You need to do the same for "Touch_Boss:" So go to that label and change this bit of the coding:

    Code (ASM):
    1.     cmpi.b  #$4D,mapping_frame(a0)
    2.     bne.s   loc_3F68E
    3.     addi.w  #$C,d3
    4.     moveq   #$A,d5
    5.  
    6. loc_3F68E:

    To this:

    Code (ASM):
    1.     cmpi.b  #9,anim(a0)     ; is Sonic spindashing?
    2.     beq.s   Duckinganddashingboss   ; if so, branch
    3.     cmpi.b  #$4D,mapping_frame(a0)
    4.     bne.s   loc_3F68E
    5. Duckinganddashingboss:
    6.     addi.w  #$C,d3
    7.     moveq   #$A,d5
    8.  
    9. loc_3F68E:

    This part of the code only runs when there is a boss present.



    Two more, we need to do it again at "loc_170D0:" Go there and change this part of the coding:

    Code (ASM):
    1.     cmpi.b  #$4D,mapping_frame(a0)
    2.     bne.s   loc_17104
    3.     addi.w  #$C,d3
    4.     moveq   #$A,d5
    5.  
    6. loc_17104:

    Change it to this:

    Code (ASM):
    1.     cmpi.b  #9,anim(a0)     ; is Sonic spindashing?
    2.     beq.s   Duckinganddashingrings  ; if so, branch
    3.     cmpi.b  #$4D,mapping_frame(a0)
    4.     bne.s   loc_17104
    5. Duckinganddashingrings:
    6.     addi.w  #$C,d3
    7.     moveq   #$A,d5
    8.  
    9. loc_17104:
    This code runs in the Ring Manager part of the coding. This only affects the rings collision.




    One more, but I'm not sure if this is important. It's part of the Specialbumpers routine for CNZ. But I don't see how you can hit the bumpers whilst spindashing. But in case you want to implement it anyway, go to "loc_174DE:" and change this part of the coding:

    Code (ASM):
    1.     cmpi.b  #$4D,mapping_frame(a0)
    2.     bne.s   loc_17508
    3.     addi.w  #$C,d3
    4.     moveq   #$A,d5
    5.  
    6. loc_17508:

    to this:

    Code (ASM):
    1.     cmpi.b  #9,anim(a0)     ; is Sonic spindashing?
    2.     beq.s   Duckinganddashingbumps  ; if so, branch
    3.     cmpi.b  #$4D,mapping_frame(a0)
    4.     bne.s   loc_17508
    5. Duckinganddashingbumps:
    6.     addi.w  #$C,d3
    7.     moveq   #$A,d5
    8.  
    9. loc_17508:


    Done. You should start to see results like this:

    [​IMG]



    Cheers,
    redhotsonic
     
  6. dsrb

    dsrb

    Member
    3,149
    0
    16
    Bloody hell, you guys just keep blowing this game apart! And then putting it back together way more awesome.

    I can't imagine how many things you might find for S1 if you were to try, but by no means should either of you break your momentum here! :thumbsup:
     
  7. Esrael

    Esrael

    Neto Tech Member
    306
    262
    63
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto MD-DOS
    I had fixed a lot of other bugs, Infinite Scrolling in Sonic 2 Beta screen used in Sonic 2 Delta when Sound Test is highlighted. In normal Sonic 2 Beta you will never notice the bug, since the Demo Mode runs.
    Metal Sonic and Spinner Legs in Sonic 2 rev 2 And others.

    Not Showed since no other persons uses Sonic 2 Beta or Sonic 2 rev 2 as bases for your hacks.

    Some of these I had fixed a long time ago, you can confirm just playing older versions of Sonic 2 Delta.
    And Thanks for all persons which show your fixes which can make the Most famous Game (Sonic the Hedgehog 2) more stable than original.

    I do know this is not important but I will release my disassembly of Sonic 2 rev 2 (extracted from Sonic Classics (in Brazil) or Compilation) soon.
     
  8. E-122-Psi

    E-122-Psi

    Member
    2,502
    681
    93
    It's pretty impressive, especially since a lot of these bugs weren't even noticed by many to begin with.

    You're really putting Sonic Team to shame, especially since they've had who knows how many tries to fix them (how could that CPZ gag not be used in any release? How?).
     
  9. Esrael

    Esrael

    Neto Tech Member
    306
    262
    63
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto MD-DOS

    While applying and testing these I have found another which are present for Miles.
    The original code only checks for Sonic Ducking. If you playing as Miles you will be Hurt while ducking.
    To Fix just add the following code in all instances:
    Normal:
    Code (ASM):
    1.  
    2.         cmpi.b  #9,anim(a0)             ; is Sonic spindashing?
    3.         beq.s   Duckinganddashing       ; if so, branch
    4. ;-------------------------------------------------------------------------------              
    5.         cmpi.b  #$02, (A0)              ; Is Miles?
    6.         bne.s   Touch_Check_Sonic       ; Not goto Sonic routine
    7.         cmpi.b  #$5B, mapping_frame(A0) ; is Miles ducking
    8.         bne.s   Touch_NoDuck                  
    9.         bra.s   Duckinganddashing
    10. Touch_Check_Sonic:
    11. ;-------------------------------------------------------------------------------  
    12.         cmpi.b  #$4D,mapping_frame(a0)  ; is Sonic ducking?
    13.         bne.s   Touch_NoDuck            ; if not, branch
    14. Duckinganddashing:              ; So, Sonic is spindashing or ducking
    15.         addi.w  #$C,d3
    16.         moveq   #$A,d5
    17. ; loc_3F592:
    18. Touch_NoDuck:
    19.  


    Boss:
    Code (ASM):
    1.  
    2.         cmpi.b  #9,anim(a0)             ; is Sonic spindashing?
    3.         beq.s   Duckinganddashingboss   ; if so, branch
    4. ;-------------------------------------------------------------------------------            
    5.         cmpi.b  #$02, (A0)              ; Is Miles?
    6.         bne.s   Touch_Boss_Check_Sonic  ; Not goto Sonic routine
    7.         cmpi.b  #$5B, mapping_frame(A0) ; is Miles ducking
    8.         bne.s   loc_3F68E                  
    9.         bra.s   Duckinganddashingboss
    10. Touch_Boss_Check_Sonic:
    11. ;-------------------------------------------------------------------------------  
    12.         cmpi.b  #$4D,mapping_frame(a0)
    13.         bne.s   loc_3F68E
    14. Duckinganddashingboss:
    15.         addi.w  #$C,d3
    16.         moveq   #$A,d5
    17.  
    18. loc_3F68E:
    19.  

    Rings:
    Code (ASM):
    1.  
    2.         cmpi.b  #9,anim(a0)             ; is Sonic spindashing?
    3.         beq.s   Duckinganddashingrings  ; if so, branch
    4. ;-------------------------------------------------------------------------------              
    5.         cmpi.b  #$02, (A0)              ; Is Miles?
    6.         bne.s   Touch_Rings_Check_Sonic ; Not goto Sonic routine
    7.         cmpi.b  #$5B, mapping_frame(A0) ; is Miles ducking
    8.         bne.s   loc_17104                  
    9.         bra.s   Duckinganddashingrings
    10. Touch_Rings_Check_Sonic:
    11. ;-------------------------------------------------------------------------------  
    12.         cmpi.b  #$4D,mapping_frame(a0)
    13.         bne.s   loc_17104
    14. Duckinganddashingrings:
    15.         addi.w  #$C,d3
    16.         moveq   #$A,d5
    17.  
    18. loc_17104:
    19.  
    Edit all codes with Miles fix
     
  10. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber


    That's a nice fix, but the problem here is that the code is starting to get too long. Seeming as Sonic AND Tails runs this all the time, it can start to slow the game down a little (okay, hardly by any, but still...)


    There is another and quicker fix, but it does have a little problem. Which I'm about to explain.

    Instead of having this:

    Code (ASM):
    1.         cmpi.b  #9,anim(a0)             ; is Sonic spindashing?
    2.         beq.s   Duckinganddashing       ; if so, branch
    3.         cmpi.b  #$4D,mapping_frame(a0)  ; is Sonic ducking?
    4.         bne.s   Touch_NoDuck            ; if not, branch
    5. Duckinganddashing:              ; So, Sonic is spindashing or ducking
    6.         addi.w  #$C,d3
    7.         moveq   #$A,d5
    8. ; loc_3F592:
    9. Touch_NoDuck:


    You could do this:

    Code (ASM):
    1.         cmpi.b  #9,anim(a0)             ; is Sonic spindashing?
    2.         beq.s   Duckinganddashing       ; if so, branch
    3.         cmpi.b  #8,anim(a0)     ; is Sonic ducking?
    4.         bne.s   Touch_NoDuck            ; if not, branch
    5. Duckinganddashing:              ; So, Sonic is spindashing or ducking
    6.         addi.w  #$C,d3
    7.         moveq   #$A,d5
    8. ; loc_3F592:
    9. Touch_NoDuck:
    Instead of mapping_frame, it will compare the anim. Both for Sonic and Tails, their duck is anim #8 and their spindash is anim #9. That way, the code won't be too long. Obviously, do the same thing at "Touch_Boss:", "loc_170D0:" and "loc_174DE:".



    This is perfect for Tails, but for Sonic, it has one very slight problem:

    [​IMG]

    Whilst going into his ducking position, he will now have the shorter y_radius. This only happens for a split second, and probably isn't noticable.


    If you're not bothered about that, then this is the way to go; replacing "#$4D,mapping_frame(a0)" with "#8,anim(a0)". But, if you are bothered about this, then Esrael's idea is the way to go. It's just a little bit slower as it has to do all these checks for both Sonic and Tails all the time.
     
  11. That One Jig

    That One Jig

    aka RichterSnipes Member
    67
    2
    8
    Somewhere in America
    (Not) Working on My PokéHack
    Man, if I could make an appropriate surprised face right now via text, I'd be doing it like crazy right now. Those CPZ and crouching fixes not only make the game more "perfect," but they add flair to it at the same time! As someone who doesn't see video games quite as timeless as other forms of media, I'm ecstatic to see all these fixes come out for the game. Excellent work, Esrael and redhotsonic!

    I hope I'm not coming off as rude, but I'm not sure if you guys caught the bug I mentioned a couple of pages back (it was post #30). I can see it easily getting buried in these posts because MoDule posed another fix just minutes after my post, making it appear a page behind. If you haven't checked it out yet, you're welcome to do so! :)
     
  12. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber

    Whoops, must have missed that, sorry. Okay, here's the fix (Xenowhirls 2007 again):





    Go to "Obj05_Main:" and find this coding:


    Code (ASM):
    1.     moveq   #0,d0
    2.     move.b  anim(a2),d0
    3.     btst    #5,status(a2)
    4.     beq.s   +
    5.     moveq   #4,d0
    6. +

    When Tails is next to something he's about to push, his pushing tails animation is set. The thing is, just before he pushes, one walking anim appears, which conflicts both tails animations. So, change it to this:


    Code (ASM):
    1.     moveq   #0,d0
    2.     move.b  anim(a2),d0
    3.     btst    #5,status(a2)       ; is Tails about to push against something?
    4.     beq.s   +           ; if not, branch
    5.     cmpi.b  #$63,mapping_frame(a2)  ; Is Tails in his pushing animation yet?
    6.     blt.s   +           ; If not yet, branch, and do not set tails' tail pushing animation
    7.     moveq   #4,d0
    8. +

    Now, as soon as he's about to push, it will still do his one walking animation, but his mapping_frame wouldn't have reach #$63 yet, so it won't set the tails tail pushing animation. That means no more conflicts. Then when he does do his pushing animation, the tails tails animation will set accordingly without conflicting.


    Resulting in this:

    [​IMG]


    Done

    Cheers,
    redhotsonic
     
  13. That One Jig

    That One Jig

    aka RichterSnipes Member
    67
    2
    8
    Somewhere in America
    (Not) Working on My PokéHack
    Dang. That was fast! Thanks for that fix, redhotsonic! It's amazing to see all these bugfixes pile up at one time.

    Here's hoping a fully-fixed Sonic 2 ROM/patch pops up someday! (That's not a request of any kind, just a thought. Or a wonder, whatever.)
     
  14. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    You're most welcome.




    We can make a new hack with all these bug fixes and call it "Sonic 2: Health and Safety" =P






    Anyway, here's another.

    Firstly, I aplogise if there has already been a fix out there for this. I am aware that people know this bug as it's on the Retro Wiki, but I couldn't see anywhere about a member telling others how to fix it. So here's how




    How to fix the Rexon badnik crash in Hill Top Zone


    [​IMG]



    As it doesn't tell you how to fix it, and I couldn't see anyone mentioning it, here's how.


    Go to "loc_37454:" and you should see this:

    Code (ASM):
    1. loc_37454:
    2.     bsr.w   loc_3750C
    3.     subq.b  #1,objoff_2A(a0)
    4.     bmi.s   loc_37462
    5.     bra.w   JmpTo39_MarkObjGone

    That "branch to subroutine - loc_3750C" is what is causing the problem. It's happening too early. We need to move that command down a little bit. So change it to this:

    Code (ASM):
    1. loc_37454:
    2.     subq.b  #1,objoff_2A(a0)
    3.     bmi.s   loc_37462
    4.     bsr.w   loc_3750C       ; Now moved here to help fix Rexon crash
    5.     bra.w   JmpTo39_MarkObjGone


    One more, go to "loc_37488:" and you should see this:

    Code (ASM):
    1. loc_37488:
    2.     bsr.w   loc_3750C
    3.     moveq   #$10,d0
    4.     add.w   d0,x_vel(a0)
    5.     subq.b  #1,objoff_2A(a0)
    6.     bmi.s   loc_374A0
    7.     bsr.w   JmpTo26_ObjectMove
    8.     bra.w   JmpTo39_MarkObjGone

    Again, "branch to subroutine - loc_3750C" is too early. So change it to this:

    Code (ASM):
    1. loc_37488:
    2.     moveq   #$10,d0
    3.     add.w   d0,x_vel(a0)
    4.     subq.b  #1,objoff_2A(a0)
    5.     bmi.s   loc_374A0
    6.     bsr.w   loc_3750C       ; Now moved here to help fix Rexon crash
    7.     bsr.w   JmpTo26_ObjectMove
    8.     bra.w   JmpTo39_MarkObjGone

    Done. The rexon crash will no longer happen.

    [​IMG]


    Cheers,
    redhotsonic
     
  15. RetroKoH

    RetroKoH

    Member
    1,728
    107
    43
    S1Fixed: A successor to ReadySonic
  16. ICEknight

    ICEknight

    Researcher Researcher
    Pretty cool stuff guys, please do keep it coming.

    Just wondering, is this the same fix as the official one from v.02?
     
  17. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    It was fixed from S2K. That's where I got this fix from =P
     
  18. Esrael

    Esrael

    Neto Tech Member
    306
    262
    63
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto MD-DOS
    In rev 2 this was fixed by Sega. As I had promissed here is the Sonic 2 rev 2 source.
    You will see some changes in the code.
    This disassembly was generated from Esrael Neto Assembly Editor using other labels definitions.
    For curiosity Your fixes for Rexon can be found in Obj_0x97.asm (label Offset_0x036F20:)
    The source was not modified by me. This is original from Sega (Sonic Compilation /Classics) with New Header Only.

    Sonic 2 rev 2 (Sonic compilation / Classics)

    Edit: 28/05/2019 - Fixed broken links

    Best regards:
    ----------------------
    Neto.
     
  19. Esrael

    Esrael

    Neto Tech Member
    306
    262
    63
    Brazil, São Paulo, Guarulhos
    Neto Assembler Editor / Sonic 2 Delta / Neto MD-DOS
    About these fixes, I don't know if this part was noticed or not.
    But without these you will be forced to do a hard reset when you die and try placing an object while debugging/testing in Real Hardware.
     
  20. RetroKoH

    RetroKoH

    Member
    1,728
    107
    43
    S1Fixed: A successor to ReadySonic