We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3124

Summary: Steelseries Stratus XL mFi controller on OSX does not detect the DPAD
Product: SDL Reporter: Rodrigo Cardoso <rodrigo.alfenas>
Component: joystickAssignee: Sam Lantinga <slouken>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2 CC: amaranth72, natbro, rodrigo.alfenas
Version: HG 2.0   
Hardware: x86   
OS: Mac OS X (All)   
Attachments: Joystick Show App (uses SDL2) showing available inputs from the Steelseries Stratus XL

Description Rodrigo Cardoso 2015-09-16 23:48:07 UTC
Created attachment 2267 [details]
Joystick Show App (uses SDL2) showing available inputs from the Steelseries Stratus XL

* It detects both sticks, all shoulder and face buttons.
* It does NOT detect the DPAD and the Start Button.

More details:

This is a "Made for iPhone" Extended Bluetooth controller, works perfectly on iOS.
It claims "Mac support" so I connected it to my mac and expecienced the described problem.

Another important quirk: The DPAD works on the tvOS simulator beta in the same mac.
Comment 1 Alex Szpakowski 2015-09-17 02:45:13 UTC
The OS X backend of SDL doesn't use Apple's GameController.framework at all right now (and neither does the iOS backend of SDL, but mostly only because I don't own a compatible controller to test with at the moment...).

I'd guess that, for whatever reason, the Steelseries drivers for OS X just don't expose those buttons as HID inputs to the IOKit HID APIs, which is what SDL uses for joystick input on OS X at the moment.
Comment 2 Rodrigo Cardoso 2015-09-17 03:43:29 UTC
Yeah, I know GameController.framework is not supported and suspected that these controllers should never work with the IOKit HID APIs.

In fact, I was surprised that this specific controller worked as is! So thought it must be something on SDL side.

Also, I just bought this controller because of the tvOS and I am tinkering with SDL... and planning some work on iOS/tvOS gamecontroller support, if this helps on OS X side too, great! :)
Comment 3 Alex Szpakowski 2015-09-17 03:57:25 UTC
I wonder if the IORegistryExplorer app will tell you anything useful? I'm a newbie to the field of HID in OS X but I was using it earlier to see if the motion sensors are exposed in the Dualshock 3 (they don't seem to be, sadly...)



Unrelated to the reported issue:

Since I don't own a capable controller myself I haven't looked into it much, but I'm wondering if it's possible to programmatically figure out whether a HID joystick also exposes itself as a GameController (or vice versa) on OS X.

If it's not possible then I probably wouldn't bother with GameController.framework in OS X since we'd get duplicate reported joysticks with no nice way to eliminate them. If it is possible, then it might be worth looking into adding it eventually.

If you plan to eventually work on GameController support on iOS it might be a good idea to collaborate – I have a tiny bit of (very incomplete and untested) code already written, and I might end up buying an MFi controller after all myself.

I also have some ideas about supporting the GCMotion profile (used by the tvOS remote) with new APIs in SDL_Joystick, which would also let SDL's iOS and Android backends report device gyro data through SDL.
Comment 4 Rodrigo Cardoso 2015-09-17 04:09:21 UTC
Thanks for the IORegistryExplorer tip, I will take a look.

------
Also unrelated to the issue:

I am very interested in supporting GCMotion profile and regular accelerometer/gyro data through SDL.

I have a bunch of gamecontroller framework related code for some unreleased projects and I am also author of this iOS app (which I am porting to tvOS):
https://itunes.apple.com/us/app/game-controller-tester/id859236726?mt=8
And plan to open source it to help other people with gamecontroller code.

If you want to share thoughts/drafts/code about that, drop me an email. :)
Comment 5 Nat Brown 2015-11-12 12:51:49 UTC
I don't have a Stratus XL, but do have a Nimbus, which acts the same way with SDL2, and since they are both MFi I suspect it's the same underlying reason.

If you download and build the HID Calibrator sample you can see that these are totally legitimate HID devices (except for inverting the Y-axis of joysticks, which is contrary to the HID specification but does make them more compatible with games compiled expecting XBOX controllers).

The Home button is a Usage Page (Consumer) / Usage (AC_Home) binary value.
The DPads are unusual in that they are pressure-sensitive, but they are under Usage Page (Generic Desktop Ctrls) and clearly marked with Usage (D-pad Up) etc.

I haven't yet dug into SDL2 to fix it, but I suspect it's not looking in those usage pages, nor expecting a non-binary dpad.

Below is the report descriptor for the Nimbus. You can create this report descriptor for any OS X HID device by opening IORegistryExplorer, narrowing the search to IOHID and finding elements with a "ReportDescriptor" key. Double click the data in the right-hand pane to copy the "<05 01 ...... xx>" string, then paste it into http://eleccelerator.com/usbdescreqparser/ and remove the leading '<' and trailing '>', then have it parse the descriptor. It's pretty easy to then create a complete expected raw input report. On OS X this is a lot better than trying to get USB.org's ancient HIDTool running under a VM.

0x05, 0x01,        // Usage Page (Generic Desktop Ctrls)
0x09, 0x05,        // Usage (Game Pad)
0xA1, 0x01,        // Collection (Application)
0x09, 0x05,        //   Usage (Game Pad)
0xA1, 0x02,        //   Collection (Logical)
0x75, 0x08,        //     Report Size (8)
0x95, 0x04,        //     Report Count (4)
0x15, 0x00,        //     Logical Minimum (0)
0x26, 0xFF, 0x00,  //     Logical Maximum (255)
0x35, 0x00,        //     Physical Minimum (0)
0x46, 0xFF, 0x00,  //     Physical Maximum (255)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x90,        //     Usage (D-pad Up)
0x09, 0x92,        //     Usage (D-pad Right)
0x09, 0x91,        //     Usage (D-pad Down)
0x09, 0x93,        //     Usage (D-pad Left)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x08,        //     Report Count (8)
0x05, 0x09,        //     Usage Page (Button)
0x19, 0x01,        //     Usage Minimum (0x01)
0x29, 0x08,        //     Usage Maximum (0x08)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x35, 0x00,        //     Physical Minimum (0)
0x45, 0x01,        //     Physical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x01,        //     Report Count (1)
0x05, 0x0C,        //     Usage Page (Consumer)
0x0A, 0x23, 0x02,  //     Usage (AC Home)
0x81, 0x02,        //     Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x95, 0x07,        //     Report Count (7)
0x81, 0x03,        //     Input (Const,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0x15, 0x00,        //     Logical Minimum (0)
0x25, 0x01,        //     Logical Maximum (1)
0x35, 0x00,        //     Physical Minimum (0)
0x45, 0x01,        //     Physical Maximum (1)
0x75, 0x01,        //     Report Size (1)
0x95, 0x04,        //     Report Count (4)
0x05, 0x08,        //     Usage Page (LEDs)
0x1A, 0x00, 0xFF,  //     Usage Minimum (0xFF00)
0x2A, 0x03, 0xFF,  //     Usage Maximum (0xFF03)
0x91, 0x02,        //     Output (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x75, 0x04,        //     Report Size (4)
0x95, 0x01,        //     Report Count (1)
0x91, 0x01,        //     Output (Const,Array,Abs,No Wrap,Linear,Preferred State,No Null Position,Non-volatile)
0x15, 0x81,        //     Logical Minimum (129)
0x25, 0x7F,        //     Logical Maximum (127)
0x35, 0x81,        //     Physical Minimum (129)
0x45, 0x7F,        //     Physical Maximum (127)
0x05, 0x01,        //     Usage Page (Generic Desktop Ctrls)
0x09, 0x01,        //     Usage (Pointer)
0xA1, 0x00,        //     Collection (Physical)
0x75, 0x08,        //       Report Size (8)
0x95, 0x04,        //       Report Count (4)
0x09, 0x30,        //       Usage (X)
0x09, 0x31,        //       Usage (Y)
0x09, 0x32,        //       Usage (Z)
0x09, 0x35,        //       Usage (Rz)
0x81, 0x02,        //       Input (Data,Var,Abs,No Wrap,Linear,Preferred State,No Null Position)
0xC0,              //     End Collection
0xC0,              //   End Collection
0xC0,              // End Collection
Comment 6 Alex Szpakowski 2015-11-13 02:57:33 UTC
Oh wow. Those tools are super useful, I didn't know about that.

You were right, SDL's IOKit HID code wasn't set up to detect those usage page / usage combinations. I've pushed a fix: https://hg.libsdl.org/SDL/rev/628225876708

I don't have much experience with those APIs though, so perhaps the code could be further improved. :)

Thanks for the detailed reply!