--- id: pod-hardware title: "Pod Hardware — the fixed target (7 monitors, D3D9, RIO)" status: established source_sections: "PROGRESS_LOG.md §3; the PLATFORM PROFILE + GAUGE DEV-COMPOSITE notes" related_topics: [gauges-hud, rendering, project-overview] key_terms: [pod, RIO, MFD, IG-board, SVGA16] --- # Pod Hardware (the fixed target) The port must run on (a) a dev box and (b) the fixed arcade pod. The pod is a hard constraint that bounds the graphics API. Full detail: `docs/PROGRESS_LOG.md §3`. ## Displays - **2 video cards → 7 monitors:** main 3D view **800×600**; radar **640×480**; five monochrome MFDs driven as one **1280×480** horizontally-spanned surface. [T1] - Requires **old NVIDIA drivers** for the MFD horizontal spanning — a hard constraint that bounds the graphics API → **Target Direct3D 9** (lowest common denominator that runs on old-driver pods AND modern cards; one codepath). NOT Vulkan/D3D11+. CUDA is irrelevant (compute, not display). [T1] ## Cockpit I/O (RIO) Joystick X/Y, throttle, pedals, buttons over **serial COM** (`L4RIO`, `L4SERIAL`). Must be remapped to keyboard/gamepad on a dev box; real wiring is a pod bring-up task (Phase 8). The engine is a PUSH model — `LBE4ControlsManager` groups are fed by all devices (RIO on the pod, DirectInput on dev); the `MechControlsMapper` interprets them ([[locomotion]]). [T2] ### The button space + lamps [T0, L4CTRL.h enum] buttonGroup addresses 0x00-0x47: `AuxLowerRight/Left 1-8` (0x00-0x0F), `Secondary1-12` (0x10-0x1B), `AuxUpperCenter/Left/Right 1-8` (0x20-0x37; **0x30-0x37 = the target HOTBOX**, pilot select), icom/door 0x39-0x3C, `Panic` 0x3D (the config-mode lamp), `Throttle1` 0x3F (throttle-head = REVERSE THRUST), joystick cluster 0x40-0x47 (Main trigger 0x40, hat 0x41-0x44, Pinky/ThumbLow/ThumbHigh 0x45-0x47 — the four MAPPABLE fire buttons). "Lamp buttons" are literal: physical illuminated pushbuttons in panels around the screens; the RIO `LampRequest` protocol lights them (`MakeLinkedLamp`), reports burned-out bulbs (`RIODeadLamps` failure page, per-lamp names). A lit button = active. Keypads are NOT buttons: `keyboardGroup[KeyboardPilot/ KeyboardExternal]` carry key VALUES ('0'-'9','A'-'F', L4CTRL.cpp:2526). RIO event convention: press = `buttonGroup[a].Update(a+1, modeMask)` (mask saved), release = `Update(-a-1, savedMask)` (L4CTRL.cpp:2470-2520). **Bank→MFD assignment (Gitea #9, from the streamed "L4" .CTL EventMapping dump [T1]):** each preset-able MFD owns the 8-button bank AROUND it, mode-mask-gated per page — **Mfd1 (lower left) = 0x08-0x0F (AuxLowerLeft), Mfd2 (upper center) = 0x20-0x27 (AuxUpperCenter), Mfd3 (lower right) = 0x00-0x07 (AuxLowerRight)**: Quad page → the outer buttons direct-select the populated Eng pages; Eng page → one button back to Quad, the rest drive the shown subsystem (generator select A-D, gen mode, weapon config/unjam). Always-active: **0x28-0x2F (AuxUpperLeft) → per-subsystem msg 0x4 to roster subs 3-9** and secondary-panel 0x1A-0x1D → subs 10-13 msg 0x4 (identities unverified — likely the condenser-valve / coolant buttons [T4]); 0x10/0x11 = map ZoomIn/Out, 0x15 = CycleDisplayMode, 0x18 = CycleControlMode (#6). Full decode: [[gauges-hud]] §preset pages. ### Desktop input remap — CONTROLS.MAP + XInput (2026-07-18) [T2 live] `game/reconstructed/btinput.cpp` + `content/CONTROLS.MAP` (WASD-classic default, compiled-in twin; `content/CONTROLS_NUMPAD.MAP` = the corrected community numpad profile). Grammar: `key button |axis deflect|rate |keypad pilot|external <0-15>|pckey |action `; `pad