Verify HID feeder end-to-end; add smoke-test tool; update docs
The RioGamepad driver now installs and enumerates, so the user-mode feeder path is verifiable. Add tools/RioJoySmokeTest, a standalone on-cabinet utility that drives the real HidFeederJoystickSink (open the device, submit reports via IOCTL_RIO_SUBMIT_REPORT) and reads the gamepad back through winmm joyGetPosEx, asserting axes (min/mid/max), buttons, and the POV hat all surface to the OS. Verified: all checks pass against the installed driver. Update docs to match reality (PLAN.md predated the HidFeederJoystickSink commit): Phase 1 is now test-signed/installed/verified with the VHF LowerFilters requirement noted; the stale "NullJoystickSink placeholder" remainders in Phases 3 and 5 are corrected to reflect the wired, verified feeder. driver/README.md notes the end-to-end verification. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+24
-13
@@ -106,7 +106,7 @@ tray menu is always available.
|
||||
(tray app); `driver/` placeholder for the WDK project.
|
||||
- This plan + [PROTOCOL.md](PROTOCOL.md).
|
||||
|
||||
### Phase 1 — Virtual HID driver — compiling ✅ (sign/install pending)
|
||||
### Phase 1 — Virtual HID driver — test-signed, installed, verified ✅
|
||||
Implemented in [`driver/RioGamepad/`](../driver/RioGamepad/); builds to
|
||||
`RioGamepad.sys` against the EWDK (KMDF 1.15 + VHF, x64, warnings-as-errors).
|
||||
- KMDF + VHF virtual HID gamepad: report descriptor = 6×16-bit axes, 1 hat,
|
||||
@@ -116,10 +116,18 @@ Implemented in [`driver/RioGamepad/`](../driver/RioGamepad/); builds to
|
||||
[`Public.h`](../driver/RioGamepad/Public.h).
|
||||
- C# side of the contract: `RioJoy.Core.Hid.RioHidReport` packs axes/hat/buttons
|
||||
into that exact report (unit-tested). Replaces the throwaway test harness idea.
|
||||
- ⏳ **Remaining (Phase 6 / on-cabinet):** test-sign + `pnputil` install + verify
|
||||
in `joy.cpl`; wire the real `DeviceIoControl` feeder sink (replacing
|
||||
`NullJoystickSink`). The EWDK's in-build catalog/sign tasks are bypassed; the
|
||||
`.cat` is made with `inf2cat`/`signtool` at install time.
|
||||
- Test-signed + `pnputil`-installed on the cabinet; INF declares `vhf` as a
|
||||
**lower filter** (`LowerFilters` AddReg) — without it `VhfCreate` fails and the
|
||||
device shows Code 31. The EWDK's in-build catalog/sign tasks are bypassed; the
|
||||
`.cat` is made with `inf2cat`/`signtool` at install time (`driver/*.ps1`,
|
||||
[`driver/README.md`](../driver/README.md)).
|
||||
- **End-to-end verified:** the real `HidFeederJoystickSink` opens the device and
|
||||
submits reports; axes (min/mid/max), buttons, and the POV hat all read back
|
||||
correctly through `winmm joyGetPosEx` / `joy.cpl`. The controller's `joy.cpl`
|
||||
name is set via the DirectInput `OEMName` registry value at install
|
||||
(VHF can't supply a HID product string).
|
||||
- ⏳ **Remaining:** none for the driver itself; redistribution off owned cabinets
|
||||
would need attestation signing (Phase 6).
|
||||
|
||||
### Phase 2 — Serial + RIO protocol core (`RioJoy.Core`) — code-complete ✅
|
||||
Implemented in `src/RioJoy.Core/Protocol` + `Serial`, covered by
|
||||
@@ -151,11 +159,12 @@ Implemented in `src/RioJoy.Core/Mapping` + `Output`, covered by the
|
||||
- Output is split behind sink interfaces (`IInputSink`, `IJoystickSink`,
|
||||
`ILampSink`, `IRioCommandSink`) so routing is pure and unit-tested; `SendInputSink`
|
||||
is the real `SendInput` keyboard/mouse adapter.
|
||||
- ⏳ **Remaining:** the joystick sink's real adapter is the **HID feeder →
|
||||
RioGamepad driver via `DeviceIoControl`**, which is blocked on the Phase 1
|
||||
driver. Routing already targets `IJoystickSink`; wire the IOCTL adapter once the
|
||||
driver exists. The legacy default map / `RIO.ini` becomes an importable profile
|
||||
(Phase 5/7).
|
||||
- The joystick sink's real adapter — the **HID feeder → RioGamepad driver via
|
||||
`DeviceIoControl`** (`Output/HidFeederJoystickSink`) — is implemented, wired in
|
||||
(`RioCoordinator` selects it when the driver is present, else `NullJoystickSink`),
|
||||
and verified end-to-end against the installed driver (Phase 1).
|
||||
- ⏳ **Remaining:** the legacy default map / `RIO.ini` becomes an importable
|
||||
profile (Phase 5/7).
|
||||
|
||||
### Phase 4 — Axis calibration + plasma display — code-complete ✅
|
||||
Implemented in `src/RioJoy.Core/Calibration` + `Plasma` (105 xUnit tests total):
|
||||
@@ -189,9 +198,11 @@ Core logic in `src/RioJoy.Core/Profiles` + `RioRuntime`; UI/OS in `src/RioJoy.Tr
|
||||
+ "start with Windows"; `RioCoordinator` owns the serial acquire/release tied to
|
||||
the watcher (native-game COM-port yield); OS adapters
|
||||
(`ForegroundProcessProvider`, `AutoStartManager`).
|
||||
- ⏳ **Remaining:** the joystick output is a `NullJoystickSink` placeholder until
|
||||
the Phase 1 HID feeder exists; full on-cabinet verification of the auto-switch +
|
||||
acquire/release lifecycle.
|
||||
- Joystick output now uses the real `HidFeederJoystickSink` when the driver is
|
||||
present (verified end-to-end); `NullJoystickSink` remains only as the
|
||||
no-driver fallback.
|
||||
- ⏳ **Remaining:** full on-cabinet verification of the auto-switch +
|
||||
acquire/release lifecycle against real RIO hardware.
|
||||
|
||||
### Phase 6 — Packaging / signing / deploy
|
||||
- Driver install via `pnputil`; app installer; test-signing script.
|
||||
|
||||
Reference in New Issue
Block a user