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

Allow SDL joysticks to be reconfigured after init #1326

Merged
merged 1 commit into from
Apr 10, 2022

Conversation

connorjclark
Copy link
Contributor

Currently joysticks do not work with programs built with emscripten+SDL backend. You can verify this by trying to use a gamepad with the joystick events example here.

The SDL joystick code reads the number of joysticks connected on init, keeping track of the number found in a count variable. If a new controller connects, SDL emits an event, but currently the event handling code ignores all events if on init it found zero controllers.

On the web, the gamepadconnected event only fires after the first input on the controller. This means that on the web, SDL will have zero controllers on setup... unless you happen to be twiddling the controller inputs on setup. The example above initializes too quickly to see this behavior, but it was the first thing I noticed while debugging this issue in my (more setup-intensive) application: controllers only worked if I was twiddling the controller during setup.

The fix is:

  1. Don't ignore events if allegro doesn't yet know about any controllers. After all, one of those events is "new controller connected"!
  2. Call sdl_reconfigure_joysticks when a controller connects or disconnects

I confirmed this patch works for my application and for the above example:
image

@beoran
Copy link
Contributor

beoran commented Apr 9, 2022

Thanks for this patch. I wonder what that count variable was supposed to do. Could you please confirm there are no unintended side effects of removing this count check?

@connorjclark
Copy link
Contributor Author

connorjclark commented Apr 10, 2022

Nothing seems to have broken for me, with 0 joysticks or 1 connected. However, I only own a single gamepad so I can't test the more complex cases of multiple gamepads and them being reconfigured in an expected manner on connect/disconnects.

I'll test more thoroughly that disconnecting and reconnecting the one joystick works.

@beoran
Copy link
Contributor

beoran commented Apr 10, 2022

That would be great, thanks. If you could buy or borrow a second joypad or joystick, that would even be better. They are relatively cheap these days.

@SiegeLord
Copy link
Member

I should be able to test with multiple controllers.

@@ -83,6 +82,7 @@ void _al_sdl_joystick_event(SDL_Event *e)
}
else if (e->type == SDL_JOYDEVICEADDED || e->type == SDL_JOYDEVICEREMOVED) {
event.joystick.type = ALLEGRO_EVENT_JOYSTICK_CONFIGURATION;
sdl_reconfigure_joysticks();
Copy link
Contributor Author

@connorjclark connorjclark Apr 10, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looking at ex_joystick_hotplugging it seems the expectation is that programs should decide themselves to reconfigure. If so, should this line be removed (and any program that needs to should call al_reconfigure_joysticks on event ALLEGRO_EVENT_JOYSTICK_CONFIGURATION themselves?)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, so does ex_joystick_events. OK, this line probably doesn't belong here.

@@ -97,7 +94,7 @@ void _al_sdl_joystick_event(SDL_Event *e)
static bool sdl_init_joystick(void)
{
count = SDL_NumJoysticks();
joysticks = calloc(count, sizeof * joysticks);
joysticks = count > 0 ? calloc(count, sizeof * joysticks) : NULL;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my testing I got errors when going from 1 -> 0 controllers because although joysticks was being freed in sdl_exit_joystick, this line here would have a count of zero and I noticed joysticks[0] still had a pointer to (free'd) data. calloc has odd behavior when size is zero. To fix, manually set to NULL when size is zero.

Also, set joysticks to NULL after freeing for good measure.

@connorjclark connorjclark changed the title Reconfigure SDL joysticks when device is added or removed Allow SDL joysticks to be reconfigured after init Apr 10, 2022
@connorjclark
Copy link
Contributor Author

I confirmed that going from 0->1 and 1->0 controllers works as expected in the demos. @SiegeLord I've uploaded emscripten builds for your convenience:

https://comfortable-badge.surge.sh/ex_joystick_events.html

https://comfortable-badge.surge.sh/ex_joystick_hotplugging.html

@SiegeLord
Copy link
Member

Seems to work fine with two controller as well. Thanks for the change!

@SiegeLord SiegeLord merged commit 7840b64 into liballeg:master Apr 10, 2022
@beoran
Copy link
Contributor

beoran commented Apr 10, 2022

Indeed, thank you very much for your extra tests and for
contributing!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants