[PATCH 2/3] winebus.sys: Process quirky DualSense bluetooth reports.

Arkadiusz Hiler ahiler at codeweavers.com
Thu Jan 27 11:17:57 CST 2022


Signed-off-by: Arkadiusz Hiler <ahiler at codeweavers.com>
---
 dlls/winebus.sys/bus_udev.c     | 40 +++++++++++++++++++++++++++++++++
 dlls/winebus.sys/unix_private.h |  1 +
 dlls/winebus.sys/unixlib.c      |  6 +++++
 3 files changed, 47 insertions(+)

diff --git a/dlls/winebus.sys/bus_udev.c b/dlls/winebus.sys/bus_udev.c
index 4bd0907fdfd..c6185adf23d 100644
--- a/dlls/winebus.sys/bus_udev.c
+++ b/dlls/winebus.sys/bus_udev.c
@@ -117,6 +117,7 @@ static inline struct base_device *impl_from_unix_device(struct unix_device *ifac
 }
 
 #define QUIRK_DS4_BT 0x1
+#define QUIRK_DUALSENSE_BT 0x2
 
 struct hidraw_device
 {
@@ -356,6 +357,36 @@ static void hidraw_device_read_report(struct unix_device *iface)
             buff[0] = 1;
         }
 
+        /* The behavior of DualSense is very similar to DS4 described above with a few exceptions.
+         *
+         * The report number #41 is used for the extended bluetooth input report. The report comes
+         * with only one extra byte in front and the format is not exactly the same as the one used
+         * for the report #1 so we need to shuffle a few bytes around.
+         *
+         * Basic #1 report:
+         *   X  Y  Z  RZ  Buttons[3]  TriggerLeft  TriggerRight
+         *
+         * Extended #41 report:
+         *   Prefix X  Y  Z  Rz  TriggerLeft  TriggerRight  Counter  Buttons[3] ...
+         */
+        if ((impl->quirks & QUIRK_DUALSENSE_BT) && report_buffer[0] == 0x31 && size >= 11)
+        {
+            BYTE trigger[2];
+            size = 10;
+            buff += 1;
+
+            buff[0] = 1; /* fake report #1 */
+
+            trigger[0] = buff[5]; /* TriggerLeft*/
+            trigger[1] = buff[6]; /* TriggerRight */
+
+            buff[5] = buff[8];    /* Buttons[0] */
+            buff[6] = buff[9];    /* Buttons[1] */
+            buff[7] = buff[10];   /* Buttons[2] */
+            buff[8] = trigger[0]; /* TriggerLeft */
+            buff[9] = trigger[1]; /* TirggerRight */
+        }
+
         bus_event_queue_input_report(&event_queue, iface, buff, size);
     }
 }
@@ -373,6 +404,12 @@ static void hidraw_disable_sony_quirks(struct unix_device *iface)
         TRACE("Disabling report quirk for Bluetooth DualShock4 controller iface %p\n", iface);
         impl->quirks &= ~QUIRK_DS4_BT;
     }
+
+    if ((impl->quirks & QUIRK_DUALSENSE_BT))
+    {
+        TRACE("Disabling report quirk for Bluetooth DualSense controller iface %p\n", iface);
+        impl->quirks &= ~QUIRK_DUALSENSE_BT;
+    }
 }
 
 static void hidraw_device_set_output_report(struct unix_device *iface, HID_XFER_PACKET *packet, IO_STATUS_BLOCK *io)
@@ -1219,6 +1256,9 @@ static void hidraw_set_quirks(struct hidraw_device *impl, DWORD bus_type, WORD v
 {
     if (bus_type == BUS_BLUETOOTH && is_dualshock4_gamepad(vid, pid))
         impl->quirks |= QUIRK_DS4_BT;
+
+    if (bus_type == BUS_BLUETOOTH && is_dualsense_gamepad(vid, pid))
+        impl->quirks |= QUIRK_DUALSENSE_BT;
 }
 
 static void udev_add_device(struct udev_device *dev, int fd)
diff --git a/dlls/winebus.sys/unix_private.h b/dlls/winebus.sys/unix_private.h
index efecf6cdbe3..e897251dea8 100644
--- a/dlls/winebus.sys/unix_private.h
+++ b/dlls/winebus.sys/unix_private.h
@@ -266,5 +266,6 @@ extern void hid_device_set_effect_state(struct unix_device *iface, BYTE index, B
 
 BOOL is_xbox_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
 BOOL is_dualshock4_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
+BOOL is_dualsense_gamepad(WORD vid, WORD pid) DECLSPEC_HIDDEN;
 
 #endif /* __WINEBUS_UNIX_PRIVATE_H */
diff --git a/dlls/winebus.sys/unixlib.c b/dlls/winebus.sys/unixlib.c
index 1269ae05c2b..3a7c3a16428 100644
--- a/dlls/winebus.sys/unixlib.c
+++ b/dlls/winebus.sys/unixlib.c
@@ -70,6 +70,12 @@ BOOL is_dualshock4_gamepad(WORD vid, WORD pid)
     return FALSE;
 }
 
+BOOL is_dualsense_gamepad(WORD vid, WORD pid)
+{
+    if (vid == 0x054c && pid == 0x0ce6) return TRUE;
+    return FALSE;
+}
+
 struct mouse_device
 {
     struct unix_device unix_device;
-- 
2.35.0




More information about the wine-devel mailing list