The XP flavor of our own virtual joystick (no third-party driver), built with WDK 7.1.0 to x86/subsystem-5.01. Exposes the identical Public.h contract as the modern KMDF+VHF driver — same GUID, IOCTL_RIO_SUBMIT_REPORT, 25-byte report, VID/PID — so HidFeederJoystickSink drives both. Design (driver/RioGamepadXP/rioxp.c): - WDM HID minidriver via HidRegisterMinidriver presenting the 6-axis/hat/ 96-button joystick. POLLED mode (DevicesArePolled=TRUE): hidclass paces IOCTL_HID_READ_REPORT and we complete each synchronously from a cached report — no pending-IRP or cancel-routine machinery (the usual crash surface in a virtual HID driver). - Named sideband control device (\Device\RioGamepadXP + \DosDevices symlink) takes IOCTL_RIO_SUBMIT_REPORT and updates the cache under a spinlock. - hidclass overwrites our CREATE/CLOSE/DEVICE_CONTROL during registration; we save its pointers and reinstall wrappers that route the control device's IRPs to us and forward the HID FDO's to hidclass. Packaging/install: - Root-enumerated, so install uses devcon (built from the same WDK) — InstallHinfSection can't create the devnode. install-core.bat runs "devcon install RioGamepadXP.inf root\RioGamepadXP"; unsigned is fine (XP x86 enforces no kernel signing). Bundled into vendor\xp\. - net40 feeder opens the driver by name (\.\RioGamepadXP); XP can't put a device interface on a bare control device (no PDO) — the one nuance. Static build only: compiles clean but runtime bring-up (joy.cpl enumeration, report flow) needs a real XP target — that's 8E. 275 tests still green. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
57 lines
2.2 KiB
C
57 lines
2.2 KiB
C
/*++
|
|
RioGamepad — HID report descriptor: a joystick with 6 16-bit axes (X,Y,Z,Rx,
|
|
Ry,Rz), one 4-direction hat with null state, and 96 buttons. This mirrors the
|
|
fidelity the legacy app drove through vJoy. The resulting input report is
|
|
RIO_REPORT_SIZE (25) bytes; see Public.h for the byte layout.
|
|
--*/
|
|
|
|
#pragma once
|
|
|
|
static const UCHAR g_RioReportDescriptor[] =
|
|
{
|
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
|
0x09, 0x04, // Usage (Joystick)
|
|
0xA1, 0x01, // Collection (Application)
|
|
|
|
0x09, 0x01, // Usage (Pointer)
|
|
0xA1, 0x00, // Collection (Physical)
|
|
0x05, 0x01, // Usage Page (Generic Desktop)
|
|
0x09, 0x30, // Usage (X)
|
|
0x09, 0x31, // Usage (Y)
|
|
0x09, 0x32, // Usage (Z)
|
|
0x09, 0x33, // Usage (Rx)
|
|
0x09, 0x34, // Usage (Ry)
|
|
0x09, 0x35, // Usage (Rz)
|
|
0x15, 0x00, // Logical Minimum (0)
|
|
0x26, 0xFF, 0x7F, // Logical Maximum (32767)
|
|
0x75, 0x10, // Report Size (16)
|
|
0x95, 0x06, // Report Count (6)
|
|
0x81, 0x02, // Input (Data,Var,Abs)
|
|
0xC0, // End Collection (Physical)
|
|
|
|
0x09, 0x39, // Usage (Hat switch)
|
|
0x15, 0x00, // Logical Minimum (0)
|
|
0x25, 0x03, // Logical Maximum (3)
|
|
0x35, 0x00, // Physical Minimum (0)
|
|
0x46, 0x0E, 0x01, // Physical Maximum (270)
|
|
0x65, 0x14, // Unit (Degrees)
|
|
0x75, 0x04, // Report Size (4)
|
|
0x95, 0x01, // Report Count (1)
|
|
0x81, 0x42, // Input (Data,Var,Abs,Null)
|
|
0x65, 0x00, // Unit (None)
|
|
0x75, 0x04, // Report Size (4)
|
|
0x95, 0x01, // Report Count (1)
|
|
0x81, 0x03, // Input (Const,Var,Abs) ; 4-bit padding
|
|
|
|
0x05, 0x09, // Usage Page (Button)
|
|
0x19, 0x01, // Usage Minimum (Button 1)
|
|
0x29, 0x60, // Usage Maximum (Button 96)
|
|
0x15, 0x00, // Logical Minimum (0)
|
|
0x25, 0x01, // Logical Maximum (1)
|
|
0x75, 0x01, // Report Size (1)
|
|
0x95, 0x60, // Report Count (96)
|
|
0x81, 0x02, // Input (Data,Var,Abs)
|
|
|
|
0xC0 // End Collection (Application)
|
|
};
|