Skip to content

The race display (HUD) ​

How POD lays out and draws the display over a race, traced for Un-POD's game app (apps/unpod/src/habi.rs). Addresses are the current WINPOD.EXE. Each finding is observed (read in code or data), measured (on the original's frames, derived/race/pod-beltane-full-shots/), inferred or unknown.

The layout file: SCRIPTS/HABI.BIN ​

load_race_display (FUN_00477884) reads it (docs/formats/lists.md, "HABI.BIN"). Each element's first line is read with sscanf("%ld %s %ld %s %ld %ld %ld %ld %ld %ld") (observed, FUN_00477884; the locals it fills and the tables they go to):

FieldWhatKept in
0slot, 0 to 30the index of the tables below
1kind, 0 to 16, or a name from the "decors" table (kind 17)0x5a7228
2the slot the element is placed from (its own for a top-level one)record +1 (0x5a3989)
3font or picture (typo020 … typo040, nulle)record +2
4a wordrecord +0x10
5the element's state for each view at the start (-1 shown)0x5a6e28, 0x5a6ea8
6display mode, compared with DAT_00634d14; -1 any
7views: 1, or 2 in split screen; 0 any
8, 9x, y0x5a72a8, 0x5a7328

The records are 0x1a4 bytes at 0x5a3988 + slot × 0x1a4; an element's option lines (the glyphs to draw, the /l /p /s /t /c lists, the view keys) follow in the record.

Measured on the original's 640 × 480 frames (mode 1, one view):

  • (x, y) is the left and the bottom of what the element draws. A y of 479 ends on the last row; a negative y counts up from the bottom (the gear digit at -5 ends on row 474).
  • Field 2 names the element it hangs off, and its x counts from that element's x: the map frame ? (x 17, from the map panel at 532) is at 549.
  • A picture element's option line has six glyphs, one per language: index 0 English with MPH, 1 French, 2 German, 3 Spanish, 4 Italian, 5 English with MPH (the glyphs of slots 20 and 21 read "Gear", "Rapport", "Gang", "Marcha", "Marcia", "Gear" and MPH, KMH, KMH, KMH, KMH, MPH). FUN_0047939c gives the index (inferred from its use in FUN_00485eb4).

The kinds ​

Each kind has four handlers at 0x5a3878 + kind × 0x10, set by FUN_00477258 (observed): +0 load, +4 set-up (called by FUN_0047cacc when the race starts), +8 the view keys (show or hide, called by FUN_00499514), +0xc draw. FUN_00499514 runs once per view and frame (row 10 of the race loop, main-loop.md): it reads the key combinations, then calls each shown element's draw with the slot in EAX, the view's racer in EDX, x in EBX and y in ECX. Most handlers were reached only through this table, so Ghidra's first export had none of them; they were decompiled with run/ghidra/CreateAndDecompile.java into derived/ghidra/hud/hud.c (62 functions).

KindDrawWhat (observed in the draw function)Un-POD
0FUN_0047e26ca picture: the element's glyph for the language (panels, labels)drawn
1FUN_00478c78the gear: car +0x44a, '0' + gear, 'R' for 8drawn (the replay has no gear: "-")
2FUN_0047e098three status bars from per-car fields; HABI supplies three fonts, glyphs and offsetsdrawn from grouped body-part damage (Deviation: POD reads separate, not-yet-traced gauge fields)
3FUN_004803a4the speed: forward velocity projected from the car's velocity; POD uses 3.6 for metric languages and 2.25 for Englishdrawn from the replay's speed
4FUN_0047f8c0the other drivers' positions around the viewed car, clipped to HABI's lower-right radar boundsdrawn with car-relative projection; exact fixed-point projection and marker glyphs remain different
5FUN_0047e980the player's per-hit body damage record (FUN_0047ed1c): damage icons at their HABI coordinatesdrawn from the live damage record
6FUN_0047d330the board: places, gaps, a coloured dot, names (2,407 bytes)places and names; gaps and dots not ported
7FUN_00485db4a time (format_time)not used at 640 × 480
9FUN_0047f388place "/" racers: "8/8"drawn
10FUN_0047f048the lap: LAPCNT LAPESP + lap + "/" + laps, or LAPCNT COMPLTD past the lastdrawn
11 to 14POD handlers not yet individually traceddebug read-outs on Shift+Ctrl keysnot ported

race_hud (FUN_00479df4) draws the rest itself: the race time at the bottom centre, the lap record ("Tour Record", CHRONO BSTLAP) and the last lap's time ("Tours") for a while after the lap line, the split times, the "last lap" sign and the end timer (race.md). In Un-POD only the race time is drawn, at its measured place (centre 320, bottom 453, typo027).

Open ​

  • Kind 2's three source fields and scale; kind 4's exact fixed-point projection and marker glyphs; kind 6's gaps and dots; field 4; the "decors" names; how POD picks the language.
  • race_hud's texts: their positions and fonts.
  • The same for the other display modes and split screen.

Prose CC0 1.0, code Apache 2.0. POD: Planet of Death is © Ubi Soft; none of its files are on this site.