Commit Graph
8 Commits
Author SHA1 Message Date
CydandClaude Fable 5 007d15e668 Wire carries stick-up as negative; Invert Y opts back to physical
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>
2026-07-07 09:47:25 -05:00
CydandClaude Fable 5 6923c9f252 Panel readout shows the wire values while the dot stays physical
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>
2026-07-06 19:33:28 -05:00
CydandClaude Fable 5 ce5ed1117a Invert Y on the wire, not in the router: the panel keeps tracking the stick
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>
2026-07-06 19:21:57 -05:00
CydandClaude Fable 5 dc9a294101 Writer thread survives write faults instead of dying mid-run
A single failed port write killed the paced writer thread permanently
while the port still reported open, so every later byte (ACKs, the
CheckRequest handshake) queued forever: wire tap showed 2 of 3 bytes of
a stray ButtonPressed at t=54ms, then 1167 unanswered CheckRequests.
The trigger was com0com flow control with the game side not yet open --
the third byte blocked past WriteTimeout, threw, and the catch returned.

A real UART cannot wedge; it shifts bits into the line whether or not
anyone listens. On a write fault, drop the stalled byte plus the stale
backlog, log the stall/recovery transition once, and keep the writer
alive -- TX resumes as soon as the host drains its end.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 13:41:16 -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 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 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