mirror of https://github.com/encounter/SDL.git
Fixed bug 4996 - Mac: XBoxOne Bluetooth rumble isn't working
rofferom
I have an annoying issue on MacOS about XBoxOne Bluetooth rumble (Vendor: 0x045e, Product: 0x02fd).
When 360controller is installed, rumble is working correctly. However, Bluetooth rumble isn't working at all, with or without 360controller installed (although it is working with Chrome + https://html5gamepad.com).
I looked at the code, and it seems that XBox controllers are managed in MacOS in this file: SDL_hidapi_xbox360.c. The XBoxOne file is disabled for MacOS in SDL_hidjoystick_c.h.
The function HIDAPI_DriverXbox360_Rumble() is called correctly, and hid_write() returns no error.
I have tried a stupid test. I took the rumble packet from 360controller: ec4e88eb2d/XBOBTFF/FFDriver.cpp (L620)
. With the patch I have attached, I manage to have rumble working on Bluetooth (with some stupid vibration level, but it proves it can if the packet is changed).
But it breaks the USB rumble with 360controller. A comment in the function makes an explicit reference to 360controller, I think that's why I have broken this specific usecase.
I don't know what is the correct way to fix this, but it seems that the current implementation has a missing case for Bluetooth support.
Note that I also tested master this morning, and I have another issue:
if (!device->ffservice) {
return SDL_Unsupported();
}
test fails in DARWIN_JoystickRumble(). This test has been done quickly, I'm not totaly confident about its accuracy.
This commit is contained in:
parent
5346216368
commit
6590d078d7
|
@ -244,6 +244,20 @@ HIDAPI_DriverXbox360_QuitWindowsGamingInput(SDL_DriverXbox360_Context *ctx)
|
||||||
|
|
||||||
#endif /* SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT */
|
#endif /* SDL_JOYSTICK_HIDAPI_WINDOWS_GAMING_INPUT */
|
||||||
|
|
||||||
|
static SDL_bool
|
||||||
|
IsBluetoothXboxOneController(Uint16 vendor_id, Uint16 product_id)
|
||||||
|
{
|
||||||
|
/* Check to see if it's the Xbox One S or Xbox One Elite Series 2 in Bluetooth mode */
|
||||||
|
if (vendor_id == USB_VENDOR_MICROSOFT) {
|
||||||
|
if (product_id == USB_PRODUCT_XBOX_ONE_S_REV1_BLUETOOTH ||
|
||||||
|
product_id == USB_PRODUCT_XBOX_ONE_S_REV2_BLUETOOTH ||
|
||||||
|
product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2_BLUETOOTH) {
|
||||||
|
return SDL_TRUE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return SDL_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static SDL_bool
|
static SDL_bool
|
||||||
HIDAPI_DriverXbox360_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
|
HIDAPI_DriverXbox360_IsSupportedDevice(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
|
||||||
{
|
{
|
||||||
|
@ -403,23 +417,38 @@ HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||||
#else /* !__WIN32__ */
|
#else /* !__WIN32__ */
|
||||||
|
|
||||||
#ifdef __MACOSX__
|
#ifdef __MACOSX__
|
||||||
/* On Mac OS X the 360Controller driver uses this short report,
|
if (IsBluetoothXboxOneController(device->vendor_id, device->product_id)) {
|
||||||
and we need to prefix it with a magic token so hidapi passes it through untouched
|
Uint8 rumble_packet[] = { 0x03, 0x0F, 0x00, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00 };
|
||||||
*/
|
|
||||||
Uint8 rumble_packet[] = { 'M', 'A', 'G', 'I', 'C', '0', 0x00, 0x04, 0x00, 0x00 };
|
|
||||||
|
|
||||||
rumble_packet[6+2] = (low_frequency_rumble >> 8);
|
rumble_packet[4] = (low_frequency_rumble >> 8);
|
||||||
rumble_packet[6+3] = (high_frequency_rumble >> 8);
|
rumble_packet[5] = (high_frequency_rumble >> 8);
|
||||||
|
|
||||||
|
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
|
||||||
|
return SDL_SetError("Couldn't send rumble packet");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* On Mac OS X the 360Controller driver uses this short report,
|
||||||
|
and we need to prefix it with a magic token so hidapi passes it through untouched
|
||||||
|
*/
|
||||||
|
Uint8 rumble_packet[] = { 'M', 'A', 'G', 'I', 'C', '0', 0x00, 0x04, 0x00, 0x00 };
|
||||||
|
|
||||||
|
rumble_packet[6+2] = (low_frequency_rumble >> 8);
|
||||||
|
rumble_packet[6+3] = (high_frequency_rumble >> 8);
|
||||||
|
|
||||||
|
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
|
||||||
|
return SDL_SetError("Couldn't send rumble packet");
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
Uint8 rumble_packet[] = { 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
Uint8 rumble_packet[] = { 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||||
|
|
||||||
rumble_packet[3] = (low_frequency_rumble >> 8);
|
rumble_packet[3] = (low_frequency_rumble >> 8);
|
||||||
rumble_packet[4] = (high_frequency_rumble >> 8);
|
rumble_packet[4] = (high_frequency_rumble >> 8);
|
||||||
#endif
|
|
||||||
|
|
||||||
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
|
if (SDL_HIDAPI_SendRumble(device, rumble_packet, sizeof(rumble_packet)) != sizeof(rumble_packet)) {
|
||||||
return SDL_SetError("Couldn't send rumble packet");
|
return SDL_SetError("Couldn't send rumble packet");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
#endif /* __WIN32__ */
|
#endif /* __WIN32__ */
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in New Issue