Files
VRIO/README.md
T
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

4.3 KiB
Raw Blame History

vRIO — virtual RIO cockpit device

A software replica of the cockpit RIO (Remote Input/Output) board: it opens a COM port and speaks the device side of the RIO serial protocol, so any host that expects the real hardware — most importantly RIOJoy — can talk to it without a cockpit attached.

The window is an interactive version of the cockpit control panel that RIOJoy's profile editor draws (the same functional layout from the original Win32 RIO design: five MFD clusters, four board columns, two keypads, encoder gauges). But where the editor edits bindings, vRIO's cells are the physical controls:

  • Left-click a cell — momentary button press (ButtonPressed/Released or KeyPressed/Released on the wire). Right-click — latch it down.
  • Drag the X/Y box and the Z / L / R gauges — the five analog axes, returned by the next AnalogReply (14-bit signed, 7-bit-pair packed). Gauges span each axis' realistic hardware travel, not the full 14-bit range: Z/L/R rest at raw 0 at the gauge bottom and travel to 800 (throttle — forward travel runs negative, matching RIOJoy's ratchet) or +500 (spring-loaded pedals), and the stick covers ±80 around center — the windows RIOJoy's calibrator expects.
  • Cells shade to the lamp state the host commands (LampRequest: off / dim / bright, with slow/med/fast flash), so RIOJoy's press-feedback lights the on-screen panel just like the real buttons.
  • Keyboard and Xbox (XInput) controller input drive the same controls through a bindings file (%APPDATA%\vRIO\bindings.txt, created with commented defaults on first run — Edit bindings… opens it, Reload bindings applies edits live). Keys and pad buttons press any RIO address; pad sticks/triggers and keys drive the axes in each axis' realistic travel window, with deflect (spring-back), rate (throttle-style, position holds), deadzone, and invert options. Defaults: arrows = stick, W/S = throttle, Q/E = pedals, numpad = internal keypad, IJKL/Space = hat + main, left stick / triggers / right stick = stick / pedals / throttle on the pad.

Wire behavior

Protocol per riojoy/docs/PROTOCOL.md (9600 8N1, [cmd][payload…][7-bit checksum], ACK 0xFC / NAK 0xFD / RESTART 0xFE / IDLE 0xFF), with device behavior grounded in the real v4.2 firmware dump (riojoy/rio-firmware/RIOv4_2-ANALYSIS.md):

  • ACKs every well-formed packet; NAKs bad-checksum packets.
  • CheckRequest → one BoardOk CheckReply per board (the 11 boards from the legacy firmware's table). VersionRequest → configurable version, default 4.2.
  • ResetRequest re-zeroes the targeted axis (or all).
  • A NAK re-sends the last event up to 4 times, then gives up with a RESTART byte — the real board's retry budget.
  • Optional v4.2 reply-wedge emulation: after retry exhaustion (or the "Wedge analog now" button), analog requests are silently dropped — still ACK'd, RX path alive — until a host ResetRequest, reproducing the latch-leak fault the firmware analysis documents. Use it to exercise RIOJoy's 5-second no-analog recovery watchdog.

Using it with RIOJoy on one PC

The two apps need a crossed serial link. Install a com0com virtual null-modem pair (e.g. COM5 ⇄ COM6), then:

  1. Run VRio.App, pick COM5, Open.
  2. Point RIOJoy at COM6.

RIOJoy's DTR open-pulse shows up in the wire log (DSR handshake), its ~55 ms analog polling drives the "analog polls served" counter, and every click on the vRIO panel arrives at RIOJoy as real cockpit input. Two physical PCs with a null-modem cable work the same way.

Repository layout

Path Contents
src/VRio.Core Protocol framing/builder/parser, the VRioDevice state machine, serial pump, panel layout data (class library)
src/VRio.App WinForms panel UI
tests/VRio.Core.Tests xUnit tests for the protocol + device engine

Building

Same toolchain as RIOJoy: .NET SDK (8.0+) with the .NET Framework 4.8 targeting pack; apps target net48 so deployed builds run in-box on Windows 10/11.

dotnet build VRio.sln -c Release
dotnet test VRio.sln

Interop is additionally verified against RIOJoy's real RioSerialLink (version/check/analog/lamp/button/keypad/reset round-trips over an in-memory transport) — see the RIOJoy repo for the host side.