I want to point out a bug in Sonic 2 Special Stages

Discussion in 'Discussion and Q&A Archive' started by nineko, Aug 10, 2012.

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

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,902
    Location:
    italy
    I noticed this a thousand years ago but I never documented it because I am lazy, but since this hasn't been mentioned (nor, obviously, fixed) yet, I guess I can take this chance to document this now.


    Basically, you know that if you release the controls, Sonic (and/or Tails and/or Knuckles) is supposed to automatically go to the bottom of the halfpipe, and display his non-tilted vertical walking animation. However, there is an area on the left side where Sonic will stay tilted even when the controls are released. This is particularly visible if you happen to be in that position at the end of the stage, because the controls are actually locked while you get the emerald.


    This is how it looks:


    [​IMG] (plain Sonic 2)


    [​IMG] (Sonic 2 & Knuckles)


    [​IMG] (Sonic Classic Heroes)


    The Sonic Classic Heroes screenshot isn't meant to be unrespectful towards that particular hack (which I really like, by the way), I just thought it was neat to show all the three players affected at the same time.


    I don't hack anymore (and, in particular, I never hacked Sonic 2), but if someone wants to fix this bug and write a tutorial about it, be my guest. It's probably as simple as changing a threshold value somewhere, anyway.
     
  2. Flamewing

    Flamewing Elite Hacker Member

    Joined:
    Aug 28, 2011
    Messages:
    37
    Location:
    France
    The issue is not that the player doesn't slide, it is that the way animation is set based on angle is not symmetric with regards to the vertical or horizontal center lines -- this goes against all other code for the SS, so by all rights, that angle in question (value 0x50) should use the same animation as the opposite angle (value 0x30). The same happens on the transition from diagonal to horizontal, then horizontal to upside-down diagonal, etc, so it is endemic.


    One way to fix it is this: find byte_33E90 in the disassembly (I am assuming the Hg disassembly, not an outdated disassembly; adjust accordingly); the important bits are these:



    byte_33E90:
    dc.b 1, 1


    dc.b 0, 0 ; 2


    dc.b 1, 0 ; 4


    dc.b 2, 0 ; 6


    dc.b 1, 2 ; 8


    dc.b 0, 2 ; 10


    dc.b 1, 3 ; 12


    dc.b 2, 1 ; 14


    ; ===========================================================================


    SSPlayer_SetAnimation:


    btst #2,status(a0)


    beq.s +


    move.b #3,anim(a0)


    andi.b #$FC,status(a0)


    rts


    ; ===========================================================================


    +


    moveq #0,d0


    move.b angle(a0),d0


    subi.b #$10,d0


    lsr.b #5,d0


    move.b d0,d1


    add.w d0,d0


    move.b byte_33E90(pc,d0.w),d2


    cmp.b anim(a0),d2


    bne.s +


    cmp.b ss_last_angle_index(a0),d1


    beq.s return_33EFE


    +


    move.b d1,ss_last_angle_index(a0)



    Then change it to this:



    AngleToAnimLUT:
    c := 0


    rept 256


    if (c>=$11)&&(c<=$2F)


    dc.b 0 ; Diagonal, head towards top left


    elseif (c>=$30)&&(c<=$50)


    dc.b 2 ; Upright


    elseif (c>=$51)&&(c<=$6F)


    dc.b 4 ; Diagonal, head towards top right


    elseif (c>=$70)&&(c<=$90)


    dc.b 6 ; Horizontal, head towards right


    elseif (c>=$91)&&(c<=$AF)


    dc.b 8 ; Diagonal, head towards bottom right


    elseif (c>=$B0)&&(c<=$D0)


    dc.b $A ; Upside down


    elseif (c>=$D1)&&(c<=$EF)


    dc.b $C ; Diagonal, head towards bottom left


    else;if (((c>=$F0)&&(c<=$FF))||((c>=$00)&&(c<=$10)))


    dc.b $E ; Horizontal, head towards left


    endif


    c := c+1


    endm


    byte_33E90:


    dc.b 1, 1 ; $11-$2F ; Diagonal, head towards top left


    dc.b 0, 0 ; $30-$50 ; Upright


    dc.b 1, 0 ; $51-$6F ; Diagonal, head towards top right


    dc.b 2, 0 ; $70-$90 ; Horizontal, head towards right


    dc.b 1, 2 ; $91-$AF ; Diagonal, head towards bottom right


    dc.b 0, 2 ; $B0-$D0 ; Upside down


    dc.b 1, 3 ; $D1-$EF ; Diagonal, head towards bottom left


    dc.b 2, 1 ; $F0-$FF,$00-$10 ; Horizontal, head towards left


    ; ===========================================================================


    ; ---------------------------------------------------------------------------


    ; Subroutine to select the animation for a special stage player character.


    ; ---------------------------------------------------------------------------


    ; ||||||||||||||| S U B R O U T I N E |||||||||||||||||||||||||||||||||||||||


    SSPlayer_SetAnimation:


    btst #2,status(a0)


    beq.s +


    move.b #3,anim(a0)


    andi.b #$FC,status(a0)


    rts


    ; ===========================================================================


    +


    moveq #0,d0


    move.b angle(a0),d0


    lea AngleToAnimLUT(pc),a2


    move.b (a2,d0.w),d0


    move.b byte_33E90(pc,d0.w),d2


    cmp.b anim(a0),d2


    bne.s +


    cmp.b ss_last_angle_index(a0),d0


    beq.s return_33EFE


    +


    move.b d0,ss_last_angle_index(a0)



    This method "wastes" 256 bytes in a lookup table to avoid having to do expensive computations to make perfectly symmetric animation selection. It does so in the form of a macro, which generates a perfectly symmetric (vertically and horizontally speaking) animation selection. The remaining changes in the code make use of that LUT, and remove some code which should never have been there to begin with.
     
    Last edited by a moderator: Aug 10, 2012
  3. nineko

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,902
    Location:
    italy
    Aaaaand once again Flamewing is awesome, nice work. I hope that people will apply this fix to their Sonic 2 hacks because this bug always bugged me (no pun intended).


    Anyways, reputation +1 :)

    Ah, yes. I thought it could be either this or that.
     
Thread Status:
Not open for further replies.