diff --git a/context/decomp-reference.md b/context/decomp-reference.md index d06c4ce..381be70 100644 --- a/context/decomp-reference.md +++ b/context/decomp-reference.md @@ -522,6 +522,7 @@ default-ON (`'0'` disables). | `BT_SECTOR_LOG` | SectorDisplay Make/Execute | | `BT_NET_TRACE` | `[net-tx]/[net-rx]/[net-upd]` MP tracing | | `BT_DEV_GAUGES` | render the 6 pod MFD surfaces in a separate dev window | +| `BT_GLASS_LAMP_SWEEP` | `0` = restore authentic once-per-gauge-cycle cockpit-lamp updates; default (on) sweeps the lamps EVERY frame in the dev/glass composite path so the lit buttons track the sim even when the throttled background gauge sweep starves under MP load (`L4VB16.cpp` `BTGlassSweepLamps`; the "lighting slow/nonexistent" fix — glass-only, pod serial cadence untouched) | | `BT_AIM="x y"` | pin the reticle crosshair (reticle coords) — headless aim harness | | `BT_AIM_LOG` | `[pick]` ray/box/hit diagnostics (Mech::PickRayHit) | | `BT_FIRE_ARC=` | OPT-IN external-camera fire-arc clamp (unset = authentic no-arc) | diff --git a/context/gauges-hud.md b/context/gauges-hud.md index aaba082..cb1902b 100644 --- a/context/gauges-hud.md +++ b/context/gauges-hud.md @@ -111,6 +111,21 @@ viewport), and `gWindowAspect` = the view rect's on-screen aspect (`BTWorldAspec the work area). Green tint tunable via `BT_COCKPIT_TINT=RRGGBB` (default `0x27E8`). Labels are a lazy GDI-baked MANAGED atlas (survives device reset). Renders in ALL builds; only the PadRIO click/lamp seam is BT_GLASS-gated. Full detail: `docs/GAUGE_COMPOSITE.md`. +- ⚠ **Cockpit-lamp LATENCY under MP load (2026-08-04, glass playtest fix) [T2 runtime-verified].** + The lit cockpit buttons are drawn every frame (`BTDrawCockpitPanels`, reading `PadRIO::GetLampState`), + but the lamp STATE sweep that fills that store — `LampManager::Update` → `AssertNewLampValue` → + `SetLamp` — authentically rides `GaugeRenderer::ExecuteForeground`, which fires only **once per full + gauge cycle** (foreground→background→copy). The cycle can't advance to the next foreground turn + until the THROTTLED background gauge sweep drains the ~140-instrument active list, and that + background task starves under load (issue #45 — "instruments freeze while fps stays healthy"). So on + a busy MP mission the lamp sweep ran ~1×/s: **buttons froze / flashes stalled while the 3D view (a + separate per-frame foreground render) stayed smooth** — the "lighting slow or nonexistent" reports + (all testers on glass surround). Fix: `BTGlassSweepLamps()` runs the lamp sweep EVERY frame on the + dev/glass composite path (`L4VB16.cpp`, in `BTDrawGaugeInset`) — cheap (deduped pushes, ~72 lamps), + decoupled from the gauge cycle. The pod never enters this path (real gauge hardware), so its + bandwidth-paced serial lamp cadence is untouched. Kill switch `BT_GLASS_LAMP_SWEEP=0`. NB the RIO + serial/lamp stack itself is byte-identical to pod-proven Red Planet (`L4LAMP.cpp`/`L4SERIAL.cpp` + diffed) — the defect was purely the glass update CADENCE, not the lamp wiring. ## MP gauge-window FREEZE = dangling bindings + permanent SEH disable (Gitea #12, 2026-07-19) [T2 log-convicted] The live-MP "dev-gauges window froze entirely mid-session" incident (issue #12) is NOT a diff --git a/engine/MUNGA_L4/L4VB16.cpp b/engine/MUNGA_L4/L4VB16.cpp index a14ef9f..05fb0a2 100644 --- a/engine/MUNGA_L4/L4VB16.cpp +++ b/engine/MUNGA_L4/L4VB16.cpp @@ -1293,6 +1293,47 @@ void BTCockpitMouseUp(void) } } +// +// (glass lamp responsiveness, 2026-08) Sweep the cockpit lamp STATE every frame. +// +// The lamp sweep -- LampManager::Update -> AssertNewLampValue -> RIO/PadRIO::SetLamp, +// which is what lights the cockpit buttons -- authentically rides the gauge +// renderer's FOREGROUND turn (GaugeRenderer::ExecuteForeground, gaugrend.cpp), and +// that turn fires only ONCE PER FULL GAUGE CYCLE (foreground -> background -> copy). +// The cycle only advances to the next foreground turn after the THROTTLED background +// gauge sweep drains the whole active-instrument list -- and that background task +// starves under load (issue #45: "every cockpit instrument freezes at its last paint +// while the underlying values AND fps stay perfectly healthy"). So on a busy MP +// mission the lamp sweep ran ~1x/second: the lit buttons froze / flashes stalled while +// the 3D view (a separate per-frame foreground render) stayed smooth -- exactly the +// "lighting slow or nonexistent" playtest reports (all on glass desktops). +// +// The lamp sweep is CHEAP -- deduped state pushes over ~72 lamps, no raster -- so on +// the dev/glass composite path we run it EVERY frame here, decoupled from the gauge +// cycle, and the buttons track the sim regardless of background-sweep slack. The pod +// NEVER enters BTDrawGaugeInset (it drives real gauge hardware), so its authentic +// bandwidth-paced serial lamp cadence is untouched. BT_GLASS_LAMP_SWEEP=0 restores the +// authentic once-per-cycle behaviour. +// +static void + BTGlassSweepLamps() +{ + static int s_on = -1; + if (s_on < 0) + { + const char *e = getenv("BT_GLASS_LAMP_SWEEP"); + s_on = (e != NULL && e[0] == '0') ? 0 : 1; + } + if (!s_on) return; + + GaugeRenderer *gr = BTResolveGaugeRenderer(); + if (gr == NULL || application == NULL) return; + LampManager *lm = gr->GetLampManager(); + ModeManager *mm = application->GetModeManager(); + if (lm != NULL && mm != NULL) + lm->Update(mm->GetModeMask()); +} + // // Free entry point the MAIN renderer calls (L4VIDEO DPLRenderer::ExecuteImplementation, // just before EndScene). No-op unless BT_DEV_GAUGES is set. Docks the 6-surface panel @@ -1301,7 +1342,9 @@ void BTCockpitMouseUp(void) // void BTDrawGaugeInset(LPDIRECT3DDEVICE9 device) { - if (!DevGaugeComposite() || !DevGaugeDocked() || device == NULL) return; + if (!DevGaugeComposite()) return; + BTGlassSweepLamps(); // keep the cockpit lamps tracking the sim EVERY frame (see above) + if (!DevGaugeDocked() || device == NULL) return; if (GlassPanelsOwnSurfaces()) return; // the per-display glass windows draw the surfaces if (gBTGaugeCockpit) {