don't click here

MoDule's bugfix guides Vol. 1

Discussion in 'Engineering & Reverse Engineering' started by MoDule, May 16, 2011.

  1. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    I know that the guide is for S2, but you should mention that S3&K fixes it differently (by taking into account the difference between the standing and rolling heights) and the fix is not needed there.

    Also, the pages are showing a wrong title for all 3 bug fixes.

    Edit: also, I think that the arrow width might be mentioned as being optional: it is an arrow, after all, and it makes sense for Sonic to try to balance on it.
     
  2. ICEknight

    ICEknight

    Researcher Researcher
    Hmm, so the arrows don't have a set width to them? If that's not causing any problems, it might indeed be debatable wether it's an oversight or a design decision to make the characters always use their balance animation when standing on them.

    Yeah, having the official bugfixes documented as well would be sweet.
     
  3. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    I don't know what you mean. I see the bug both in S3 and S3&K. The camera is always a few pixels too high when Tails rolls. I even checked the vertical scroll routine and it makes the same mistake as S2.

    I know. That happened when I moved the guides from my personal space to the guides section and screwed up the first time. Now they're stuck with those weird titles and I don't know how to fix it.

    You raise a good point. I'll do that right away.
     
  4. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    Really? That is odd: when I look in frame advance, I don't see the camera moving at all when Sonic, Tails or Knuckles roll in S3&K (or Sonic/Knuckles in S2), but I see the jerking you mention in S2 with Tails.

    Edit: the above is not meant as sarcasm, by the way: I am genuinely stumped (but rereading the post left some ambiguity in interpretation).
     
  5. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    It's not so much during the roll as in the transition from walking to rolling. I just tested it with debug mode in CNZ act 1 (Carnival Night Zone, S3&K), looking at the camera positions. For walking it gives me a y position of $670 and for rolling a position of $66C. It's also pretty noticeable if you look at the bottom of the screen. This is with Tails; it doesn't happen for the other two.
     
  6. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    You are correct. As it turns out, I was testing at the start of AIZ1, where strangely it doesn't happen. I also assumed that S3&K fixed by using the height difference because I had already fixed it in my hack when I ported S3&K default height/default width to fix a few bugs with ground iteraction that rendered the bubble shield useless. So at least for S3&K, there is an alternate bug fix which is worth singling out.

    Regarding the page titles: they were wrong because the page was being incorrectly redirected to itself. I moved the content from the redirected target page to the correct location.
     
  7. FraGag

    FraGag

    Tech Member
    The actual problem was that MoDule first moved them by adding http://info.sonicretro.org/ at the beginning of the article name. In the revision history, I can see that he tried again without, but it was already too late, apparently. The articles starting with Http://info.sonicretro.org/ (with a capital H due to the wiki naming rules) cannot be accessed through the short URL because MediaWiki moves a slash around, which causes it to not find the page. I tried to move one of the pages back, but it gave me an error so I gave up. The bad articles should be deleted by a wiki sysop: here, here and here.
     
  8. This is an awesome topic with vital information and insight to various bugs for hack developers. But I'm curious though if any of these fixes can be utilized by the normal gamer using Game Genie or Pro Action Replay codes.
     
  9. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    I have updated this guide because the bug fix was slightly buggy in itself, and the description of the bug wasn't 100%. As an additional bonus, the new fix also removes the bug where pressing jump right after releasing a spindash causes Sonic to jump straight up instead of forward.
     
  10. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    I'm curious, what was wrong with the original one? The new version is quite different.

    So I finally got around to writing another guide. This time it's about a known bug in OOZ (you know, the fun one which lets you go really fast).

    How-to:Fix the OOZ launcher speed up glitch

    I also updated the Tails roll camera guide. The original fix only worked if the player was on the ground. There's a similar bug when a player rolls while going up/down a wall, but I haven't been able to come up with a satisfactory fix for this yet.

    Lastly, I added my version for that other Super Sonic bug. If you want to add yours as an alternative, feel free to do so.

    Just for fun, here's a list of text files to show what else I'm working on (slowly):
    • Fix the Rexxon crash bug.txt
    • Retain speed on slope after getting hit.txt
    • Give characters individual chain bonus counters.txt
    • Fix CPZ spin tube bug.txt
    • Fix bug in pinball mode object.txt
    They're all empty right now and there's a few for which I haven't even made a file yet, but I'm sure you get the idea.
     
  11. flamewing

    flamewing

    Emerald Hunter Tech Member
    1,161
    65
    28
    France
    Sonic Classic Heroes; Sonic 2 Special Stage Editor; Sonic 3&K Heroes (on hold)
    As it turns out, it worked around the bug in a way that was as close to fixing it as possible, but without truly fixing it and adding other bugs in the mix. As it was, a character could prevent being scrolled into the boss arena by starting a spindash and not releasing it, for example.

    Nice work on the other guides.
     
  12. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    Possible, probably, easy, no. The simplest one I can think of is the roll jump height fix, since all you'd have to do there is replace the offending instructions with NOPs, or ones where you just have to change a number or branch type.

    Ah yes, that makes sense.

    Now I just have to write them...
     
  13. Elratauru

    Elratauru

    Little Shiny Emurralds Member
    Thank you for this! I just noticed the jump rolling 5-px thing bug and that explained why my old Flash Sonic engine did that sometimes :P!

    Even though Im not gonna use it for hacking, it will come handy for future updates and re-writes of that old engine! :)
     
  14. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    Since it's been a while, I thought I'd post a new little bug fix I just finished. No wiki this time, sorry. If someone would be kind enough to volunteer to wiki this, I'd be very thankful. Otherwise, I'd just take care of it myself, (whe)never.
    What I've got this time is a bug I've actually already posted partial fixes for in the past and even made a slightly better fix recently. Pretty much out of the blue, a much more elegant solution came to me just a few minutes ago.

    The bug: The player object's speed values behave inconsistently when entering and exiting water. For instance, if a player falls into water while speed shoes are active, the sped up movement stats will be lost; should the power up run out under water, then the player will receive above water normal stats. This bug exists in all of the four main series games.

    The fix (s2 semi recent hg disassembly):
    First, locate Obj01_InWater and comment out or remove a few lines as follows:
    Code (ASM):
    1.     (...)
    2. ;   move.w  #$300,(Sonic_top_speed).w
    3. ;   move.w  #6,(Sonic_acceleration).w
    4. ;   move.w  #$40,(Sonic_deceleration).w
    5. ;   tst.b   (Super_Sonic_flag).w
    6. ;   beq.s   +
    7. ;   move.w  #$500,(Sonic_top_speed).w
    8. ;   move.w  #$18,(Sonic_acceleration).w
    9. ;   move.w  #$80,(Sonic_deceleration).w
    10. ;+
    11.     (...)
    Do the same for Obj01_OutWater:
    Code (ASM):
    1.     (...)
    2. ;   move.w  #$600,(Sonic_top_speed).w
    3. ;   move.w  #$C,(Sonic_acceleration).w
    4. ;   move.w  #$80,(Sonic_deceleration).w
    5. ;   tst.b   (Super_Sonic_flag).w
    6. ;   beq.s   +
    7. ;   move.w  #$A00,(Sonic_top_speed).w
    8. ;   move.w  #$30,(Sonic_acceleration).w
    9. ;   move.w  #$100,(Sonic_deceleration).w
    10. ;+
    11.     (...)
    It might seem odd to simply remove these lines, as they are what make the players slower/faster under/above water, but the next set of changes should make the solution clear:
    Locate Sonic_Move, which should look like this:
    Code (ASM):
    1. Sonic_Move:
    2.     move.w  (Sonic_top_speed).w,d6
    3.     move.w  (Sonic_acceleration).w,d5
    4.     move.w  (Sonic_deceleration).w,d4
    5.     (...)
    Underneath the last displayed line, add this:
    Code (ASM):
    1.     btst    #6,status(a0)   ; is Sonic under water?
    2.     beq.s   +       ; if not, branch
    3.     lsr.w   #1,d4   ; reduce stats
    4.     lsr.w   #1,d5
    5.     lsr.w   #1,d6
    6. +
    Next, do the same for Sonic_RollSpeed:
    Code (ASM):
    1.     move.w  (Sonic_top_speed).w,d6
    2.     asl.w   #1,d6
    3.     move.w  (Sonic_acceleration).w,d5
    4.     asr.w   #1,d5   ; natural roll deceleration = 1/2 normal acceleration
    5.     move.w  #$20,d4 ; controlled roll deceleration... interestingly,
    6.             ; this should be Sonic_deceleration/4 according to Tails_RollSpeed,
    7.             ; which means Sonic is much better than Tails at slowing down his rolling when he's underwater
    8.     btst    #6,status(a0)   ; is Sonic under water?
    9.     beq.s   +       ; if not, branch
    10.     lsr.w   #1,d5   ; reduce stats
    11.     lsr.w   #1,d6
    12. +
    and Sonic_ChgJumpDir:
    Code (ASM):
    1.     move.w  (Sonic_top_speed).w,d6
    2.     move.w  (Sonic_acceleration).w,d5
    3.     asl.w   #1,d5
    4.     btst    #6,status(a0)   ; is Sonic under water?
    5.     beq.s   +       ; if not, branch
    6.     lsr.w   #1,d5   ; reduce stats
    7.     lsr.w   #1,d6
    8. +
    Finally, in Sonic_RevertToNormal remove the following lines:
    Code (ASM):
    1.     (...)
    2. ;   btst    #6,status(a0)   ; Check if underwater, return if not
    3. ;   beq.s   return_1AC3C
    4. ;   move.w  #$300,(Sonic_top_speed).w
    5. ;   move.w  #6,(Sonic_acceleration).w
    6. ;   move.w  #$40,(Sonic_deceleration).w
    Of course, these same changes need to be applied to the other player objects where applicable.
    In S3&K, the speed stats are not read or written to directly by the player objects. Instead, the address of the first value is loaded into a4 and the RAM addresses are accessed as follows:
    Code (ASM):
    1.     move.w  #$600,(a4)  ; top speed
    2.     move.w  #$C,2(a4)   ; acceleration
    3.     move.w  #$80,4(a4)  ; deceleration
    If this fix is applied, the Wrong speed when transforming under water part of the Super Sonic fixes no longer needs to, or rather, should not be applied.

    An explanation: The original problem comes from the fact that there are so many cases to consider when assigning the correct speed values with and without speed shoes and when super. Most of the cases were simply left out. Our fix simply circumvents the problem by calculating the correct under water stats when necessary.

    Incidentally, this only works if you wish to preserve the original under water physics, namely making everything half as fast. If for whatever reason someone wants to use a custom set of speed values under water, I will gladly post my previous fix as well.
     
  15. Tiddles

    Tiddles

    Diamond Dust Tech Member
    471
    0
    0
    Leicester, England
    Get in an accident and wake up in 1973
    Nice one. I'd been thinking I wanted to fix that pretty soon, so I'll give this a whirl sometime.
    Thanks for this, and for the many other bits and pieces I've used from this topic.
     
  16. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    Bit of a big bump, sorry, but I just noticed there's a bug in one of my bug-fixes. The one about the ARZ boss's pillars, to be more precise: this one.
    I forgot to clear the pillar object's standing and pushing bits, which would result in characters sliding along the ground, because they'd be put into an in-air state every frame until the pillars are gone. Anyway, that's fixed now.

    I'll try and see if I can come up with some new things soon.
     
  17. redhotsonic

    redhotsonic

    Also known as RHS Tech Member
    1,587
    10
    18
    United Kingdom
    YouTuber
    Fixing the bug where ARZ boss leaves too early (leaves immediately after the 8th hit) or the DEZ boss when Silver Sonic goes upside down and you can't move on would be a nice addition. I've tried, but no luck so far.
     
  18. Tiddles

    Tiddles

    Diamond Dust Tech Member
    471
    0
    0
    Leicester, England
    Get in an accident and wake up in 1973
    By the way, I did apply your latest water fix to S3C, and it works very nicely indeed. :)
    There were a couple of other places I had to alter in S3, I think, but I did this ages ago so I can't remember for sure... if anyone's interested I can try to dig it out at some point.
     
  19. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    Speaking of the water fix, I think I might have left out a few edge cases in the original fix. I'll post that one tomorrow.


    I think someone's already fixed the first one, not sure, though. Never even seen the second one. I'll try giving it a look, can't make any guarantees.

    Edit: OK, here's a short writeup on what I changed in my water fix. Let me know if this makes sense. For reference, here's the original guide.
    To begin with, let's look at the code in vanilla Sonic 2:

    Code (ASM):
    1. ; loc_1A18E:
    2. Obj01_InWater:
    3.     move.w  (Water_Level_1).w,d0
    4.     cmp.w   y_pos(a0),d0    ; is Sonic above the water?
    5.     bge.s   Obj01_OutWater  ; if yes, branch
    6.  
    7.     ; <-- (1)
    8.  
    9.     bset    #6,status(a0)   ; set underwater flag
    10.     bne.s   return_1A18C    ; if already underwater, branch
    11.  
    12.     movea.l a0,a1
    13.     bsr.w   ResumeMusic
    14.     move.b  #ObjID_SmallBubbles,(Sonic_BreathingBubbles+id).w ; load Obj0A (sonic's breathing bubbles) at $FFFFD080
    15.     move.b  #$81,(Sonic_BreathingBubbles+subtype).w
    16.     move.l  a0,(Sonic_BreathingBubbles+$3C).w
    17.     move.w  #$300,(Sonic_top_speed).w
    18.     move.w  #6,(Sonic_acceleration).w
    19.     move.w  #$40,(Sonic_deceleration).w
    20.     tst.b   (Super_Sonic_flag).w
    21.     beq.s   +
    22.     move.w  #$500,(Sonic_top_speed).w
    23.     move.w  #$18,(Sonic_acceleration).w
    24.     move.w  #$80,(Sonic_deceleration).w
    25. +
    26.     asr.w   x_vel(a0)
    27.     asr.w   y_vel(a0)   ; memory operands can only be shifted one bit at a time
    28.  
    29.     ; <-- (3)
    30.  
    31.     asr.w   y_vel(a0)
    32.     beq.s   return_1A18C
    33.     move.w  #$100,(Sonic_Dust+anim).w   ; splash animation
    34.     move.w  #SndID_Splash,d0    ; splash sound
    35.     jmp (PlaySound).l
    What I did in the original guide was to place a check if Sonic is moving upward while entering water at (1) to prevent his y_vel from being lowered. This was so jumping while close to the water surface doesn't unexpectedly lower your jump height. I figured, it's probably better to have such a check for exiting water, as well, even if I can't think of a scenario in which you'd move above the water while falling. So here it is:
    In the following code:

    Code (ASM):
    1. ; loc_1A1FE:
    2. Obj01_OutWater:
    3.     bclr    #6,status(a0) ; unset underwater flag
    4.     beq.s   return_1A18C ; if already above water, branch
    5.  
    6.     movea.l a0,a1
    7.     bsr.w   ResumeMusic
    8.     move.w  #$600,(Sonic_top_speed).w
    9.     move.w  #$C,(Sonic_acceleration).w
    10.     move.w  #$80,(Sonic_deceleration).w
    11.     tst.b   (Super_Sonic_flag).w
    12.     beq.s   +
    13.     move.w  #$A00,(Sonic_top_speed).w
    14.     move.w  #$30,(Sonic_acceleration).w
    15.     move.w  #$100,(Sonic_deceleration).w
    16. +
    17.     cmpi.b  #4,routine(a0)  ; is Sonic falling back from getting hurt?
    18.     beq.s   +       ; if yes, branch
    19.  
    20.     ; <-- (2)
    21.  
    22.     asl y_vel(a0)
    23. +
    24.     tst.w   y_vel(a0)
    25.     beq.w   return_1A18C
    26.     move.w  #$100,(Sonic_Dust+anim).w   ; splash animation
    27.     movea.l a0,a1
    28.     bsr.w   ResumeMusic
    29.     cmpi.w  #-$1000,y_vel(a0)
    30.     bgt.s   +
    31.     move.w  #-$1000,y_vel(a0)   ; limit upward y velocity exiting the water
    32. +
    33.     move.w  #SndID_Splash,d0    ; splash sound
    34.     jmp (PlaySound).l
    35. ; End of subroutine Sonic_Water
    add this:

    Code (ASM):
    1.     tst.w   y_vel(a0)   ; is Sonic moving downward?
    2.     bpl.w   return_1A18C    ; if yes, don't boost his speed
    at the location indicated by (2). Of course, this also needs to be done for Tails and any other characters other than Sonic.
    Another thing I experimented with, was to move the check at (1) to the location at (3). This sort of still allows the bug to happen, but it only divides Sonic's y_vel by 2, avoiding the original problem. I'm not sure which one I like better, though.
     
  20. MoDule

    MoDule

    Tech Member
    327
    24
    18
    Procrastinating from writing bug-fix guides
    Double post, so
    After tinkering with this a little more, I think I've found something satisfying.
    So now my routines look like this:

    Code (ASM):
    1. ; loc_1A18E:
    2. Obj01_InWater:
    3.     move.w  (Water_Level_1).w,d0
    4.     cmp.w   y_pos(a0),d0    ; is Sonic above the water?
    5.     bge.s   Obj01_OutWater  ; if yes, branch
    6.  
    7.     bset    #6,status(a0)   ; set underwater flag
    8.     bne.s   return_1A18C    ; if already underwater, branch
    9.  
    10.     movea.l a0,a1
    11.     bsr.w   ResumeMusic
    12.     move.b  #ObjID_SmallBubbles,(Sonic_BreathingBubbles+id).w ; load Obj0A (sonic's breathing bubbles) at $FFFFD080
    13.     move.b  #$81,(Sonic_BreathingBubbles+subtype).w
    14.     move.l  a0,(Sonic_BreathingBubbles+$3C).w
    15.     move.w  #$300,(Sonic_top_speed).w
    16.     move.w  #6,(Sonic_acceleration).w
    17.     move.w  #$40,(Sonic_deceleration).w
    18.     tst.b   (Super_Sonic_flag).w
    19.     beq.s   +
    20.     move.w  #$500,(Sonic_top_speed).w
    21.     move.w  #$18,(Sonic_acceleration).w
    22.     move.w  #$80,(Sonic_deceleration).w
    23. +
    24. ;   asr.w   x_vel(a0)
    25. ;   asr.w   y_vel(a0)   ; memory operands can only be shifted one bit at a time
    26. ;   asr.w   y_vel(a0)
    27. ;-- new stuff starts here
    28.     asr.w   y_vel(a0)   ; reduce Sonic's falling speed
    29.     bmi.s   return_1A18C    ; if Sonic is moving upward (I.e. from jumping), don't slow him down
    30.     asr.w   x_vel(a0)   ; else, slow him down...
    31.     asr.w   y_vel(a0)   ; ... and reduce his falling speed more
    32. ;-- new stuff ends here
    33.     beq.s   return_1A18C
    34.     move.w  #$100,(Sonic_Dust+anim).w   ; splash animation
    35.     move.w  #SndID_Splash,d0    ; splash sound
    36.     jmp (PlaySound).l
    Here, I replaced the commented out block with the four lines underneath.
    In the other routine, I just moved the check up a few lines:

    Code (ASM):
    1. ; loc_1A1FE:
    2. Obj01_OutWater:
    3.     bclr    #6,status(a0) ; unset underwater flag
    4.     beq.s   return_1A18C ; if already above water, branch
    5.  
    6.     movea.l a0,a1
    7.     bsr.w   ResumeMusic
    8.     move.w  #$600,(Sonic_top_speed).w
    9.     move.w  #$C,(Sonic_acceleration).w
    10.     move.w  #$80,(Sonic_deceleration).w
    11.     tst.b   (Super_Sonic_flag).w
    12.     beq.s   +
    13.     move.w  #$A00,(Sonic_top_speed).w
    14.     move.w  #$30,(Sonic_acceleration).w
    15.     move.w  #$100,(Sonic_deceleration).w
    16. +
    17.     ; <-- here
    18.     tst.w   y_vel(a0)       ; is Sonic moving downward?
    19.     bpl.w   return_1A18C    ; if yes, don't boost his speed
    20.  
    21.     cmpi.b  #4,routine(a0)  ; is Sonic falling back from getting hurt?
    22.     beq.s   +       ; if yes, branch
    23.     asl y_vel(a0)
    24. +
    25.     tst.w   y_vel(a0)
    26.     beq.w   return_1A18C
    27.     move.w  #$100,(Sonic_Dust+anim).w   ; splash animation
    28.     movea.l a0,a1
    29.     bsr.w   ResumeMusic
    30.     cmpi.w  #-$1000,y_vel(a0)
    31.     bgt.s   +
    32.     move.w  #-$1000,y_vel(a0)   ; limit upward y velocity exiting the water
    33. +
    34.     move.w  #SndID_Splash,d0    ; splash sound
    35.     jmp (PlaySound).l
    36. ; End of subroutine Sonic_Water
    I'm probably over-thinking this...

    Edit: Just noticed a small bug in my edited InWater routine. I was shifting x_vel(a0) and y_vel(a0) in the wrong order, which caused the branch to return_1A18C to be true when the x_vel is 0, even though it should have been the y_vel. Anyway, I've fixed it in the code block above.