Files
VRIO/.claude/skills/verify/SKILL.md
T
CydandClaude Fable 5 a1b7dae3da vPLASMA: companion app emulating the cockpit plasma display
The cockpit's second serial device joins vRIO: the 128x32 dot-matrix
plasma on COM2 (9600 8N1) that the game draws mission text and status
graphics on. VPlasma.App opens the device end of a COM port, decodes
the display's command stream, and renders the matrix in plasma orange.

The command set is recovered from two Tesla 4.10 artifacts: the game's
driver (L4PLASMA.CPP — ESC P packed-bitmap row writes, ESC G 0 cursor
hide at boot) and the factory test tool PLASMA.EXE, whose data segment
pairs each command literal with its printf description (BS/HT/LF/VT/CR
motion, ESC @ clear, ESC L home, ESC G cursor, ESC K fonts, ESC H
attributes: intensity/underline/reverse/flash). Text renders through
the classic public-domain 5x7 set standing in for the lost ROM glyphs;
fonts 0-3 give 21x4 cells, fonts 4-7 the doubled 10x2. A Self test
cycles banner/charset/graphics pages through the same parser the wire
feeds, and the wire log shows every decoded command.

Verified end-to-end over the second com0com pair (host writing COM2,
vPLASMA listening on COM12). The verify skill gains the cross-process
combo-box lesson: string-carrying CB_* messages hang across processes,
so select ports by locally computed index via CB_SETCURSEL.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-07 14:22:00 -05:00

67 lines
3.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: verify
description: Build, launch, and drive the vRIO WinForms app to verify changes at the GUI surface — screenshots via PrintWindow, input via PostMessage, no focus stealing.
---
# Verifying vRIO changes
Build + tests (tests are CI's job; run the app for verification):
```powershell
dotnet build vrio.sln -v q -nologo # Debug
# exe: src\VRio.App\bin\Debug\net48\VRio.App.exe
# exe: src\VPlasma.App\bin\Debug\net48\VPlasma.App.exe (companion display)
```
Everything below applies to vPLASMA too. Its serial path can be tested
end-to-end on this machine: vPLASMA opens **COM12**, the script plays the
game writing **COM2** (second com0com pair; vRIO/RIOJoy use COM1⇄COM11).
Killing a writer mid-stream can leave stale bytes queued in the com0com
buffer — the next session's byte counter will run high; re-run clean
before trusting counts.
## Driving the GUI without touching the user's desktop
This is the user's live desktop — **never** use SetForegroundWindow +
SendKeys/mouse_event: focus-stealing prevention leaves the app behind
VS Code and your clicks land in the user's windows. Instead:
- **Screenshots**: `PrintWindow(hwnd, dc, 2)` (PW_RENDERFULLCONTENT) —
captures the window even when occluded. CopyFromScreen captures
whatever is on top; don't use it.
- **Canvas input** (stick drags, cell clicks): PostMessage
`WM_LBUTTONDOWN/WM_MOUSEMOVE/WM_LBUTTONUP` straight to the canvas
child HWND. Find it by descending `RealChildWindowFromPoint` from the
form. Canvas geometry is compile-time constant (PanelCanvas.cs):
CellW=66, BoxXY = x 416..496, y 6..74 (X/Y stick box).
The **first** posted drag after launch can half-land (only the
button-down registers); do a throwaway drag first, then the measured
one, screenshot **while held** (spring-back recenters on up).
- **Checkboxes/buttons**: WinForms controls expose no UIA TogglePattern
(they surface as bare Panes) and don't answer BM_GETCHECK — but
`SendMessage(hwnd, BM_CLICK, 0, 0)` works. Get the HWND from the UIA
element's NativeWindowHandle (find by Name).
- **Combo boxes** (COM port pickers): string-carrying messages
(`CB_FINDSTRINGEXACT`, `CB_GETLBTEXT`) do **not** marshal across
processes — the SendMessage hangs. Compute the item index locally
(both apps fill from `SerialPort.GetPortNames()` sorted
OrdinalIgnoreCase) and send index-only `CB_SETCURSEL`; the apps read
`SelectedItem` lazily so no CBN_SELCHANGE notification is needed.
Find the combo child HWND via EnumChildWindows + GetClassName
containing `COMBOBOX` (UIA ClassName "ComboBox" doesn't match).
- Pattern that works: Add-Type user32 P/Invokes, Start-Process the exe,
drive via messages, PrintWindow screenshot to the scratchpad, kill
the process in `finally`.
## Environment gotchas
- Bindings load from `%APPDATA%\vRIO\bindings.txt` (the user's file),
not the built-in defaults — arrow keys are bound to Hat *buttons*,
not the joystick axis. Drive axes via the X/Y box.
- A real XInput gamepad is connected on this machine ("Controller #1
connected"); the router only writes an axis when its composed value
changes, so a centered pad won't fight a canvas drag.
- The wire readout (top center, green) shows `GetWireAxis` values —
joystick Y is natively negated on the wire (stick up = 80) unless
"Invert Y" is checked.