Scrolling HUD - RetroKoH/S1Fixed GitHub Wiki
(Original guide by RetroKoH)
Source: See commits
Original Commit: 356736a
This mod can be toggled in S1Fixed by setting HUDScrolling to 0 or 1.
So, anyone who's played Sonic 1 might notice one minor (maybe annoying?) detail. Sonic and the HUD both pop into view during the title screen sequence. Sonic pops into view once his object is created, shortly before the level fades into view. In stock Sonic 1, the HUD pops in along with Sonic, but if you followed the S2/3K HUD Manager guide, you'll find that your new HUD pops in as the fade-in is occuring, which does look a little less jarring, but still not ideal.
We don't notice anything like this in Sonic 2, because the HUD is covered by the giant colorful title card that covers the whole screen. Once Sonic, the HUD, and the level palette are ready for view, the parts of the title card zoom out of view, so nothing appears out of the ordinary. In Sonic 3K, this pop-up can be seen just like in Sonic 1, but it's less apparent because most of the HUD uses the second palette line instead of the first, and as a result, it fades in along with the rest of the level. The only part that is seen "popping-in" is the lives icon (which uses the player character's palette), and any part of the HUD appearing over the red bar of the title card.
This guide will apply a scroll in feature to the HUD which will completely mitigate the odd pop-in that happens with the HUD. The first thing we are going to do is add a RAM variable which will help determine where our HUD is located on-screen. If you have followed the S2/3K HUD guide linked above, you might recall that we set aside two bytes of RAM for our HUD. If not, let's do it right here. There is a series of $C (12) unused bytes after v_ssrotate. Let's reserve the last two bytes of this 12 byte group.
v_ssangle: ds.w 1 ; Special Stage angle
v_ssrotate: ds.w 1 ; Special Stage rotation speed
- ds.b $C ; unused
+ ds.b $A ; unused
+ ds.b 1 ; Reserved for the level start flag (if you want the S2 HUD and/or S2 Rings)
+v_hudscrollpos ds.b 1 ; Scrolling x-position for the HUD
If you are already using the S2 HUD, you should still declare the new variable like so. In that case, here's what it should look like:
v_ssangle: ds.w 1 ; Special Stage angle
v_ssrotate: ds.w 1 ; Special Stage rotation speed
- ds.b $C ; unused
+ ds.b $A ; unused
+f_levelstarted: ds.b 1 ; Level start flag (for drawing non-objects)
+v_hudscrollpos: ds.b 1 ; Scrolling x-position for the HUD
The next thing we are going to do is apply the new variable to the HUD's x-position. We can do this with either version of the HUD (Object-based, or BuildHUD), so I'll walk you through both. If you are using Sonic 1's HUD object, go to _incObj/21 HUD.asm and find obX(a0) under HUD_Main. Remove the instruction like so:
addq.b #2,obRoutine(a0)
- move.w #$90,obX(a0)
move.w #$108,obScreenY(a0)
If you are using the S2/3K HUD, go to _inc/BuildHUD.asm and find the label .goahead. We see that the same x-position value of $90 (144) is being loaded to register d3. Instead, we are going to clear the register and load our new variable into d3 instead. v_hudscrollpos itself will be updated elsewhere.
.goahead:
- move.w #128+16,d3 ; set X pos to $90
+ moveq #0,d3
+ move.b (v_hudscrollpos).w,d3 ; set X pos. Will scroll to $90.
move.w #128+136,d2 ; set Y pos
lea (Map_HUD).l,a1
movea.w #make_art_tile(ArtTile_HUD,0,0),a3 ; set art tile and flags
We want to leave the x-position at 0 initially, because we will use v_hudscrollpos to set the HUD's x-position as the level starts. To ensure this happens, we first need to clear the scroll counter, and then have it increment at the right time. Clearing it is easy. Let's go to GM_Title, and underneath the bsr.w ClearScreen
instruction, let's add a clear for the new variable:
clr.b (v_hudscrollpos).w ; clear scroll counter
If you already have the S2/3K HUD, and you placed v_hudscrollpos immediately after f_levelstarted, you can use this instruction instead:
clr.w (f_levelstarted).w ; clear level start flag AND scroll counter
This will clear both bytes, because the instruction is for word-length RAM locations.
Finally, we are going to make the HUD scroll in! To do this, jump further down in sonic.asm to Level_SkipScroll. We are going to add a chunk of code right at the start:
Level_SkipScroll:
+ cmpi.b #128+16,(v_hudscrollpos).w
+ beq.s Level_SkipHUDScroll
+ add.b #4,(v_hudscrollpos).w
+Level_SkipHUDScroll:
jsr (BuildSprites).l
jsr (ObjPosLoad).l
bsr.w PaletteCycle
And with that, we're all set! We now have a HUD that scrolls into view once the fade-in is complete.