Files
BT411/context/glass-cockpit.md
T
arcattackandClaude Fable 5 5dd35365c7 Glass input audit: RIO mapper id fix (panel banks live), keyboard reconciliation
Root cause of the dead on-screen panel: MechRIOMapper's message-id enum
chained off L4MechControlsMapper::NextMessageID (=0x19), registering all 18
RIO override handlers at 0x19-0x2a while the streamed .CTL EventMapping
records carry the binary's ids -- the binary RIO table @0051dd30 re-registers
the BASE aux/zoom ids 3..0x13 (Hotbox 0x1a @0051de98).  Every MFD-bank/zoom
press hit the base ConfigureMappableMessageHandler FAIL trap (26/72 buttons
dead; an abort() on a trap-armed pod).  Ids now pinned to the binary
numbering + static_assert-locked (btl4mppr.hpp) -- panel goes 26 -> 52
working buttons (8 await handler reconstruction, filed on Gitea; 12 have no
streamed mapping authored = authentically inert).

Keyboard reconciliation (glass-only): the merged map -- keyboard hosts the
~20 core gameplay actions on the CONTROLS.MAP keys, the panel covers every
pod address by click (right-click = hold latch):
- W/S throttle lever, A/D pedals, Q/E twist, R/F elevation, X all-stop,
  arrows drive; numpad flight cluster kept (Cyd)
- 1/2/3/4/Space/LCTRL/RCTRL fire, LALT reverse, B look-behind (0x41)
- M=0x18 mode cycle, N=0x15 display cycle, H=0x2C coolant flush (hold),
  C=0x2F Condenser1 valve, G=0x0E weapon-1 configure (Mfd1-Quad-gated)
- F5-F9 = Mfd2 bank 0x27-0x24 + 0x22 (page-gated gen A-D / gen mode)
- hardcoded: ` or V = view toggle, J/K/L = Mfd1/2/3 preset-page cycle
  (PadRIO edges -> gBTPresetCycle; no pod "cycle" button exists)
- PadRIO::SuppressKey: bound keys are swallowed from the typed 1995 channel
  (the btinput suppression pattern, glass side) -- ends the glass double
  dispatch ('w'=pilot select 0, 'a'..'g'=MFD2 presets, NUMPAD/F-key key-up
  VK aliases like VK_F5=0x74='t').  Unbound keys keep their authentic
  meanings (5/z presets, t-o pilot select, +/- zoom, F1/F2 align).

DISPLACED from Cyd's default bindings (each reachable on the panel or by a
bindings.txt edit -- flagging for Cyd's veto): number row -> secondary panel
(1-4 now fire), QWERTY row -> pilot keypad (dropped), arrows -> hat looks
(now drive), V/C/B -> fire 0x47/0x46/0x45 (now view/valve/look-behind),
LCTRL -> throttle-down (now fire).  XInput pad section untouched.

Audit by-products (KB updated): the always-active msg-4 records identified
(0x2C = Reservoir flush, 0x29-0x2F = condenser valves, 0x1A-0x1D =
GeneratorA-D ToggleGeneratorOnOff @004b1ed0 unreconstructed); 0x13 = Mech
DuckRequest (crouch), 0x28 = BalanceCoolant; Searchlight/ThermalSight
ToggleLamp handler-sets are default-constructed EMPTY; weapon Eng-page msgs
0x3/0xb = ToggleCooling / ToggleSeekVoltage / EjectAmmo, all unwired;
unhandled messages are SILENT (no [FAIL] -- census = BT_CTRLMAP_LOG dump x
handler tables).

Verified live (build-glass2, ARENA1): panel presets/zoom/display/flush;
W drive (speedDemand 61.5, gait advances), Q turn (BAS), M -> MID, A turn
(MID), Space fires, N display, J/K/L presets, H flush drain, C valve 1->5;
suppression ('w' swallowed, 't' flows, F5-keyup swallowed); BT_SHOT frame.
Un-regression: pod build (gates OFF) compiles 0 errors, forced-walk drives,
streamed ids unchanged; CONTROLS.MAP/btinput untouched.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-20 08:35:55 -05:00

92 lines
6.3 KiB
Markdown

---
id: glass-cockpit
title: "Glass Cockpit — the desktop developer layer (BT_GLASS / BT_STEAM)"
status: living
source_sections: "plan 2026-07-17; CMakeLists.txt gates; BT412 prior art (reference only)"
related_topics: [pod-hardware, build-and-run, multiplayer, gauges-hud]
key_terms: [PadRIO, miniconsole, glass-cockpit]
open_questions: []
---
# Glass Cockpit — the desktop developer layer
**Purpose:** developer tooling so game developers can test their work WITHOUT booting a Tesla II
pod — and stay far enough out of the game that nothing a real pod requires can break. NOT a
consumer product (GDI-grade UI is the ceiling). Pod fidelity outranks desktop convenience in
every trade-off.
## The compile gates (the ONLY compile-time feature gates in the tree)
| Gate | Default | Adds |
|---|---|---|
| `BT_GLASS` | OFF | PadRIO input (XInput+keyboard), on-screen cockpit button panel, desktop plasma window, `glass` platform preset, miniconsole mission launcher |
| `BT_STEAM` | OFF (requires `BT_GLASS`) | Steam transport (`ISteamNetworkingSockets`) + `ISteamMatchmaking` lobby |
- A **no-flags configure is the pure pod game** — the build of record. `cmake` options are
cached, so a developer configures a `build/` with `-DBT_GLASS=ON` once.
- Build dirs: `build-pod/` (defaults, purity), `build/` (dev, glass ON), `build-steam/` (ON/ON).
- **Convention:** `BT_GLASS`/`BT_STEAM` are compile gates; every other `BT_*` name is a RUNTIME
env gate (`BTEnvOn`) — do not add compile gates without updating this file.
- No weak-linkage/optional symbols — `/FORCE` turns unresolved externals into runtime AVs
([[reconstruction-gotchas]]); gated calls must be structurally present-or-absent at compile time.
## Plan of record (2026-07-17)
Working branch `glass-cockpit` (from master `e2c21c4`). Steps: (1) gates+scaffolding [THIS],
(2) PadRIO glass cockpit, (3) miniconsole self-launch, (4) Steam transport+lobby. Full plan:
the approved plan file; running detail: `docs/GLASS_COCKPIT.md`. The retired BT412 trees
(`C:\VWE\BT412`; local branch `local-abandoned-20260717`) are read-only reference — no code is
copied from them.
## Status
- **Step 1 (gates + scaffolding): DONE 2026-07-17.** CMake options + defines; 3-config
configure matrix + negative test + defaults build verified.
- **Step 2a (.CTL id audit): DONE 2026-07-17 [T2].** The streamed `.CTL` positional ids landed
every `MechControlsMapper` record ONE MEMBER LATE (our chain starts at 2, the binary's at 3)
— a latent REAL-POD bug (RIO throttle would drive pedalsPosition), masked on dev boxes by the
keyboard bridge. Fixed ungated: ids pinned to binary numbering + id-2 pad + static_assert
locks (`mechmppr.hpp/.cpp`); torso/weapon chains were already aligned. Permanent env-gated
diagnostic: `BT_CTRLMAP_LOG=1` dumps every streamed record's resolved member offset
(`L4CTRL.cpp CreateStreamedMappings`). Full evidence: `docs/GLASS_COCKPIT.md` §2a.
- **Step 2 (PadRIO glass cockpit): DONE 2026-07-17 [T2].** `RIOBase` seam (`L4RIO.h`,
unconditional) + gated `L4CONTROLS=PAD``PadRIO` (`L4PADRIO.*` XInput+keyboard,
`L4PADBINDINGS.*` `content\bindings.txt`); bridge stand-downs auto-yield to a live device
(`BTRIODevicePresent`, `BT_KEY_BRIDGE` unset=auto/0=off/1=on); on-screen panel `L4PADPANEL.*`
follows **vRIO** (`C:\VWE\vrio` CockpitLayout/PanelCanvas — 104 controls incl. the two hex
keypads → real KeyEvents; right-click latch); desktop plasma `L4PLASMAWIN.*`
(`L4PLASMA=SCREEN`, buffer is top-down); `-platform glass` preset + run.cmd token. Secondary
displays reuse the EXISTING dev-gauge modes (dock / `BT_DEV_GAUGES_WINDOW=1` window /
`_DOCK=1` overlay — [[gauges-hud]]); no new MFD code, no `L4VB16.cpp` exposure.
**Button-trap guard:** base `ConfigureMappableMessageHandler` no longer `abort()`s by default
(`BT_BUTTON_TRAP=1` restores) — each `[FAIL]` log = a missing L4 override to reconstruct.
Verified: authentic-path input (engine push → streamed `.CTL` → mapper), panel-click
survival, 2-node loopback MP un-regressed on the pod build. Detail: `docs/GLASS_COCKPIT.md`.
- **Step 3 (miniconsole): DONE 2026-07-17 [T2].** `game/glass/btl4fe.*` (menu + console-shape
egg writer, golden-tested vs MP.EGG) + `btl4console.*` (the marshal: a worker-thread console
CLIENT speaking the btconsole.py wire verbatim; `content\marshal.log`). ZERO engine hooks —
the engine runs the stock console ladder. Per-mission process relaunch; `BT_FE_*` env arms the
marshal (menu relaunches clear it). Verified: solo cycle (menu→mission→60s clock→stop→menu)
and menu-hosted 2-node LAN.
- **Step 4 (Steam): CODE COMPLETE 2026-07-18 [T2 single-machine].** See [[steam-networking]] —
the wire seam + `L4STEAMNET` identity-token transport + `btl4lobby`. Live 2-account
cross-machine session pending (`docs/STEAM_TEST.md`).
- **Input-coverage audit + keyboard reconciliation: DONE 2026-07-20 [T2].** Root cause of the
dead panel: `MechRIOMapper`'s message ids were chained one enum too high (0x19-0x2a) — the
binary RIO table @0051dd30 re-registers the BASE aux/zoom ids 3..0x13 (Hotbox 0x1a); fixed
ungated + static_assert-locked (`btl4mppr.hpp`) → all 24 MFD-bank + 2 zoom buttons live
(52/72 panel buttons now work; 8 dead await handler reconstruction — Gitea backlog issue;
12 have no streamed mapping authored, authentically inert). **Keyboard = the ~20 core
gameplay actions on the CONTROLS.MAP keys; the PANEL covers every pod address by click**
(right-click = hold latch) — the merged default profile lives in `L4PADBINDINGS.cpp`
(auto-writes `content\bindings.txt`; W/S/A/D/Q/E/R/F/X drive, 1-4/Space/Ctrl fire, M/N/H/C =
pod buttons 0x18/0x15/0x2C/0x2F, `/V view toggle + J/K/L preset cycles hardcoded in PadRIO).
Bound keys are SUPPRESSED from the typed 1995 channel (`PadRIO::SuppressKey`, the btinput
pattern — ended the glass double-dispatch: 'w'=pilot-select, numpad/F-key key-up aliases);
unbound keys keep their authentic meanings (5/z presets, t-o pilot select, +/- zoom).
In BAS control mode the pod turns with the STICK (Q/E) and pedals are inactive — authentic;
A/D turn in MID/ADV. Full audit + census: `docs/GLASS_COCKPIT.md` §2026-07-20.
## Key Relationships
- Extends: [[pod-hardware]] (RIO input path) · Uses: [[gauges-hud]] dev-gauge modes ·
Feeds: [[multiplayer]] (miniconsole hosting, Steam transport) · Build: [[build-and-run]]