libsdl-org / SDL

Simple Directmedia Layer
https://libsdl.org
zlib License
9.79k stars 1.82k forks source link

Request: Haptic feedback on Stadia controller bluetooth #7224

Closed tinus closed 1 year ago

tinus commented 1 year ago

Would it be possible to enable haptic feedback on the Stadia controller when it is connected by Bluetooth?

slouken commented 1 year ago

It looks like the controller doesn't support rumble over Bluetooth. If you find out how to enable that, please let me know!

slouken commented 1 year ago

It turns out that this works on Linux and macOS, but the Windows Bluetooth stack blocks the packet that controls rumble because it's not available in the HID descriptor for the device. Google would have to release a new driver or firmware update to enable this on Windows.

DJm00n commented 1 year ago

@slouken I have dumped Bluetooth LE HID report descriptor with Wireshark:

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x05,        // Usage (Game Pad)
0xA1, 0x01,        // Collection (Application)
0x85, 0x03,        //   Report ID (3)
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x75, 0x04,        //   Report Size (4)
0x95, 0x01,        //   Report Count (1)
0x25, 0x07,        //   Logical Maximum (7)
0x46, 0x3B, 0x01,  //   Physical Maximum (315)
0x65, 0x14,        //   Unit (System: English Rotation, Length: Centimeter)
0x09, 0x39,        //   Usage (Hat switch)
0x81, 0x42,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,Null State)
0x45, 0x00,        //   Physical Maximum (0)
0x65, 0x00,        //   Unit (None)
0x75, 0x01,        //   Report Size (1)
0x95, 0x04,        //   Report Count (4)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x09,        //   Usage Page (Button)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x75, 0x01,        //   Report Size (1)
0x95, 0x0F,        //   Report Count (15)
0x09, 0x12,        //   Usage (0x12)
0x09, 0x11,        //   Usage (0x11)
0x09, 0x14,        //   Usage (0x14)
0x09, 0x13,        //   Usage (0x13)
0x09, 0x0D,        //   Usage (0x0D)
0x09, 0x0C,        //   Usage (0x0C)
0x09, 0x0B,        //   Usage (0x0B)
0x09, 0x0F,        //   Usage (0x0F)
0x09, 0x0E,        //   Usage (0x0E)
0x09, 0x08,        //   Usage (0x08)
0x09, 0x07,        //   Usage (0x07)
0x09, 0x05,        //   Usage (0x05)
0x09, 0x04,        //   Usage (0x04)
0x09, 0x02,        //   Usage (0x02)
0x09, 0x01,        //   Usage (0x01)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x75, 0x01,        //   Report Size (1)
0x95, 0x01,        //   Report Count (1)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x01,        //   Usage Page (Generic Desktop Ctrls)
0x15, 0x01,        //   Logical Minimum (1)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x09, 0x01,        //   Usage (Pointer)
0xA1, 0x00,        //   Collection (Physical)
0x09, 0x30,        //     Usage (X)
0x09, 0x31,        //     Usage (Y)
0x75, 0x08,        //     Report Size (8)
0x95, 0x02,        //     Report Count (2)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0x09, 0x01,        //   Usage (Pointer)
0xA1, 0x00,        //   Collection (Physical)
0x09, 0x32,        //     Usage (Z)
0x09, 0x35,        //     Usage (Rz)
0x75, 0x08,        //     Report Size (8)
0x95, 0x02,        //     Report Count (2)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //   End Collection
0x05, 0x02,        //   Usage Page (Sim Ctrls)
0x75, 0x08,        //   Report Size (8)
0x95, 0x02,        //   Report Count (2)
0x15, 0x00,        //   Logical Minimum (0)
0x26, 0xFF, 0x00,  //   Logical Maximum (255)
0x09, 0xC5,        //   Usage (Brake)
0x09, 0xC4,        //   Usage (Accelerator)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x05, 0x0C,        //   Usage Page (Consumer)
0x15, 0x00,        //   Logical Minimum (0)
0x25, 0x01,        //   Logical Maximum (1)
0x09, 0xE9,        //   Usage (Volume Increment)
0x09, 0xEA,        //   Usage (Volume Decrement)
0x75, 0x01,        //   Report Size (1)
0x95, 0x02,        //   Report Count (2)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x09, 0xCD,        //   Usage (Play/Pause)
0x95, 0x01,        //   Report Count (1)
0x81, 0x02,        //   Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x05,        //   Report Count (5)
0x81, 0x01,        //   Input (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x85, 0x05,        //   Report ID (5)
0x06, 0x0F, 0x00,  //   Usage Page (PID Page)
0x09, 0x97,        //   Usage (0x97)
0x75, 0x10,        //   Report Size (16)
0x95, 0x02,        //   Report Count (2)
0x27, 0xFF, 0xFF, 0x00, 0x00,  //   Logical Maximum (65534)
0x91, 0x02,        //   Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0xC0,              // End Collection

// 182 bytes

It does contain output Report ID (5) and looks the same as via USB connection.

Here is diff of Windows preparsed data structs in USB and BLE modes: https://www.diffchecker.com/BoY3c9if/ (made with WIP hidapi tool)

Looks like we have another nasty bug in Windows bluetooth HID drivers (or missing documentation at least) - this is why it works in Linux and macOS.

Seems use HidD_SetOutputReport instead of WriteFile may be workaround for BLE...

PS: I already had issues with BLE implementation under Windows.

DJm00n commented 1 year ago

@slouken Looks like you have already found this bluetooth issue several years ago: https://github.com/libsdl-org/SDL/commit/eb83da023473f2f2afc7247a79eae2b17fa983ff

slouken commented 1 year ago

Did you try HidD_SetOutputReport? I tried that and I also tried the upstream hidapi and they both failed with GetLastError() returning 87 (ERROR_INVALID_PARAMETER)

DJm00n commented 1 year ago

Thank you for looking into it.

I'll try to do it too on my side and collect some traces.

If it turns out that it is still impossible to send ouptut report to Stadia Controller via hid api, then I planning try to do it directly using BluetoothGATTSetCharacteristicValue.

alizafeer commented 1 year ago

@DJm00n Did you manage to find something for the rest of us novices?

ZelunZhang commented 1 year ago

Hey @DJm00n , how should this no vibration on windows be fixed?

DJm00n commented 1 year ago

Hi guys! I have looked at this issue lately more closely. Tried to do direct BLE API calls (BluetoothGATTSetCharacteristicValue and friends) and still no luck with it. It looks like there is some kind of issue with controller firmware..that prevents Windows to properly communicate with it. I out of ideas right now. 🙁

PS: Same results are here from ReWASD devs.