The game loop pumps ONE message per frame (APPMGR.cpp PeekMessage), and
WM_PAINT is synthesized only when the queue is otherwise empty - so the
child panes queued invalidations that never delivered: the map stayed
black and button lamps froze at their first-paint state on the live
screen. (PrintWindow-based captures forced paints and the synthetic
SendMessage click bypassed the queue, which is why every automated
verification looked fine while the live window was frozen.)
MFDSplitView::Repaint and PlasmaScreen::Update now paint synchronously
via RedrawWindow(RDW_INVALIDATE|RDW_UPDATENOW) at fill time, and the
button press/release feedback goes through the same path. Verified with
a true screen capture (CopyFromScreen): map drawing live, timer
counting, the active preset lamp bright on the map right column.
Lamp anchor sanity-check against the game code: mode switch NOV/STD/
VET/EXP = ButtonAuxUpperRight5-8 = 0x33..0x30 = the upper-right MFD
bottom strip left-to-right; presets = Secondary7-12 = 0x18-0x1D = the
map right column - both match the placed buttons.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The assembled shell could exceed the work area (1291px tall at default
scale) - on a 1080p monitor the whole lower row, map included, hung off
the bottom of the screen, which read as the map not rendering, and the
lamp-reactive preset buttons were unreachable down there. (The render
and click paths themselves were verified fine: a synthetic press on a
map preset button lights it through the game lamp command.)
The layout now measures SPI_GETWORKAREA and fits: the pane scale steps
down (to 20% minimum) and the viewscreen takes the leftover height at
the 3D aspect, shrinking below native when needed - Present stretches,
so the scene scales cleanly. Rows and viewscreen center in the shell,
which is sized to the work area. Verified: at 70% panes in a 1392-high
work area the viewscreen reduced to 609x457 with everything on screen.
The plasma glass sits out of the cockpit for the moment
(PlasmaScreen::Hide) per playtest direction.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The main game window becomes the cockpit shell (enlarged, clipping
children); every display folds in as a chrome-less child pane in the
pod interior arrangement:
[ MFD UL ] [ MFD UC ] [ MFD UR ]
[ plasma (reduced) ][ viewscreen (centered) ]
[ MFD LL ] [ Map ] [ MFD LR ]
The 3D scene presents into a black STATIC viewscreen child via
Present's hDestWindowOverride (new gMainPresentWindow global) - no
swap-chain changes, and STATIC's transparent hit-testing keeps mouse
input over the 3D view flowing to the game window. MFDSplitView gains a
parent/child mode; PlasmaScreen::Position reparents the glass into the
shell. Main window class background goes black for the cockpit gaps.
Verified by screenshot: live green gauges (LIFT CUT / BOOST / CHUTE /
trigger-program screens) with their red button strips, the 3D canyon in
the centered viewscreen, plasma score glass at its left, map with lit
amber preset lamps - one window, 976x1132 client at 50% scale.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
[ MFD UL ] [ MFD UC ] [ MFD UR ]
[ plasma (reduced) ][ main screen (centered) ]
[ MFD LL ] [ Map ] [ MFD LR ]
SVGA16 moves the main game window into the middle band (centered under
the MFD columns) and shrinks the plasma glass to fill the space at its
left via a new PlasmaScreen::Position hook (the glass paint stretches to
the client area, so resizing rescales it). Lower row sits below the
main screen band.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The pod drove five monochrome MFDs from the color channels of two video
outputs - SVGA16 packs bit-slices of the shared gauge canvas into R/G/B
of gauge window 3 (upper MFDs) and R/G of window 4 (lower MFDs), with the
map palettized on the secondary and physically mounted portrait. The
desktop reconstruction previously required an external BitBlt-mirror
wrapper.
With L4MFDSPLIT=1, SVGA16 renders each display into its own window
(MFDSplitView, plain GDI) straight from the canvas + port bit-masks:
five green-screen MFD windows and the 90CW-rotated Map, tiled in the pod
grid to the right of the main view (L4MFDSCALE percent, default 50). The
packed D3D windows stay hidden but keep presenting off-screen, leaving
the original path untouched. Handles spanning mode (2-window setups).
Also: the plasma glass now opens directly below the main view (clamped
to the work area; L4PLASMAPOS=x,y overrides) per playtest feedback.
Verified: window grid comes up as main + 5 MFDs + Map + plasma with the
packed windows hidden; screenshots confirm a green MFD score readout and
the portrait tactical map rendering correctly. dist packer and BUILD.md
updated; the launcher wrapper is obsolete for split-mode use.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Splits the control surface the game consumes from the RIO board into
RIOBase (8 virtuals + the five analog scalars); the serial RIO is now one
implementation of it. Adds two new ones:
- PadRIO (L4CONTROLS=PAD): in-process RIO speaking the full surface from
an XInput controller + PC keyboard using vRIO's default profile (left
stick/WASD = stick, triggers/Q,E = pedals, right stick Y/PgUp,PgDn =
rate throttle that holds position, A/Space = trigger, B/R = reverse,
dpad/arrows = hat, Start,Back/F1,F2 = config). Samples in GetNextEvent
so button latency does not depend on the 15 s menu-time analog cadence;
hot-plugs pads; L4PADFLIP=XY inverts stick axes; lamp commands land in
lampState[] for the planned on-screen cockpit panel. The stock
VTVRIOMapper/lamp/button path runs unchanged.
- PlasmaScreen (L4PLASMA=SCREEN): the 128x32 plasma glass as a desktop
window in plasma orange (L4PLASMASCALE, default x4), rendering the same
Video8BitBuffered surface the gauge system always drew; no COM port.
Verified in the sandbox with vRIO off and no serial devices: boots to a
running mission, controller hot-detected, plasma window drawing live game
content (score readout). BUILD.md 4 documents the desktop environ.ini and
bindings; roadmap updated.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>