docs: record the map (radar) gauge as done + its follow-ups

GAUGE_COMPOSITE.md + CLAUDE.md: add the map/MapDisplay radar (increment 6, the
view wedge renders) to the done list; note the systemic pattern (a newly-consumed
reconstructed gauge is the first reader of stubbed helpers -- the map exposed 3);
narrow the remaining gauge widgets to PlayerStatus + vehicleSubSystems, and list
the map follow-ups (contact classification / stubbed pip+name infra, SetTargetRange
zoom).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
arcattack
2026-07-06 21:17:52 -05:00
co-authored by Claude Opus 4.8
parent 48ed3a8b73
commit 1746c5bb1f
2 changed files with 37 additions and 16 deletions
+16 -9
View File
@@ -711,15 +711,22 @@ gap slots uninitialized and `Find` strcmps EVERY slot → a published table MUST
`NextAttributeID`; fill gaps with a shared read-only pad member.** Done: **HeatSink table** (`CurrentTemperature`
→ Heat readout shows 77), **Mech table** (dense prefix 0x15..0x21, `LinearSpeed` → SPEED readout shows ~225),
**vertBar** (coolant bars; x87 pixel math recovered by disassembly), **segmentArcRatio** (speed arc; thin subclass
of engine `SegmentArc`), and **oneOfSeveralPixInt** (the button-state lamps — reconstructed the whole OneOfSeveral
strip-selector family + PixMap8 blit path). **Base primitives `numeric`/`numericSpeed`/`digitalClock`/`rankAndScore`
are ENGINE (L4GAUGE.cpp) — only need the data; `vertBar`/`segmentArcRatio`/`oneOfSeveralPixInt`/`map`/`PlayerStatus`/
`vehicleSubSystems` are BT-specific (reconstruct + register).** Technique added: `tools/disas2.py <VA> <len>`
(recover FPU math Ghidra drops — `FUN_004dcd94`=round, `FUN_004dcd00`=fabs) + `tools/vtdump.py <vtVA> <n>`
(find a vtable override the assert-anchored decomp didn't export). REMAINING: `map` (radar — the marquee, needs the
Mech table extended to 0x31 + a Sensor table + the `MapDisplay` renderer), `PlayerStatus`, `vehicleSubSystems`
(task #13) + the aggregate HeatSink-bank `AmbientTemperature` (`#if 0`'d 0xBBE) + the Reservoir `coolantCapacity`
shadow + making the duck/searchlight buttons dynamic (extend the Mech table to 0x37 + a Searchlight table).
of engine `SegmentArc`), **oneOfSeveralPixInt** (the button-state lamps — reconstructed the whole OneOfSeveral
strip-selector family + PixMap8 blit path), and **map** (the RADAR / tactical display — the marquee; the MapDisplay
renderer was already reconstructed, so this was the registration glue + data: the Mech table extended to the full
0x15..0x38 with the radar Point3D*/Quaternion* attributes + a Sensor "Avionics"/RadarPercent table + a reconstructed
`MapDisplay::Make`/`methodDescription`; renders the FOV view wedge live). **Base primitives `numeric`/`numericSpeed`/
`digitalClock`/`rankAndScore` are ENGINE (L4GAUGE.cpp) — only need the data; `vertBar`/`segmentArcRatio`/
`oneOfSeveralPixInt`/`map`/`PlayerStatus`/`vehicleSubSystems` are BT-specific (reconstruct + register).** Technique
added: `tools/disas2.py <VA> <len>` (recover FPU math Ghidra drops — `FUN_004dcd94`=round, `FUN_004dcd00`=fabs) +
`tools/vtdump.py <vtVA> <n>` (find a vtable override the assert-anchored decomp didn't export). **⚠ SYSTEMIC PATTERN
(map): a newly-consumed reconstructed subsystem/gauge is often the FIRST reader of a stubbed helper — the map
exposed 3 (Sensor radarPercent negative from un-normalized heatEnergy; `ResolveOperatorEntity`→NULL; unguarded NULL
entity), each fixed with the established viewpoint-fallback/guard patterns.** REMAINING: `PlayerStatus`,
`vehicleSubSystems` (task #13) + the map's contact classification (0 contacts — the spatial-query `Get*
EntitiesWithinBounds` + the stubbed pip/name/video-object infra) + `SetTargetRange` (radar zoom, 500m default) + the
aggregate HeatSink-bank `AmbientTemperature` (`#if 0`'d 0xBBE) + the Reservoir `coolantCapacity` shadow + the
Searchlight `LightOn` table (duck button already resolves via the 0x37 Mech entry).
**Alternate route considered:** run original `btrel410.exe` under DOSBox — **blocked**: it needs the
VPX/IG board DOSBox can't emulate; bypassing it = the shim work anyway.
+21 -7
View File
@@ -406,6 +406,21 @@ fill the gaps (bind not-yet-needed ids to a shared read-only pad member).
frame index; added the missing `OneOfSeveral::foregroundColor`@0x9C. Config binds duck/searchlight/
display-mode/piloting-mode buttons; `ControlsMapper/DisplayMode` resolves live, the rest degrade to
frame 0 until their tables land.
6. **map** (MapDisplay, btl4rdr) — the RADAR / tactical display (the marquee). The renderer was already
reconstructed (Execute phases: bounds → gather static/moving entities → DrawViewWedge/DrawStatic/
DrawMoving/DrawNames); only the registration glue + data were missing. Extended the Mech table to the
full 0x15..0x38 (RadarRange/RadarLinearPosition[Point3D*]/RadarAngularPosition[Quaternion*]/DuckState;
`AttributePointer`=`int Simulation::*` so the ATTRIBUTE_ENTRY reinterpret binds pointer members),
published the Sensor("Avionics") RadarPercent table, and reconstructed `MapDisplay::methodDescription`+
`Make` from the config (the "center"/"bottom" enum keyword typed as a STRING + converted in Make → no
ModeManager named-constant needed). Renders the view wedge (mech FOV cone) live. THREE pre-existing
stubs the map was the first consumer of, each fixed: Sensor `radarPercent` went negative (un-normalized
`heatEnergy` in the not-byte-exact heat-leaf → guarded to no-penalty); `ResolveOperatorEntity` returned
NULL (→ viewpoint fallback); `MapName::ExtractFromEntity` didn't NULL-guard the entity. ⚠ Debug via
`BT_MAP_LOG` (phase/draw trace). FOLLOW-UPS: contacts show 0 (the `GetStaticEntitiesWithinBounds`/
`GetMovingEntitiesWithinBounds` classification finds nothing — the enemy dummy isn't in the spatial
lists); the pip/name/video-object infrastructure (`GetVideoObject`/`LookUpPip`/`GetNameID`) is stubbed
so contacts/labels need it; radarRange is a 500m default until `SetTargetRange` is un-stubbed.
### Reconstruction-technique additions (durable)
- **x87 float math Ghidra drops** (`FUN_004dcd94()`/`FUN_004dcd00()` show no args = FPU-stack operands):
@@ -425,10 +440,9 @@ fill the gaps (bind not-yet-needed ids to a shared read-only pad member).
- Reservoir shadow: `Reservoir::coolantCapacity`@0x128 shadows the inherited `thermalCapacity` the gauge
reads → `Reservoir/CoolantCapacity` reads the base default; fix = delete the shadow + write thermalCapacity
in the Reservoir ctor (bundle with the Reservoir coolant-bar verification).
-**oneOfSeveralPixInt** DONE (increment 5 above). To make its `DuckState`/`Searchlight/LightOn`
buttons DYNAMIC (they read frame 0 today): extend the Mech dense table to 0x37 (DuckState@0x3f8) + add a
Searchlight `LightOn` table.
- Remaining widgets (task #13): `map` (radar — the marquee; needs the Mech dense table extended to 0x31 for
RadarRange/RadarLinearPosition/RadarAngularPosition + a Sensor `RadarPercent` table + the map/radar
renderer reconstruction, base `MapDisplay` in btl4rdr.cpp), `PlayerStatus` (comm/score, 8 uses),
`vehicleSubSystems` (26 uses).
-**oneOfSeveralPixInt** DONE (increment 5). The Mech table now reaches 0x37 so `DuckState` resolves;
`Searchlight/LightOn` still needs a Searchlight `LightOn` table to make that button dynamic.
-**map** DONE (increment 6) — renders the view wedge. FOLLOW-UPS: the spatial-query contact
classification (0 contacts today) + the stubbed pip/name/video-object infrastructure (contacts + labels)
+ `SetTargetRange` (radar zoom, currently a 500m default).
- Remaining widgets (task #13): `PlayerStatus` (comm/score, 8 uses), `vehicleSubSystems` (26 uses).