Update in-flight SDL_CONTROLLERDEVICEADDED messages when a device is removed

This fixes the application trying to open the wrong device index when a device is removed and another has just been added
This commit is contained in:
Sam Lantinga 2022-08-03 19:39:37 -07:00
parent 5d50fa52df
commit ea7fbf7947
1 changed files with 29 additions and 10 deletions

View File

@ -1331,13 +1331,13 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID device_instance)
* to have the right value for which, because the number of controllers in * to have the right value for which, because the number of controllers in
* the system is now one less. * the system is now one less.
*/ */
static void UpdateEventsForDeviceRemoval(int device_index) static void UpdateEventsForDeviceRemoval(int device_index, Uint32 type)
{ {
int i, num_events; int i, num_events;
SDL_Event *events; SDL_Event *events;
SDL_bool isstack; SDL_bool isstack;
num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED); num_events = SDL_PeepEvents(NULL, 0, SDL_PEEKEVENT, type, type);
if (num_events <= 0) { if (num_events <= 0) {
return; return;
} }
@ -1347,20 +1347,38 @@ static void UpdateEventsForDeviceRemoval(int device_index)
return; return;
} }
num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, SDL_JOYDEVICEADDED, SDL_JOYDEVICEADDED); num_events = SDL_PeepEvents(events, num_events, SDL_GETEVENT, type, type);
for (i = 0; i < num_events; ++i) { for (i = 0; i < num_events; ++i) {
if (events[i].cdevice.which < device_index) { Sint32 which = -1;
/* No change for index values lower than the removed device */ switch (type) {
case SDL_JOYDEVICEADDED:
which = events[i].jdevice.which;
break;
case SDL_CONTROLLERDEVICEADDED:
which = events[i].cdevice.which;
break;
default:
break;
} }
else if (events[i].cdevice.which == device_index) { if (which < device_index) {
/* No change for index values lower than the removed device */
} else if (which == device_index) {
/* Drop this event entirely */ /* Drop this event entirely */
SDL_memmove(&events[i], &events[i + 1], sizeof(*events) * (num_events - (i + 1))); SDL_memmove(&events[i], &events[i + 1], sizeof(*events) * (num_events - (i + 1)));
--num_events; --num_events;
--i; --i;
} } else {
else {
/* Fix up the device index if greater than the removed device */ /* Fix up the device index if greater than the removed device */
switch (type) {
case SDL_JOYDEVICEADDED:
--events[i].jdevice.which;
break;
case SDL_CONTROLLERDEVICEADDED:
--events[i].cdevice.which; --events[i].cdevice.which;
break;
default:
break;
}
} }
} }
SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0); SDL_PeepEvents(events, num_events, SDL_ADDEVENT, 0, 0);
@ -1427,7 +1445,8 @@ void SDL_PrivateJoystickRemoved(SDL_JoystickID device_instance)
SDL_PushEvent(&event); SDL_PushEvent(&event);
} }
UpdateEventsForDeviceRemoval(device_index); UpdateEventsForDeviceRemoval(device_index, SDL_JOYDEVICEADDED);
UpdateEventsForDeviceRemoval(device_index, SDL_CONTROLLERDEVICEADDED);
#endif /* !SDL_EVENTS_DISABLED */ #endif /* !SDL_EVENTS_DISABLED */
SDL_LockJoysticks(); SDL_LockJoysticks();