Some changes and fixes for Sonic 2

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

  1. E-122-Psi

    E-122-Psi

    Member
    2,107
    252
    63
    Has the bug in VS mode concerning the power up music changes staying on if the utilising player loses a life got a fix?
     
  2. MoDule

    MoDule

    Tech Member
    323
    5
    18
    Procrastinating from writing bug-fix guides
    I could've sworn I made a fix for this at some point, but I can't find it anymore. Anyway, here's the fix:

    Code (Text):
    1. ; loc_3F926: KillSonic:
    2. KillCharacter:
    3.     tst.w    (Debug_placement_mode).w
    4.     bne.s    .return
    5.  
    6. ;-------- bugfix --------
    7. ; reset stats and music upon death
    8.     move.w    #1,invincibility_time(a0)    ; make invincibility run out
    9.     move.w    #1,speedshoes_time(a0)        ; make speed shoes run out
    10.     cmpa.w    #MainCharacter,a0
    11.     bne.s    .p2
    12.  
    13.     tst.b    (Super_Sonic_flag).w
    14.     beq.s    .notSuper
    15.  
    16.     move.b    #0,(Super_Sonic_flag).w        ; remove super status
    17.     move.b    #2,(Super_Sonic_palette).w
    18.     move.w    #$28,(Palette_frame).w
    19.  
    20. .notSuper:
    21.     jsr    (Obj01_ChkInvin).l    ; remove player 1's power ups
    22.     bra.s    .kill
    23.  
    24. .p2:
    25.     jsr    (Obj02_ChkInvinc).l    ; remove player 2's power ups
    26. ;---- end bugfix --------
    27.  
    28.  
    29. .kill:
    30.     clr.b    status_secondary(a0)
    31.     move.b    #6,routine(a0)
    32.     jsrto    (Sonic_ResetOnFloor_Part2).l, JmpTo_Sonic_ResetOnFloor_Part2
    33.     bset    #1,status(a0)
    34.     move.w    #-$700,y_vel(a0)
    35.     move.w    #0,x_vel(a0)
    36.     move.w    #0,inertia(a0)
    37.     move.b    #AniIDSonAni_Death,anim(a0)
    38.     bset    #high_priority_bit,art_tile(a0)
    39.     move.w    #SndID_Hurt,d0
    40.     cmpi.b    #ObjID_Spikes,id(a2)
    41.     bne.s    .playSound
    42.     move.w    #SndID_HurtBySpikes,d0
    43.  
    44. .playSound:
    45.     jsr    (PlaySound).l
    46.  
    47. .return:
    48.     moveq    #-1,d0
    49.     rts
    The changes are between the two bugfix comments. The only other thing I changes was replace the nameless temporary symbols with named local symbols. As a bonus, I threw in a Super Sonic detransformation.
     
  3. E-122-Psi

    E-122-Psi

    Member
    2,107
    252
    63
    You probably did, but this is a hard to track gold mine of fixes now. :P
     
  4. MoDule

    MoDule

    Tech Member
    323
    5
    18
    Procrastinating from writing bug-fix guides
    If anything, it's hidden away on an old hard drive somewhere. I have at least one old disassembly somewhere with a bunch of bugfixes that I never published.
     
  5. Hitaxas

    Hitaxas

    Retro 80's themed Twich streamer Member
    Here is one more design choice change that can be made.
    Extending the limit to how many frames Sonic, Tails or Knuckles can have!

    Now, this is a bit limited due to how the animation subroutine for player characters works, but it does allow for more frames than what the game normally allows.
    In this example, I will be using Sonic. However, this can be applied to Tails or Knuckles as well.

    For Sonic, locate the label
    Code (Text):
    1. SAnim_Do2
    now, look for a line that reads
    Code (Text):
    1. cmpi.b    #$F0,d0
    Change this to
    Code (Text):
    1. cmpi.b    #$FD,d0
    This will allow for 12 more frames of animation!

    Edit: Actually, change it to $FD, as this is supposed to be the number AFTER the max amount of frames. Therefore, setting to $FD allows for $FC amount of frames to be usable.
     
    Last edited: Jul 26, 2020
  6. Alex Field

    Alex Field

    シュート! カオス・エメラルド・ザが消えようとしている! Member
    112
    64
    28
    Downunda, Mobius
    Sonic the Hedgehog 2+, Sonic the Hedgehog 3+
    Tails on the title screen doesn't have its priority set during the fade-in, meaning a few of his pixels will appear behind Sonic; to fix this, add "move.b #3,priority(a0)" under loc_130A2:.
     
    Last edited: Sep 14, 2020
  7. E-122-Psi

    E-122-Psi

    Member
    2,107
    252
    63
    Counts more as an extra than a fix, but for those who wanna add in Knuckles, there's an INCREDIBLY easy way to add in some exclusive shortcuts for him. The breakable wall from Sonic 1 (obj3C) conveniently still exists in Sonic 2 unused. When you've added it to your level route and mapped it to some new art, go to it's routine and make this edit in loc_15DAE:

    Code (Text):
    1.  
    2. loc_15DAE:
    3.     lea    (MainCharacter).w,a1 ; a1=character
    4.     cmp.b     #$XX,(a1)    ;is player Knuckles? (replace XX with Knuckles' obj number)
    5.     beq.w    Smash_Things
    6.   ;  cmpi.b    #2,anim(a1)
    7.   ;  bne.s    return_15DAC
    8.     move.w    objoff_30(a0),d0
    9.     bpl.s    loc_15DC2
    10.     neg.w    d0
    11.  
    12. loc_15DC2:
    13.     cmpi.w    #$480,d0
    14.     bcs.s    return_15DAC
    15. Smash_Things:
    16.     move.w    objoff_30(a0),x_vel(a1)
    17.     addq.w    #4,x_pos(a1)
    This will change so instead of recognising Sonic's ball form, it will just recognise Knuckles only and let him plow through the wall.
     
  8. Alex Field

    Alex Field

    シュート! カオス・エメラルド・ザが消えようとしている! Member
    112
    64
    28
    Downunda, Mobius
    Sonic the Hedgehog 2+, Sonic the Hedgehog 3+
    Warning! Making objects continue to move after dying causes Sonic to continually die on the lava collision object (i.e. he dies and bounces on it forever). To be safe, add this above the Debug Mode check:
    Code (Text):
    1.     cmpi.b    #6,(MainCharacter+routine).w    ; is Sonic/Knuckles dead?
    2.     bhs.s    +                ; if yes, branch
    3.     cmpi.b    #6,(Sidekick+routine).w        ; is Tails dead?
    4.     bhs.s    +                ; if yes, branch
     
    Last edited: Oct 3, 2020
  9. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,143
    6
    18
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    There is an asymmetry between left and right when braking on all Genesis games (S1, S2, S3, S&K): when you start braking, the skidding animation is triggered when you are above 4.5 pixels/frame going right, or 3.5 pixels/frame when going left. This can become particularly noticeable if you increase the top speed of Sonic and test underwater.

    So here is the fix for S1, S2, and S&K disassemblies: first, go to the following locations and find the code shown:
    • S1: loc_130BA, loc_13120
      Code (ASM):
      1.         move.b    obAngle(a0),d0
      2.         addi.b    #$20,d0
      3.         andi.b    #$C0,d0
    • S2: Sonic_TurnLeft, Sonic_TurnRight, Tails_TurnLeft, Tails_TurnRight
      Code (ASM):
      1.     move.b    angle(a0),d0
      2.     addi.b    #$20,d0
      3.     andi.b    #$C0,d0
      4.  
    • S&K: loc_11438, loc_114BE, loc_14C62, loc_14CE8, loc_1746A, loc_174F0, loc_3559E, loc_35620
      Code (ASM):
      1.         move.b    $26(a0),d0
      2.         addi.b    #$20,d0
      3.         andi.b    #-$40,d0
      4.  
    Now change all instances of d0 to d1 in the code shown above. That is it, the bug is fixed. Both left and right will now trigger skidding animation when braking above 4.5 pixels/frame.

    What is going on is that the ground speed/inertia is stored in d0. When the data for ground angle is for this fragment, it overwrites part of the value for inertia. Right after this code fragment, there is a check to see if the character should brake (this happens only for shallow angles), and right after this, there is a check for ground speed/inertia for braking. So the braking check is done after the register is partially overwritten. And the reason why it is 4.5 pixels/frame instead of 4 pixels/frame is because 1 frame's worth of deceleration is applied before the comparison.
     
    Last edited: Jan 19, 2021
    • Informative Informative x 3
    • Useful Useful x 2
    • List
  10. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,143
    6
    18
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    Another asymmetry, this time between left and right: take a look as these diveboard springs:
    [​IMG]
    No matter how hard you try, you can never get a launch off the left-facing diveboard with the same speed you can from the right-facing one. The code that causes this is here:
    Code (ASM):
    1. loc_2645E:
    2.     move.w    x_pos(a0),d0
    3.     subi.w    #$1C,d0
    4.     sub.w    x_pos(a1),d0
    5.     neg.w    d0
    6.     btst    #0,status(a0)
    7.     beq.s    loc_2647A
    8.     not.w    d0
    9.     addi.w    #$27,d0
    The reason for the bug is that it misplaces the characters relative to the board for computing the power of the launch. The fix is dead easy: take the last line:
    Code (ASM):
    1.     addi.w    #$27,d0
    And change it to this:
    Code (ASM):
    1.     addi.w    #2*$1C,d0
     
    Last edited: Jan 19, 2021
  11. Fred

    Fred

    Taking a break Oldbie
    1,563
    114
    43
    Portugal
    Sonic 3 Unlocked
    Hmm, $1C times 2 is $38... but 38 decimal is $26 hex, which is only one off from $27.

    Wonder what happened there?
     
  12. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,143
    6
    18
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    You might have figured out what happened. Because
    Code (Text):
    1. not.w d0 == neg.w d0 ; subq.w #1, d0
    they might have thought that they needed to add +1 to $38 to get $39. But then they forgot to write the $ in the code, and it became a $27 when reverse engineered.

    As it turns out, that +1 gives the wrong result -- the last pixel you can stand on when the dive board is flipped will loop back to minimal strength launch, which is not what happens on the unflipped dive board.
     
  13. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,143
    6
    18
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    Here is a CPZ boss crash: https://www.twitch.tv/videos/47314506

    In case you are curious, this bug is of the "how the hell this boss even works" variety. To fix it, find this:

    Code (ASM):
    1.  
    2. Obj5D_Pipe_Retract_ChkID:
    3.     moveq   #0,d7
    4.     move.b  #ObjID_CPZBoss,d7
    5.     cmp.b   id(a1),d7   ; is object a subtype of the CPZ Boss?
    6.  
    and change it to this:

    Code (ASM):
    1.  
    2. Obj5D_Pipe_Retract_ChkID:
    3.     cmpi.b   #ObjID_CPZBoss,id(a1)   ; is object a subtype of the CPZ Boss?
    4.  
    What is the bug?

    Register d7 is used by RunObjects routine to keep track of how many objects remain to be processed. Using it without saving before (as this code does) is a recipe for disaster. This piece of code runs when Eggman is retracting his pipe, and whenever an object with the same Y position as the next-to-last pipe segment. When this happens, the following may occur:
    • if there remains more than $5D objects to process (ObjID_CPZBoss is equal to $5D in stock S2), some objects may remain unprocessed;
    • if there remains between $59 and $5D objects, all objects will be processed, and some of the $200 bytes after will be treated as objets; if this area is clear, no ill effects will occur;
    • if there remains less than $59 objects to process, primary collision, then secondary collision, etc., will start to be interpreted as object data, and you can get all sorts of crashes.
     
    Last edited: Apr 15, 2021
    • Like Like x 2
    • Useful Useful x 2
    • List
  14. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,143
    6
    18
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    A double post, and another bug from the Chemical Plant boss. This time it is a graphical bug which was originally found and fixed by djohe; I am just sharing it.

    After you beat the CPZ boss and the explosions finish, the boss is supposed to spawn a puff of smoke when blasting off. There is even code for it. However, due to a mistake in the code, it never appears. If you fix this mistake, you will see it appearing with incorrect graphics and palette, so we will fix that too.

    Open your disassembly and find this code:

    Code (ASM):
    1.  
    2. loc_2E9A8:
    3.     movea.l Obj5D_parent(a0),a1 ; a1=object
    4.     btst    #6,Obj5D_status2(a1)
    5.     bne.s   +
    6.     rts
    7. ; ===========================================================================
    8. +
    9.     addq.b  #2,routine_secondary(a0)
    10.     move.l  #Obj5D_MapUnc_2EEA0,mappings(a0)
    11.     move.w  #make_art_tile(ArtTile_ArtNem_EggpodJets_1,0,0),art_tile(a0)
    12.  
    Change this to:

    Code (ASM):
    1.  
    2. loc_2E9A8:
    3.     movea.l Obj5D_parent(a0),a1 ; a1=object
    4.     btst    #6,Obj5D_status2(a1)
    5.     bne.s   +
    6.     rts
    7. ; ===========================================================================
    8. +
    9.     addq.b  #2,routine(a0)
    10.     move.l  #Obj5D_MapUnc_2EEA0,mappings(a0)
    11.     move.w  #make_art_tile(ArtTile_ArtNem_BossSmoke_1,1,0),art_tile(a0)
    12.  
    This will fix the spawning of the smoke puff (the change from routine_secondary to routine) and set correct graphics and palette (the other change).
     
    • Useful Useful x 2
    • Informative Informative x 1
    • List
  15. Clownacy

    Clownacy

    Tech Member
    828
    61
    28