How to fix the y-wrap camera glitch (Sonic 2 and S3K)

Discussion in 'Tutorials Archive' started by redhotsonic, Aug 4, 2012.

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

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England

    KingofHarts wanted to know the answer to this question. I actually always wanted this to be fixed, but never bothered looking. But as someone else wants to know the answer, I thought I'll investigate. And I've come up with a fix! For Sonic 2 and Sonic 3K.


    Sonic 2 fix - XenoWhirl's Disassembly


    Go to "sub_D77A:" and change this:



    sub_D77A:
    moveq #0,d1


    move.w y_pos(a0),d0


    sub.w (a1),d0


    cmpi.w #-$100,(Camera_Min_Y_pos).w


    bne.s loc_D78E


    andi.w #$7FF,d0



    to this:



    sub_D77A:
    moveq #0,d1


    move.w y_pos(a0),d0


    sub.w (a1),d0


    tst.w (Camera_Min_Y_pos).w ; Does this level y-wrap?


    bpl.s loc_D78E ; If not, branch and skip looping


    cmpi.w #$60,(Camera_Y_pos_bias).w ; Is screen in its default position?


    beq.s + ; If so, branch, and loop


    ; It's not at its default position; Sonic must be looking up or down


    tst.w (Sonic_Look_delay_counter).w ; Is Sonic still looking up or down?


    bne.s + ; If so, branch, and keep looping, Sonic ain't moving anywhere!


    ; So, Sonic was looking up or down, but now he isn't


    move.w #$60,(Camera_Y_pos_bias).w ; move the screen to its default position quickly


    +


    andi.w #$7FF,d0 ; Forever loop



    Done, explanation further below after these disassembly fixes.


    Sonic 2 fix - SVN disassembly


    Go to "ScrollVerti:" and change this:



    ScrollVerti:
    moveq #0,d1


    move.w y_pos(a0),d0


    sub.w (a1),d0 ; subtract camera Y pos


    cmpi.w #-$100,(Camera_Min_Y_pos).w ; does the level wrap vertically?


    bne.s + ; if not, branch


    andi.w #$7FF,d0



    to this:



    ScrollVerti:
    moveq #0,d1


    move.w y_pos(a0),d0


    sub.w (a1),d0 ; subtract camera Y pos


    tst.w (Camera_Min_Y_pos).w ; Does this level y-wrap?


    bpl.s ++ ; If not, branch and skip looping


    cmpi.w #$60,(Camera_Y_pos_bias).w ; Is screen in its default position?


    beq.s + ; If so, branch, and loop


    ; It's not at its default position; Sonic must be looking up or down


    tst.w (Sonic_Look_delay_counter).w ; Is Sonic still looking up or down?


    bne.s + ; If so, branch, and keep looping, Sonic ain't moving anywhere!


    ; So, Sonic was looking up or down, but now he isn't


    move.w #$60,(Camera_Y_pos_bias).w ; move the screen to its default position quickly


    +


    andi.w #$7FF,d0 ; Forever loop



    Done, explanation further below after the last disassembly fix.


    Sonic 3K fix - SVN disassembly


    Go to "MoveCameraY:" and change this:



    MoveCameraY:
    moveq #0,d1


    move.w $14(a0),d0


    sub.w (a1),d0


    cmpi.w #-$100,(Camera_min_Y_pos).w


    bne.s loc_1C132


    and.w (Screen_Y_wrap_value).w,d0



    to this:



    MoveCameraY:
    moveq #0,d1


    move.w $14(a0),d0


    sub.w (a1),d0


    tst.w (Camera_Min_Y_pos).w ; Does this level y-wrap?


    bpl.s loc_1C132 ; If not, branch and skip looping


    cmpi.w #$60,(Distance_from_screen_top).w ; Is screen in its default position?


    beq.s + ; If so, branch, and loop


    ; It's not at its default position; Sonic must be looking up or down


    tst.b ($FFFFB039).w ; Is Sonic still looking up or down?


    bne.s + ; If so, branch, and keep looping, Sonic ain't moving anywhere!


    ; So, Sonic was looking up or down, but now he isn't


    move.w #$60,(Distance_from_screen_top).w ; move the screen to its default position quickly


    +


    and.w (Screen_Y_wrap_value).w,d0 ; Forever loop



    Done.


    Explanation, using Xenowhirls as a guide


    What originally happened is that when the camera scrolled down, then Sonic immediately jumps, He jumps "above" the camera. Because the game is forever-ing and'ing Sonic's y_pos, the camera then thinks that Sonic is all the way at the bottom! So it scrolls down for ages until it sees Sonic. The level has to let Sonic always "and" his y_pos otherwise when Sonic reaches the y-wrap, he will die and not cross it.



    tst.w (Camera_Min_Y_pos).w ; Does this level y-wrap?
    bpl.s loc_D78E ; If not, branch and skip looping



    All this has done has replaced the "cmpi.w #-$100,(Camera_Min_Y_pos).w". The reason why is because tst'ing it is slightly quicker. You do not have to change it, but it's recommended.


    Anyway, it's asking if the level y-wraps. If not, skip all this code. Sonic doesn't need to cross the y-wrap because there isn't one, so we can leave his position alone.


    If it is a y-wrap level, it will NOT branch, and continue with the coding. Originally, it would just "and" Sonic's y_pos so he can cross the y-wrap, but we have a bug to fix!



    cmpi.w #$60,(Camera_Y_pos_bias).w ; Is screen in its default position?
    beq.s + ; If so, branch, and loop



    When Sonic is not looking up or down, the "Camera_Y_pos_bias" is always at 60. So, is it at 60? If so, branch and loop Sonic's y_pos. So he can still cross the y-wrap. If NOT 60, then do NOT branch, and continue on to the next command.



    tst.w (Sonic_Look_delay_counter).w ; Is Sonic still looking up or down?
    bne.s + ; If so, branch, and keep looping, Sonic ain't moving anywhere!



    This is needed. Elsewhere (in Sonic's code specifically) when Sonic is looking up or down, this has its RAM address added by 1. When it equals 78, the camera will stop moving. As soon as you let go of the up or down button, the RAM address gets cleared.


    Anyway, the reason why we need it here is because if Sonic is close to the y-wrap, the looking can go wrong. If you hold down, the camera will scroll up, if you hold up, the camera will still scroll up. Why? The camera thinks Sonic is miles away again. This only happens when the camera is at $7A0 or more.


    The reason why, is because Sonic has crossed the y-wrap, but the camera itself hasn't. Say, Sonic fell and crossed the y-wrap, and got to y_pos $C, the camera will be at $7AC. So, the camera thinks its miles below! So, hold up or down, it will scroll.


    The only way to get round this is to make Sonic's y_pos "and" itself again. So, when you hold up or down and make the camera scroll, "Sonic_Look_delay_counter" will not be 0, so it will branch and "and" Sonic's y_pos. As soon as you let go, "Sonic_Look_delay_counter" will be cleared, so it will no longer branch to "and" Sonic's y_pos! So, it only leaves us with one more command.



    move.w #$60,(Camera_Y_pos_bias).w ; move the screen to its default position quickly



    This will move the camera back to normal extremely quickly. So quickly, that Sonic has NO chance of pulling that glitch off again.


    So what we have here now, is if you're on a level that does NOT y-wrap, nothing will be changed. Everything will still be normal. And you cannot pull this glitch off in non-y-wrap levels (to my knowledge). After looking up or down, the camera will still scroll back to normal at normal speeds.


    If you're on a y-wrap level, the camera will now scroll back so quickly, you cannot pull the glitch off. I got so close to the y-wrap, Sonic was actually at y_pos $0. 1 pixel away from crossing the y-wrap. I then tried pulling this glitch off then, and it didn't happen. Camera is too fast. It's definitely impossible to do this glitch now.


    Ta-dah!
     
  2. Mike B Berry

    Mike B Berry A grandiose return Member

    Joined:
    Jun 6, 2012
    Messages:
    377
    Location:
    New places, newer motivation
    To be honest, I've never witnessed this. Well, I'd best tend to this fix. Thanks RHS.
     
  3. redhotsonic

    redhotsonic Also known as RHS Member

    Joined:
    Aug 10, 2007
    Messages:
    2,969
    Location:
    England
    It's normally used to cheat your way through the game, or to get a fast time.


    Check this video out. Go to



    and also go to


    You'll see the glitch in action and it's uses.
     
  4. Mike B Berry

    Mike B Berry A grandiose return Member

    Joined:
    Jun 6, 2012
    Messages:
    377
    Location:
    New places, newer motivation
    Tested the glitch in Sonic 1. I haven't seen it happen. What you propose RHS, is it present in S1 either way?
     
  5. MarkeyJester

    MarkeyJester ♡ ! Member

    Joined:
    Jun 27, 2009
    Messages:
    2,867
    It is not present in Sonic 1, the screen doesn't try to follow Sonic downwards.
     
Thread Status:
Not open for further replies.