Author the custom virtual HID gamepad that replaces vJoy, and pin its wire format on both sides. Builds clean to RioGamepad.sys against the EWDK (KMDF 1.15 + VHF, x64, warnings-as-errors). driver/RioGamepad/: - ReportDescriptor.h: 6x16-bit axes (X,Y,Z,Rx,Ry,Rz), one 4-direction hat with null state, and 96 buttons — the legacy vJoy layout. 25-byte input report. - Device.c/Driver.c: KMDF root-enumerated device that creates the VHF virtual HID device (VhfCreate in DeviceAdd, VhfStart in D0Entry, VhfDelete on cleanup) and exposes a device interface + IOCTL_RIO_SUBMIT_REPORT that forwards the caller's report bytes to VhfReadReportSubmit. Thin relay: no report logic in the kernel. - Public.h: device-interface GUID, IOCTL, and the report byte layout shared with the C# client. RioGamepad.inf + build.cmd (EWDK build, catalog/sign disabled). src/RioJoy.Core/Hid/RioHidReport.cs: packs AxisOutputs + hat + 96 buttons into the exact 25-byte report (LE axes, hat nibble with 0x0F=centered, button bitmap). 13 new xUnit tests (136 total). Remaining (deploy-side): test-sign + pnputil install + verify in joy.cpl, and wire the real DeviceIoControl feeder sink (replacing NullJoystickSink). The EWDK's in-build catalog task (DrvCat) can't load Microsoft.Kits.Logger on this image, so the .cat is produced with inf2cat/signtool at install time instead. Co-Authored-By: Claude Opus 4.8 <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)
|
|
};
|