Porting Sonic 2's HUD code to Sonic 1

Discussion in 'Tutorials' started by Bright Neon Colors, Jul 28, 2020.

  1. Bright Neon Colors

    Bright Neon Colors Newcomer Member

    Joined:
    May 9, 2013
    Messages:
    14
    Location:
    Somewhere in the United States
    The HUD code in Sonic 1 has it where it's part of the normal object system whereas in Sonic 2, 3 and Knuckles, it's manually written into the priority table and gets called from the sprite rendering routine. To port this over to Sonic 1 (Hivebrain), the old HUD code needs to be removed and to do that, go to Obj21 and you should see something like this:

    Code:
    Obj21:                    ; XREF: Obj_Index
            moveq    #0,d0
            move.b    $24(a0),d0
            move.w    Obj21_Index(pc,d0.w),d1
            jmp    Obj21_Index(pc,d1.w)
    ; ===========================================================================
    Obj21_Index:    dc.w Obj21_Main-Obj21_Index
            dc.w Obj21_Flash-Obj21_Index
    ; ===========================================================================
    
    Obj21_Main:                ; XREF: Obj21_Main
            addq.b    #2,$24(a0)
            move.w    #$90,8(a0)
            move.w    #$108,$A(a0)
            move.l    #Map_obj21,4(a0)
            move.w    #$6CA,2(a0)
            move.b    #0,1(a0)
            move.b    #0,$18(a0)
    
    Obj21_Flash:                ; XREF: Obj21_Main
            tst.w    ($FFFFFE20).w    ; do you have any rings?
            beq.s    Obj21_Flash2    ; if not, branch
            clr.b    $1A(a0)        ; make all counters yellow
            jmp    DisplaySprite
    ; ===========================================================================
    
    Obj21_Flash2:
            moveq    #0,d0
            btst    #3,($FFFFFE05).w
            bne.s    Obj21_Display
            addq.w    #1,d0        ; make ring counter flash red
            cmpi.b    #9,($FFFFFE23).w ; have    9 minutes elapsed?
            bne.s    Obj21_Display    ; if not, branch
            addq.w    #2,d0        ; make time counter flash red
    
    Obj21_Display:
            move.b    d0,$1A(a0)
            jmp    DisplaySprite
    ; ===========================================================================
    
    change it to look like this:

    Code:
    Obj21:                    ; XREF: Obj_Index
            rts
    ; ===========================================================================
    
    You won't need the old HUD code anymore because it's handled by this new routine which I will post below.

    Now for the new HUD code, add this below the rts in the block of code posted above:

    Code:
    ; ---------------------------------------------------------------------------
    ; HUD Object code - SCORE, TIME, RINGS
    ; --------------------------------------------------------------------------- 
    loc_40804:
        tst.w    ($FFFFFE20).w
        beq.s    loc_40820
        moveq    #0,d1
        btst    #3,($FFFFFE05).w
        bne.s    BranchTo_loc_40836
        cmpi.b    #9,($FFFFFE23).w
        bne.s    BranchTo_loc_40836
        addq.w    #2,d1
    
    BranchTo_loc_40836
        bra.s    loc_40836
    ; ===========================================================================
    
    loc_40820:
        moveq    #0,d1
        btst    #3,($FFFFFE05).w
        bne.s    loc_40836
        addq.w    #1,d1
        cmpi.b    #9,($FFFFFE23).w
        bne.s    loc_40836
        addq.w    #2,d1
    
    loc_40836:
        move.w    #$90,d3
        move.w    #$108,d2
        lea    (Map_Obj21).l,a1
        movea.w    #$6CA,a3
        add.w    d1,d1
        adda.w    (a1,d1.w),a1
        moveq    #0,d1
        move.b    (a1)+,d1
        subq.b    #1,d1
        bmi.s    return_40858
        jsr    sub_D762
    
    return_40858:
        rts
    ; End of function h
    
    This is the HUD code from S2 slightly modified to work with Sonic 1's mapping system. For the rest of the code, go to BuildSprites and change this part:
    Code:
    BuildSprites:                ; XREF: TitleScreen; et al
            lea    ($FFFFF800).w,a2 ; set address for sprite table
            moveq    #0,d5
            lea    ($FFFFAC00).w,a4
            moveq    #7,d7
    
    to this:

    Code:
    BuildSprites:                ; XREF: TitleScreen; et al
            lea    ($FFFFF800).w,a2 ; set address for sprite table
            moveq    #0,d5
            moveq    #0,d4
            tst.b    ($FFFFFFD0).w ; this was level_started_flag
            beq.s    BuildSprites_2
            jsr    loc_40804
    BuildSprites_2:
            lea    ($FFFFAC00).w,a4
            moveq    #7,d7
    
    For the level_started_flag you can use any unused RAM address for it. I used $FFFFFFD0 for this guide. Go to SegaScreen and then scroll down until you see this line:

    Code:
            move.w    #0,($FFFFF660).w
    
    add this below it:

    Code:
            move.b    #0,($FFFFFFD0).w
    
    Go to Title_ClrPallet and you should see this line somewhere below it:

    Code:
            move.b    #$8A,($FFFFD080).w ; load "SONIC TEAM PRESENTS"    object
    

    add this below it:

    Code:
            move.b    #0,($FFFFFFD0).w
    
    Go to Level and you should see this somewhere below it:

    Code:
            bset    #7,($FFFFF600).w ; add $80 to screen mode (for pre level sequence)
    
    add this below it:

    Code:
            move.b    #0,($FFFFFFD0).w
    
    Further down at loc_3946 you should see this somewhere below the label:

    Code:
            move.b    #$21,($FFFFD040).w ; load HUD object
    
    replace that with this:

    Code:
            move.b    #1,($FFFFFFD0).w
    
    Go to SS_ClrNemRam and find this line below it:

    Code:
            move.b    #9,($FFFFD000).w ; load    special    stage Sonic object
    
    add this below it:

    Code:
            move.b    #0,($FFFFFFD0).w
    
    Go to End_LoadSonic and find this line below it:
    Code:
            move.b    #$21,($FFFFD040).w ; load HUD object
    
    replace it with this:

    Code:
            move.b    #1,($FFFFFFD0).w
    
    Then go to Cred_ClrPallet and find this line below it:

    Code:
            move.b    #$8A,($FFFFD080).w ; load credits object
    
    and add this below it:

    Code:
            move.b    #0,($FFFFFFD0).w
    
    You're now done and should have a near perfect port of S2's HUD code to Sonic 1. It also fixes the bug where "Time" does not flash if you have 9 minutes on the timer and have rings. The source code with all steps applied is provided below.
     

    Attached Files:

    Last edited: Jul 28, 2020
    maple_t, Iso Kilo, KCEXE and 6 others like this.