(Sonic 1) Porting S2NA Wall Recoil

Discussion in 'Tutorials' started by Iso Kilo, Sep 28, 2020.

  1. Iso Kilo

    Iso Kilo Is it a fox? Is it a wolf? It's Kilo! Member

    Joined:
    Oct 9, 2017
    Messages:
    332
    Location:
    A warm and lovely place~
    Though most might think this would've been an annoying feature in the final game, I personally feel that it would work with a higher speed limit. So here's a guide for porting the bonk to Sonic 1 Hivebrain and increasing the speed limit so it's more bearable.
    Note, this will not cover adding the tripping animation, I'll just be using the hurt animation.
    You'll also probably want to remove the speed cap so our new recoil speed can be more easily achieved.

    First you'll need a Sonic 2 Nick Arcade disassembly. I recommend Super Egg's disasm
    Go ahead and open S2NA.asm, the disasm's main program file. Thankfully, this disasm is formatted similarly to the Sonic 1 Hivebrain disasm which makes porting the recoil very easy. The routine we're looking for is
    Sonic_WallRecoil:
    Code:
    Sonic_WallRecoil:            ; CODE XREF: Sonic_Move+180j
                        ; Sonic_Move+1A0j
            move.b    #4,$24(a0)
            bsr.w    Sonic_ResetOnFloor
            bset    #1,$22(a0)
            move.w    #$FE00,d0
            tst.w    $10(a0)
            bpl.s    Sonic_WallRecoil_Right
            neg.w    d0
    
    Sonic_WallRecoil_Right:            ; CODE XREF: Sonic_Move+1D2j
            move.w    d0,$10(a0)
            move.w    #$FC00,$12(a0)
            move.w    #0,$14(a0)
            move.b    #$A,$1C(a0)
            move.b    #1,$25(a0)
            move.w    #$A3,d0    ; '�'
            jsr    (PlaySound_Special).l
            rts
    You could just paste this function right into your disasm as is, but let's make some changes and comment some things, just so it's more pretty.
    Code:
    Sonic_WallRecoil:   ; Routine to bounce Sonic off a wall when going too fast
            move.b    #4,$24(a0)
            bsr.w    Sonic_ResetOnFloor
            bset    #1,$22(a0)  ; Set Sonic as in air
            move.w    #$FE00,d0   ; Move recoil speed into d0 for later
            tst.w    $10(a0) ; Check if player is moving right
            bpl.s    @cont  ; If so, branch
            neg.w    d0  ; Negate recoil speed if facing left
    
    @cont
            move.w    d0,$10(a0)  ; Move recoil speed into X speed
            move.w    #$FC00,$12(a0)  ; Vertical recoil speed
            move.w    #0,$14(a0)  ; Clear inertia
            move.b    #$A,$1C(a0) ; Play recoil animation
            move.b    #1,$25(a0)
            move.w    #$A3,d0 ; Initiate bonk sound
            jsr    (PlaySound_Special).l   ; Play bonk sound
            rts ; Return
    Place this above Sonic_MoveLeft:

    Now we need to make the game actually use the bonk!
    Go to loc_13024: and in between here
    Code:
            beq.s    loc_13060
            ; Here
            add.w    d1,$10(a0)
    Place these 2 lines
    Code:
            cmpi.w    #$600,$10(a0)    ; Check if player is at running speed
            bge.s    Sonic_WallRecoil    ; If so, bonk
    And next immediately under loc_13066:
    Code:
            cmpi.w    #-$600,$10(a0)    ; If player is at running speed to the left
            ble.s    Sonic_WallRecoil    ; Bonk!
    Now it should function!
    upload_2020-9-27_19-46-17.png
    Er. That's not quite right.
    So what's causing this?!
    It's our wall recoil code of course, it's not broken, in fact it's doing exactly what we asked it to. Play animation $A. While in Sonic 2 Nick Arcade, it was an animation of Sonic tripping, in Sonic 1 it's the unused squish animation (Yes it's a squish, not a spindash, homing attack or warp, I will carry this to my grave.)
    In this guide, we'll just use the hurt animation, it's fitting enough.
    Let's go back to Sonic_WallRecoil: and find
    Code:
    move.b    #$A,$1C(a0) ; Play recoil animation
    Since we want to use the hurt animation, just change the $A to $1A.
    upload_2020-9-27_19-51-45.png
    Much better!
    Now we have one last thing to do, obviously tripping by running into a wall at regular running speed is quite annoying. It can work at a higher speed, however. You can use whatever top speeds you want. I suggest either the speed it takes to use the dash animation in Sonic CD, $A00. Or the top speed when you get the speed shoes, $C00. To make these the top speeds, change these lines from earlier that calls the recoil routine
    Code:
    ; loc_13024
    ; ...
            cmpi.w    #$600,$10(a0)    ; Check if player is at running speed. Change this to your top speed
    ; ...
    ; loc_13066
            cmpi.w    #-$600,$10(a0)    ; If player is at running speed to the left. Change this to your top speed
    ; ...
    With that done, you now have a functioning wall recoil from Sonic 2 Nick Arcade in Sonic 1!
    Attached is a disasm with the recoil implemented and the speed cap removed.
     

    Attached Files: