Cockpit buttons on the split displays, lamp-lit and clickable

Each MFDSplitView window now carries its display's physical button bank,
placed as in the pod (addresses per vRIO CockpitLayout): a 4x2 red
cluster around each MFD glass (anchors 0x2F/0x27/0x37 upper, 0x0F/0x07
lower, addresses descending row-major) and 6 amber buttons down each
side of the map - Secondary 0x10-0x15 left, Screen 0x18-0x1D right; the
remaining column addresses are Tesla relays, per the pod wiring, so they
get no buttons.

Buttons light from the lamp state the game commands: PadRIO grows a
static active-instance hook (SetScreenButton/GetLampState); mouse
press/release feeds PadRIO's desired-state sampling alongside pad and
keyboard, and paint decodes the lamp byte (state1/state2 brightness,
solid/slow/med/fast flash animated by tick). With real serial hardware
(no PadRIO) the buttons draw dark and inert.

Verified: map flank buttons light per the game's preset lamps, aligned
with the labels the glass draws at its edges; MFD clusters render 4+4.
Roadmap: queued the vRIO Dynamic Lighting RGB-keyboard lamp mirror as a
polish-pass item. dist repacked.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Cyd
2026-07-12 14:22:38 -05:00
co-authored by Claude Fable 5
parent 214a8e079c
commit 1058de326d
8 changed files with 432 additions and 62 deletions
+28 -8
View File
@@ -3859,30 +3859,50 @@ SVGA16::SVGA16(
int frame_h = GetSystemMetrics(SM_CYCAPTION) + 2 * GetSystemMetrics(SM_CYFIXEDFRAME);
int frame_w = 2 * GetSystemMetrics(SM_CXFIXEDFRAME);
int grid_x = init_width + frame_w;
int row2_y = cell_h + frame_h;
// the MFD button strips grow each window (mirror of
// MFDSplitView::LayoutButtons so the grid rows still tile)
int strip_h = cell_h / 8;
if (strip_h < 18) strip_h = 18;
if (strip_h > 40) strip_h = 40;
int mfd_extra_h = 2 * (strip_h + 8);
int row2_y = cell_h + mfd_extra_h + frame_h;
//---------------------------------------------------------------
// Button banks per display (addresses per vRIO CockpitLayout,
// bank-to-display placement per the pod cockpit):
// upper left MFD 0x2F.. / upper center 0x27.. / upper right
// 0x37.. / lower left 0x0F.. / lower right 0x07.. and the map
// flanked by Secondary 0x10-0x15 / Screen 0x18-0x1D.
//---------------------------------------------------------------
splitView[SplitMFDUpperLeft] = new MFDSplitView(
"MFD upper left", init_width, init_height,
cell_w, cell_h, grid_x, 0);
cell_w, cell_h, grid_x, 0,
MFDSplitView::MFDStrips, 0x2F);
splitView[SplitMFDUpperCenter] = new MFDSplitView(
"MFD upper center", init_width, init_height,
cell_w, cell_h, grid_x + (cell_w + frame_w), 0);
cell_w, cell_h, grid_x + (cell_w + frame_w), 0,
MFDSplitView::MFDStrips, 0x27);
splitView[SplitMFDUpperRight] = new MFDSplitView(
"MFD upper right", init_width, init_height,
cell_w, cell_h, grid_x + 2 * (cell_w + frame_w), 0);
cell_w, cell_h, grid_x + 2 * (cell_w + frame_w), 0,
MFDSplitView::MFDStrips, 0x37);
splitView[SplitMFDLowerLeft] = new MFDSplitView(
"MFD lower left", init_width, init_height,
cell_w, cell_h, grid_x, row2_y);
cell_w, cell_h, grid_x, row2_y,
MFDSplitView::MFDStrips, 0x0F);
splitView[SplitMFDLowerRight] = new MFDSplitView(
"MFD lower right", init_width, init_height,
cell_w, cell_h, grid_x + 2 * (cell_w + frame_w), row2_y);
cell_w, cell_h, grid_x + 2 * (cell_w + frame_w), row2_y,
MFDSplitView::MFDStrips, 0x07);
// map is portrait: source rotated 90 degrees clockwise
splitView[SplitMap] = new MFDSplitView(
"Map", init_height, init_width,
cell_h, cell_w,
grid_x + (cell_w + frame_w) + (cell_w - cell_h) / 2, row2_y);
grid_x + (cell_w + frame_w) + (cell_w - cell_h) / 2, row2_y,
MFDSplitView::SideColumns, 0x10, 0x18);
DEBUG_STREAM << "SVGA16: split views active - 5 MFD windows + rotated map (scale "
DEBUG_STREAM << "SVGA16: split views active - 5 MFD windows + rotated map, cockpit buttons on (scale "
<< scale_percent << "%)\n" << std::flush;
}
//STUBBED: VIDEO RB 1/15/07