High Jump and Spike Behavior Monitors Guide

Discussion in 'Tutorials' started by Kilo, Sep 19, 2018.

  1. Kilo

    Kilo Foxy Fren Exiled

    Joined:
    Oct 9, 2017
    Messages:
    391
    Location:
    A warm and lovely place~
    So recently, I've been showcasing a lot of monitors I've made. Like the bomb monitor and high jump, and more recently, the spike behavior monitor. Today I'll teach you how to add them, but only the high jump and spike behavior boxes, because the bomb item was based off of MarkeyJester's "Destroy All Enemies on Screen" guide, found in the archived tutorials. Note: This isn't a copy and paste guide, the high jump and spike behavior monitors both use unused RAM addresses, however I don't want to assume what RAM addresses you want to use. And if I used ($FFFFFFF9).w, like some extra character guides, it could interfere. So instead look here for unused RAM addresses: http://info.sonicretro.org/SCHG:Sonic_the_Hedgehog_(16-bit)/RAM_Editing So whenever I use "($FFFFXXXX).w" or "($FFFFYYYY).w" replace it with whatever 2 RAM addresses you decided to use. This guide targets the Hivebrain 2005 disassembly, but could easily be ported to the GitHub disassembly. Anyways, let's begin!
    Step 1: Art
    This is really the only part I'm fully doing for you. Go and download this file; http://www.mediafire.com/file/188c1nq60kcu1u0/monitors.bin/file And replace it with the one in the artnem folder of your disassembly. And that's pretty much step 1 done. You could go into a level editor and place them down to see how they look, they'll still act the same though, and that's where step 2 comes in!

    Step 2: Monitors
    In sonic1.asm, go to "Obj2E:" and scroll down until you see this:
    Code:
    Obj2E_ChkS:
            cmpi.b    #7,d0        ; does monitor contain 'S'
            bne.s    Obj2E_ChkEnd
            nop
    Obj2E_ChkEnd:
            rts            ; 'S' and goggles monitors do nothing
    This isn't what we want, so instead replace it with this:
    Code:
    Obj2E_ChkSpike:
            cmpi.b    #7,d0        ; does monitor contain Spike?
            bne.s    Obj2E_ChkHighJump
            tst.b    ($FFFFXXXX).w ;Check if spike flag is inactive.
            beq.s    Spike_Enable ;If so branch to activate it
    Spike_Disable:
            clr.b    ($FFFFXXXX).w ;Turn off spike flag
            move.w    #$A6,d0
            jmp    PlaySound    ; play spike sound
            bra.s    Obj2E_ChkHighJump
    Spike_Enable:
            move.b    #$1,($FFFFXXXX).w ;Turn on spike flag
            move.w    #$CD,d0
            jmp    PlaySound    ; play clink sound
    
    You now have the code to make the monitor switch between an "on" and an "off" state.
    If you try building you'll get a few errors, 2 undefined errors, these are easy to fix. And lead into the next part of the guide. I'll teach you how to fix these real quick. Go to "Obj2E_ChkRings:" and find this line:
    Code:
            bne.s    Obj2E_ChkS
    Simply replace the branch location to Obj2E_ChkSpike.
    Now we add our next monitor to fix the second undefined error.
    Below the Spike_Enable: routine, insert this
    Code:
    Obj2E_ChkHighJump:
            cmpi.b    #8,d0 ;Does monitor contain high jump?
            bne.s    Obj2E_ChkEnd
            move.b    #$1,($FFFFYYYY).w ;Enable High Jump flag
            move.w    #$CC,d0
            jmp    PlaySound    ; play spring sound
    
    Try building now and everything will be fine, you can even go ahead and place them into a level. They now do something! Internally that is, nothing will take place except for a noise. Which leads nicely into step 3!
    Step 3: Actual Code

    Now you got the monitors working, you just need to make the code actually do something, first we'll start with the spike behavior monitor, as it's the easiest of the 2.
    All you need to do is to go to "Obj36_Hurt:" and replace everything before "move.l a0,-(sp)" with

    Code:
            tst.b    ($FFFFFE2D).w    ; is Sonic invincible?
            bne.s    Obj36_Display    ; if yes, branch
            cmpi.b     #$1,($FFFFXXXX).w    ; was the Spike Behavior enabled
            bne.s    Obj36_HurtContinue    ; if yes, branch
            tst.w    ($FFFFD030).w    ; is Sonic invulnerable? (Spike Behavior check)
            bne.s    Obj36_Display    ;  if yes, branch
    
    Obj36_HurtContinue:
    That's all the code needed for the spike monitor, feel free to test it out! Now to add the high jump! Go to "Sonic_Jump:" and before "move.w #$680,d2" add these 2 lines:
    Code:
            cmpi.b     #$1,($FFFFYYYY).w
            beq.s     High_Jump
    And after the "move.w #$380,d2", but before "loc_1341C:" insert this:
    Code:
            beq.s     loc_1341C
    High_Jump:
            move.w    #$9C0,d2 ;Sonic's new jump height
            btst    #6,$22(a0)
            beq.s    loc_1341C
            move.w    #$380,d2
    Feel free to modify "move.w #$9C0,d2" for different heights. Now that's just about everything, except there's no way to deactivate the high jump, so lets do that, we'll make it so Sonic loses the high jump after getting hurt. Go to "HurtSonic:" you should see this:
    Code:
    HurtSonic:
            tst.b    ($FFFFFE2C).w    ; does Sonic have a shield?
            bne.s    Hurt_Shield    ; if yes, branch
            tst.w    ($FFFFFE20).w    ; does Sonic have any rings?
            beq.w    Hurt_NoRings    ; if not, branch
            jsr    SingleObjLoad
            bne.s    Hurt_Shield
            move.b    #$37,0(a1)    ; load bouncing    multi rings object
            move.w    8(a0),8(a1)
            move.w    $C(a0),$C(a1)
    In between the label and the first command insert these lines:
    Code:
            cmpi.b     #$01,($FFFFYYYY).w ;Check if Sonic has the high jump
            beq.s     Hurt_High
    Now below "Hurt_Shield:" and before "Hurt_Reverse:" insert this:
    Code:
    Hurt_High:
            clr.b    ($FFFFYYYY).w ; remove high jump
            move.b    #4,$24(a0)
            bsr.w    Sonic_ResetOnFloor
            bset    #1,$22(a0)
            move.w    #-$400,$12(a0)    ; make Sonic bounce away from the object
            move.w    #-$200,$10(a0)
            btst    #6,$22(a0)
            beq.s    Hurt_Reverse
            move.w    #-$200,$12(a0)
            move.w    #-$100,$10(a0)
    There's one last thing to do, you don't want these to come with you into the next level, so this part is easy. Go to "Obj0D_Touch:" and before "locret_EBBA:" place these lines:
    Code:
            clr.b    ($FFFFXXXX).w ;Clear Spike flag
            clr.b    ($FFFFYYYY).w ;Clear high jump flag
    Now, go to "Obj3E_Switched:" and after
    Code:
            clr.b    ($FFFFFE1E).w    ; stop time counter
            clr.b    ($FFFFF7AA).w    ; lock screen position
            move.b    #1,($FFFFF7CC).w ; lock    controls
            move.w    #$800,($FFFFF602).w ; make Sonic run to    the right
    Insert the same code that you placed above "locret_EBBA:"
    Congrats! You now have 2 new monitors, that can let you jump 1.5 times higher and enable/disable the Sonic 1 spike behavior. Enjoy! And thanks for reading my first guide. If there's any errors I made, please notify me.
    s1built000.png
     
    Last edited: May 10, 2019