gauges: all 6 cockpit MFD surfaces in a SEPARATE dev window (Milestone C)
Generalizes the single-'sec'-inset (Milestone B) into a full 6-surface compositor presented in its own top-level window -- the default under BT_DEV_GAUGES (BT_DEV_GAUGES_DOCK=1 docks it into the main window instead). A 960x384 window tiles all six pod instrument screens: Heat (COOLANT/BALANCE/ RES + condenser gauges), Comm (KILLS/DEATHS/SELECT TARGET), Mfd1/2/3 (DISPLAY/ PROGRAM/NEAREST frames), and the color radar (SCALE grid + dials + ARMOR DAMAGE). Main 800x600 3D view is un-occluded; default DEV un-regressed (TARGET DESTROYED after 8 hits, 0 crashes). Design (mapped by the mfd-multisurface-map workflow): - All 6 surfaces are bit-plane MASKS over the ONE shared SVGA16/pixelBuffer (sec=palette low byte; Heat=0x4000 UL, Mfd2=0x0400 UC, Comm=0x8000 UR, Mfd1=0x0100 LL, Mfd3=0x1000 LR), so the compositor reaches the SVGA16 once and extracts each by mask. No port-name reconcile needed on the dev path -- fetch the BT names directly; the RP aux* names only matter to the pod's own SVGA16::Update demux (a deferred pod-only fallback). - SVGA16::DrawDevSurface: two kernels -- palette-LUT (sec) + mono bit-plane-> tint ((word&mask)?tint:0). BTDrawGaugeSurfaces iterates a 6-entry table. - Separate window = one CreateAdditionalSwapChain on the existing device (no 2nd D3D device). BTGaugeWindowRenderAndPresent (after the main EndScene): SetRenderTarget -> SetDepthStencilSurface(NULL) -> Clear -> BeginScene -> 6 tiles -> EndScene -> restore -> swap->Present. - KEY BUG fixed: the main 800x600 depth surface stays bound when rendering to the 960x384 gauge backbuffer; a bound depth smaller than the RT is invalid -> all draws silently fail (clear color, no geometry). Unbind depth (Z is off), restore after. Pod SVGA16::Update/BuildWindows path byte-unchanged; all gated BT_DEV_GAUGES. Content is still the authored cockpit frames + base-table gauges -- the live MFD widgets need the BTL4MethodDescription reconstruction (this window is now the live viewer for that work). Details: docs/GAUGE_COMPOSITE.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
a256813395
commit
b526e92cad
+47
-6
@@ -172,10 +172,51 @@ accommodations (skip/guard) stand in for. Files touched: `L4VB16.{h,cpp}` (Draw
|
||||
`L4VIDEO.cpp` (the EndScene hook), `btl4app.{cpp,hpp}` (the override fix), `GAUGREND.cpp` (tolerant skip),
|
||||
`gauge.h` + `GAUGE.{h,cpp}` (NULL-source + SEH guards).
|
||||
|
||||
## Follow-ups (after Milestone B)
|
||||
## Milestone C DONE (2026-07) — ALL SIX instrument surfaces in a SEPARATE dev window
|
||||
|
||||
- **Widget recon (the real fix):** reconstruct `BTL4MethodDescription` (BT gauge classes) + the gauge→mech
|
||||
data bindings so the skipped/guarded gauges show real data and the POD path (strict `Fail`, no guards) works.
|
||||
- **Step 2** — reconcile the MFD port names (`auxUL2/auxC/...` in `SVGA16::Update` vs `Heat/Comm/Mfd1-3` in
|
||||
`L4GAUGE.CFG`) → the 5 MFD surfaces render (only `sec`/radar works today).
|
||||
- **Step 3** — the 2-window layout (3D-view window + an instrument-panel window tiling radar + the 5 MFDs).
|
||||
The beachhead's single-`sec`-inset is now a full **6-surface compositor in its own top-level window** (the
|
||||
default under `BT_DEV_GAUGES`; `BT_DEV_GAUGES_DOCK=1` docks the panel into the main window instead). The
|
||||
960×384 gauge window tiles all six pod instrument screens with authentic content: **Heat** (COOLANT/BALANCE/
|
||||
RES + condenser & temp-leak gauges), **Comm** (KILLS/DEATHS/SELECT TARGET scoreboard), **Mfd1/Mfd2/Mfd3**
|
||||
(DISPLAY/PROGRAM/NEAREST/TEMP-STATUS frames), and the color **radar** (SCALE grid + speed/heading dials +
|
||||
ARMOR DAMAGE schematic). Verified live: gauge window renders all 6; main 800×600 3D view is un-occluded;
|
||||
default DEV (no gauges) un-regressed (TARGET DESTROYED after 8 hits, 0 crashes).
|
||||
|
||||
**Architecture (mapped by the `mfd-multisurface-map` workflow, then implemented):**
|
||||
- **One buffer, six bit-plane views.** All gauge ports share ONE `SVGA16`/`pixelBuffer`; a "surface" is a
|
||||
MASK over that one 640×480×16 buffer. The compositor reaches the `SVGA16` once (via any port) and extracts
|
||||
each surface by its own plane mask. BT plane map (`L4GAUGE.CFG` MechInit @4395): `sec`=radar (palette,
|
||||
low byte) · `Heat`=UL (0x4000) · `Mfd2`=UC (0x0400) · `Comm`=UR (0x8000) · `Mfd1`=LL (0x0100) ·
|
||||
`Mfd3`=LR (0x1000). `Eng1/2/3` are the engineering-mode alt planes of UC/LL/LR, not extra monitors.
|
||||
- **No port-name reconcile needed on the dev path.** The RP names `auxUL2/auxC/…` hardcoded in
|
||||
`SVGA16::Update` only matter to the POD demux (a deferred pod-only follow-up); our compositor fetches the
|
||||
BT names (`Heat/Comm/Mfd1/Mfd2/Mfd3`) directly via `GetGraphicsPort` (`stricmp`).
|
||||
- **Two extract kernels** in `SVGA16::DrawDevSurface`: palette-LUT (sec/radar, == `Update` case 0) and mono
|
||||
bit-plane → tint (`(word & mask) ? tint : 0`, the reduced core of `Update` cases 1/2; MFD masks are single
|
||||
bits so no DWORD SIMD/pack). `BTDrawGaugeSurfaces` iterates a `{name,tint,cellRect}` table over all 6.
|
||||
- **Separate window = one ADDITIONAL SWAP CHAIN on the existing device** (no 2nd D3D device — textures/verts
|
||||
are shared). `BTGaugeWindowRenderAndPresent` (called AFTER the main `EndScene`, before the main Present):
|
||||
`GetBackBuffer` → `SetRenderTarget` → **`SetDepthStencilSurface(NULL)`** → Clear → BeginScene → 6 tiles →
|
||||
EndScene → restore RT+DS → `swap->Present`. The pod's own per-surface `BuildWindows`/`Update` path is
|
||||
byte-unchanged (dev mode already NULLs those objects).
|
||||
- **⚠ THE KEY BUG (cost a cycle): depth-stencil size mismatch.** The main 800×600 depth surface stays bound
|
||||
when you `SetRenderTarget` to the 960×384 gauge backbuffer; a bound depth surface SMALLER than the render
|
||||
target is INVALID → every draw silently fails (window showed the Clear color but no tiles). Fix:
|
||||
`SetDepthStencilSurface(NULL)` before the gauge draws (Z is disabled anyway), restore after. Symptom to
|
||||
remember: render-to-a-second-swap-chain shows the clear color but no geometry ⇒ check the bound depth size.
|
||||
|
||||
**Content reality (unchanged from Milestone B):** the surfaces show the authored cockpit FRAME art + a few
|
||||
base-table gauges (heat numerics, radar) — the live animated MFD widgets are BT-specific gauge classes not
|
||||
yet reconstructed (parse-skipped). The separate window is now the **live viewer** for that widget-recon work.
|
||||
|
||||
## Follow-ups (after Milestone C)
|
||||
|
||||
- **Widget recon (the real fix, the big remaining workstream):** populate `BTL4MethodDescription` (give each
|
||||
BT gauge class a `methodDescription`) + wire the gauge→game-state `Execute()` data bindings, so the
|
||||
skipped/guarded widgets (`map`/`GeneratorCluster`/`vehicleSubSystems`/`pilotList`/`cmArmor`/heat clusters)
|
||||
render live data. The Milestone-C window shows them coming online as they're reconstructed.
|
||||
- **Pod MFD port-name reconcile (pod-only):** a ~5-line positional dual-name fallback in `SVGA16::Update`
|
||||
(`UL = GetGraphicsPort("auxUL2"); if(!UL) UL = GetGraphicsPort("Heat"); …`) so BT MFDs reach the pod's real
|
||||
monitors. NOT a CFG rename (the CFG uses BT names pervasively + `MUNGA_L4` is shared with RP's aux names).
|
||||
- **Polish:** overlay-plane compositing over `sec`; a pod-accurate RGB-packing toggle; texture atlas
|
||||
(one lock/upload); device-reset recreate hardening for the additional swap chain.
|
||||
|
||||
Reference in New Issue
Block a user