diff --git a/crates/punktfunk-host/src/inject.rs b/crates/punktfunk-host/src/inject.rs index 9fc1696a..0bf07aa6 100644 --- a/crates/punktfunk-host/src/inject.rs +++ b/crates/punktfunk-host/src/inject.rs @@ -527,7 +527,9 @@ pub mod steam_gadget; #[path = "inject/proto/steam_proto.rs"] pub mod steam_proto; /// Pure fallback-remap policy (Steam-only inputs onto a non-Steam backend) + the Deck motion rescale. -#[cfg(target_os = "linux")] +/// Shared by the Linux and Windows DualSense/DS4 backends (the slot-less pads that must fold the +/// Steam back grips); the Deck motion rescale is Linux-only but harmless to compile on Windows. +#[cfg(any(target_os = "linux", target_os = "windows"))] #[path = "inject/proto/steam_remap.rs"] pub mod steam_remap; /// Linux: virtual Steam Deck over **USB/IP** (`vhci_hcd`) — the shippable, Secure-Boot-clean, diff --git a/crates/punktfunk-host/src/inject/windows/dualsense_windows.rs b/crates/punktfunk-host/src/inject/windows/dualsense_windows.rs index cc6ce9d9..9f1b3659 100644 --- a/crates/punktfunk-host/src/inject/windows/dualsense_windows.rs +++ b/crates/punktfunk-host/src/inject/windows/dualsense_windows.rs @@ -389,6 +389,9 @@ pub struct DualSenseWindowsManager { /// Create-retry gate: a transient UMDF-channel failure backs off and retries instead of /// permanently disabling every pad for the session. gate: PadGate, + /// Fallback policy for the Steam back grips a client may send (the DualSense has no back-button + /// HID slot). `PUNKTFUNK_STEAM_REMAP=paddles=…`; default drop. Parity with `linux/dualsense.rs`. + remap: crate::inject::steam_remap::RemapConfig, } impl Default for DualSenseWindowsManager { @@ -405,6 +408,7 @@ impl DualSenseWindowsManager { last_rumble: vec![(0, 0); MAX_PADS], last_write: vec![Instant::now(); MAX_PADS], gate: PadGate::new(), + remap: crate::inject::steam_remap::RemapConfig::from_env(), } } @@ -433,8 +437,13 @@ impl DualSenseWindowsManager { } self.ensure(idx); let prev = self.state[idx]; + // Steam back grips have no DualSense slot — fold them onto standard buttons per the + // configured policy (default drop) so they aren't silently lost, exactly as + // `linux/dualsense.rs` does. + let buttons = + crate::inject::steam_remap::fold_paddles(f.buttons, self.remap.paddles); let mut s = DsState::from_gamepad( - f.buttons, + buttons, f.ls_x, f.ls_y, f.rs_x, diff --git a/crates/punktfunk-host/src/inject/windows/dualshock4_windows.rs b/crates/punktfunk-host/src/inject/windows/dualshock4_windows.rs index fd91f308..29ba5d1a 100644 --- a/crates/punktfunk-host/src/inject/windows/dualshock4_windows.rs +++ b/crates/punktfunk-host/src/inject/windows/dualshock4_windows.rs @@ -153,6 +153,9 @@ pub struct DualShock4WindowsManager { /// Create-retry gate: a transient UMDF-channel failure backs off and retries instead of /// permanently disabling every pad for the session. gate: PadGate, + /// Fallback policy for the Steam back grips a client may send (the DS4 has no back-button HID + /// slot). `PUNKTFUNK_STEAM_REMAP=paddles=…`; default drop. Parity with `linux/dualshock4.rs`. + remap: crate::inject::steam_remap::RemapConfig, } impl Default for DualShock4WindowsManager { @@ -170,6 +173,7 @@ impl DualShock4WindowsManager { last_led: vec![None; MAX_PADS], last_write: vec![Instant::now(); MAX_PADS], gate: PadGate::new(), + remap: crate::inject::steam_remap::RemapConfig::from_env(), } } @@ -199,8 +203,13 @@ impl DualShock4WindowsManager { } self.ensure(idx); let prev = self.state[idx]; + // Steam back grips have no DS4 slot — fold them onto standard buttons per the + // configured policy (default drop) so they aren't silently lost, exactly as + // `linux/dualshock4.rs` does. + let buttons = + crate::inject::steam_remap::fold_paddles(f.buttons, self.remap.paddles); let mut s = DsState::from_gamepad( - f.buttons, + buttons, f.ls_x, f.ls_y, f.rs_x,