How to add a cheat code based on song numbers in Sonic 1

Discussion in 'Approved' started by nineko, Mar 18, 2009.

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
    This is a very simple guide to add a cheat code in Sonic 1 using the songs played in the level select screen. I know there are other ways to do this (Sonic 2 does it differently, for example), but I came up with my own implementation when I added a cheat in my hack, and I thought to share it with the world since I think it's pretty simple and good at the same time. Please note that this only works with sequences of 4 songs.


    This is how the LevelSelect routine looks like in a clean Sonic 1 disasm:



    LevelSelect:
    move.b #4,($FFFFF62A).w


    bsr.w DelayProgram


    bsr.w LevSelControls


    bsr.w RunPLC_RAM


    tst.l ($FFFFF680).w


    bne.s LevelSelect


    andi.b #$F0,($FFFFF605).w; is A, B, C, or Start pressed?


    beq.s LevelSelect; if not, branch


    move.w ($FFFFFF82).w,d0


    cmpi.w #$14,d0; have you selected item $14 (sound test)?


    bne.s LevSel_Level_SS; if not, go to Level/SS subroutine


    move.w ($FFFFFF84).w,d0


    addi.w #$80,d0


    tst.b ($FFFFFFE3).w; is Japanese Credits cheat on?


    beq.s LevSel_NoCheat; if not, branch


    cmpi.w #$9F,d0; is sound $9F being played?


    beq.s LevSel_Ending; if yes, branch


    cmpi.w #$9E,d0; is sound $9E being played?


    beq.s LevSel_Credits; if yes, branch


    LevSel_NoCheat:


    cmpi.w #$94,d0; is sound $80-$94 being played?


    bcs.s LevSel_PlaySnd; if yes, branch


    cmpi.w #$A0,d0; is sound $95-$A0 being played?


    bcs.s LevelSelect; if yes, branch


    LevSel_PlaySnd:


    bsr.w PlaySound_Special


    bra.s LevelSelect



    And this is how it looks in my hack:

    LevelSelect:
    move.b #4,($FFFFF62A).w


    bsr.w DelayProgram


    bsr.w LevSelControls


    bsr.w RunPLC_RAM


    tst.l ($FFFFF680).w


    bne.s LevelSelect


    andi.b #$F0,($FFFFF605).w; is A, B, C, or Start pressed?


    beq.s LevelSelect; if not, branch


    move.w ($FFFFFF82).w,d0


    cmpi.w #$15,d0; have you selected item $15 (sound test)?


    bne.s LevSel_Level_SS; if not, go to Level/SS subroutine


    move.w ($FFFFFF84).w,d0


    addi.w #$80,d0


    move.l ($FFFFC60C).w,d1; move the last 4 songs played into d1


    rol.l #8,d1; rotate d1 by 8 bits


    move.l d1,($FFFFC60C).w; put the rotated d1 back there


    move.b d0,($FFFFC60F).w; overwrite the right-most song


    cmpi.l #$91999894,($FFFFC60C).w; did you play 91, 99, 98, 94?


    bne.b LevSel_PlaySnd; if not, proceed normally


    bra.s LevSel_Bonus; let's play the bonus stage


    LevSel_PlaySnd:


    bsr.w PlaySound_Special


    bra.s LevelSelect



    Please note that I removed the japanese credits cheat because I wasn't using it (the japanese credits are visible by default in my hack), but this doesn't mean that you can't have both of them. I also removed the two bcs.s instructions because I use all the song slots so they're not needed anymore. One more note, the sound test is on line $15 in my sound test, don't alter that line if your sound test is still on line $14.
    What does this cheat do? In my case, if you play songs 91, 99, 98, 94 in the sound test, you will play the secret bonus stage (the one with 1080 rings and shit). But you can do whatever you want, just change the bra.s LevSel_Bonus with something else to suit your needs. Also you can have more than one cheat by doing multiple CMPI checks.


    And yeah, I know that now I spoiled that 91 99 98 94 is the cheat code for my hack, I wanted it to stay secret but whatever :p


    Bonus points to everyone who knows why I chose those numbers.


    One more thing, you can replace $FFFFC60C with any other free RAM address, but keep in mind that it MUST be dword-aligned (e.g. a multiple of 4).
     
    Last edited by a moderator: Mar 18, 2009
    HackGame likes this.
  2. Hanoch

    Hanoch Well-Known Member Member

    Joined:
    Aug 3, 2008
    Messages:
    312
    Location:
    Israel
    You know, you could always do something like moving a routine with dc.b's into d2 and then compare d2 to the RAM address. You chose $91 because its credits (with 1 up to 5 emeralds) $99 is the last scrap brain level (sbz 3 is final boss, not counted as a level) $98 and $94 because they are both act 3. Other than that, good guide. Maybe I will use it as a options menu cheat or something.
     
  3. nineko

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,902
    Location:
    italy
    No, I chose those songs because 91 99 98 94 is my year of birth :)
     
  4. Selbi

    Selbi The Euphonic Mess Member

    Joined:
    Jul 20, 2008
    Messages:
    2,429
    Location:
    Northern Germany
    I was searching for this everywhere! Thanks nineko! :)


    Also:

    EPIC WIN!!!
     
  5. EMK-20218

    EMK-20218 The Fuss Maker Exiled

    Joined:
    Aug 8, 2008
    Messages:
    1,067
    Location:
    Jardim Capelinha, São Paulo
    Hahahaha. I don't believe we have the same age. It's pretty nice to hear. ^^
     
  6. c1owd

    c1owd Previously 'CarrascoZX0' Member

    Joined:
    Dec 13, 2008
    Messages:
    364
    I would use this... It's just that I have the Sonic 2 Level Select and it already came with that. =P


    But! Good job nineko!


    P.S.: My big brother is born in that year too! xD
     
  7. Tongara

    Tongara Well-Known Member Exiled

    Joined:
    Feb 10, 2009
    Messages:
    353
    Location:
    Birmingham, UK
    Nice work, nineko.



    ; ---------------------------------------------------------------------------
    ; Level Select


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


    LevelSelect:


    move.b #4,($FFFFF62A).w


    bsr.w DelayProgram


    bsr.w LevSelControls


    bsr.w RunPLC_RAM


    tst.l ($FFFFF680).w


    bne.s LevelSelect


    andi.b #$F0,($FFFFF605).w; is A, B, C, or Start pressed?


    beq.s LevelSelect; if not, branch


    move.w ($FFFFFF82).w,d0


    cmpi.w #$14,d0; have you selected item $14 (sound test)?


    bne.s LevSel_Level_SS; if not, go to Level/SS subroutine


    move.w ($FFFFFF84).w,d0


    addi.w #$80,d0


    move.l ($FFFFC60C).w,d1; move the last 4 songs played into d1


    rol.l #8,d1; rotate d1 by 8 bits


    move.l d1,($FFFFC60C).w; put the rotated d1 back there


    move.b d0,($FFFFC60F).w; overwrite the right-most song


    cmpi.l #$83818981,($FFFFC60C).w; change the numbers "83818981" to what you want to play


    bne.b LevSel_PlaySnd; if the cheat wasn't entered then gtfo


    bra.s LevSel_Credits; if it was then the credits screen will show up


    move.b #$B5,d0; ring sound doesn't work


    bsr.w PlaySound_Special; Doesn't work


    tst.b ($FFFFFFE3).w; is Japanese Credits cheat on?


    beq.s LevSel_NoCheat; if not, branch


    cmpi.w #$9F,d0; is sound $9F being played?


    beq.s LevSel_Ending; if yes, branch


    cmpi.w #$9E,d0; is sound $9E being played?


    beq.s LevSel_Credits; if yes, branch


    LevSel_NoCheat:


    cmpi.w #$94,d0; Change 94 to whatever number of songs you have, unless you have added no more, in which case, keep it at 94


    bcs.s LevSel_PlaySnd; if yes, branch


    cmpi.w #$A0,d0; is sound $95-$A0 being played?


    bcs.s LevelSelect; if yes, branch


    LevSel_PlaySnd:


    bsr.w PlaySound_Special


    bra.s LevelSelect



    Just a little fix for people who want to use the jap credits cheat, and currently only have the normal amount of songs in their hack. Also, this plays the ending credits, rather than that special stage. The ring sound doesn't work, I tried to get it to, but it doesn't. So if someone wants to fix that, feel free. :)
     
    Last edited by a moderator: May 7, 2009
    nineko likes this.
Thread Status:
Not open for further replies.