Emscripten: Fixed out of range joystick device index after joystick disconnect.

After disconnecting a joystick the remaining kept their original device index.
This was not correct because the device index must be a number between 0 and
SDL_NumJoysticks(). It was fixed with ideas from SDL's joystick implementation
for Android. Some range checks were removed as the caller already checks them.
This commit is contained in:
Philipp Wiesemann 2015-02-22 23:21:32 +01:00
parent 5c43207fad
commit 8321efba33
1 changed files with 27 additions and 23 deletions

View File

@ -112,7 +112,7 @@ Emscripten_JoyStickConnected(int eventType, const EmscriptenGamepadEvent *gamepa
event.type = SDL_JOYDEVICEADDED; event.type = SDL_JOYDEVICEADDED;
if (SDL_GetEventState(event.type) == SDL_ENABLE) { if (SDL_GetEventState(event.type) == SDL_ENABLE) {
event.jdevice.which = item->index; event.jdevice.which = numjoysticks - 1;
if ( (SDL_EventOK == NULL) || if ( (SDL_EventOK == NULL) ||
(*SDL_EventOK) (SDL_EventOKParam, &event) ) { (*SDL_EventOK) (SDL_EventOKParam, &event) ) {
SDL_PushEvent(&event); SDL_PushEvent(&event);
@ -235,6 +235,21 @@ SDL_SYS_JoystickInit(void)
return 0; return 0;
} }
/* Returns item matching given SDL device index. */
static SDL_joylist_item *
JoystickByDeviceIndex(int device_index)
{
SDL_joylist_item *item = SDL_joylist;
while (0 < device_index) {
--device_index;
item = item->next;
}
return item;
}
/* Returns item matching given HTML gamepad index. */
static SDL_joylist_item * static SDL_joylist_item *
JoystickByIndex(int index) JoystickByIndex(int index)
{ {
@ -265,27 +280,15 @@ void SDL_SYS_JoystickDetect()
/* Function to get the device-dependent name of a joystick */ /* Function to get the device-dependent name of a joystick */
const char * const char *
SDL_SYS_JoystickNameForDeviceIndex(int index) SDL_SYS_JoystickNameForDeviceIndex(int device_index)
{ {
SDL_joylist_item *item = JoystickByIndex(index); return JoystickByDeviceIndex(device_index)->name;
if (item == NULL) {
SDL_SetError("Joystick with index %d not found", index);
return NULL;
}
return item->name;
} }
/* Function to perform the mapping from device index to the instance id for this index */ /* Function to perform the mapping from device index to the instance id for this index */
SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int index) SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int device_index)
{ {
SDL_joylist_item *item = JoystickByIndex(index); return JoystickByDeviceIndex(device_index)->device_instance;
if (item == NULL) {
SDL_SetError("Joystick with index %d not found", index);
return 0;
}
return item->device_instance;
} }
/* Function to open a joystick for use. /* Function to open a joystick for use.
@ -294,9 +297,9 @@ SDL_JoystickID SDL_SYS_GetInstanceIdOfDeviceIndex(int index)
It returns 0, or -1 if there is an error. It returns 0, or -1 if there is an error.
*/ */
int int
SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int index) SDL_SYS_JoystickOpen(SDL_Joystick * joystick, int device_index)
{ {
SDL_joylist_item *item = JoystickByIndex(index); SDL_joylist_item *item = JoystickByDeviceIndex(device_index);
if (item == NULL ) { if (item == NULL ) {
return SDL_SetError("No such device"); return SDL_SetError("No such device");
@ -405,18 +408,19 @@ SDL_SYS_JoystickQuit(void)
emscripten_set_gamepaddisconnected_callback(NULL, 0, NULL); emscripten_set_gamepaddisconnected_callback(NULL, 0, NULL);
} }
SDL_JoystickGUID SDL_SYS_JoystickGetDeviceGUID(int index) SDL_JoystickGUID
SDL_SYS_JoystickGetDeviceGUID(int device_index)
{ {
SDL_JoystickGUID guid; SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */ /* the GUID is just the first 16 chars of the name for now */
const char *name = SDL_SYS_JoystickNameForDeviceIndex(index); const char *name = SDL_SYS_JoystickNameForDeviceIndex(device_index);
SDL_zero(guid); SDL_zero(guid);
SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name))); SDL_memcpy(&guid, name, SDL_min(sizeof(guid), SDL_strlen(name)));
return guid; return guid;
} }
SDL_JoystickGUID
SDL_JoystickGUID SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick) SDL_SYS_JoystickGetGUID(SDL_Joystick * joystick)
{ {
SDL_JoystickGUID guid; SDL_JoystickGUID guid;
/* the GUID is just the first 16 chars of the name for now */ /* the GUID is just the first 16 chars of the name for now */