The old Invert joystick Y box (checked by default) is now the wire's
native convention: full up = -80 in AnalogReply with the flag off.
Checking the renamed Invert Y sends the physical direction (up = +80).
Control strip cleanup: test-mode buttons and the firmware selector are
gone (the device still reports 4.2), Keyboard/Gamepad/Invert Y share
one line, the help text drops the bindings sentence, and the wire log
gets the reclaimed height.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
With Invert Y checked the readout claimed "Y 80" while the AnalogReply
carried -80. The flip is factored into VRioDevice.WireY, shared by the
reply builder and the new GetWireAxis accessor; the canvas readout uses
a WireAxisProvider fed from it, and toggling the checkbox repaints so
the sign flips in place. Dot and gauges keep tracking the stick.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
InputRouter.InvertJoystickY flipped the stored axis, so the X/Y dot and
readout moved opposite the physical stick. The toggle now lives on
VRioDevice and negates joystick Y only while building AnalogReply: local
state keeps the physical direction for every source (pad, keys, panel
drags) and only the host sees the flip. Negating a full -8192 deflection
lands one past the 14-bit Max, so the reply clamps it to 8191.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- InputRouter.InvertJoystickY flips the composed joystick Y (keys and
pad alike) before wire scaling; panel drags write the device directly
and stay untouched. New "Invert joystick Y" checkbox in the Input
group, default on.
- StampGitVersion target bakes "YYYY.MM.DD (shortsha)" of HEAD into
InformationalVersion; the title shows it via Application.ProductVersion
so a running build can be matched to its vYYYY.MM.DD release tag.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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>
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>
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>