A HUD that doesn't move a single pixel
The hardware scroll that moves the scenery so nicely on STe has an awkward side effect: it shifts the entire screen, including the HUD at the top. So my brand new HUD wanted to slide left and right with the scenery. The story of the technique that nails it in place, and the one-frame hiccup that nearly ruined everything.
The scenery streams past, and the HUD goes with it
On the STe, scrolling is done with a single hardware setting: it shifts the displayed image from zero to fifteen pixels to the left, for as long as it takes the camera to cross one tile. That small offset is what makes the scroll smooth, on top of the big jump from one tile to the next.
The trap is that this setting acts on the entire screen. It cannot tell the difference between the play area and the HUD sitting right at the top, the one showing the hearts, the score, the lantern gauge and the remaining lives. As long as that banner was a plain black strip, nobody could see that it was sliding too. The day I put the real content back into it, the HUD started sliding a few pixels left and right in time with the scroll. A HUD that moves with the scenery is exactly what you don't want.
Sixteen copies, one per offset
The idea behind the fix is to turn the problem around. Since the hardware is going to shift the whole screen N pixels to the left, I prepare the HUD content already shifted N pixels to the right. The two offsets cancel out, and the banner lands exactly where it belongs.
The trouble is that N changes every frame, and takes every value from zero to fifteen, because the camera advances pixel by pixel. So I prepare sixteen versions of the banner, each shifted one notch further than the last. On every frame I look at how far the hardware is about to push the screen, and I pick the version that compensates exactly. The banner looks frozen while the scenery streams past beneath it.
What makes the trick viable is that it costs next to nothing. Once the sixteen versions are prepared, picking the right one on each frame asks almost nothing: no computation, no copying. And the memory for those sixteen copies comes from an area already reserved for the scroll, so the game doesn't grow and still fits in its megabyte, on STe as well as STf.
Updating without redoing everything
When you take a hit or empty the lantern, the HUD changes. Rebuilding all sixteen copies in full at that moment would cause very visible flicker, with the banner reconstructing itself version by version across several frames. I had already learned that lesson hunting a similarly nasty defect earlier in the project.
So I only touch the element that changes. A heart emptying, a notch of the gauge going out: I redraw that small piece, and only that, across all sixteen copies at once, in a single frame. The score and the lives don't flinch, and the change goes through without the slightest shimmer.
The one-frame hiccup
With the first version in hand, the banner displayed its content properly, the hearts reacted cleanly to damage, nothing overflowed. But while moving, the HUD hiccuped and flickered. Every so often, a small jolt, as if it jumped by a pixel before catching itself.
The cause lies in a timing detail I had properly accounted for elsewhere without thinking of it here. To avoid another defect, I apply the new scroll at the very precise moment the new image appears on screen, not before. But I was changing the HUD copy a touch earlier, without waiting for that same instant. For one frame, the banner was already showing its next position while the scenery was still showing the previous one. The mismatch between the two lasted just one frame, but it came back intermittently, hence the hiccups.
The fix is to make the copy change wait until the exact instant the scroll switches. Now the banner and the scenery change together, on the same frame, never one without the other. The HUD is perfectly still again.
Taking stock
The HUD now holds at the top of the screen, hearts, score, lantern gauge and lives, perfectly fixed while the scenery scrolls at full speed beneath it. Damage and refills are visible without flicker, and there isn't a stray line under the banner. All of it without costing anything in frame rate, and still within a single megabyte.
The moral fits into a rule I'm noting down for later: with this kind of scroll applied at the last moment, everything tied to the frame, the scenery offset as much as the choice of HUD copy, has to switch at the same precise instant.
The current version of the game is downloadable here as an .st floppy image. Mount it as floppy A in Hatari, in STe mode for the hardware scroll, or in STf mode for the software scroll: it's the same file, it detects the machine at boot. For the current version of the game, see also the homepage.
Leave a comment