# 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](../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. - **TX is paced at the wire rate** — one byte per 10-bit frame (~1.04 ms at 9600 8N1), never closer. A virtual null-modem has no UART, so unpaced writes would land at the host in microsecond bursts no real board could produce; vRIO's writer thread schedules each byte against a monotonic slot deadline instead, so e.g. the 45-byte CheckRequest response takes the same ~47 ms it takes real hardware. - `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](https://com0com.sourceforge.net/) 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. ```sh 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.