Restore the GHZ Ball from Sonic 1 Prototype

Discussion in 'Tutorials' started by GottaGoFast, Feb 15, 2021.

Tags:
  1. GottaGoFast

    GottaGoFast Newcomer Trialist

    Joined:
    Jan 15, 2021
    Messages:
    9
    In new dumped prototype Hidden Palace streamed, we finally got to see the ball in action. However I heard people like me had some errors porting it in and now ill show you guys how to restore it perfectly in the final! This tutorial is for github only.

    1: Importing the code
    Everyone knows that the Ball id is "19" (not to get confused with 48 "Swinging Ball Boss"), so we will be porting the code into Obj19! So heres the code in raw form:

    Code:
    ObjRollingBall:
            moveq    #0,d0
            move.b    $24(a0),d0
            move.w    off_5C8E(pc,d0.w),d1
            jmp    off_5C8E(pc,d1.w)
    ; ---------------------------------------------------------------------------
    
    off_5C8E:    dc.w loc_5C98-off_5C8E, loc_5D2C-off_5C8E, loc_5D86-off_5C8E, loc_5E4A-off_5C8E, loc_5CEE-off_5C8E
    ; ---------------------------------------------------------------------------
    
    loc_5C98:
            move.b    #$18,$16(a0)
            move.b    #$C,$17(a0)
            bsr.w    ObjectFall
            jsr    ObjectHitFloor
            tst.w    d1
            bpl.s    locret_5CEC
            add.w    d1,$C(a0)
            move.w    #0,$12(a0)
            move.b    #8,$24(a0)
            move.l    #MapRollingBall,4(a0)
            move.w    #$43AA,2(a0)
            move.b    #4,1(a0)
            move.b    #3,$19(a0)
            move.b    #$18,$18(a0)
            move.b    #1,$1F(a0)
            bsr.w    sub_5DC8
    
    locret_5CEC:
            rts
    ; ---------------------------------------------------------------------------
    
    loc_5CEE:
            move.w    #$23,d1
            move.w    #$18,d2
            move.w    #$18,d3
            move.w    8(a0),d4
            bsr.w    sub_A2BC
            btst    #5,$22(a0)
            bne.s    loc_5D14
            move.w    (ObjectsList+8).w,d0
            sub.w    8(a0),d0
            bcs.s    loc_5D20
    
    loc_5D14:
            move.b    #2,$24(a0)
            move.w    #$80,$14(a0)
    
    loc_5D20:
            bsr.w    sub_5DC8
            bsr.w    ObjectDisplay
            bra.w    loc_5E2A
    ; ---------------------------------------------------------------------------
    
    loc_5D2C:
            btst    #1,$22(a0)
            bne.w    loc_5D86
            bsr.w    sub_5DC8
            bsr.w    sub_5E50
            bsr.w    ObjectMove
            move.w    #$23,d1
            move.w    #$18,d2
            move.w    #$18,d3
            move.w    8(a0),d4
            bsr.w    sub_A2BC
            jsr    ObjSonic_AnglePosition
            cmpi.w    #$20,8(a0)
            bcc.s    loc_5D70
            move.w    #$20,8(a0)
            move.w    #$400,$14(a0)
    
    loc_5D70:
            btst    #1,$22(a0)
            beq.s    loc_5D7E
            move.w    #$FC00,$12(a0)
    
    loc_5D7E:
            bsr.w    ObjectDisplay
            bra.w    loc_5E2A
    ; ---------------------------------------------------------------------------
    
    loc_5D86:
            bsr.w    sub_5DC8
            bsr.w    ObjectMove
            move.w    #$23,d1
            move.w    #$18,d2
            move.w    #$18,d3
            move.w    8(a0),d4
            bsr.w    sub_A2BC
            jsr    ObjSonic_Floor
            btst    #1,$22(a0)
            beq.s    loc_5DBE
            move.w    $12(a0),d0
            addi.w    #$28,d0
            move.w    d0,$12(a0)
            bra.s    loc_5DC0
    ; ---------------------------------------------------------------------------
    
    loc_5DBE:
            nop
    
    loc_5DC0:
            bsr.w    ObjectDisplay
            bra.w    loc_5E2A
    ; ---------------------------------------------------------------------------
    
    sub_5DC8:
            tst.b    $1A(a0)
            beq.s    loc_5DD6
            move.b    #0,$1A(a0)
            rts
    ; ---------------------------------------------------------------------------
    
    loc_5DD6:
            move.b    $14(a0),d0
            beq.s    loc_5E02
            bmi.s    loc_5E0A
            subq.b    #1,$1E(a0)
            bpl.s    loc_5E02
            neg.b    d0
            addq.b    #8,d0
            bcs.s    loc_5DEC
            moveq    #0,d0
    
    loc_5DEC:
            move.b    d0,$1E(a0)
            move.b    $1F(a0),d0
            addq.b    #1,d0
            cmpi.b    #4,d0
            bne.s    loc_5DFE
            moveq    #1,d0
    
    loc_5DFE:
            move.b    d0,$1F(a0)
    
    loc_5E02:
            move.b    $1F(a0),$1A(a0)
            rts
    ; ---------------------------------------------------------------------------
    
    loc_5E0A:
            subq.b    #1,$1E(a0)
            bpl.s    loc_5E02
            addq.b    #8,d0
            bcs.s    loc_5E16
            moveq    #0,d0
    
    loc_5E16:
            move.b    d0,$1E(a0)
            move.b    $1F(a0),d0
            subq.b    #1,d0
            bne.s    loc_5E24
            moveq    #3,d0
    
    loc_5E24:
            move.b    d0,$1F(a0)
            bra.s    loc_5E02
    ; ---------------------------------------------------------------------------
    
    loc_5E2A:
            move.w    8(a0),d0
            andi.w    #$FF80,d0
            move.w    (CameraX).w,d1
            subi.w    #$80,d1
            andi.w    #$FF80,d1
            sub.w    d1,d0
            cmpi.w    #$280,d0
            bhi.w    ObjectDelete
            rts
    ; ---------------------------------------------------------------------------
    
    loc_5E4A:
            bsr.w    ObjectDelete
            rts
    ; ---------------------------------------------------------------------------
    
    sub_5E50:
            move.b    $26(a0),d0
            bsr.w    GetSine
            move.w    d0,d2
            muls.w    #$38,d2
            asr.l    #8,d2
            add.w    d2,$14(a0)
            muls.w    $14(a0),d1
            asr.l    #8,d1
            move.w    d1,$10(a0)
            muls.w    $14(a0),d0
            asr.l    #8,d0
            move.w    d0,$12(a0)
            rts
    ; ---------------------------------------------------------------------------
            include "levels/GHZ/RollingBall/Sprite.map"
            even
    ; ---------------------------------------------------------------------------
    
    Replace this:
    Code:
    ObjRollingBall:
    With this:
    Code:
    Obj19:

    2: Valid Code
    This doesn't mean build up your rom, when building it will show up errors. That is because the code seen in Obj19 doesn't have any existing code! Lets fix that.

    This is out first problem, the mapping code. The maps doesnt exist and so does the GFX, so all we have to do is replace this:

    Code:
            move.l    #MapRollingBall,4(a0)
    
            move.w    #$43AA,2(a0)
    With this:
    Code:
            move.l    #Map_GBall,obMap(a0)
            move.w    #$43AA,obGfx(a0)
    Our second problem is sub_A2BC. It doesn't exist either! sub_A2BC is a more earlier version of SpeedToPos. So replace any instances of sub_A2BC to SpeedToPos. This also goes with the GetSine code, replace all GetSine with the newer version (CalcSine). This is for every code (Obj_SonicAnglePosition,ObjectDelete,ObjectDisplay,Obj_SonicFloor). Do not add ObjectDelete, as it will remove the Ball in the process of it moving!

    Our third problem is the ObjectMove code, it also doesn't exist! ObjectMove is basically BossMove. but again, an earlier version. Get the BossMove code from sonic.asm and put it in 19.asm (obj19). Then replace "BossMove:" with "ObjectMove:"

    The last problem is ObjectFloorDistance. Replace that with ObjFloorDist.

    3. Solid Ball

    All we have to do is add the SolidObject code. you need to put this under all "bsr.w SpeedToPos". Here is the code:
    Code:
    move.w   #$20,d1
    move.w   #$1B,d2
    move.w   #$18,d3
    bsr.w       SolidObject
    Also, delete any instances of ObjectList!

    4. Build

    Build it an it should be done. Enjoy your new Rolling Ball!




     
    Last edited: Feb 16, 2021
  2. Stdh

    Stdh Newcomer Trialist

    Joined:
    Jan 11, 2021
    Messages:
    7
    thank you for this!
     
  3. GottaGoFast

    GottaGoFast Newcomer Trialist

    Joined:
    Jan 15, 2021
    Messages:
    9
    No problem! However, if it says theres errors in sub SolidObject about the "bsr.w MvSonicOnPlatform", change bsr.w to jsr instead.

    Edit: set it to jsr not jmp
     
    Last edited: Feb 16, 2021
  4. Inferno

    Inferno Rom Hacker Member

    Joined:
    Oct 27, 2015
    Messages:
    69
    Location:
    Hidden Palace Zone, Westside Island
    Don't do this, that's not the right instruction for any distance branching and returning.

    Do jsr instead, jmp is for bra instructions.
     
  5. Ichigo

    Ichigo Newcomer Trialist

    Joined:
    Jan 31, 2021
    Messages:
    1
    Thank you GottaGoFast. Now i can build my own Sonic 1 Beta Remake. :D
     
  6. TomTalker

    TomTalker Newcomer Trialist

    Joined:
    Feb 20, 2021
    Messages:
    7
    Location:
    Emerald Hill
    Thank you so much for this tutorial! I hope to see more working GHZ Prototype Balls in new hacks! ;P