From 0d9d78398c0465da34c1ffb734d51ecc77629a13 Mon Sep 17 00:00:00 2001 From: enricobuehler Date: Sun, 26 Jul 2026 16:31:25 +0200 Subject: [PATCH] =?UTF-8?q?fix(drivers/windows):=20name=20each=20virtual?= =?UTF-8?q?=20pad=20for=20what=20it=20is=20=E2=80=94=20one=20shared=20desc?= =?UTF-8?q?ription=20read=20as=20"the=20setting=20did=20nothing"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `pf_dualsense.inx` gave all four hardware ids a single %DeviceDesc%, so Device Manager labelled an emulated DualShock 4, DualSense Edge and Steam Deck pad "punktfunk Virtual DualSense". The HID layer was always per-type — device_type picks the PID (09CC for DS4), the report descriptor and the product string — but the one place a user goes to check said DualSense for every choice, which reads exactly like the controller-type setting being ignored. Split into four model lines over the same install section, one description each. No binding, service or descriptor change; stampinf's 9.9.MMdd.HHmm DriverVer increments on every build, so pnputil takes the update. InfVerif on the WDK runner: INF is VALID. Also correct the Slot.pref comment from the previous commit: emulating a DualShock 4 gives up adaptive triggers by construction. HidOutput::Trigger is emitted only by dualsense_proto, and a DS4 has no trigger-effect reports — the host never generates any to send. Rumble and the lightbar remain. Co-Authored-By: Claude Opus 5 (1M context) --- .../PunktfunkKit/Gamepad/GamepadCapture.swift | 8 +++--- .../drivers/pf-dualsense/pf_dualsense.inx | 25 +++++++++++++++---- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/clients/apple/Sources/PunktfunkKit/Gamepad/GamepadCapture.swift b/clients/apple/Sources/PunktfunkKit/Gamepad/GamepadCapture.swift index 8236b2b7..1d679aae 100644 --- a/clients/apple/Sources/PunktfunkKit/Gamepad/GamepadCapture.swift +++ b/clients/apple/Sources/PunktfunkKit/Gamepad/GamepadCapture.swift @@ -57,9 +57,11 @@ public final class GamepadCapture { let pad: UInt32 /// The controller KIND declared to the host (GamepadArrival) when the slot opened — the /// user's explicit "Controller type" setting when they picked one, else the detected - /// kind (`GamepadManager.declaredKind(for:)`). NOT the physical pad's kind: local - /// feedback keys off the live `GCController` subclass instead, so an emulated type never - /// costs a DualSense its lightbar or adaptive triggers. + /// kind (`GamepadManager.declaredKind(for:)`). NOT the physical pad's kind: local feedback + /// keys off the live `GCController` subclass instead, so whatever the host DOES send is + /// applied natively to the pad in the user's hands. What the host sends is bounded by the + /// emulated type, though — a virtual DualShock 4 has no adaptive-trigger reports in its + /// protocol, so emulating one gives those up by construction (rumble + lightbar remain). let pref: PunktfunkConnection.GamepadType var buttons: UInt32 = 0 var axes: [Int32] = [0, 0, 0, 0, 0, 0] diff --git a/packaging/windows/drivers/pf-dualsense/pf_dualsense.inx b/packaging/windows/drivers/pf-dualsense/pf_dualsense.inx index e686ef8f..38516a62 100644 --- a/packaging/windows/drivers/pf-dualsense/pf_dualsense.inx +++ b/packaging/windows/drivers/pf-dualsense/pf_dualsense.inx @@ -1,5 +1,6 @@ ;/*++ -; punktfunk virtual DualSense — UMDF2 HID minidriver INF (M0 spike). +; punktfunk virtual PlayStation/Valve pads — UMDF2 HID minidriver INF (M0 spike). +; One package, four hardware ids: DualSense, DualShock 4, DualSense Edge, Steam Deck. ; Adapted from the WDK vhidmini2 UMDF2 sample (VhidminiUm.inx). ; Depends on MsHidUmdf.inf (build >= 22000). ; Install: devgen /add /hardwareid "root\pf_dualsense" (after pnputil /add-driver /install) @@ -27,10 +28,19 @@ pf_dualsense.dll=1 [pf.NT$ARCH$.10.0...22000] ; Hardware ids: `root\pf_dualsense` for a root-enumerated devnode (devgen/devcon tests); `pf_dualsense` ; for the host's SwDeviceCreate'd DualSense (the `root\` prefix is reserved for root enumeration, so -; SwDeviceCreate rejects it with E_INVALIDARG); `pf_dualshock4` / `pf_dualsenseedge` for the host's -; virtual DualShock 4 / DualSense Edge — the same driver binds all of them and serves the matching -; identity per the device_type byte the host stamps into shared memory. -%DeviceDesc%=pfDualSense, root\pf_dualsense, pf_dualsense, pf_dualshock4, pf_dualsenseedge, pf_steamdeck +; SwDeviceCreate rejects it with E_INVALIDARG); `pf_dualshock4` / `pf_dualsenseedge` / `pf_steamdeck` +; for the host's other virtual pads — ONE driver binds all of them (every model line below installs +; the same `pfDualSense` section) and serves the matching HID identity per the device_type byte the +; host stamps into shared memory. +; +; Each id carries its OWN description: Device Manager reads this string, and a single shared +; "Virtual DualSense" made an emulated DualShock 4 look like the controller-type setting had been +; ignored. The HID layer (VID/PID, report descriptor, product string) was always per-type; this +; makes the human-readable name agree with it. +%DeviceDesc%=pfDualSense, root\pf_dualsense, pf_dualsense +%DeviceDescDS4%=pfDualSense, pf_dualshock4 +%DeviceDescEdge%=pfDualSense, pf_dualsenseedge +%DeviceDescDeck%=pfDualSense, pf_steamdeck [pfDualSense.NT] CopyFiles=UMDriverCopy @@ -78,4 +88,9 @@ ProviderString ="punktfunk" ManufacturerString ="punktfunk" ClassName ="HID device" Disk_Description ="punktfunk DualSense Installation Disk" +; One per hardware id — these are what Device Manager shows. Keep them aligned with the product +; strings the driver serves per device_type (src/lib.rs `on_get_string`). DeviceDesc ="punktfunk Virtual DualSense" +DeviceDescDS4 ="punktfunk Virtual DualShock 4" +DeviceDescEdge ="punktfunk Virtual DualSense Edge" +DeviceDescDeck ="punktfunk Virtual Steam Deck Controller"