Possible game controller event bug in SDL2.0.3

Hi all, I’d appreciate some help with this issue I’ve encountered in SDL 2.0.3 with game controller events. The issue is that after disconnecting and reconnecting a game controller, subsequent events generated for that controller have the wrong joystick index. This appears to be a bug, but it’s possible I’ve misunderstood something. Assistance would be appreciated.

Reproduction steps:

  1. Connect a game controller and start the application, or connect a game controller while running the application (both cases produce the same result).
  2. Handle the event SDL_CONTROLLERDEVICEADDED and note the joystick device index given by SDL_Event::cdevice.which.
  3. Generate input events by using the device (such as SDL_CONTROLLERBUTTONDOWN) and note the joystick device index given by (for example) SDL_Event::cbutton.which. Observe that the index matches the one noted in step 2.
  4. Disconnect the device.
  5. Handle the event SDL_CONTROLLERDEVICEREMOVED and note the joystick device index given by SDL_Event::cdevice.which.
  6. Reconnect the device.
  7. Handle the event SDL_CONTROLLERDEVICEADDED and note the joystick device index given by SDL_Event::cdevice.which.
  8. Generate input events by using the device (such as SDL_CONTROLLERBUTTONDOWN) and note the joystick device index given by (for example) SDL_Event::cbutton.which. Observe that the index does not match the one noted in step 7.

Thanks in advance.

Also, I should point out that I’ve so far only tested this on Windows, in case the issue is platform-specific.

OK, I believe I’ve solved the issue and it looks like it was indeed in my understanding. This is a gotcha that might help anyone else getting started with SDL game controllers.

The “which” member in the relevant event structure has a different meaning for SDL_CONTROLLERDEVICEADDED than for SDL_CONTROLLERDEVICEREMOVED and controller input events such as SDL_CONTROLLERBUTTONDOWN. For SDL_CONTROLLERDEVICEADDED, it describes an index into the list of active devices, not the actual joystick ID (SDL_JoystickInstanceID) which is the meaning of the value for those other events.

The “which” member in the relevant event structure has a different
meaning for SDL_CONTROLLERDEVICEADDED than for
SDL_CONTROLLERDEVICEREMOVED and controller input events such as
SDL_CONTROLLERBUTTONDOWN. For SDL_CONTROLLERDEVICEADDED, it describes an
index into the list of active devices, not the actual joystick ID
(SDL_JoystickInstanceID) which is the meaning of the value for those
other events.

We should document this better (and probably change the API for 2.1 to
be more clear)…it’s a very common misunderstanding.

–ryan.