fix(windows): add VHF-backed gamepad emulation#36
Merged
Conversation
Major refactor of Windows driver packaging and installation: - Switch WiX packaging from source files (.wxs) to patch files (.xml) with CMake-based extension management - Remove devcon dependency; use SetupAPI and pnputil for device creation and removal - Add UMDF library version configuration (defaults to 2.15) with validation during build - Implement lazy VHF target initialization in driver; gamepad creation opens VHF on demand - Add detailed trace logging to driver and install scripts for debugging - Improve device detection to handle both PnP enumeration and registry lookups - Set VhfMode=1 on root devices before driver start - Change driver device class from HIDClass to System; include WUDFRD.inf for proper service setup - Link MSVC runtime statically to avoid VC runtime dependencies in UMDF host - Add -LogPath parameter to install script for WiX integration - Update README with comprehensive driver architecture details
Update the Windows UMDF backend to translate report IDs correctly between the client protocol and VHF: strip the leading report ID byte from input reports before submission, restore it on output events, and reject malformed input. Also treat stale global symbolic link collisions as non-fatal during rapid driver reinstalls, and document both behaviors in the README.
Convert gamepad stick axes from 16-bit signed to 8-bit unsigned in HID descriptors and reports. This reduces the common gamepad report size from 14 to 10 bytes and improves compatibility with browsers and DirectInput-style HID consumers that don't expect 16-bit stick fields to be split into byte-sized axes. Updates profiles, report packing logic, and corresponding unit tests.
Update gamepad HID descriptor to use standard stick axes (X/Y/Z/Rz) and Slider usage for triggers instead of Rx/Ry. Negate Y-axis values for both sticks to match HID conventions. Adds test validation for new descriptor layout and updates expected report values.
Reworked the common gamepad descriptor/report format to a 23-byte input report (report ID + 18 ordered 8-bit button/trigger fields + 4 stick axes), replacing the prior bitfield/hat/slider layout so generic HID consumers map controls more reliably. Updated report packing and unit tests to match the new ordering and semantics. Also made built-in profile manufacturer strings explicit per device family (e.g., Microsoft, Nintendo) and updated the Windows UMDF backend to publish explicit HID hardware IDs (VID/PID/REV) through VHF so hosts can identify selected profiles instead of a generic VHF device. README coverage was updated accordingly.
Switch the libvirtualhid Windows driver from System class to HIDClass for proper device classification. Explicitly register the WUDFRd reflector service in the INF instead of using Include/Needs directives. Remove dynamic VhfMode registry manipulation and instead clean up legacy devices with stale VhfMode settings or System class during installation. Add install-time validation to verify driver package files exist and the catalog is not stale. Update documentation to reflect the architectural changes and simplify the INF configuration.
Enable VHF source mode by setting VhfMode=1 in both the INF file and PowerShell installer. Changed root device class from HIDClass to System, refactored INF to include standard WUDFRD sections instead of manual service installation, and added registry configuration for both new and existing device installations. Added build-time check to prevent Debug configuration packaging.
Optimize HID descriptor format by packing buttons as 16 one-bit fields followed by 6 eight-bit axes (X, Y, Rx, Ry, Z, Rz) for better DirectInput and browser compatibility. This reduces the common report size from 23 to 9 bytes. Add Windows PnP device interface discovery with fallback to legacy device paths for robust control device enumeration. Implement automatic VHF gamepad cleanup on process exit via file cleanup callbacks. Update the UMDF driver to track file object ownership and clean up virtual gamepads when their owning file handles close. Enhance the gamepad adapter example with command-line argument parsing and interactive demo mode for testing sustained input. Link setupapi library for device enumeration on Windows.
Update the Windows UMDF driver package to better support development and non-admin usage by expanding device ACLs and disabling UMDF host process sharing. Add richer driver trace points and move the trace output to C:\Windows\Temp\libvirtualhid-umdf-driver.log for easier diagnostics around create/destroy/report flows. The gamepad adapter example now creates Runtime with explicit RuntimeOptions using the platform-default backend.
Move VHF IO target ownership onto each virtual gamepad record so creation, cleanup, and failure handling are isolated per device. Also normalize HID report handling to preserve complete report buffers consistently when sending input and output through VHF, and update the README to match the new lifecycle behavior.
Add XboxGIP-based profiles for Xbox One and Series controllers with unnumbered 17-byte input reports. Update common gamepad descriptor to use 12 buttons plus a hat switch instead of 16 buttons. Support unnumbered reports (report_id=0) throughout the API. Improve driver device lifecycle management by tracking gamepad ownership and cleaning up only devices associated with the device being released. Add device restart functionality to the installer and Xbox interface IDs to hardware enumeration.
Add a PowerShell helper that verifies the installed libvirtualhid test driver starts, opens the control device, and can expose a started gamepad child device for a held `gamepad_adapter` instance. Wire the check into the Windows MSVC pull request CI leg and document the manual validation flow in the README.
Align Xbox One/Series input reports with expected XInput behavior by encoding stick axes as unsigned 16-bit centered values, shifting hat values so neutral maps to 0, and defaulting unknown battery strength to 0xFF. Added/updated unit coverage for both active and neutral Xbox GIP reports, and enhanced the Windows installed-driver smoke test to probe XInput state changes before passing.
Adds a new Windows PowerShell helper (`scripts/windows/test-browser-gamepad.ps1`) that launches Edge/Chrome with DevTools, runs `gamepad_adapter`, and verifies the browser Gamepad API detects the expected controller ID plus changing button/axis input. The MSVC pull request CI job now runs this browser check across all supported gamepad profiles, and README testing docs were updated to include the new command and browser-based validation flow.
Create a neutral input report immediately after adapter creation so OS consumers can enumerate the virtual controller before any client input arrives. Update the adapter tests and README to reflect the extra initial submit.
Updates gamepad profile behavior to match real-device expectations and Windows backend limits. Generic and Switch now use a standard 16-button browser-friendly descriptor/report layout, Xbox One switches to PID 0x02FF, and DualSense/Switch naming is adjusted for expected Gamepad API IDs. Input packing now inverts Y axes consistently across Xbox GIP, DualShock, and DualSense paths. Windows UMDF/VHF creation now rejects the x360 profile as unsupported (XUSB-only), and tests/docs/scripts were updated accordingly: defaults move to xseries, hardware-id expectations are corrected, browser automation targeting is made more reliable, and PR CI no longer runs the browser gamepad step.
Update built-in profile identities so Xbox One uses VID/PID 045E:02EA and Xbox Series uses 045E:02FF, with USB bus metadata and matching Windows driver-test expectations. Replace the Switch Pro generic descriptor/profile with a dedicated HID descriptor and 64-byte report format, and add Switch-specific input report packing (buttons, hat, 16-bit stick axes, trigger-click bits). Refresh README details and unit tests to validate the new profile metadata, descriptor shape, output capabilities, and packed report bytes.
Change the Xbox Series public profile PID from HIDMaestro's GIP driverPid (0x02FF) to the physical USB identity (0x0B12). The UMDF driver now publishes 0x02FF as an additional hardware ID (HID\VID_045E&PID_02FF&IG_00) for xinputhid.inf matching while keeping the profile PID at 0x0B12. Update test scripts, browser gamepad ID patterns, and unit tests to match the new identity.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #36 +/- ##
==========================================
+ Coverage 87.81% 89.77% +1.96%
==========================================
Files 14 14
Lines 4235 4500 +265
Branches 1436 1512 +76
==========================================
+ Hits 3719 4040 +321
+ Misses 357 345 -12
+ Partials 159 115 -44
Flags with carried forward coverage won't be shown. Click here to find out more.
... and 1 file with indirect coverage changes Continue to review full report in Codecov by Harness.
|
Set DualShock 4 profile version to 0x0100 and manufacturer name to 'Sony Computer Entertainment' to match first-generation controller specs used by ViGEmBus DS4 target and HIDMaestro's DS4 v1 reference. Update documentation to clarify default profiles vs. transport-specific variants. Add test assertions for version, name, and manufacturer.
Replace the per-build driver package build/sign/install steps with a reusable windows_driver job that produces a windows-driver-installer artifact consumed by all Windows build legs. Key changes: - Build job now depends on both setup_release and windows_driver - Download and install/uninstall driver via MSI artifact instead of raw INF+cert steps - Expand driver install/verify/uninstall and gamepad adapter steps to cover msys2 legs, not just msvc - Rename `-Profile` to `-GamepadProfile` (with backward-compat alias) in test-installed-driver.ps1 and test-browser-gamepad.ps1 to avoid collision with PowerShell's built-in $Profile variable - Refactor internal helper functions to accept explicit parameters instead of relying on script-level variables - Add HardwareIds multi-value parsing to ConvertFrom-PnPUtilDeviceOutput; fix pnputil /enum-devices invocation - Add SupportsShouldProcess to transcript helpers in install-driver.ps1 - Minor formatting fixes in windows_wix.cmake and CMakeLists.txt
6820ee8 to
6aedab4
Compare
Refactors `test-installed-driver.ps1` to focus on PnP/HID readiness and control-device checks by removing the XInput report-flow probe for xone/xseries profiles. It also improves verbose diagnostics by logging only matched PnP records (instance ID, status, driver, hardware IDs, and problem fields) instead of dumping all `pnputil` output. README wording was updated to clarify the expected Xbox Series-compatible HID child identity.
Extract duplicated Windows driver device-enumeration logic into a new shared `libvirtualhid-driver-common.ps1` module, source it from install/uninstall scripts, and package it in CMake so distributed scripts stay in sync. The uninstall flow was updated to consume the shared registry helper output. In core report/profile code, improve readability and maintainability by splitting hex nibble assembly into named locals, replacing repetitive button-bit setters with constexpr button maps + a shared `button_bits` helper, and centralizing d-pad hat bit packing with `dpad_hat_bits()`.
ed03050 to
4ff8a63
Compare
Convert the static gamepad button map arrays in `report.cpp` into `constexpr` helper functions and update all bitmask builders to call them. This keeps the mappings unchanged while localizing `using enum GamepadButton` usage and avoiding a file-scope enum import.
Introduce shared `CMAKE_BUILD_CONFIG` and `DRIVER_BUILD_CONFIG` environment variables in CI, then use them consistently for build/install commands, artifact paths, test/example execution, driver packaging, and signing inputs. This removes hardcoded `Debug`/`Release` values and keeps MSVC and non-MSVC steps aligned. README Windows driver packaging docs were updated to include `cpack -C Release` so local instructions match CI behavior.
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Description
Replace the Windows gamepad path with UMDF/VHF-backed virtual HID devices,
add native controller profiles and report packing for Xbox, PlayStation, and
Switch gamepads, and harden driver install/uninstall handling.
Add driver smoke and browser Gamepad API validation scripts, expand unit
coverage for profile/report behavior, and document the Windows driver,
packaging, and validation workflow.
Screenshot
Issues Fixed or Closed
Roadmap Issues
Type of Change
Checklist
AI Usage