Restore Sonic 1's Prototype Victory

Discussion in 'Tutorials' started by Kilo, Nov 29, 2019.

  1. Kilo

    Kilo Foxy Fren Exiled

    Joined:
    Oct 9, 2017
    Messages:
    391
    Location:
    A warm and lovely place~
    In pre-release screenshots of Sonic 1, it was shown that Sonic used to have a sort of victory animation during the results screen. However, it was scrapped in the final game, possibly because it looked a bit much like the way a certain rival character jumps.
    [​IMG]
    Thankfully, the animation was still left in the final, and it can be worked with.
    Step 1: Modifying the Signpost
    Most of the code surrounding Sonic's actions, the tally, and whatnot, are controlled by the signpost. So logically, most of the work to be had is there.
    First, go to Obj0D_Index and replace:
    Code:
            dc.w Obj0D_SonicRun-Obj0D_Index
    with:
    Code:
            dc.w GotThroughAct-Obj0D_Index
    Next, go to Obj0D_SonicRun and delete, or comment out all of this:
    Code:
    Obj0D_SonicRun:                ; XREF: Obj0D_Index
            tst.w    ($FFFFFE08).w    ; is debug mode    on?
            bne.w    locret_ECEE    ; if yes, branch
            btst    #1,($FFFFD022).w
            bne.s    loc_EC70
            move.b    #1,($FFFFF7CC).w ; lock    controls
            move.w    #$800,($FFFFF602).w ; make Sonic run to    the right
    
    loc_EC70:
            tst.b    ($FFFFD000).w
            beq.s    loc_EC86
            move.w    ($FFFFD008).w,d0
            move.w    ($FFFFF72A).w,d1
            addi.w    #$128,d1
            cmp.w    d1,d0
            bcs.s    locret_ECEE
    
    loc_EC86:
            addq.b    #2,$24(a0)
    Now if you were to build the ROM, the player can remain on screen after hitting the signpost, instead of running off to the right. But there's a bit of an issue, the player can still run off to the right if they wanted to. It's not necessarily a major issue, but it's still nice to fix. Just go to Obj0D_Touch and under:
    Code:
            bcs.s    locret_EBBA
            cmpi.w    #$20,d0        ; is Sonic within $20 pixels of    the signpost?
            bcc.s    locret_EBBA    ; if not, branch
    place:
    Code:
            move.b  #1,($FFFFF7AA).w ; Lock the screen
    This will now lock the right side of the screen, once you reach it. The next steps are to set up the victory animation itself.
    Directly below GotThroughAct insert this line:
    Code:
            move.b  #1,($FFFFXXXX).w ; Set victory animation flag
    It sets a flag that will be put to use later. Note that you'll have to select a RAM address for this flag, any unused one should do. Now we need to make sure that it gets cleared once the next level starts, or else Sonic will be constantly doing his victory animation after playing 1 level. The fix is pretty simple, in Level_ClrVars3, above:
    Code:
            cmpi.b    #1,($FFFFFE10).w ; is level LZ?
            bne.s    Level_LoadPal    ; if not, branch
            move.w    #$8014,(a6)
    Put a clear instruction for whatever RAM address you've chosen.

    Step 2: Making the Animation Work
    Thankfully, this part is the easiest. Simply go to Sonic_Jump and replace:
    Code:
            move.b    #2,$1C(a0)    ; use "jumping"    animation
    with:
    Code:
    Result_Check:
            tst.b   ($FFFFXXXX).w ; Has the victory animation flag been set?
            beq.s   NormalJump ; If not, branch
            move.b  #$13,$1C(a0) ; Play the victory animation
            bra.s   cont ; Continue
    NormalJump:
            move.b  #2,$1C(a0)    ; use "jumping"    animation
    cont:
    The logic of this works as so: If the victory flag has been set, use the victory animation when Sonic jumps, if not, use the normal jumping animation.

    Now, if everything has been done properly, you should have something like this:
    [​IMG]
     
    Last edited: Dec 2, 2019
    TomTalker, Nick46, Bluestreak and 5 others like this.
  2. JoenickROS

    JoenickROS ROS (bug fixing in progress) Member

    Joined:
    Feb 5, 2012
    Messages:
    929
    This has been up for a while so Im surprised no one pointed this out yet.
    Code:
    move.b  #1,($FFFFXXXX).w ; Set victory animation flag
    
    Result_Check:
           tst.w   ($FFFFXXXX).w ; Has the victory animation flag been set?
           beq.s   NormalJump ; If not, branch
    
    See the issue here?
     
  3. Kilo

    Kilo Foxy Fren Exiled

    Joined:
    Oct 9, 2017
    Messages:
    391
    Location:
    A warm and lovely place~
    Edit, actually nevermind. The tst command checks if the source is zero. If the animation flag is zero then Sonic should branch to a normal jump. It works as intended.
    Edit 2, oh. I set it to a word.
     
  4. DeltaW

    DeltaW The noob next door Member

    Joined:
    Aug 7, 2019
    Messages:
    378
    Any reason why the victory animation is still there? Even after sorting out the RAM address, it still continues the animation. Can you be a bit specific about "Level_ClrVars3" for my understanding?
     
  5. Kilo

    Kilo Foxy Fren Exiled

    Joined:
    Oct 9, 2017
    Messages:
    391
    Location:
    A warm and lovely place~
    The victory animation flag needs to be cleared just above the check for Labyrinth Zone.
     
  6. SoniMania2000

    SoniMania2000 Newcomer Trialist

    Joined:
    Dec 7, 2019
    Messages:
    5
    It's astounding that people can do this!
     
  7. Bluestreak

    Bluestreak Lady in red, living in dread. Member

    Joined:
    Apr 1, 2016
    Messages:
    227
    Location:
    Eastwatch Island
    I'm new to this, so how should I write the clear instruction for the RAM address I decided to use for the victory animation? I'm using GitHub btw. The other parts I understood just fine.
     
  8. Inferno

    Inferno Rom Hacker Member

    Joined:
    Oct 27, 2015
    Messages:
    132
    Location:
    Sky Base Zone, South Island
    Ok, so, there's two ways you can do it.

    The first one is moving 0 to the ram address:
    Code:
    move.b  #0,($FFFFXXXX).w
    However, there's a instruction made just for this, which, IIRC, is also quicker. This instruction is called clr (Clear). Using the above instruction as a guide, this should be the instruction you get for clearing the RAM address:
    Code:
    clr.b  ($FFFFXXXX).w
    Hopefully, that helps you with this guide.
     
    TomTalker and Kilo like this.
  9. Bluestreak

    Bluestreak Lady in red, living in dread. Member

    Joined:
    Apr 1, 2016
    Messages:
    227
    Location:
    Eastwatch Island
    Thank you! This will come in handy in the future.
     
    Inferno likes this.
  10. Samey

    Samey Le Bored Hedgie Member

    Joined:
    May 3, 2017
    Messages:
    57
    While adding this into my hack, I noticed a few problems, specifically in act 3, Sonic would start jumping when the act results came up, and in Scrap Brain Zone act 2, the results screen would go away, but immediately come back, re-add the score up, and repeat for eternity.

    The only difference I had done was make it into more of the Sonic 3 style of victory animation.

    Here's what I did to fix the issues I stated earlier.
    first, change this:
    Code:
            dc.w GotThroughAct-Obj0D_Index
    back into this:
    Code:
            dc.w Obj0D_SonicRun-Obj0D_Index
    afterwards, go back to where Obj0D_Sonicrun was when you deleted/commented it out, and place this where it was

    Code:
    Obj0D_SonicRun:               ; XREF: Obj0D_Index
           tst.w   ($FFFFFE08).w   ; is debug mode   on?
           bne.w   locret_ECEE   ; if yes, branch
           move.b  #1,($FFFFXXXX).w ; Set victory animation flag
           
    loc_EC86:
           addq.b   #2,$24(a0)
    Make sure to delete this from GotThroughAct
    Code:
           move.b  #1,($FFFFXXXX).w ; Set victory animation flag

    This all fixes most of the issues, but if you go back to SBZ2 to test if its working, you'll notice that the animation will still play after the Results screen goes away.

    all this requires is the flag to be cleared in 1 other spot.

    go to Obj3A_SBZ2 and place this line of code under the line with the "Unlock Controls" comment.
    Code:
           clr.b   ($FFFFF75D).w       ; clear victory anim
    and that should be all the bugs fixed (That I could find anyway..)
     
  11. DeltaW

    DeltaW The noob next door Member

    Joined:
    Aug 7, 2019
    Messages:
    378
    Is there a way I can do it the Sonic 3 way when the controls are locked after Sonic goes on the floor and does his animation until the next act because the tutorial above Samey doesn't seem to work for me. The signpost goes crazy and the results card doesn't show up.

    Code:
    Obj01_NotRight:
            move.b    $26(a0),d0
            addi.b    #$20,d0
            andi.b    #$C0,d0        ; is Sonic on a    slope?
            bne.w    Obj01_ResetScr    ; if yes, branch
            tst.w    $14(a0)        ; is Sonic moving?
            bne.w    Obj01_ResetScr    ; if yes, branch
            bclr    #5,$22(a0)
            tst.b   ($FFFFF530).w ; Has the victory animation flag been set?
            beq.s   NormalJump ; If not, branch
            move.b  #$23,$1C(a0) ; Play the victory animation
            bra.s   cont ; Continue
    NormalJump:
            move.b    #5,$1C(a0)    ; use "standing" animation
    cont:        
    I'm trying to let Sonic do the animation once he is at the signpost and the results card goes up. When I tell the game to lock controls and do the animation. He will do it anytime I'm standing on a platform or random occasions.

    Screenshot 2020-04-17 at 11.34.29.png
     
    Last edited: Apr 17, 2020
  12. Samey

    Samey Le Bored Hedgie Member

    Joined:
    May 3, 2017
    Messages:
    57
    could you post the code in Obj0D_sonicrun?

    it looks similar to a issue I was having before I found this tutorial


    heres what the code should look like if you're doing it more like sonic 3

    Code:
    Obj0D_SonicRun:                ; XREF: Obj0D_Index
            tst.w    ($FFFFFE08).w    ; is debug mode    on?
            bne.w    locret_ECEE    ; if yes, branch
            move.b  #1,($FFFFXXXX).w ; Set victory animation flag
            move.b    #1,($FFFFF7CC).w ; lock    controls
            move.w    d0,($FFFFF602).w ; stop    Sonic moving
    
    loc_EC86:
            addq.b    #2,$24(a0)
    Specifically, the 2 lines that lock the controls and stop Sonic from moving.

    also, theres another place that tells sonic to use his standing animation. loc_131AA
    Just to be safe, I added the check there also:

    Code:
    loc_131AA:
            tst.w    $14(a0)        ; is Sonic moving?
            bne.s    loc_131CC    ; if yes, branch
            bclr    #2,$22(a0)
            move.b    #$13,$16(a0)
            move.b    #9,$17(a0)
    loc_131AAcheck:
            tst.b   ($FFFFXXXX).w ; Has the victory animation flag been set?
            beq.s   loc_131AAidle ; If not, branch
            move.b  #$24,$1C(a0) ; Play the victory animation
            bra.s   loc_131CC ; Continue
    loc_131AAidle:
            move.b  #5,$1C(a0)    ; use "standing" animation
            subq.w    #5,$C(a0)
     
    Last edited: Apr 29, 2020
  13. DeltaW

    DeltaW The noob next door Member

    Joined:
    Aug 7, 2019
    Messages:
    378
    It is the same thing as you showed us.
     
  14. Samey

    Samey Le Bored Hedgie Member

    Joined:
    May 3, 2017
    Messages:
    57
    oh wait, the Sonic 3 way where it transitions to the next act?

    Well, it'll be similar to Obj3A_SBZ2 I assume?
    You just need to put
    Code:
            clr.b    ($FFFFF7CC).w    ; unlock controls
            clr.b    ($FFFFXXXX).w        ; clear victory anim
    in the routine that handles transitioning between the acts, but I might be wrong.

    edit: I misread the post, and I don't think I know how to fix that
     
    Last edited: Apr 29, 2020
  15. DeltaW

    DeltaW The noob next door Member

    Joined:
    Aug 7, 2019
    Messages:
    378
    So everything does seem to work, however on some occasions during gameplay, Sonic would branch to his victory animation when standing still.
     
  16. Samey

    Samey Le Bored Hedgie Member

    Joined:
    May 3, 2017
    Messages:
    57
    Then I suppose the flag your using is used somewhere else in your code.

    the flag I used specifically is
    $FFFFF75D

    maybe try going through your code to see what else might be using the flag, cuz obviously something is setting the flag.
     
  17. Kilo

    Kilo Foxy Fren Exiled

    Joined:
    Oct 9, 2017
    Messages:
    391
    Location:
    A warm and lovely place~
    Certified accurate by the recent footage. :p
     
    Samey likes this.
  18. rafit_000

    rafit_000 Newcomer In Limbo

    Joined:
    Jul 10, 2018
    Messages:
    10
    Location:
    Brazil
    Well, I tried to use the code but this is what happend on GitHub:
    Sonic plays 1 frame and plays the animation at the all parts of the act at the all zones.
    ReadySonic_000.png
    And to me in the Hivebrain disassembly, nothing happend! Sonic still curls to a ball!
    I cleared the RAM on Level_ClrVars3 and nothing, HAPPEND! What do I do again with $FFFFF5C0?, yeah, this is the original address.
    I saw on the tutorial of How to get lives through points and I tried to add This:

    Code:
    Play_the_victory_animation =        $FFFFF5C0
    On the start of my assembly, and guess what occur? Yes, Sonic curls to a ball.
     
  19. Candy_TheCat

    Candy_TheCat CandyTehRat Member

    Joined:
    Jan 15, 2021
    Messages:
    29
    Location:
    Chemical Plant Zone
    do move.b #0,$FFFFF5C0 instead.

    Edit: oops, replied to an in-limbo user
     
    Last edited: Feb 16, 2021
  20. OrdosAlpha

    OrdosAlpha RIGHT! Naebody move! Root Admin

    Joined:
    Aug 5, 2007
    Messages:
    1,793
    Location:
    Glasgow, Scotland
    Don't necro-bump threads, and especially don't do it when replying to anyone in the Limbo group.
     
    Miles Sebas Prower, Samey and silvs64 like this.