Skip to content
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

controller not properly supported after release-2.0.22 on macOS #8769

Open
markasbach opened this issue Jan 1, 2024 · 9 comments
Open

controller not properly supported after release-2.0.22 on macOS #8769

markasbach opened this issue Jan 1, 2024 · 9 comments
Assignees
Labels
Apple Apple is tracking this bug internally
Milestone

Comments

@markasbach
Copy link

Summary

I'm trying to get a USB dance mat to work with Project Outfox that uses a recent version of SDL2. When plugging in the controller, it is recognized as being present, but not button presses are seen. I could get it to work using the "SDL2 Gamepad Tool" using SDL version 2.0.7.

The original issue is filed as TeamRizu/OutFox#716

Now, I've dug into it and could narrow it down to changes between release-2.0.22 and release-2.24.0.

How to reproduce

I've written a small Python test script that will print events related to game pads and joysticks to stdout that I named sdl_gamepad_test.py:

#! /usr/bin/env python3

"""Simple test script for USB game pads and SDL2.

This script will run until the "arrow up" on the keyboard is pressed. It will print
messages for plugged and removed game pads and joysticks, and for button presses on those
game pads and joysticks.

2024-01-01, Mark Asbach
"""

import sdl2.ext

sdl2.ext.init(controller=True)
running=True
while running:
    events = sdl2.ext.get_events()
    for event in events:
        if event.type == sdl2.SDL_QUIT:
            running = False
            break
        elif event.type == sdl2.SDL_KEYDOWN:
            if event.key.keysym.sym == sdl2.SDLK_UP:
                running = False
        elif event.type == sdl2.SDL_CONTROLLERDEVICEADDED:
            print("Controller added")
            controller = sdl2.SDL_GameControllerOpen(event.cdevice.which)
        elif event.type == sdl2.SDL_JOYDEVICEADDED:
            print("Joystick added")
        elif event.type == sdl2.SDL_CONTROLLERDEVICEREMAPPED:
            print("Controller remapped")
        elif event.type == sdl2.SDL_CONTROLLERDEVICEREMOVED:
            print("Controller removed")
        elif event.type == sdl2.SDL_JOYDEVICEREMOVED:
            print("Joystick removed")
        elif event.type == sdl2.SDL_CONTROLLERBUTTONDOWN:
            print("Controller button down: " + str(event.cbutton.button))
        elif event.type == sdl2.SDL_CONTROLLERBUTTONUP:
            print("Controller button up: " + str(event.cbutton.button))
        elif event.type == sdl2.SDL_JOYBUTTONDOWN:
            print("Joystick button down: " + str(event.cbutton.button))
        elif event.type == sdl2.SDL_JOYBUTTONUP:
            print("Joystick button up: " + str(event.cbutton.button))
        else:
            print(event.type)
    sdl2.SDL_Delay(10)

These are the steps I do:

  1. Install a version of SDL2
  2. Start the script sdl_gamepad_test.py
  3. Plug in the dance mat
  4. Press start and up button on the dance mat
  5. Unplug the dance mat

Expected result

This is the (expected) result when trying the procedure above with SDL version 2.0.22.post1 :

 python3.10 -m pip install pysdl2 pysdl2-dll==2.0.22.post1 && python3.10 sdl_gamepad_test.py
UserWarning: Using SDL2 binaries from pysdl2-dll 2.0.22.post1
Controller added
Joystick added
Controller button down: 6
Joystick button down: 9
Controller button up: 6
Joystick button up: 9
Controller removed
Joystick removed

Actual result

This is the (buggy) result when trying the procedure above with SDL version 2.24.0 :

 python3.10 -m pip install pysdl2 pysdl2-dll==2.24.0 && python3.10 sdl_gamepad_test.py
UserWarning: Using SDL2 binaries from pysdl2-dll 2.24.0
Joystick added
Joystick removed

Additional info

I've got the following versions of SDL2 that I could test:

2.0.10, 2.0.12, 2.0.14, 2.0.14.post1, 2.0.14.post2, 2.0.16, 2.0.18, 2.0.20, 2.0.22, 2.0.22.post1, 2.24.0, 2.24.1, 2.24.2, 2.26.0, 2.26.1, 2.26.2, 2.26.5, 2.28.0, 2.28.2, 2.28.4, 2.28.5

These are the findings for versions newer that 2.0.22.post1:

  • 2.24.1, 2.24.2 all behave as described for 2.24.0 above
  • 2.26.0, 2.26.1', 2.26.2nearly behave as described for2.24.0above, but additionally showController removed`:
    UserWarning: Using SDL2 binaries from pysdl2-dll 2.26.2
    Joystick added
    Controller removed
    Joystick removed
    Joystick added
    Controller removed
    Joystick removed
    
  • 2.28.0, 2.28.2, 2.28.4, 2.28.5 nearly behave as described for 2.26.x above, but additionally crash with various strange errors when unplugging the dance mat:
    UserWarning: Using SDL2 binaries from pysdl2-dll 2.28.0
    Joystick added
    Controller removed
    Joystick removed
    Joystick added
    Controller removed
    Joystick removed
    zsh: segmentation fault  python3.10 sdl_gamepad_test.py
    

System information

The tests were run on an intel MacBook Pro 2017, using macOS Ventura 13.6.3 (22G436).

@slouken
Copy link
Collaborator

slouken commented Jan 1, 2024

I don't have a dance mat for testing. Are you able to debug using lldb on SDL testjoystick to see what's happening?

@markasbach
Copy link
Author

I could do so in the coming days and will update this ticket.

@markasbach
Copy link
Author

I'm doing all experiments on 8c9beb0c8.

Okay, so after getting to compile testjoystick.c with Xcode, I could dig a bit. I don't understand it fully, but it seems that based on some random (timing?) effects, the dance mat is found by SDL_iokitjoystick or not. Every time, though, the dance mat is found by SDL_mfijoystick. That explains why it is sometimes found twice by OutFox and by Python test code.

SDL_mfijoystick reports a device with nbuttons=0 and no other inputs - it is basically non-working. SDL_iokitjoystick reports nbuttons=10, axes=5 for my dance mat. That's the working device.

So, when I comment out the IOKit driver in SDL_joystick.c as follows (lines 72++), sometimes a plugged in joypad is not recognised at all, but if it is recognised, it will work:

#ifdef SDL_JOYSTICK_IOKIT
    &SDL_DARWIN_JoystickDriver,
#endif
//#if (defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__)) && !defined(SDL_JOYSTICK_DISABLED)
//    &SDL_IOS_JoystickDriver,
//#endif

Can someone here make any sense out of this and/or help me fix the issue?

An unrelated remark: The output on testjoystick.c about event.jdevice.which is strange. When SDL_JOYDEVICEADDED gets reported, the number is typically 0 (after I commented out mfijoystick), but the numbers reported by SDL_JOYDEVICEREMOVED and the SDL_JoystickInstanceID(joy) are incrementing with every unplug/replug cycle.

@slouken
Copy link
Collaborator

slouken commented Jan 18, 2024

SDL_mfijoystick reports a device with nbuttons=0 and no other inputs - it is basically non-working. SDL_iokitjoystick reports nbuttons=10, axes=5 for my dance mat. That's the working device.

I think in your case, you just need to disable the MFi joystick driver. What's happening is that GCController is reporting that the dance mat is handled by that driver but then doesn't actually know how to handle it.

You can disable it by setting the environment variable SDL_JOYSTICK_MFI=1

An unrelated remark: The output on testjoystick.c about event.jdevice.which is strange. When SDL_JOYDEVICEADDED gets reported, the number is typically 0 (after I commented out mfijoystick), but the numbers reported by SDL_JOYDEVICEREMOVED and the SDL_JoystickInstanceID(joy) are incrementing with every unplug/replug cycle.

SDL_JOYDEVICEADDED reports indices, the other APIs report instance IDs. This is fixed in SDL3 where instance IDs are used in all cases.

I'll leave this open for now, but short of somebody from Apple stopping by and letting us know they have a fix, I don't think there's anything we can do.

@slouken slouken added the Apple Apple is tracking this bug internally label Jan 18, 2024
@slouken
Copy link
Collaborator

slouken commented Jan 18, 2024

Actually, I just double checked and we've done a bunch of MFi driver improvements since the version you're testing. Can you update to the latest SDL2 code and check that?

@markasbach
Copy link
Author

I've done so, but (please compare my tests from Python) there was little further insight I could gain:

As described above, tag 2.28.5 crashes randomly but frequently when plugging, unplugging, even when doing nothing while the device is plugged. There is something deeply broken in respect to Cocoa event handling in newer versions at it looks like. You can see that from my reports gathered using the Python module. Strangely, I've got a Logitech Gamepad F310 that will not trigger any crashes when plugged.

Regarding the actual issue here, support for my dance mat: in contrast to 8c9beb0c8, no SDL_iokitjoystick picks up the device, but the SDL_mfijoystick always reports the device back, but with 0 buttons, 0 axes, etc.

I've looked at git diff -r 8c9beb0c8 src/joystick/darwin/SDL_iokitjoystick.c and there are mostly formatting changes, just one functional change: GetDeviceInfo() has been slightly modified. Maybe I'll have some time on the weekend to check if that change leads to SDL_iokitjoystick not picking it up. That would still mean, I'd have to disable the MFi driver when trying to use this dance mat. The Logitech Gamepad F310, though, is picked up by exactly that MFi driver. So it seems the issue is routed somewhere deep in the code (that does not have too many lines ...).

Not sure what direction I could look into to take this further.

@slouken
Copy link
Collaborator

slouken commented Jan 18, 2024

Can you post an Amazon link? Maybe I can pick up that dance mat and investigate further. I also haven't seen any crashes, so I'm not sure if it's specific to that device or a general problem.

@markasbach
Copy link
Author

Can you post an Amazon link? Maybe I can pick up that dance mat and investigate further.

It's this one: https://www.amazon.de/dp/B00FJ2KTXC/

@slouken
Copy link
Collaborator

slouken commented Mar 3, 2024

Okay, I bought this mat, I should get it in a month or so and will take a look.

@slouken slouken added this to the 2.32.0 milestone Mar 3, 2024
@slouken slouken self-assigned this Mar 3, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Apple Apple is tracking this bug internally
Projects
None yet
Development

No branches or pull requests

2 participants