Files
Sylpheed/docs/re/structures/hud-config.md
Claude (auto) 418fbf30ed re: the executable's own PG* HUD roster; the disc side was already owned
Took the biggest of the five unowned base-solver blocks, sub_822215D0 (205/206).

Grep-and-READ first, and it paid.  PGHUD* pointed at mission-script-manifest.md,
which documents HudResource's 24 fields -- but hud-config.md owns the whole
family: all 16 records in the six GP_MAIN_GAME_*2D paks, 419 distinct asset
paths.  Stopping at the first grep hit would have "discovered" a documented table
for the second time in three iterations.

Control: counting PG* field names straight off the paks reproduces that
document's own numbers exactly -- Sight 35, Radar 29, Marker 27, Wing 23,
Manuva 15; HudResource 23 PG* + HUD_RES_FONT = its stated 24.

The increment: the executable carries its own roster.  sub_822215D0 reads a
205-name block at base 0x820A0000, 205/205 PG*-prefixed, zero partials -- PGHUD
77, PGTARGET 31, PGGAUGE 25, PGMANUVA 16, PGMARK 12, PGWARNING 10, PGMARKTGT 9.
The disc has 228 distinct PG* names; 200 are in both, 5 code-only, 28 disc-only.
200 + 5 = 205 and 200 + 28 = 228, closing both ways.

Four of the five code-only names are printf families whose stem is a disc field
(PGHUD_HIT_NUM_EFF%d, PGHUD_HIT_NUM_RED%d, PGREMAIN_NUM%d, PGTIMER_NUM%d) and all
four stems sit in the disc-only 28: the code builds indexed instance names from a
base name the table declares.  After pairing, the residual is one code-only name
(PGMANUVA_EFF0) and 24 disc-only ones, listed in the doc.

Not settled: what the block is for -- the function body was not read.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PMRJjbxLqZtsb5Vb7KunPE
2026-08-27 22:25:40 +00:00

7.7 KiB
Raw Blame History

The in-game HUD configuration — 16 records, and a per-stage resource table

The GP_MAIN_GAME_*2D.pak archives carry six IDXD entries that are the in-game counterpart of tables.pak's menu configs. Only HudResource had been opened (mission-script-manifest); the other fifteen records had not. No docs/re/ file mentions ArmsStatus, RangeFinder, Radar, Sight, Wing, NamePlate or ResourceTable — checked before writing this. Artefact ../data/hud-config.txt (697 lines), regenerator tools/re-capture/hud_config.py.

entry records
0x10b9d584, 0x4abcfc43 16ArmsStatus, Map, ArmsItem, RangeFinder, Marker, Manuva, Number, HudResource, NamePlate, ActiveArm, Information, Wing, ArmsItemFile, Radar, Speed, Sight
0x927b29f8, 0xccb12a6b 13ObjectiveMarker_{Acropolis,SubObjective,Guard,WayPoint,Tanker,Target}, TutorialMarker_{…}, Enumerate_ObjectiveMarkers, Parameters
0x59ecbedd Face — 52 positional pjf001_*.t32 portrait sprites
0x87fd28c0 ResourceTable — 58 positional entries

Between them these name 419 distinct asset paths. That is the whole flight HUD: the arms panel (ArmsStatus 16, ActiveArm 13, ArmsItemFile 59), the range finder (10), the target/lock markers and their HP-gauge strips (Marker 27), the manoeuvre gauge (Manuva 15), the radar (29), the reticle (Sight 35), the wingman panel (Wing 23), nameplates (60), speed (9), and the digit strips (Number, %d-templated: pghud_speed_num%d.t32, pgtimer_num%d.t32, pglockon_%d.t32).

🔑 The values carry subdirectory prefixes the corpus had not seen — ArmsSt\, ActvArm\, RangeF\, Marker\, Manuva\, Map\, Speed\, Radar\, Sight\, Wing\, Hitmark\, Lockon\, Info\.

🧪 The whole in-game HUD is NOT name-hash addressed

Taking the config's own exact path strings — no guessing left in the loop:

419 distinct .prt / .t32 / .tbl values; 0 resolve as a pak entry under 10 prefixes. The four config FILENAMES (HudResource.tbl, HudMarkerResource.tbl, and their _S26 overrides) resolve to nothing either.

The .t32 sprites certainly exist — the E2D pak holds 574 T8aD entries. So the 2D pak's contents are simply not addressed by name_hash of the name the config uses, and that closes the previous iteration's puzzle properly: the 28 "dangling" .prt names were never a missing-asset story, they are 28 of a set where none of the 419 resolves.

⚠️ This supersedes the framing in mission-script-manifest: the right statement is not "these five/28 are absent" but "the in-game asset namespace is not the archive namespace".

ResourceTable — a per-stage HUD config table

58 positional fields = 29 pairs, alternating HudResource.tbl / HudMarkerResource.tbl. Exactly one pair differs — index 25, which reads HudResource_S26.tbl / HudMarkerResource_S26.tbl. Identical in all six language paks.

🟡 The reading: the table is indexed by stage number 1, so 29 entries cover S1…S29 (the numbering that runs to S29 with S17 absent), and index 25 is S26 — the one stage with its own HUD configuration. The arithmetic is exact and the _S26 suffix names the same stage, but nothing here proves the indexing, so this is a reading, not adopted.

The objective / tutorial MARKER records

hud-config.md listed these as "in the artefact but unread". Opened now — and they are portable HUD data, 11 records of 12 named fields each:

ObjectiveMarker_Target   ColorNormal 0xFFFF0000  Emph1 0xFFFF0000  Emph2 0xFF800000
                         Normal pgmark_ob.t32    NormalSub pgmark_ob_s.t32
                         Emphasis pgmark_em_ob.prt  EmphasisSub pgmark_em_ob_s.prt
                         HPGauge 2  HPGaugeSub 0  BlinkCycle 0x800
                         RadarCursorType (blank)  TutorialTarget No
  • Colour is ARGB, three per marker: ColorNormal, ColorEmphasis1, ColorEmphasis2. Objectives are red 0xFFFF0000, guard/waypoint green 0xFF20FF20, Acropolis/tanker cyan 0xFF00FFFF, sub-objective yellow 0xFFFFFF00, and every TutorialMarker_* is amber 0xFFFFA010.
  • Each marker carries a Normal sprite and an Emphasis part, optionally with …Sub companions; HPGauge is 0 / 1 / 2; RadarCursorType is Circle (Acropolis, tanker), Rectangle (guard) or blank; BlinkCycle is 0x800 on all eleven.
  • TutorialTarget is Yes on exactly the five TutorialMarker_* records and No on the six ObjectiveMarker_* — the two families are otherwise the same shape.

Parameters (4 fields) binds the roles:

TargetMarker      ObjectiveMarker_Target
HelpMarker        ObjectiveMarker_SubObjective
TutoTargetMarker  TutorialMarker_Target
ReloadDispTime    0.1

Enumerate_ObjectiveMarkers is the 11-name roster of the set — the same shape as the Enumerate_Squadrons record unit-group-table uses.

⚠️ pgmark_em_ob_s.prt here is one of the 28 names archive-naming shows resolving nowhere — consistent with the namespace finding, not a missing asset.

🟡 Not settled

  • How the 2D pak's 574 T8aD and 130 RATC entries are addressed, if not by name_hash of the config path. That is now the question.
  • What HudMarkerResource.tbl is — presumably the 13-record marker entry, but the filename does not resolve, so the pairing is by content, not by hash.
  • Parameters and Enumerate_ObjectiveMarkers unread. Opened above.

The executable's own PG* block — sub_822215D0 (2026-08-27)

Found by the base-solver (player-tuning-tables); reproduce from ../data/name-block-bases.txt (the sub_822215D0 section) against hud_config.py's record dump.

The disc side above is confirmed independently. Counting PG*-prefixed field names straight off the paks gives Sight 35, Radar 29, Marker 27, Wing 23, Manuva 15 — the same numbers this document already states, and HudResource 23 PG* + HUD_RES_FONT = its documented 24. A re-derivation that lands on the same counts is the control for what follows.

🔑 What this document did not say: the executable carries its own roster. sub_822215D0 reads a 205-name block at base 0x820A0000205/205 are PG*-prefixed, zero partials — led by PGHUD 77, PGTARGET 31, PGGAUGE 25, PGMANUVA 16, PGMARK 12, PGWARNING 10, PGMARKTGT 9.

distinct PG* names on the disc (across all 16 records) 228
the code block 205
in both 200
code-only 5
disc-only 28

200 + 5 = 205 and 200 + 28 = 228 — the arithmetic closes both ways.

⚠️ Four of the five "code-only" names are printf families whose stem is a disc field: PGHUD_HIT_NUM_EFF%d, PGHUD_HIT_NUM_RED%d, PGREMAIN_NUM%d, PGTIMER_NUM%d — and PGHUD_HIT_NUM_EFF, PGHUD_HIT_NUM_RED, PGREMAIN_NUM, PGTIMER_NUM are all four sitting in the disc-only 28. The code builds indexed instance names from a base name the table declares. Pair them off and the real residual is one code-only name — PGMANUVA_EFF0 — and 24 disc-only ones (PGHUD_LOCATOR, PGHUD_CAMERA, PGHUD_PITCH_*, PGHUD_YAW*, PGLOCKON, …), i.e. elements the table names that this particular function never mentions.

🟡 What the block is for is not settled: whether it is a lookup table, a registration order, or a paint list. The function was not read.