-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SDL_JoystickSetVirtualAxis handles triggers oddly #6130
Comments
Triggers are actually not handled any differently than other axes in SDL2, but you're expecting them to be, which is the cause of confusion. For what it's worth, using only half the axis range for triggers (and analog buttons) makes a lot of sense, which is why the game controller API exposes it that way. I'll add a note to the documentation, thanks! |
BTW, is there a way to get the HIDAPI driver working for Xbox controllers on macOS? The Xbox controllers aren't HID devices, so they don't show up in the normal device filter... |
I've never looked at SDL's HIDAPI internals, but the 360 controller (and its 3rd party variants) all follow a common protocol that's pretty simple to handle with libusb (what my code is using, via pyusb). There's a pretty good explanation/documentation of the USB interface for these controllers here: https://www.partsnotincluded.com/understanding-the-xbox-360-wired-controllers-usb-data/ No clue how easy that would be to graft on to the existing HIDAPI code, but it would be great if it was possible! |
The existing HIDAPI code already supports the 360 controller, I just haven't been able to get at the USB device on macOS. Using hidapi, the controller is never enumerated, and using libusb, the controller is in use by a kernel driver and can't be detached. |
The code from the (now discontinued) 360Controller driver for macOS might be helpful here: https://github.com/360Controller/360Controller/blob/d6290c7969dd4b89eeed3f0162a516e4c6e5115c/360Daemon/360Daemon.m#L306 In SDL_hidapi.c, the bit responsible for finding/filtering HID devices on macOS seems to be this bit here: Lines 252 to 261 in 3d516b8
In the 360Controller code, they seemingly have two codepaths for USB controllers: either they use Alternatively, it looks like you can replace |
So I've built libusb, and it can see the controllers, but it looks like at least on macOS 10.12 that another kernel driver has the device locked so userspace applications can't open it. |
Do you have the 360Controller kext installed by any chance? On Monterey, all I have to do with PyUSB (Python wrapper around libusb-1) to interface with the controller is a) find the device based on pid/vid, b) claim the interface for the device, and c) set the configuration of the device to its first. Maybe it's something that recently changed in macOS? I've got some older machines with 10.11 and 10.14 handy, I can see if my code works any different on those versions. |
No, I don't have the kext installed. For me, claiming the interface fails. |
Isn't libusb able to detach kernel drivers for a device in user space? I based my code off an older PyUSB script written for macOS circa ~10.12 and it had a little if-statement that checked for/detached an attached kernel driver for the controller (seemingly without any special permissions). Could very well be necessary on older macOS releases. |
Yes, and the detach fails here. |
Just tested my PyUSB script on macOS 10.14, it works and reads input events from the controller just the same as on Monterey. However, on my 10.11 machine it errors out when I try to claim the interface, same as you. Looks like something changed in 10.13 or 10.14, then? EDIT: Disregard that, the libusb binary I was using on my 10.11 machine was problematic. Switching to brew's binary (libusb 1.0.22, a few versions old since |
I updated macOS to 12.5.1 and it's working correctly for me now. :) |
Hi all,
Yesterday I managed to set up an SDL virtual joystick as a bridge between SDL2 and the raw USB packet data from a wired 360 controller (macOS doesn't have a driver for it, and the popular 3rd-party driver no longer works right on Monterey), which means parsing the button/axis events from the controller and sending them to a virtual controller in SDL2.
In the process, I noticed something a little odd: in SDL2, trigger values are always reported as being between 0 (not pressed at all) and 32767 (pressed all the way). However, if I run the following:
value
becomes 16384 instead of 0. To set the virtual trigger properly, I need to scale the input toSDL_JoystickSetVirtualAxis
to the full range of Sint16 (with 0 being -32768 and the midpoint being 0), after which it works properly.I understand that SDL joysticks themselves don't have a concept of a "trigger axis" versus any other type of axis so I get why this might be tricky to handle on the backend, but this behaviour is still pretty unexpected. If there's no nicer way to handle this in terms of API, this quirk should at least be documented in the Wiki/docstring for the function to reduce future confusion.
Thanks in advance!
EDIT: Maybe an
SDL_JoystickSetVirtualTrigger
function that respects the normal limits for trigger axes? Would avoid breaking API with anyone currently usingSDL_JoystickSetVirtualAxis
for triggers, and respect that triggers are handled a bit differently than other axes in SDL2.The text was updated successfully, but these errors were encountered: