don't click here

Bug fixes in the S2 Super Sonic palette cycle

Discussion in 'Engineering & Reverse Engineering' started by Tets, Aug 29, 2008.

Thread Status:
Not open for further replies.
  1. Tets

    Tets

    one rude dude Oldbie
    903
    70
    28
    Here are a couple of easy fixes for seldom seen bugs in Sonic 2's Super Sonic palette cycle. I came up with these while working on modifications for my own hack. These bug are almost never seen, but if you've spent as much time screwing around with SS code as I have, they really stand out. I'm using Xenowhirl's 2007 disasm for this quick guide.

    The first one isn't really a bug so much as an oversight. The "transformation" part of the cycle doesn't update the underwater palette at all, potentially resulting in strange colors while transforming underwater. This usually isn't a problem, as the average player is past CPZ and ARZ by the time he gets all the chaos emeralds, but if you're changing the level order or adding water to later levels, you'll probably want to fix it. First, we'll have a look at the first two parts of the palcycle code, which deal with the transformation and de-transformation, respectively:
    Code (ASM):
    1. PalCycle_SuperSonic:
    2.     move.b  (Super_Sonic_palette).w,d0
    3.     beq.s   return_2186
    4.     bmi.w   loc_21E6
    5.     subq.b  #1,d0
    6.     bne.s   loc_2188
    7.     subq.b  #1,(Palette_frame_count).w
    8.     bpl.s   return_2186
    9.     move.b  #3,(Palette_frame_count).w
    10.     lea (Pal_2246).l,a0
    11.     move.w  ($FFFFF65C).w,d0
    12.     addq.w  #8,($FFFFF65C).w
    13.     cmpi.w  #$30,($FFFFF65C).w
    14.     bcs.s   +
    15.     move.b  #-1,(Super_Sonic_palette).w
    16.     move.b  #0,(MainCharacter+obj_control).w
    17. +   lea (Normal_palette+4).w,a1
    18.     move.l  (a0,d0.w),(a1)+
    19.     move.l  4(a0,d0.w),(a1)
    20.  
    21. return_2186:
    22.     rts
    23. ; ===========================================================================
    24.  
    25. loc_2188:
    26.     subq.b  #1,(Palette_frame_count).w
    27.     bpl.s   return_2186
    28.     move.b  #3,(Palette_frame_count).w
    29.     lea (Pal_2246).l,a0
    30.     move.w  ($FFFFF65C).w,d0
    31.     subq.w  #8,($FFFFF65C).w
    32.     bcc.s   loc_21B0
    33.     move.b  #0,($FFFFF65C).w
    34.     move.b  #0,(Super_Sonic_palette).w
    35. loc_21B0:
    36.     lea (Normal_palette+4).w,a1
    37.     move.l  (a0,d0.w),(a1)+
    38.     move.l  4(a0,d0.w),(a1)
    39.     lea (Pal_22C6).l,a0
    40.     cmpi.b  #$D,(Current_Zone).w
    41.     beq.s   +
    42.     cmpi.b  #$F,(Current_Zone).w
    43.     bne.s   return_2186
    44.     lea (Pal_2346).l,a0
    45. +   lea (Underwater_palette+4).w,a1
    46.     move.l  (a0,d0.w),(a1)+
    47.     move.l  4(a0,d0.w),(a1)
    48.     rts
    You'll notice the second part, starting at loc_2188, has two zone checks near the end which aren't present in the first part. One line above the first zone check is where the first underwater palette is loaded, Pal_22C6. Copy all the lines from there to before the rts and paste them in their corresponding place in the transformation cycle.
    Code (ASM):
    1. PalCycle_SuperSonic:
    2.     move.b  (Super_Sonic_palette).w,d0
    3.     beq.s   return_2186
    4.     bmi.w   loc_21E6
    5.     subq.b  #1,d0
    6.     bne.s   loc_2188
    7.     subq.b  #1,(Palette_frame_count).w
    8.     bpl.s   return_2186
    9.     move.b  #3,(Palette_frame_count).w
    10.     lea (Pal_2246).l,a0
    11.     move.w  ($FFFFF65C).w,d0
    12.     addq.w  #8,($FFFFF65C).w
    13.     cmpi.w  #$30,($FFFFF65C).w
    14.     bcs.s   +
    15.     move.b  #-1,(Super_Sonic_palette).w
    16.     move.b  #0,(MainCharacter+obj_control).w
    17. +   lea (Normal_palette+4).w,a1
    18.     move.l  (a0,d0.w),(a1)+
    19.     move.l  4(a0,d0.w),(a1)
    20.     lea (Pal_22C6).l,a0
    21.     cmpi.b  #$D,(Current_Zone).w
    22.     beq.s   +
    23.     cmpi.b  #$F,(Current_Zone).w
    24.     bne.s   return_2186
    25.     lea (Pal_2346).l,a0
    26. +   lea (Underwater_palette+4).w,a1
    27.     move.l  (a0,d0.w),(a1)+
    28.     move.l  4(a0,d0.w),(a1)
    29.  
    30. return_2186:
    31.     rts
    The transformation will now look perfect underwater.

    Now on to the next bug. This has to do with transforming, reverting, and then transforming again in the same level. This was another thing that probably wasn't expected. You can't revert at will, so most players would probably only transform once per level. This bug has a simple cause, a particular RAM address is not properly zeroed during the de-transformation cycle, and it manifests itself as Sonic flashing a completely different color the next time he transforms. To fix it, simply change this line:
    Code (ASM):
    1.     move.b  #0,($FFFFF65C).w
    to this:
    Code (ASM):
    1.     move.w  #0,($FFFFF65C).w
    It took me a while to figure that out because it wasn't immediately obvious to me what address F65C was used for. It turns out that it contains the offset used by the cycle code to determine which colors to load. If its value is $0, it loads the first set of colors, if it's $8 it loads the second set (remember, two bytes per palette entry, and S2 Sonic has four blues), and so on. All other instructions dealing with this address use word-length values, so using a byte-length move instruction to zero it is entirely ineffective.

    And that concludes my guide. Assuming I didn't make some tragic mistake, everything should be just peachy after applying the changes documented above.
     
  2. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    I did this a while ago in my own hack when I was adding Super Tails and stuff. This is one of those things that should be in every hack, so good work writing a guide.
    :psyduck:
     
  3. ICEknight

    ICEknight

    Researcher Researcher
    Great post, I didn't know about these.
    Yeah, we need a "Sonic 2 known bugs" topic...
     
  4. saxman

    saxman

    Oldbie Tech Member
    I don't remember ever seeing this bug personally.

    In regards to bugs in general, has anyone fixed the bug that crashes the game sometimes when hitting Rexon?
     
  5. muteKi

    muteKi

    Fuck it Member
    7,850
    131
    43
    It's funny -- I actually only encountered the bug you refer to for the first time yesterday.
     
  6. saxman

    saxman

    Oldbie Tech Member
    Actually, I'd love to see a hack that corrects all these bugs -- http://info.sonicretro.org/Sonic_the_Hedge...list#Level_bugs

    (I added two to the list and deleted one that was irrelevent).

    And nothing else added or changed -- just a release that fixes some of the unfixed bugs. Maybe release the source code to the whole thing for download so that people beginning their hacks can start with a bug-fixed version of Sonic 2.
     
  7. ICEknight

    ICEknight

    Researcher Researcher
    Wasn't it fixed in v.02?
     
  8. saxman

    saxman

    Oldbie Tech Member
    I don't know. I haven't actually played Rev 02 and know very little about it.
     
  9. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    I might do that at some point, most of those bugs are quick fixes.

    But someone will probably get to it before me...
     
  10. Tets

    Tets

    one rude dude Oldbie
    903
    70
    28
    qiuu already posted a quick fix for the EHZ foreground scrolling bug in MoDule's LZ water ripple in s2 thread:
    As for the 14 continues chime bug, I fixed that years ago using a hex editor, before ASM hacking became popular. It's an even easier fix with the disassembly though. You just have to know where to look. 8)

    And if I'm not mistaken, Rev02 fixes the "Super Sonic at the end of a level" bug by just adding a timer update check at the beginning of Sonic_CheckGoSuper. At least that's how I did it. I can still trigger the bug by transforming at precisely the moment Sonic passes the end sign, but I've only been able to do so twice.
     
  11. ICEknight

    ICEknight

    Researcher Researcher
    Well, it would be useful if the wiki had a link to each fix, near the correspondent bug...
     
  12. saxman

    saxman

    Oldbie Tech Member
    Another bug I just thought of, and it happens all the time. Aquatic Ruin act 1, when you go up one of the slopes and Grounder approaches, Sonic goes right through him. I don't have revision 2, so I can't say if this was fixed. But I think it's worthy of being fixed.
     
  13. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    I've never had that problem, either that, or I thought that the grounder was still in the wall, thus not hurting Sonic.
     
  14. muteKi

    muteKi

    Fuck it Member
    7,850
    131
    43
    I know about that bug; it occurs at around coordinates 1A94 027C.


    Makes the level a lot easier to deal with.
     
  15. FraGag

    FraGag

    Tech Member
    If my memory's good, it happens because the engine only tests collision with one object at a time, and Sonic collides with the leaves object first. That's the reason why you can't collect rings when you touch the lava.
     
  16. ICEknight

    ICEknight

    Researcher Researcher
    ...Wasn't there an object that just makes Sonic invulnerable when touching it, as if the enemies couldn't find him behind all those plants, or something?
     
  17. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    I don't believe so. I've been working with S2 for a while, and I have not come across such an item.


    Edit: Grammar, mine sucks when I wake up.
     
  18. ICEknight

    ICEknight

    Researcher Researcher
    That object might be actually the same that spawns leaves as you pass by, which is when Sonic "can't be seen" by the badniks.
     
  19. Hitaxas

    Hitaxas

    Retro 80's themed Twitch streamer ( on hiatus) Member
    I just checked, the object IS the falling leaves object.

    Code (ASM):
    1. ; Object 2C - Sprite that makes leaves fly off when you hit it from ARZ
     
Thread Status:
Not open for further replies.