Commit Graph
12 Commits
Author SHA1 Message Date
CydandClaude Fable 5 0674cf5ba4 Drop unused Microsoft.Bcl.HashCode, fix README typo
HashCode.Combine is called nowhere; the package (and its DLL in the dist
zip) was dead weight since the Core projects were created.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-11 20:40:14 -05:00
CydandClaude Fable 5 90bf6723dc vRIO builds in the vPLASMA display
The plasma glass now lives in vRIO's encoder strip: PlasmaCanvas grew a
dot-pitch parameter (default keeps the standalone glass pixel-identical)
and is compile-linked into VRio.App at pitch 3, parked at the strip's
left slot. The axis gauges move to the grid's right edge, the strip is
as tall as the glass, and the status text sits between them with the
axis readout split onto two lines. The button grid also compacts: rows
shift up past the layout's empty row 0 and the spare bottom row is
trimmed (the shared CockpitLayout is untouched, so coordinates still
match RIOJoy's map).

Control strip: the COM row labels are now the device names -- vRIO and
vPLASMA -- coloured by port status (green open, gray closed), replacing
the port-status line. The plasma row auto-opens COM12 at startup like
the RIO row does COM11; one Rescan refreshes both pickers. Plasma log
lines share the wire log under a vPLASMA: prefix, and the standalone
gestures carry over (double-click self-test, right-click reset).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-10 15:30:51 -05:00
CydandClaude Fable 5 19a1abbff2 vPLASMA slims to a bare glass hardwired to COM12
The window is now just the display: 640x160 dot field (5 px pitch,
4 px bezel) plus the title bar, which carries the port status. COM12 —
the device end of the plasma's null-modem pair — is hardwired and
opened at startup, with a retry timer that keeps trying while the port
is missing or busy and reopens it if it dies. The control strip, port
picker, counters, and wire log are gone; the glass keeps two gestures:
double-click cycles the self-test pages, right-click resets the
display to its power-on state.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 15:06:36 -05:00
CydandClaude Fable 5 a1b7dae3da vPLASMA: companion app emulating the cockpit plasma display
The cockpit's second serial device joins vRIO: the 128x32 dot-matrix
plasma on COM2 (9600 8N1) that the game draws mission text and status
graphics on. VPlasma.App opens the device end of a COM port, decodes
the display's command stream, and renders the matrix in plasma orange.

The command set is recovered from two Tesla 4.10 artifacts: the game's
driver (L4PLASMA.CPP — ESC P packed-bitmap row writes, ESC G 0 cursor
hide at boot) and the factory test tool PLASMA.EXE, whose data segment
pairs each command literal with its printf description (BS/HT/LF/VT/CR
motion, ESC @ clear, ESC L home, ESC G cursor, ESC K fonts, ESC H
attributes: intensity/underline/reverse/flash). Text renders through
the classic public-domain 5x7 set standing in for the lost ROM glyphs;
fonts 0-3 give 21x4 cells, fonts 4-7 the doubled 10x2. A Self test
cycles banner/charset/graphics pages through the same parser the wire
feeds, and the wire log shows every decoded command.

Verified end-to-end over the second com0com pair (host writing COM2,
vPLASMA listening on COM12). The verify skill gains the cross-process
combo-box lesson: string-carrying CB_* messages hang across processes,
so select ports by locally computed index via CB_SETCURSEL.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 14:22:00 -05:00
CydandClaude Opus 4.8 391c53f294 Capture a chosen keyboard's keys without window focus (Raw Input)
The WinForms focus path only sees keys while vRIO is foreground and can't
tell one keyboard from another, so vRIO went deaf the moment the sim took
focus. The new "Capture keyboard" picker in the Input panel taps one
physical keyboard through the Win32 Raw Input API (RIDEV_INPUTSINK) and
routes its keys to the panel even in the background — the input-side twin
of the lamp mirror writing that keyboard's LEDs under the same condition.

Raw Input observes without intercepting, so keys still reach the focused
app; the picker defaults to "All keyboards (focus only)", preserving the
prior focus-bound behavior, and only registers Raw Input while a specific
device is selected. While capturing, the focus path stands down but still
swallows bound keys so they can't click panel buttons.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-06 21:31:49 -05:00
CydandClaude Fable 5 f77cd55b11 pkg: package identity so Dynamic Lighting grants background control
The Settings "Background light control" list only offers apps that have
BOTH package identity and the com.microsoft.windows.lighting
windows.appExtension in their manifest (declaration verified against
Lenovo's LegionLightingController manifest) — without a grant, Windows
hands the LEDs to vRIO only while it is the foreground window, i.e.
never during gameplay.

pkg/AppxManifest.xml is a sparse package (external location) that
grants the existing VRio.App.exe identity as-is: win32App runtime
behavior, runFullTrust + unvirtualizedResources, and the lighting
app-extension. Register-vRIO.ps1 registers/unregisters it against any
exe folder (repo build or an extracted dist zip); unsigned registration
needs Developer Mode. Identity is granted through shell activation
only — launch from the Start menu entry or an AUMID taskbar pin, not by
double-clicking the exe (the script prints this warning).

Verified end-to-end on this machine: process reports the package full
name, vRIO appears in the background-control list, and the wire log
shows the withheld → available transition once granted.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 15:08:38 -05:00
CydandClaude Fable 5 1eded793af CheckRequest: send the real board's test-mode handshake
The host waits up to 5s after CheckRequest for TestModeChange ENTER
(8C 01 0D) before anything else, and sends no requests until the
matching EXIT (8C 00 0C) arrives; vRIO jumped straight to the
CheckReply dump, so hosts logged "RIO never came back from check
request" and skipped the version exchange. Bracket the per-board
BoardOk replies with enter/exit, byte-for-byte what the real v4.2
board sends on the wire tap.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:13:06 -05:00
CydandClaude Fable 5 44dc8e48e7 Default bindings: pad-mandatory axes, full keyboard button field
Rework the shipped default profile around a required Xbox controller,
refined from live-game testing:

- All five axes are pad-only now (left stick / triggers / right stick);
  the key-axis bindings (arrows/WASD-style deflect and rate) are gone
  from the defaults, though the grammar remains supported.
- Keyboard becomes the button field, geometry mirroring the panel:
  number row + QWERTY row = upper MFD bank, home + bottom rows =
  lower MFD bank as two 4-key blocks with an unbound gap key (G / B)
  standing in for the panel keypad gap, F1-F6 / F7-F12 = the
  Secondary / Screen columns top-to-bottom (0x16/0x17, 0x1E/0x1F
  deliberately unmapped), numpad = the full internal keypad with the
  hex keys on the operators (/ * - + . Enter = A-F).
- Hat rides the arrow keys, Main stays on Space; Pinky / Middle /
  Upper / Panic are pad-only so no panic key sits inside the MFD field.
- Pad B and LeftShoulder swap to Middle / Panic.
- Rest of the throttle column and the external keypad stay unmapped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 12:17:40 -05:00
CydandClaude Fable 5 d26000f906 Pace TX bytes at the 9600-baud wire rate
vRIO wrote whole reply packets in one SerialPort.Write; through a
com0com null-modem (no UART) the host saw the bytes ~30-40 us apart,
a burst no real board can produce and the prime suspect in a rocky
game init. Replies now leave one byte per 10-bit frame (~1.04 ms), so
the 45-byte CheckRequest response takes ~47 ms like real hardware
(measured 0.94-1.10 ms gaps over a com0com pair).

- Transmit frames queue to a writer thread; each byte is scheduled
  against a monotonic slot deadline slot = max(prev + period, now),
  so the stream averages true 9600 baud without bursting after idle.
- After a write the schedule is floored at the actual emission time:
  a late wake-up can never be followed by a catch-up burst - two
  frames closer than the frame time is structurally impossible.
- 1 ms system timer resolution while the port is open (timeBeginPeriod)
  so the pacer sleeps most of each gap and only spins the last ~1.8 ms.
- Side benefit: UI clicks no longer block on SerialPort.Write (a
  stalled port could previously hang the UI for the 2 s write timeout).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 11:31:39 -05:00
CydandClaude Fable 5 e590b89c47 Keyboard and Xbox-gamepad input drive the panel
New input pipeline: sources feed an InputRouter (VRio.Core.Input) that
calls the same VRioDevice press/release/axis entry points the mouse
canvas uses, so routed input is indistinguishable on the wire.

- Bindings live in %APPDATA%\vRIO\bindings.txt (plain text, commented
  defaults written on first run; Reload/Edit buttons in the new Input
  group). Keys and pad buttons press any RIO address, momentary or
  toggle; axes bind in normalized units of each axis realistic travel
  window with deflect (spring-back), rate (position holds), deadzone,
  and invert options - RioAxisRange supplies the wire signs.
- Router suppresses key auto-repeat, edge-detects pad buttons, and
  hold-counts per address so overlapping sources press once and
  release last; axes only write when the composed value changes, so
  mouse drags keep working while sources idle.
- Xbox pad via a zero-dependency XInput P/Invoke poller (xinput1_4,
  fallback xinput9_1_0), throttled rescan while disconnected.
- MainForm intercepts bound keys in ProcessCmdKey so arrows/space
  reach the panel instead of moving focus; keys release on focus
  loss; center-axes and host ResetRequest reset the rate integrators.
- Canvas highlights router-held addresses like clicks.
- Defaults: arrows=stick, W/S=throttle, Q/E=pedals, numpad=internal
  keypad, IJKL/Space=hat+main; pad left stick/triggers/right stick =
  stick/pedals/throttle-rate, ABXY/dpad/shoulders = named buttons.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 11:30:55 -05:00
CydandClaude Fable 5 1f0781f06a Realistic axis travel, wire-log fixes, compact layout
- Axes now span the hardware windows from RIOJoy's calibrator instead of
  the full 14-bit wire range: throttle rests at 0 and travels to -800
  (forward runs negative, matching the ratchet math), spring-loaded
  pedals rest at 0 and press to +500, stick covers +/-80 around center
  (new RioAxisRange in VRio.Core documents the provenance).
- Stick X sign flipped: RIOJoy maps negative samples to the high half of
  its output axis, so dragging right now lowers raw X.
- Removed the Rz mix bar - the real RIO has no such indicator.
- Wire log: newest entries on top with the bound trimming the oldest
  lines, and fixed the anchoring bug that let the box grow past the
  window edge (the panel got its height only after children snapshotted
  their anchors), which also hid the Clear log button.
- Tighter layout: axis readout sits under the status lines, encoder
  strip shrunk to fit the gauges, and the window sizes itself to the
  canvas + control strip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 10:33:01 -05:00
CydandClaude Fable 5 7995c0b1c1 vRIO: virtual RIO cockpit device emulator
Speaks the device side of the RIO serial protocol (per riojoy's
PROTOCOL.md) on a COM port, behind an interactive replica of the
profile editor's cockpit panel: click cells to press buttons/keys,
drag the encoder gauges to move the five analog axes, and watch
host-commanded lamp states (incl. flash modes) light the cells.

Device behavior grounded in the real v4.2 firmware dump: version 4.2,
4-retry NAK budget ending in RESTART, and an optional emulation of the
analog reply-wedge latch leak for exercising host recovery watchdogs.

Verified: 33 unit tests, plus an interop harness driving RIOJoy's
actual RioSerialLink against VRioDevice over an in-memory transport
(version/check/analog/lamp/button/keypad/reset all round-trip).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 07:39:38 -05:00