From 63107524f6c0bb8922553ecd4fe9150e761802dd Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 15 Aug 2018 19:53:34 -0700 Subject: [PATCH] Fixed input from the Steam Virtual Gamepad on Mac OS X --- src/joystick/SDL_gamecontrollerdb.h | 2 +- src/joystick/android/SDL_sysjoystick.c | 2 +- src/joystick/darwin/SDL_sysjoystick.c | 2 +- src/joystick/hidapi/SDL_hidapi_ps4.c | 2 +- src/joystick/hidapi/SDL_hidapi_switch.c | 2 +- src/joystick/hidapi/SDL_hidapi_xbox360.c | 6 +++++- src/joystick/hidapi/SDL_hidapi_xboxone.c | 2 +- src/joystick/hidapi/SDL_hidapijoystick.c | 16 +++++++++------- src/joystick/hidapi/SDL_hidapijoystick_c.h | 4 ++-- src/joystick/linux/SDL_sysjoystick.c | 2 +- src/joystick/windows/SDL_dinputjoystick.c | 2 +- src/joystick/windows/SDL_xinputjoystick.c | 2 +- 12 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/joystick/SDL_gamecontrollerdb.h b/src/joystick/SDL_gamecontrollerdb.h index a33a8c983905f..0c3833f530ee3 100644 --- a/src/joystick/SDL_gamecontrollerdb.h +++ b/src/joystick/SDL_gamecontrollerdb.h @@ -324,7 +324,7 @@ static const char *s_ControllerMappings [] = "03000000811700007e05000000000000,Sega Saturn,a:b2,b:b4,dpdown:b16,dpleft:b15,dpright:b14,dpup:b17,leftshoulder:b8,lefttrigger:a5,leftx:a0,lefty:a2,rightshoulder:b9,righttrigger:a4,start:b13,x:b0,y:b6,", "030000004c050000cc09000000000000,Sony DualShock 4 V2,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", "030000004c050000a00b000000000000,Sony DualShock 4 Wireless Adaptor,a:b1,b:b2,back:b13,dpdown:h0.4,dpleft:h0.8,dpright:h0.2,dpup:h0.1,guide:b12,leftshoulder:b4,leftstick:b10,lefttrigger:a3,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b11,righttrigger:a4,rightx:a2,righty:a5,start:b9,x:b0,y:b3,", - "030000005e0400008e02000001000000,Steam Virtual GamePad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", + "030000005e0400008e02000001000000,Steam Virtual Gamepad,a:b0,b:b1,back:b9,dpdown:b12,dpleft:b13,dpright:b14,dpup:b11,leftshoulder:b4,leftstick:b6,lefttrigger:a2,leftx:a0,lefty:a1,rightshoulder:b5,rightstick:b7,righttrigger:a5,rightx:a3,righty:a4,start:b8,x:b2,y:b3,", "03000000110100002014000000000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3,start:b12,x:b2,y:b3,", "03000000110100002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,", "03000000381000002014000001000000,SteelSeries Nimbus,a:b0,b:b1,dpdown:b9,dpleft:b11,dpright:b10,dpup:b8,guide:b12,leftshoulder:b4,lefttrigger:b6,leftx:a0,lefty:a1~,rightshoulder:b5,righttrigger:b7,rightx:a2,righty:a3~,x:b2,y:b3,", diff --git a/src/joystick/android/SDL_sysjoystick.c b/src/joystick/android/SDL_sysjoystick.c index 9937723d009e1..c60555166fc02 100644 --- a/src/joystick/android/SDL_sysjoystick.c +++ b/src/joystick/android/SDL_sysjoystick.c @@ -344,7 +344,7 @@ Android_AddJoystick(int device_id, const char *name, const char *desc, int vendo } #ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(vendor_id, product_id)) { + if (HIDAPI_IsDevicePresent(vendor_id, product_id, 0)) { /* The HIDAPI driver is taking care of this device */ return -1; } diff --git a/src/joystick/darwin/SDL_sysjoystick.c b/src/joystick/darwin/SDL_sysjoystick.c index 88cc92b7ac00f..3d0de56e43cec 100644 --- a/src/joystick/darwin/SDL_sysjoystick.c +++ b/src/joystick/darwin/SDL_sysjoystick.c @@ -451,7 +451,7 @@ GetDeviceInfo(IOHIDDeviceRef hidDevice, recDevice *pDevice) } #ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(vendor, product)) { + if (HIDAPI_IsDevicePresent(vendor, product, version)) { /* The HIDAPI driver is taking care of this device */ return 0; } diff --git a/src/joystick/hidapi/SDL_hidapi_ps4.c b/src/joystick/hidapi/SDL_hidapi_ps4.c index 44e9b9913bff9..f620d000ebbf5 100644 --- a/src/joystick/hidapi/SDL_hidapi_ps4.c +++ b/src/joystick/hidapi/SDL_hidapi_ps4.c @@ -206,7 +206,7 @@ static uint8_t GetPlaystationVolumeFromFloat(float fVolume) } static SDL_bool -HIDAPI_DriverPS4_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, int interface_number, Uint16 usage_page, Uint16 usage) +HIDAPI_DriverPS4_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, Uint16 usage_page, Uint16 usage) { /* The Revolution Pro Controller exposes multiple interfaces on Windows */ const Uint16 NACON_USB_VID = 0x146b; diff --git a/src/joystick/hidapi/SDL_hidapi_switch.c b/src/joystick/hidapi/SDL_hidapi_switch.c index 79628d7027a79..221995f0d9b77 100644 --- a/src/joystick/hidapi/SDL_hidapi_switch.c +++ b/src/joystick/hidapi/SDL_hidapi_switch.c @@ -210,7 +210,7 @@ typedef struct { static SDL_bool -HIDAPI_DriverSwitch_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, int interface_number, Uint16 usage_page, Uint16 usage) +HIDAPI_DriverSwitch_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, Uint16 usage_page, Uint16 usage) { return SDL_IsJoystickNintendoSwitchPro(vendor_id, product_id); } diff --git a/src/joystick/hidapi/SDL_hidapi_xbox360.c b/src/joystick/hidapi/SDL_hidapi_xbox360.c index ab4f417b23786..8411121ff5feb 100644 --- a/src/joystick/hidapi/SDL_hidapi_xbox360.c +++ b/src/joystick/hidapi/SDL_hidapi_xbox360.c @@ -170,9 +170,13 @@ typedef struct { static SDL_bool -HIDAPI_DriverXbox360_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, int interface_number, Uint16 usage_page, Uint16 usage) +HIDAPI_DriverXbox360_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, Uint16 usage_page, Uint16 usage) { #ifdef __MACOSX__ + if (vendor_id == 0x045e && product_id == 0x028e && version == 1) { + /* This is the Steam Virtual Gamepad, which isn't supported by this driver */ + return SDL_FALSE; + } return SDL_IsJoystickXbox360(vendor_id, product_id) || SDL_IsJoystickXboxOne(vendor_id, product_id); #else return SDL_IsJoystickXbox360(vendor_id, product_id); diff --git a/src/joystick/hidapi/SDL_hidapi_xboxone.c b/src/joystick/hidapi/SDL_hidapi_xboxone.c index 16fab5a1fadb7..78a9239eba13f 100644 --- a/src/joystick/hidapi/SDL_hidapi_xboxone.c +++ b/src/joystick/hidapi/SDL_hidapi_xboxone.c @@ -171,7 +171,7 @@ typedef struct { static SDL_bool -HIDAPI_DriverXboxOne_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, int interface_number, Uint16 usage_page, Uint16 usage) +HIDAPI_DriverXboxOne_IsSupportedDevice(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, Uint16 usage_page, Uint16 usage) { return SDL_IsJoystickXboxOne(vendor_id, product_id); } diff --git a/src/joystick/hidapi/SDL_hidapijoystick.c b/src/joystick/hidapi/SDL_hidapijoystick.c index 8f738066e3c3a..aa0087a1f7ab4 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick.c +++ b/src/joystick/hidapi/SDL_hidapijoystick.c @@ -64,6 +64,7 @@ typedef struct _SDL_HIDAPI_Device char *path; Uint16 vendor_id; Uint16 product_id; + Uint16 version; SDL_JoystickGUID guid; int interface_number; /* Available on Windows and Linux */ Uint16 usage_page; /* Available on Windows and Mac OS X */ @@ -378,13 +379,13 @@ HIDAPI_ShutdownDiscovery() static SDL_bool -HIDAPI_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id) +HIDAPI_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id, Uint16 version) { int i; for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; - if (driver->enabled && driver->IsSupportedDevice(vendor_id, product_id, -1, 0, 0)) { + if (driver->enabled && driver->IsSupportedDevice(vendor_id, product_id, version, -1, 0, 0)) { return SDL_TRUE; } } @@ -402,7 +403,7 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device) for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) { SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i]; - if (driver->enabled && driver->IsSupportedDevice(device->vendor_id, device->product_id, device->interface_number, device->usage_page, device->usage)) { + if (driver->enabled && driver->IsSupportedDevice(device->vendor_id, device->product_id, device->version, device->interface_number, device->usage_page, device->usage)) { return driver; } } @@ -532,6 +533,7 @@ HIDAPI_AddDevice(struct hid_device_info *info) device->seen = SDL_TRUE; device->vendor_id = info->vendor_id; device->product_id = info->product_id; + device->version = info->release_number; device->interface_number = info->interface_number; device->usage_page = info->usage_page; device->usage = info->usage; @@ -539,7 +541,7 @@ HIDAPI_AddDevice(struct hid_device_info *info) /* FIXME: Is there any way to tell whether this is a Bluetooth device? */ const Uint16 vendor = device->vendor_id; const Uint16 product = device->product_id; - const Uint16 version = 0; + const Uint16 version = device->version; Uint16 *guid16 = (Uint16 *)device->guid.data; *guid16++ = SDL_SwapLE16(SDL_HARDWARE_BUS_USB); @@ -608,7 +610,7 @@ HIDAPI_AddDevice(struct hid_device_info *info) } #ifdef DEBUG_HIDAPI - SDL_Log("Adding HIDAPI device '%s' interface %d, usage page 0x%.4x, usage 0x%.4x\n", device->name, device->interface_number, device->usage_page, device->usage); + SDL_Log("Adding HIDAPI device '%s' VID 0x%.4x, PID 0x%.4x, version %d, interface %d, usage page 0x%.4x, usage 0x%.4x\n", device->name, device->vendor_id, device->product_id, device->version, device->interface_number, device->usage_page, device->usage); #endif /* Add it to the list */ @@ -696,12 +698,12 @@ HIDAPI_UpdateDeviceList(void) } SDL_bool -HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id) +HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version) { SDL_HIDAPI_Device *device; /* Don't update the device list for devices we know aren't supported */ - if (!HIDAPI_IsDeviceSupported(vendor_id, product_id)) { + if (!HIDAPI_IsDeviceSupported(vendor_id, product_id, version)) { return SDL_FALSE; } diff --git a/src/joystick/hidapi/SDL_hidapijoystick_c.h b/src/joystick/hidapi/SDL_hidapijoystick_c.h index a21a69d1866fe..fea73b60de309 100644 --- a/src/joystick/hidapi/SDL_hidapijoystick_c.h +++ b/src/joystick/hidapi/SDL_hidapijoystick_c.h @@ -46,7 +46,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver { const char *hint; SDL_bool enabled; - SDL_bool (*IsSupportedDevice)(Uint16 vendor_id, Uint16 product_id, int interface_number, Uint16 usage_page, Uint16 usage); + SDL_bool (*IsSupportedDevice)(Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, Uint16 usage_page, Uint16 usage); const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id); SDL_bool (*Init)(SDL_Joystick *joystick, hid_device *dev, Uint16 vendor_id, Uint16 product_id, void **context); int (*Rumble)(SDL_Joystick *joystick, hid_device *dev, void *context, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); @@ -63,7 +63,7 @@ extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360; extern SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne; /* Return true if a HID device is present and supported as a joystick */ -extern SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id); +extern SDL_bool HIDAPI_IsDevicePresent(Uint16 vendor_id, Uint16 product_id, Uint16 version); #endif /* SDL_JOYSTICK_HIDAPI_H */ diff --git a/src/joystick/linux/SDL_sysjoystick.c b/src/joystick/linux/SDL_sysjoystick.c index ede8fb124ee49..795f92b35eb74 100644 --- a/src/joystick/linux/SDL_sysjoystick.c +++ b/src/joystick/linux/SDL_sysjoystick.c @@ -211,7 +211,7 @@ IsJoystick(int fd, char *namebuf, const size_t namebuflen, SDL_JoystickGUID *gui } #ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(inpid.vendor, inpid.product)) { + if (HIDAPI_IsDevicePresent(inpid.vendor, inpid.product, inpid.version)) { /* The HIDAPI driver is taking care of this device */ return 0; } diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c index 4b736918ab171..67d7d25cdaf7f 100644 --- a/src/joystick/windows/SDL_dinputjoystick.c +++ b/src/joystick/windows/SDL_dinputjoystick.c @@ -535,7 +535,7 @@ EnumJoysticksCallback(const DIDEVICEINSTANCE * pdidInstance, VOID * pContext) } #ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(vendor, product)) { + if (HIDAPI_IsDevicePresent(vendor, product, 0)) { /* The HIDAPI driver is taking care of this device */ SDL_free(pNewJoystick); return DIENUM_CONTINUE; diff --git a/src/joystick/windows/SDL_xinputjoystick.c b/src/joystick/windows/SDL_xinputjoystick.c index 623a75645e726..5a0f466231ead 100644 --- a/src/joystick/windows/SDL_xinputjoystick.c +++ b/src/joystick/windows/SDL_xinputjoystick.c @@ -261,7 +261,7 @@ AddXInputDevice(Uint8 userid, BYTE SubType, JoyStick_DeviceData **pContext) #if 0 /* There's no controller that's supported by both XInput and HIDAPI */ #ifdef SDL_JOYSTICK_HIDAPI - if (HIDAPI_IsDevicePresent(vendor, product)) { + if (HIDAPI_IsDevicePresent(vendor, product, version)) { /* The HIDAPI driver is taking care of this device */ SDL_free(pNewJoystick); return;