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>
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>