(Sonic 1) Sonic CD Roll-Jump & Freeing a Status Bit

Discussion in 'Tutorials' started by Iso Kilo, Jun 16, 2020.

  1. Iso Kilo

    Iso Kilo Local Wolf-Fox Member

    Joined:
    Oct 9, 2017
    Messages:
    251
    Location:
    Small Town in BC, Canada
    In Sonic 1, if you are to jump out of a roll, you'll notice that you can't control Sonic's direction afterward. This is not a bug, surprising as it may seem. The reason why it was implemented is unknown, but most speculate it has to do with collision, something relating to the LZ water slides, or a remnant from some prototype feature. Whatever the reason, it's pretty annoying. A bonus that comes with this tutorial is that in the end, you'll have a free bit in the status SST variable, for Sonic, at least, since the roll jump bit will obviously go unused. So let's start! Of course, as usual with my guides, this is designed for the Hivebrain ASM68K disassembly, but it's easy enough to port it to other disassemblies, and games.
    First step is to make sure that the roll jump isn't activated. To do this you'll want to go to Sonic_Jump and find this general area;
    Code:
            move.b    #$13,$16(a0)
            move.b    #9,$17(a0)
            btst    #2,$22(a0)
            bne.s    loc_13490
            move.b    #$E,$16(a0)
            move.b    #7,$17(a0)
            move.b    #2,$1C(a0)    ; use "jumping"    animation
            bset    #2,$22(a0)
            addq.w    #5,$C(a0)
    
    locret_1348E:
            rts   
    ; ===========================================================================
    
    loc_13490:
            bset    #4,$22(a0)
            rts   
    ; End of function Sonic_Jump
    Firstly, delete loc_13490, and it's contents. All it does is set bit 4 (The roll jump bit) and then rts. Pretty simple. But if you're to build, you'll get an undefined error, because you'll see a few lines up it's called here:
    Code:
            btst    #2,$22(a0)
            bne.s    loc_13490
    It checks if the player is rolling or jumping (In this context, rolling), and then branches to set the roll jump bit. All you have to do is delete it.

    Now technically, you could just end it here, the Sonic CD roll jump works. But if you still want that free status bit there's some more work that needs to be done.

    Head on over to Sonic_ResetOnFloor, and take a look at this;
    Code:
    Sonic_ResetOnFloor:            ; XREF: PlatformObject; et al
            btst    #4,$22(a0)
            beq.s    loc_137AE
            nop   
            nop   
            nop   
    
    loc_137AE:
            bclr    #5,$22(a0)
            bclr    #1,$22(a0)
            bclr    #4,$22(a0)
            btst    #2,$22(a0)
            beq.s    loc_137E4
    Oh dear, it appears the whole start of this routine is pointless, whether or not the roll jump status bit is set, the code will always go to loc_137AE. Along with removing the references to the roll jump bit, let's optimize the whole routine in general. You should have this in the end:
    Code:
    Sonic_ResetOnFloor:            ; XREF: PlatformObject; et al
            bclr    #5,$22(a0)
            bclr    #1,$22(a0)
            btst    #2,$22(a0)
            beq.s    loc_137E4
    Look at how much cleaner and smaller that is!
    Next, you'll want to track down Sonic_ChgJumpDir, and remove these two lines;
    Code:
            btst    #4,$22(a0)
            bne.s    Obj01_ResetScr2
    This is the code that actually prevents the player from controlling their movement in the air after roll jumping. If it sees that the roll jump status is set, it'll skip over a bunch of other code. But earlier we made it so the roll jump status would never be set, making this unused and useless.
    The last thing to do is just delete a few lines that are clearing the roll jump bit. These can be found in Obj47_Hit and Obj64_Wobble.
    You now have the Sonic CD rolling jump behavior and a free bit in Sonic's status variable! Enjoy~
     
  2. death rapunzel

    death rapunzel i don't care anymore Member

    Joined:
    Aug 26, 2013
    Messages:
    1,062
    Location:
    Hell
    It should be worth noting that if you do this, let's say you are rolling down a slope really fast, and then you jump. Without the rolljump bit preventing any horizontal movement, the speed cap will kick in. This is why I personally believe the flag was added to hackishly make it so that you don't lose momentum after jumping from a fast roll. It just makes the most sense to me.

    With that in mind, removing the air speed cap should probably also be taken into account.

     
    Last edited: Jun 16, 2020
  3. ProjectFM

    ProjectFM Optimistic and self-dependent Member

    Joined:
    Oct 4, 2014
    Messages:
    845
    Location:
    Portland, Maine
    This guide came at just the right time for me. I had no idea this was a thing Sonic 1 did. I recently implemented the drop dash and found that while doing the move Sonic couldn't change direction, and this was the reason why.

    However, I found an error worth fixing. Implementing this change causes this code in Sonic_Jump to run while Sonic is roll jumping:
    Code:
            move.b    #$E,$16(a0)
            move.b    #7,$17(a0)
            move.b    #2,$1C(a0)    ; use "jumping"    animation
            bset    #2,$22(a0)
            addq.w    #5,$C(a0)
    
    locret_1348E:
            rts   
    Sonic has a lower height while rolling, so when he goes into his rolling animation, his y-position is moved downward to compensate. When Sonic is already rolling, Sonic's height doesn't change and this just pushes Sonic into the ground.
    s1built_000.png To fix this, just make it so the code which changes Sonic's y-position is skipped over.
    Code:
            move.b    #$E,$16(a0)
            move.b    #7,$17(a0)
            btst    #2,$22(a0)
            bne.s   locret_1348E
            move.b    #2,$1C(a0)    ; use "jumping"    animation
            bset    #2,$22(a0)
            addq.w    #5,$C(a0)
    
    locret_1348E:
            rts  
    Edit: Also, in the original code, if Sonic is roll jumping, then his width and height are set to what it is when he's not rolling. That code is fortunately cut out in this guide. Why is it there in the first place?
     
    Last edited: Jun 18, 2020
    Pacca likes this.
  4. Iso Kilo

    Iso Kilo Local Wolf-Fox Member

    Joined:
    Oct 9, 2017
    Messages:
    251
    Location:
    Small Town in BC, Canada
    I hadn't realized that Sonic sunk into the ground a little, also, as for Sonic's hitbox- It's either Yuji Naka being silly (As he's quite well known for with his code) or it leans into one of the reasons why it was implemented in the first place. Thanks for the additions, though!
     
    ProjectFM likes this.
  5. nineko

    nineko I am the Holy Cat Member

    Joined:
    Mar 24, 2008
    Messages:
    1,786
    Location:
    italy
    Yeah, the Y thing leads to a funny side effect in Sonic 3 & Knuckles, if you roll after you spin the signpost, Sonic will do his celebration pose a few pixels sunk in the ground, I often do that in my videos. But this is off-topic, please carry on.