Signed-off-by: Arkadiusz Hiler ahiler@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;