Adapt the spark-lesson / expert-seed.md progressive-context pattern to the bt411 port:
a thin router + context/*.md knowledge graph so the 2236-line CLAUDE.md's deep knowledge
loads on-demand instead of every session.
NON-DESTRUCTIVE foundation pass (live CLAUDE.md unchanged; proposed router is a draft):
- reference/glossary.yaml -- ~45 terms (engine/formats/scene/reconstruction)
- context/decomp-reference.md -- the quantitative hub: resource types, ClassID map,
mech offsets, damage delivery, weapon constants, env gates, tools
- context/reconstruction-gotchas.md -- the 12 systemic bug classes (conventions/DO-NOT hub)
- context/bgf-format.md -- geometry format + CONN/PCONN + LOD-sqrt3 + ramp shading
- context/gauges-hud.md -- the gauge/MFD system (the just-completed wave)
- context/open-questions.md -- deferred systems + get-from-Nick
- context/_ROUTER-DRAFT.md -- the proposed slim CLAUDE.md (identity, protocols,
quick-lookup, evidence tiers T0-T4, conventions, structure)
- phases/phase-01-context-restructure.md -- design + migration plan + status
docs/*.md ledgers stay as the DETAILED logs; context/*.md are the curated digests that
route into them. Remaining: ~10 topic files (project-overview, subsystems, combat-damage,
rendering, locomotion, wintesla-port, build-and-run, ...) then the CLAUDE.md swap.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
87 lines
5.6 KiB
Markdown
87 lines
5.6 KiB
Markdown
---
|
||
id: gauges-hud
|
||
title: "Cockpit Gauges / MFD HUD system"
|
||
status: established
|
||
source_sections: "docs/GAUGE_COMPOSITE.md (full map); CLAUDE.md §8"
|
||
related_topics: [reconstruction-gotchas, decomp-reference, subsystems, pod-hardware]
|
||
key_terms: [gauge, methodDescription, attribute-pointer, GaugeRenderer, MFD, PCC]
|
||
open_questions:
|
||
- "Valve/message CONTROL routes need the 0xBD3 SubsystemMessageManager (WAVE 8)"
|
||
- "Status-message queue (StatusMessagePool) is a NULL stub -> MessageBoard is empty"
|
||
---
|
||
|
||
# Cockpit Gauges / MFD HUD
|
||
|
||
The pod's cockpit instruments: the secondary MFD (radar/heat/comm), the 5 mono MFDs, and the
|
||
engineering screens. Full map + per-widget history in **`docs/GAUGE_COMPOSITE.md`**. **The gauge
|
||
system is COMPLETE** at the registration+binding level: all 50 config attribute bindings resolve
|
||
(0 NULL) and every config gauge primitive is registered + built (0 parse-skips). [T2]
|
||
|
||
## Architecture (three layers)
|
||
1. **The config** `content/GAUGE/l4gauge.cfg` — a text file the engine `GaugeInterpreter` parses
|
||
(`BuildConfigurationFile → Initialize → GetProcedureBody → ParsePrimitive`). Each mech's gauge
|
||
tree is built from the label `GetGameModel()+"Init"` (e.g. `bhk1Init`), which invokes shared
|
||
blocks (`MechInit`, `Secondary1`) that `configure` the ports and call gauge primitives. [T1]
|
||
2. **Widgets** — each `keyword(...)` in the config resolves to a `MethodDescription` in
|
||
`BTL4MethodDescription[]` (btl4grnd.cpp). An UNREGISTERED keyword is **parse-skipped** (never
|
||
built). Base primitives (`numeric`/`digitalClock`/`rankAndScore`/`vertBar`-base/`segmentArc`)
|
||
are ENGINE (L4GAUGE.cpp); BT-specific ones (`vertBar`/`map`/`pilotList`/`GeneratorCluster`/
|
||
`sectorDisplay`/`prepEngr`/`messageBoard`/`vehicleSubSystems`/the ColorMapper family) are
|
||
reconstructed + registered. [T2]
|
||
3. **Data binding** — gauges bind to game state by NAME via the engine [[attribute-pointer]]
|
||
system: the config's `Subsystem/Attribute` (e.g. `HeatSink/CurrentTemperature`) resolves
|
||
through `ParseAttribute → FindSubsystem (stricmp GetName()) → GetAttributePointer`. A class
|
||
PUBLISHES an attribute via a `<Name>AttributeID` enum + `static AttributePointers[]`
|
||
(`ATTRIBUTE_ENTRY`) + `GetAttributeIndex()` chained to its parent. ⚠ DENSE-TABLE HAZARD (see
|
||
[[reconstruction-gotchas]] §11). [T2]
|
||
|
||
## Reconstructing a widget — the recipe
|
||
`MethodDescription Class::methodDescription = { "keyword", Class::Make, { ParameterDescription
|
||
rows } };` + a line in `BTL4MethodDescription[]` before `&BTL4ChainToPrevious`. The static
|
||
`Make(int port, Vector2DOf<int> pos, Entity*, GaugeRenderer*)` reads `methodDescription.parameterList[]`,
|
||
allocs (`operator new(binSize)` or plain `new`), placement-news the ctor. Then ctor/dtor/
|
||
TestInstance/BecameActive/Execute. **Gotchas that bite EVERY widget:**
|
||
- Container-Execute must override (§10 gotchas) — else `Gauge::Execute` aborts.
|
||
- `/FORCE` trap — a prose-only slot AVs on first call.
|
||
- Databinding trap — never raw-read owner offsets; use a bridge (`BTGetSubsystemAuxScreen`, …).
|
||
- ReconStream no-op — use `DEBUG_STREAM` for logs, not `DebugStream`.
|
||
- Lazy build — wait for the gauge window before concluding "not built" (`BT_GAUGE_SKIP_LOG`). [T2]
|
||
|
||
## The completed widgets (this project's gauge wave)
|
||
- **Attributes published:** HeatSink table (Degradation/Failure/NormalizedPressure/CoolantMassLeakRate/
|
||
ValveSetting/…), PoweredSubsystem (InputVoltage), MechWeapon (OutputVoltage), Mech (LinearSpeed,
|
||
radar Position/Quaternion), Sensor (RadarPercent), **AggregateHeatSink (AmbientTemperature=300 —
|
||
the LAST NULL)**. [T2]
|
||
- **Widgets reconstructed + registered:** ColorMapper family (cmHeat/cmCrit/cmArmor/multiArmor),
|
||
headingPointer, vertBar (VertTwoPartBar), segmentArcRatio, oneOfSeveralPixInt, map (radar),
|
||
PlayerStatus, vehicleSubSystems (the engineering cluster panels), LeakGauge, vertNormalSlider,
|
||
**pilotList** (Comm KILLS/DEATHS), **GeneratorCluster**, **SectorDisplay** (radar SECTOR X/Z
|
||
read-out — live), **PrepEngrScreen** (12 engineering-screen label overlays), **MessageBoard**
|
||
(comm ticker — deferred-empty). [T2]
|
||
- **Condenser valve gauge:** ValveSetting→coolantFlowScale reads the authentic **1/N**
|
||
(`RecomputeCondenserValves`, FUN_0049f788, was a no-op stub). [T2]
|
||
|
||
## Dev composite (off-pod)
|
||
`BT_DEV_GAUGES` renders the 6 pod [[MFD]] surfaces in a separate 960×384 window (bit-plane masks
|
||
over one shared `SVGA16` pixelBuffer; `SVGA16::DrawDevSurface`). On the POD they come from
|
||
`SETENV.BAT`/`L4GAUGE` on the real multi-adapter hardware (`FindBestAdapterIndices`/`BuildWindows`,
|
||
intact). The `overlay` port (SectorDisplay lives there) shares the `sec` physical surface via a
|
||
different bit-plane (0x00C0). [T2]
|
||
|
||
## Authentically-static (do NOT "fix")
|
||
`currentTemperature ~77` (huge thermalMass ~1.39e6 → a 3.5-heat shot rounds to zero);
|
||
Degradation/Failure temps are fixed markers; AmbientTemperature 300; CoolantMassLeakRate 0 on a
|
||
pristine mech (damage-gated); cmArmor/cmCrit all-green (undamaged solo player — BT is PvP-only);
|
||
RANK 1 solo; MessageBoard empty (no status messages exist in bring-up). The Heat MFD is
|
||
authentically NEAR-STATIC, not a live heat-accumulation display. [T2]
|
||
|
||
## Remaining = DATA FEEDS, not widgets (deferred systems)
|
||
The valve/message CONTROL routes need the **0xBD3 SubsystemMessageManager** (WAVE 8); the
|
||
status-message queue needs **StatusMessagePool** (a NULL stub); `SeekVoltageGraph`'s 4 Seek*
|
||
attrs are a cluster-child (not config-called). See [[open-questions]]. [T2]
|
||
|
||
## Key Relationships
|
||
- Full history: `docs/GAUGE_COMPOSITE.md`.
|
||
- Uses: [[attribute-pointer]] + [[reconstruction-gotchas]]; reads [[subsystems]] state.
|
||
- Renders on: [[pod-hardware]] MFD surfaces.
|