(Sonic 1) Sonic CD HUD Centiseconds Timer

Discussion in 'Tutorials' started by paranoimia, Mar 2, 2021.

  1. paranoimia

    paranoimia Newcomer Trialist

    Joined:
    Feb 19, 2021
    Messages:
    2
    Ever wanted to replace the vanilla timer with a Centiseconds timer akin to Sonic CD/ Chaotix/ Mania/ 3 A.I.R in your hack? This short tutorial is aimed towards Hivebrain ASM68K users with code ported from ReadySonic with Mercury's permission.

    Centiseconds.png

    First you'll need to download the HUD Centiseconds Resources zip file attached below and replace the files to their respective folders in your disassembly.

    Next, open sonic1.asm and under Level_LoadObj insert this line between the clear time and lives counter flags:
    Code:
            move.w    d0,($FFFFFE20).w ; clear rings
            move.l    d0,($FFFFFE22).w ; clear time
            move.b    d0,($FFFFFEBF).w ; value used to increment centiseconds
            move.b    d0,($FFFFFE1B).w ; clear lives counter
    Make sure to delete this line in loc_39E8:
    Code:
    move.b     #1,($FFFFFE1E).w
    in Level_StartGame, add this line above bclr #7,($FFFFF600).w:
    Code:
            move.b    #1,($FFFFFE1E).w ; update time counter
            bclr    #7,($FFFFF600).w ; subtract 80 from screen mode
    Next, go to Cont_GotoLevel and insert this line between clear time and clear score:
    Code:
            move.l    d0,($FFFFFE22).w ; clear time
            move.b    d0,($FFFFFEBF).w ; value used to increment centiseconds
            move.l    d0,($FFFFFE26).w ; clear score
    Go to Obj21_Main, and change move.w #$6CA,2(a0) to
    Code:
            move.w    #$6BA,2(a0)
    Next, replace everything from Hud_ChkTime to Hud_End with this:
    Code:
    Hud_ChkTime:
            tst.b    ($FFFFFE1E).w    ; does the time    need updating?
            beq.w    Hud_ChkLives    ; if not, branch    ;Mercury HUD Centiseconds (bsr.s => bsr.w) ported by -paranoimia-
            tst.w    ($FFFFF63A).w    ; is the game paused?
            bne.w    Hud_ChkLives    ; if yes, branch    ;Mercury HUD Centiseconds (bsr.s => bsr.w) ported by -paranoimia-
            lea    ($FFFFFE22).w,a1
            cmpi.l    #$93B63,(a1)+    ; is the time 9'59"99?
            beq.w    TimeOver    ; if yes, branch    ;Mercury HUD Centiseconds (bsr.s => bsr.w) ported by -paranoimia-
            move.b    ($FFFFFEBF).w,d1
            addi.b    #1,d1
            cmpi.b    #3,d1
            bne.s    Cent_Skip
            move.b    #0,d1
          
    Cent_Skip:
            move.b    d1,($FFFFFEBF).w
            cmpi.b    #2,d1
            beq.s    Cent_Skip2
            addi.b    #1,d1
          
    Cent_Skip2:
            add.b    d1,-(a1)
            cmpi.b    #100,(a1)
            bcs.s    Hud_DoCent
            move.b    #0,(a1)
            addq.b    #1,-(a1)
            cmpi.b    #60,(a1)
            bcs.s    loc_1C734
            move.b    #0,(a1)
            addq.b    #1,-(a1)
            cmpi.b    #9,(a1)
            bcs.s    loc_1C734
            move.b    #9,(a1)
    
    loc_1C734:
            move.l    #$5E400003,d0
            moveq    #0,d1
            move.b    ($FFFFFE23).w,d1 ; load    minutes
            bsr.w    Hud_Mins
            move.l    #$5EC00003,d0
            moveq    #0,d1
            move.b    ($FFFFFE24).w,d1 ; load    seconds
            bsr.w    Hud_Secs
          
    Hud_DoCent:
            move.l    #$57800003,d0    ;Mercury Macros ported by -paranoimia-
            moveq    #0,d1
            move.b    ($FFFFFE25).w,d1 ; load    centiseconds
            bsr.w    Hud_Secs
    
    Hud_ChkLives:
            tst.b    ($FFFFFE1C).w    ; does the lives counter need updating?
            beq.s    Hud_ChkBonus    ; if not, branch
            clr.b    ($FFFFFE1C).w
            bsr.w    Hud_Lives
    
    Hud_ChkBonus:
            tst.b    ($FFFFF7D6).w    ; do time/ring bonus counters need updating?
            beq.s    Hud_End        ; if not, branch
            clr.b    ($FFFFF7D6).w
            move.l    #$6E000002,($C00004).l
            moveq    #0,d1
            move.w    ($FFFFF7D2).w,d1 ; load    time bonus
            bsr.w    Hud_TimeRingBonus
            moveq    #0,d1
            move.w    ($FFFFF7D4).w,d1 ; load    ring bonus
            bsr.w    Hud_TimeRingBonus
    
    Hud_End:
            rts
    then add this new subroutine below LoadZero:
    Code:
    ; ---------------------------------------------------------------------------
    ; Subroutine to    load " on the    HUD        ported by -paranoimia-
    ; ---------------------------------------------------------------------------
    
    ; ||||||||||||||| S U B    R O U T    I N E |||||||||||||||||||||||||||||||||||||||
    
    
    Hud_LoadMarks:                ; XREF: HUD_Update
            move.l    #$57400003,($D00004).l  ;locVRAM    $D740
            lea    Hud_TilesMarks(pc),a2
            move.w    #2,d2
            bra.s    loc_1C83E
    ; End of function Hud_LoadMarks
    in Hud_Base insert this below bsr.w Hud_Lives:
    Code:
    bsr.s    Hud_LoadMarks
    and finally, below End of function Hud_Base, replace this:
    Code:
    Hud_TilesBase:    dc.b $16, $FF, $FF, $FF, $FF, $FF, $FF,    0, 0, $14, 0, 0
    Hud_TilesZero:    dc.b $FF, $FF, 0, 0
    with this:
    Code:
    Hud_TilesMarks:    dc.b $1A, 0, 0, 0
    Hud_TilesBase:    dc.b $16, $FF, $FF, $FF, $FF, $FF, $FF,    0, 0, $18, 0, 0
    Hud_TilesZero:    dc.b $FF, $FF, 0, 0
    Now you should have a functioning Centiseconds Counter in your hack.

    Bug to note:
    • If the player were to pass a checkpoint then lose a life and wait until the timer reached 9'59"99, the timer will reset back at the 9 minute mark instead of prompting the Time Over routine which is present in the original ReadySonic source.
    Credits:
    • Mercury for the ReadySonic Source
    • Hivebrain ASM68K code porting by paranoimia
     

    Attached Files: