From 0c5e7a1067e78fb50fb8c1beaca7b06b3ee9325b Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 15 Dec 2016 14:27:22 -0800 Subject: [PATCH] Fixed handling joysticks that send multiple events for a single control, e.g. both a button and axis event for a trigger. Tested with the 8Bitdo NES30 Pro on Linux --- test/controllermap.c | 494 ++++++++++++++++++++++++++----------------- 1 file changed, 304 insertions(+), 190 deletions(-) diff --git a/test/controllermap.c b/test/controllermap.c index 30d88ce55ce68..6ea20a24835b4 100644 --- a/test/controllermap.c +++ b/test/controllermap.c @@ -32,16 +32,66 @@ #define MARKER_BUTTON 1 #define MARKER_AXIS 2 -typedef struct MappingStep +#define BINDING_COUNT (SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_AXIS_MAX) + +static struct { int x, y; double angle; int marker; - char *field; - int axis, button, hat, hat_value; - char mapping[4096]; -}MappingStep; +} s_arrBindingDisplay[BINDING_COUNT] = { + { 387, 167, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_A */ + { 431, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_B */ + { 342, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_X */ + { 389, 101, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_Y */ + { 174, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_BACK */ + { 233, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_GUIDE */ + { 289, 132, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_START */ + { 75, 154, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_LEFTSTICK */ + { 305, 230, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_RIGHTSTICK */ + { 77, 40, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_LEFTSHOULDER */ + { 396, 36, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_RIGHTSHOULDER */ + { 154, 188, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_UP */ + { 154, 249, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_DOWN */ + { 116, 217, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_LEFT */ + { 186, 217, 0.0, MARKER_BUTTON }, /* SDL_CONTROLLER_BUTTON_DPAD_RIGHT */ + { 75, 154, 0.0, MARKER_AXIS }, /* SDL_CONTROLLER_AXIS_LEFTX */ + { 75, 154, 90.0, MARKER_AXIS }, /* SDL_CONTROLLER_AXIS_LEFTY */ + { 305, 230, 0.0, MARKER_AXIS }, /* SDL_CONTROLLER_AXIS_RIGHTX */ + { 305, 230, 90.0, MARKER_AXIS }, /* SDL_CONTROLLER_AXIS_RIGHTY */ + { 91, 0, 90.0, MARKER_AXIS }, /* SDL_CONTROLLER_AXIS_TRIGGERLEFT */ + { 375, 0, 90.0, MARKER_AXIS }, /* SDL_CONTROLLER_AXIS_TRIGGERRIGHT */ +}; + +static int s_arrBindingOrder[BINDING_COUNT] = { + SDL_CONTROLLER_BUTTON_A, + SDL_CONTROLLER_BUTTON_B, + SDL_CONTROLLER_BUTTON_Y, + SDL_CONTROLLER_BUTTON_X, + SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_AXIS_LEFTX, + SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_AXIS_LEFTY, + SDL_CONTROLLER_BUTTON_LEFTSTICK, + SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_AXIS_RIGHTX, + SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_AXIS_RIGHTY, + SDL_CONTROLLER_BUTTON_RIGHTSTICK, + SDL_CONTROLLER_BUTTON_LEFTSHOULDER, + SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_AXIS_TRIGGERLEFT, + SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, + SDL_CONTROLLER_BUTTON_MAX + SDL_CONTROLLER_AXIS_TRIGGERRIGHT, + SDL_CONTROLLER_BUTTON_DPAD_UP, + SDL_CONTROLLER_BUTTON_DPAD_RIGHT, + SDL_CONTROLLER_BUTTON_DPAD_DOWN, + SDL_CONTROLLER_BUTTON_DPAD_LEFT, + SDL_CONTROLLER_BUTTON_BACK, + SDL_CONTROLLER_BUTTON_GUIDE, + SDL_CONTROLLER_BUTTON_START, +}; + +static SDL_GameControllerButtonBind s_arrBindings[BINDING_COUNT]; +static int s_iCurrentBinding; +static Uint32 s_unPendingAdvanceTime; +static SDL_bool s_bBindingComplete; SDL_Texture * LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) @@ -93,45 +143,99 @@ LoadTexture(SDL_Renderer *renderer, const char *file, SDL_bool transparent) return texture; } -static SDL_bool +void SetCurrentBinding(int iBinding) +{ + SDL_GameControllerButtonBind *pBinding; + + if (iBinding < 0) { + return; + } + + if (iBinding == BINDING_COUNT) { + s_bBindingComplete = SDL_TRUE; + return; + } + + s_iCurrentBinding = iBinding; + + pBinding = &s_arrBindings[s_arrBindingOrder[s_iCurrentBinding]]; + SDL_zerop(pBinding); + + s_unPendingAdvanceTime = 0; +} + + +static void +ConfigureBinding(const SDL_GameControllerButtonBind *pBinding) +{ + SDL_GameControllerButtonBind *pCurrent; + int iIndex; + int iCurrentElement = s_arrBindingOrder[s_iCurrentBinding]; + + /* Do we already have this binding? */ + for (iIndex = 0; iIndex < SDL_arraysize(s_arrBindings); ++iIndex) { + if (SDL_memcmp(pBinding, &s_arrBindings[iIndex], sizeof(*pBinding)) == 0) { + if (iIndex == SDL_CONTROLLER_BUTTON_A && iCurrentElement != SDL_CONTROLLER_BUTTON_B) { + /* Skip to the next binding */ + SetCurrentBinding(s_iCurrentBinding + 1); + return; + } + + if (iIndex == SDL_CONTROLLER_BUTTON_B) { + /* Go back to the previous binding */ + SetCurrentBinding(s_iCurrentBinding - 1); + return; + } + + /* Already have this binding, ignore it */ + return; + } + } + + /* Should the new binding override the existing one? */ + pCurrent = &s_arrBindings[iCurrentElement]; + if (pCurrent->bindType != SDL_CONTROLLER_BINDTYPE_NONE) { + SDL_bool bNativeDPad, bCurrentDPad; + SDL_bool bNativeAxis, bCurrentAxis; + + bNativeDPad = (iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_UP || + iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_DOWN || + iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_LEFT || + iCurrentElement == SDL_CONTROLLER_BUTTON_DPAD_RIGHT); + bCurrentDPad = (pCurrent->bindType == SDL_CONTROLLER_BINDTYPE_HAT); + if (bNativeDPad == bCurrentDPad) { + /* We already have a binding of the type we want, ignore the new one */ + return; + } + + bNativeAxis = (iCurrentElement >= SDL_CONTROLLER_BUTTON_MAX); + bCurrentAxis = (pCurrent->bindType == SDL_CONTROLLER_BINDTYPE_AXIS); + if (bNativeAxis == bCurrentAxis) { + /* We already have a binding of the type we want, ignore the new one */ + return; + } + } + + *pCurrent = *pBinding; + + s_unPendingAdvanceTime = SDL_GetTicks(); +} + +static void WatchJoystick(SDL_Joystick * joystick) { SDL_Window *window = NULL; SDL_Renderer *screen = NULL; SDL_Texture *background, *button, *axis, *marker; const char *name = NULL; - SDL_bool retval = SDL_FALSE; - SDL_bool done = SDL_FALSE, next=SDL_FALSE; + SDL_bool done = SDL_FALSE; SDL_Event event; SDL_Rect dst; - int s, _s; Uint8 alpha=200, alpha_step = -1; Uint32 alpha_ticks = 0; - char mapping[4096], temp[4096]; - MappingStep *step, *prev_step; - MappingStep steps[] = { - {342, 132, 0.0, MARKER_BUTTON, "x", -1, -1, -1, -1, ""}, - {387, 167, 0.0, MARKER_BUTTON, "a", -1, -1, -1, -1, ""}, - {431, 132, 0.0, MARKER_BUTTON, "b", -1, -1, -1, -1, ""}, - {389, 101, 0.0, MARKER_BUTTON, "y", -1, -1, -1, -1, ""}, - {174, 132, 0.0, MARKER_BUTTON, "back", -1, -1, -1, -1, ""}, - {233, 132, 0.0, MARKER_BUTTON, "guide", -1, -1, -1, -1, ""}, - {289, 132, 0.0, MARKER_BUTTON, "start", -1, -1, -1, -1, ""}, - {116, 217, 0.0, MARKER_BUTTON, "dpleft", -1, -1, -1, -1, ""}, - {154, 249, 0.0, MARKER_BUTTON, "dpdown", -1, -1, -1, -1, ""}, - {186, 217, 0.0, MARKER_BUTTON, "dpright", -1, -1, -1, -1, ""}, - {154, 188, 0.0, MARKER_BUTTON, "dpup", -1, -1, -1, -1, ""}, - {77, 40, 0.0, MARKER_BUTTON, "leftshoulder", -1, -1, -1, -1, ""}, - {91, 0, 0.0, MARKER_BUTTON, "lefttrigger", -1, -1, -1, -1, ""}, - {396, 36, 0.0, MARKER_BUTTON, "rightshoulder", -1, -1, -1, -1, ""}, - {375, 0, 0.0, MARKER_BUTTON, "righttrigger", -1, -1, -1, -1, ""}, - {75, 154, 0.0, MARKER_BUTTON, "leftstick", -1, -1, -1, -1, ""}, - {305, 230, 0.0, MARKER_BUTTON, "rightstick", -1, -1, -1, -1, ""}, - {75, 154, 0.0, MARKER_AXIS, "leftx", -1, -1, -1, -1, ""}, - {75, 154, 90.0, MARKER_AXIS, "lefty", -1, -1, -1, -1, ""}, - {305, 230, 0.0, MARKER_AXIS, "rightx", -1, -1, -1, -1, ""}, - {305, 230, 90.0, MARKER_AXIS, "righty", -1, -1, -1, -1, ""}, - }; + Uint32 bound_ticks = 0; + SDL_JoystickID nJoystickID; + Uint32 unDeflectedAxes = 0; /* Create a window to display joystick axis position */ window = SDL_CreateWindow("Game Controller Map", SDL_WINDOWPOS_CENTERED, @@ -139,14 +243,14 @@ WatchJoystick(SDL_Joystick * joystick) SCREEN_HEIGHT, 0); if (window == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window: %s\n", SDL_GetError()); - return SDL_FALSE; + return; } screen = SDL_CreateRenderer(window, -1, 0); if (screen == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create renderer: %s\n", SDL_GetError()); SDL_DestroyWindow(window); - return SDL_FALSE; + return; } background = LoadTexture(screen, "controllermap.bmp", SDL_FALSE); @@ -173,23 +277,14 @@ WatchJoystick(SDL_Joystick * joystick) To skip a button, press SPACE or click/touch the screen\n\ To exit, press ESC\n\ ====================================================================================\n"); - - /* Initialize mapping with GUID and name */ - SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), temp, SDL_arraysize(temp)); - SDL_snprintf(mapping, SDL_arraysize(mapping), "%s,%s,platform:%s,", - temp, name ? name : "Unknown Joystick", SDL_GetPlatform()); + + nJoystickID = SDL_JoystickInstanceID(joystick); /* Loop, getting joystick events! */ - for(s=0; smapping, mapping, SDL_arraysize(step->mapping)); - step->axis = -1; - step->button = -1; - step->hat = -1; - step->hat_value = -1; - - switch(step->marker) { + while (!done && !s_bBindingComplete) { + int iElement = s_arrBindingOrder[s_iCurrentBinding]; + + switch (s_arrBindingDisplay[iElement].marker) { case MARKER_AXIS: marker = axis; break; @@ -200,137 +295,182 @@ WatchJoystick(SDL_Joystick * joystick) break; } - dst.x = step->x; - dst.y = step->y; + dst.x = s_arrBindingDisplay[iElement].x; + dst.y = s_arrBindingDisplay[iElement].y; SDL_QueryTexture(marker, NULL, NULL, &dst.w, &dst.h); - next=SDL_FALSE; - - SDL_SetRenderDrawColor(screen, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE); - while (!done && !next) { - if (SDL_GetTicks() - alpha_ticks > 5) { - alpha_ticks = SDL_GetTicks(); - alpha += alpha_step; - if (alpha == 255) { - alpha_step = -1; - } - if (alpha < 128) { - alpha_step = 1; - } + if (SDL_GetTicks() - alpha_ticks > 5) { + alpha_ticks = SDL_GetTicks(); + alpha += alpha_step; + if (alpha == 255) { + alpha_step = -1; } + if (alpha < 128) { + alpha_step = 1; + } + } + + SDL_SetRenderDrawColor(screen, 0xFF, 0xFF, 0xFF, SDL_ALPHA_OPAQUE); + SDL_RenderClear(screen); + SDL_RenderCopy(screen, background, NULL, NULL); + SDL_SetTextureAlphaMod(marker, alpha); + SDL_SetTextureColorMod(marker, 10, 255, 21); + SDL_RenderCopyEx(screen, marker, NULL, &dst, s_arrBindingDisplay[iElement].angle, NULL, SDL_FLIP_NONE); + SDL_RenderPresent(screen); - SDL_RenderClear(screen); - SDL_RenderCopy(screen, background, NULL, NULL); - SDL_SetTextureAlphaMod(marker, alpha); - SDL_SetTextureColorMod(marker, 10, 255, 21); - SDL_RenderCopyEx(screen, marker, NULL, &dst, step->angle, NULL, SDL_FLIP_NONE); - SDL_RenderPresent(screen); - - if (SDL_PollEvent(&event)) { - switch (event.type) { - case SDL_JOYAXISMOTION: - if ((event.jaxis.value > 20000 || event.jaxis.value < -20000) && event.jaxis.value != -32768) { - for (_s = 0; _s < s; _s++) { - if (steps[_s].axis == event.jaxis.axis) { - break; - } - } - if (_s == s) { - step->axis = event.jaxis.axis; - SDL_strlcat(mapping, step->field, SDL_arraysize(mapping)); - SDL_snprintf(temp, SDL_arraysize(temp), ":a%u,", event.jaxis.axis); - SDL_strlcat(mapping, temp, SDL_arraysize(mapping)); - s++; - next=SDL_TRUE; - } + while (SDL_PollEvent(&event) > 0) { + switch (event.type) { + case SDL_JOYDEVICEREMOVED: + if (event.jaxis.which == nJoystickID) { + done = SDL_TRUE; + } + break; + case SDL_JOYAXISMOTION: + if (event.jaxis.which == nJoystickID) { + uint32_t unAxisMask = (1 << event.jaxis.axis); + SDL_bool bDeflected = (event.jaxis.value <= -20000 || event.jaxis.value >= 20000); + if (bDeflected && !(unDeflectedAxes & unAxisMask)) { + SDL_GameControllerButtonBind binding; + SDL_zero(binding); + binding.bindType = SDL_CONTROLLER_BINDTYPE_AXIS; + binding.value.axis = event.jaxis.axis; + ConfigureBinding(&binding); } - - break; - case SDL_JOYHATMOTION: - if (event.jhat.value == SDL_HAT_CENTERED) { - break; /* ignore centering, we're probably just coming back to the center from the previous item we set. */ - } - for (_s = 0; _s < s; _s++) { - if (steps[_s].hat == event.jhat.hat && steps[_s].hat_value == event.jhat.value) { - break; - } - } - if (_s == s) { - step->hat = event.jhat.hat; - step->hat_value = event.jhat.value; - SDL_strlcat(mapping, step->field, SDL_arraysize(mapping)); - SDL_snprintf(temp, SDL_arraysize(temp), ":h%u.%u,", event.jhat.hat, event.jhat.value ); - SDL_strlcat(mapping, temp, SDL_arraysize(mapping)); - s++; - next=SDL_TRUE; - } - break; - case SDL_JOYBALLMOTION: - break; - case SDL_JOYBUTTONUP: - for (_s = 0; _s < s; _s++) { - if (steps[_s].button == event.jbutton.button) { - break; - } + if (bDeflected) { + unDeflectedAxes |= unAxisMask; + } else { + unDeflectedAxes &= ~unAxisMask; } - if (_s == s) { - step->button = event.jbutton.button; - SDL_strlcat(mapping, step->field, SDL_arraysize(mapping)); - SDL_snprintf(temp, SDL_arraysize(temp), ":b%u,", event.jbutton.button); - SDL_strlcat(mapping, temp, SDL_arraysize(mapping)); - s++; - next=SDL_TRUE; + } + break; + case SDL_JOYHATMOTION: + if (event.jhat.which == nJoystickID) { + if (event.jhat.value != SDL_HAT_CENTERED) { + SDL_GameControllerButtonBind binding; + SDL_zero(binding); + binding.bindType = SDL_CONTROLLER_BINDTYPE_HAT; + binding.value.hat.hat = event.jhat.hat; + binding.value.hat.hat_mask = event.jhat.value; + ConfigureBinding(&binding); } + } + break; + case SDL_JOYBALLMOTION: + break; + case SDL_JOYBUTTONDOWN: + if (event.jbutton.which == nJoystickID) { + SDL_GameControllerButtonBind binding; + SDL_zero(binding); + binding.bindType = SDL_CONTROLLER_BINDTYPE_BUTTON; + binding.value.button = event.jbutton.button; + ConfigureBinding(&binding); + } + break; + case SDL_FINGERDOWN: + case SDL_MOUSEBUTTONDOWN: + /* Skip this step */ + SetCurrentBinding(s_iCurrentBinding + 1); + break; + case SDL_KEYDOWN: + if (event.key.keysym.sym == SDLK_BACKSPACE || event.key.keysym.sym == SDLK_AC_BACK) { + SetCurrentBinding(s_iCurrentBinding - 1); break; - case SDL_FINGERDOWN: - case SDL_MOUSEBUTTONDOWN: - /* Skip this step */ - s++; - next=SDL_TRUE; - break; - case SDL_KEYDOWN: - if (event.key.keysym.sym == SDLK_BACKSPACE || event.key.keysym.sym == SDLK_AC_BACK) { - /* Undo! */ - if (s > 0) { - prev_step = &steps[--s]; - SDL_strlcpy(mapping, prev_step->mapping, SDL_arraysize(prev_step->mapping)); - next = SDL_TRUE; - } - break; - } - if (event.key.keysym.sym == SDLK_SPACE) { - /* Skip this step */ - s++; - next=SDL_TRUE; - break; - } - - if ((event.key.keysym.sym != SDLK_ESCAPE)) { - break; - } - /* Fall through to signal quit */ - case SDL_QUIT: - done = SDL_TRUE; + } + if (event.key.keysym.sym == SDLK_SPACE) { + SetCurrentBinding(s_iCurrentBinding + 1); break; - default: + } + + if ((event.key.keysym.sym != SDLK_ESCAPE)) { break; } + /* Fall through to signal quit */ + case SDL_QUIT: + done = SDL_TRUE; + break; + default: + break; } } + SDL_Delay(15); + + /* Wait 100 ms for joystick events to stop coming in, + in case a controller sends multiple events for a single control (e.g. axis and button for trigger) + */ + if (s_unPendingAdvanceTime && SDL_GetTicks() - s_unPendingAdvanceTime >= 100) { + SetCurrentBinding(s_iCurrentBinding + 1); + } } - if (s == SDL_arraysize(steps) ) { + if (s_bBindingComplete) { + char mapping[1024]; + char trimmed_name[128]; + char *spot; + int iIndex; + char pszElement[12]; + + SDL_strlcpy(trimmed_name, name, SDL_arraysize(trimmed_name)); + while (SDL_isspace(trimmed_name[0])) { + SDL_memmove(&trimmed_name[0], &trimmed_name[1], SDL_strlen(trimmed_name)); + } + while (trimmed_name[0] && SDL_isspace(trimmed_name[SDL_strlen(trimmed_name) - 1])) { + trimmed_name[SDL_strlen(trimmed_name) - 1] = '\0'; + } + while ((spot = SDL_strchr(trimmed_name, ',')) != NULL) { + SDL_memmove(spot, spot + 1, SDL_strlen(spot)); + } + + /* Initialize mapping with GUID and name */ + SDL_JoystickGetGUIDString(SDL_JoystickGetGUID(joystick), mapping, SDL_arraysize(mapping)); + SDL_strlcat(mapping, ",", SDL_arraysize(mapping)); + SDL_strlcat(mapping, trimmed_name, SDL_arraysize(mapping)); + SDL_strlcat(mapping, ",", SDL_arraysize(mapping)); + SDL_strlcat(mapping, "platform:", SDL_arraysize(mapping)); + SDL_strlcat(mapping, SDL_GetPlatform(), SDL_arraysize(mapping)); + SDL_strlcat(mapping, ",", SDL_arraysize(mapping)); + + for (iIndex = 0; iIndex < SDL_arraysize(s_arrBindings); ++iIndex) { + SDL_GameControllerButtonBind *pBinding = &s_arrBindings[iIndex]; + if (pBinding->bindType == SDL_CONTROLLER_BINDTYPE_NONE) { + continue; + } + + if (iIndex < SDL_CONTROLLER_BUTTON_MAX) { + SDL_GameControllerButton eButton = (SDL_GameControllerButton)iIndex; + SDL_strlcat(mapping, SDL_GameControllerGetStringForButton(eButton), SDL_arraysize(mapping)); + } else { + SDL_GameControllerAxis eAxis = (SDL_GameControllerAxis)(iIndex - SDL_CONTROLLER_BUTTON_MAX); + SDL_strlcat(mapping, SDL_GameControllerGetStringForAxis(eAxis), SDL_arraysize(mapping)); + } + SDL_strlcat(mapping, ":", SDL_arraysize(mapping)); + + pszElement[0] = '\0'; + switch (pBinding->bindType) { + case SDL_CONTROLLER_BINDTYPE_BUTTON: + SDL_snprintf(pszElement, sizeof(pszElement), "b%d", pBinding->value.button); + break; + case SDL_CONTROLLER_BINDTYPE_AXIS: + SDL_snprintf(pszElement, sizeof(pszElement), "a%d", pBinding->value.axis); + break; + case SDL_CONTROLLER_BINDTYPE_HAT: + SDL_snprintf(pszElement, sizeof(pszElement), "h%d.%d", pBinding->value.hat.hat, pBinding->value.hat.hat_mask); + break; + default: + SDL_assert(!"Unknown bind type"); + break; + } + SDL_strlcat(mapping, pszElement, SDL_arraysize(mapping)); + SDL_strlcat(mapping, ",", SDL_arraysize(mapping)); + } + SDL_Log("Mapping:\n\n%s\n\n", mapping); /* Print to stdout as well so the user can cat the output somewhere */ printf("%s\n", mapping); } - while(SDL_PollEvent(&event)) {}; - SDL_DestroyRenderer(screen); SDL_DestroyWindow(window); - return retval; } int @@ -378,9 +518,6 @@ main(int argc, char *argv[]) #else if (argv[1]) { #endif - SDL_bool reportederror = SDL_FALSE; - SDL_bool keepGoing = SDL_TRUE; - SDL_Event event; int device; #ifdef __ANDROID__ device = 0; @@ -388,34 +525,11 @@ main(int argc, char *argv[]) device = atoi(argv[1]); #endif joystick = SDL_JoystickOpen(device); - - while ( keepGoing ) { - if (joystick == NULL) { - if ( !reportederror ) { - SDL_Log("Couldn't open joystick %d: %s\n", device, SDL_GetError()); - keepGoing = SDL_FALSE; - reportederror = SDL_TRUE; - } - } else { - reportederror = SDL_FALSE; - keepGoing = WatchJoystick(joystick); - SDL_JoystickClose(joystick); - } - - joystick = NULL; - if (keepGoing) { - SDL_Log("Waiting for attach\n"); - } - while (keepGoing) { - SDL_WaitEvent(&event); - if ((event.type == SDL_QUIT) || (event.type == SDL_FINGERDOWN) - || (event.type == SDL_MOUSEBUTTONDOWN)) { - keepGoing = SDL_FALSE; - } else if (event.type == SDL_JOYDEVICEADDED) { - joystick = SDL_JoystickOpen(device); - break; - } - } + if (joystick == NULL) { + SDL_Log("Couldn't open joystick %d: %s\n", device, SDL_GetError()); + } else { + WatchJoystick(joystick); + SDL_JoystickClose(joystick); } } else {