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:
arcattack
2026-07-06 11:43:31 -05:00
co-authored by Claude Opus 4.8
parent a256813395
commit b526e92cad
5 changed files with 333 additions and 49 deletions
+21
View File
@@ -675,6 +675,27 @@ method table (BT gauge classes: `PlayerStatus` + ~16 recovered `methodDescriptio
game-state DATA BINDINGS (why some gauges resolve NULL) — that is what the dev skip/guards stand in for, and
what the POD needs. Then Step 2 (RP↔BT MFD port-name reconcile → the 5 MFDs) + Step 3 (2-window layout).
**✅✅ GAUGE MILESTONE C — ALL SIX instrument surfaces in a SEPARATE dev window (default under
`BT_DEV_GAUGES`; `BT_DEV_GAUGES_DOCK=1` = docked-in-main-window instead; full map: `docs/GAUGE_COMPOSITE.md`).**
Steps 2+3 done for the dev path. A 960×384 top-level window tiles all 6 pod screens with authentic content:
**Heat** (COOLANT/BALANCE/RES + condenser/temp-leak gauges), **Comm** (KILLS/DEATHS/SELECT TARGET), **Mfd1/2/3**
(DISPLAY/PROGRAM/NEAREST/TEMP-STATUS frames), and the color **radar** (SCALE grid + dials + ARMOR DAMAGE). Main
800×600 3D view is un-occluded; default DEV un-regressed (TARGET DESTROYED, 0 crashes). **Architecture (from 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;
`Eng1-3` = engineering-mode alt planes, not extra monitors), so the compositor reaches the SVGA16 ONCE and
extracts each by mask. **No port-name reconcile needed on the dev path** — we fetch the BT port names directly via
`GetGraphicsPort` (the RP `auxUL2/…` names only matter to the POD's own `SVGA16::Update` demux — a deferred
pod-only fallback). `SVGA16::DrawDevSurface` has two kernels: palette-LUT (sec, == Update case 0) + mono bit-plane→
tint (`(word&mask)?tint:0`, the reduced core of Update cases 1/2); `BTDrawGaugeSurfaces` iterates a 6-entry table.
The **separate window = one `CreateAdditionalSwapChain` on the EXISTING device** (no 2nd D3D device); rendered
AFTER the main `EndScene` (`BTGaugeWindowRenderAndPresent`, L4VIDEO): SetRenderTarget→**SetDepthStencilSurface(NULL)**
→Clear→BeginScene→6 tiles→EndScene→restore→`swap->Present`. **⚠ KEY BUG (cost a cycle): depth-stencil size
mismatch** — the main 800×600 depth stays bound when you SetRenderTarget to the 960×384 gauge backbuffer; a bound
depth SMALLER than the RT is INVALID → all draws silently fail (window shows the Clear color, no geometry). Fix:
unbind depth (Z is off anyway), restore after. Pod `BuildWindows`/`Update` path byte-unchanged. REMAINING = the
widget recon (above) + the pod MFD port-name fallback.
**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.