Fixed bug 2950 - wrong axes values are set on joystick initialization
authorSam Lantinga
Sat, 12 Aug 2017 17:41:59 -0700
changeset 112550302e7e91db7
parent 11254 390de4b9f84f
child 11256 49fe11ad0425
Fixed bug 2950 - wrong axes values are set on joystick initialization

Edward Rudd

Device: Logitech Rumble Gamepad F510 in Xinput mode.

Upon opening the joystick the values of the axes are queried via PollAllValues are not actually set on the device all the time.

This can easily be seen in the testjoystick or testgamecontroller test programs,as the testjoystick shows all axes in the center until one 'tickles' the triggers., and the testgamecontroller will show the triggers as 'on' until on 'tickles' the triggers.

Upon further research the culprit is the SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS hint. In the default value events are ignored until there is an active window, Thus in cases where the joystick system is initialized and controllers opened before the initial window is created & focuses, the initial values will be incorrect.

Here is my current workaround in the game I'm working on porting..

SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "1");
SDL_GameController* gamepad = SDL_GameControllerOpen(index);
SDL_SetHint(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS, "0");
src/joystick/SDL_joystick.c
src/video/SDL_sysvideo.h
src/video/SDL_video.c
     1.1 --- a/src/joystick/SDL_joystick.c	Sat Aug 12 17:01:14 2017 -0700
     1.2 +++ b/src/joystick/SDL_joystick.c	Sat Aug 12 17:41:59 2017 -0700
     1.3 @@ -31,6 +31,7 @@
     1.4  #if !SDL_EVENTS_DISABLED
     1.5  #include "../events/SDL_events_c.h"
     1.6  #endif
     1.7 +#include "../video/SDL_sysvideo.h"
     1.8  
     1.9  
    1.10  static SDL_bool SDL_joystick_allows_background_events = SDL_FALSE;
    1.11 @@ -582,16 +583,10 @@
    1.12          return SDL_FALSE;
    1.13      }
    1.14  
    1.15 -    if (SDL_WasInit(SDL_INIT_VIDEO)) {
    1.16 -        if (SDL_GetKeyboardFocus() == NULL) {
    1.17 -            /* Video is initialized and we don't have focus, ignore the event. */
    1.18 -            return SDL_TRUE;
    1.19 -        } else {
    1.20 -            return SDL_FALSE;
    1.21 -        }
    1.22 +    if (SDL_HasWindows() && SDL_GetKeyboardFocus() == NULL) {
    1.23 +        /* We have windows but we don't have focus, ignore the event. */
    1.24 +        return SDL_TRUE;
    1.25      }
    1.26 -
    1.27 -    /* Video subsystem wasn't initialized, always allow the event */
    1.28      return SDL_FALSE;
    1.29  }
    1.30  
     2.1 --- a/src/video/SDL_sysvideo.h	Sat Aug 12 17:01:14 2017 -0700
     2.2 +++ b/src/video/SDL_sysvideo.h	Sat Aug 12 17:41:59 2017 -0700
     2.3 @@ -403,6 +403,7 @@
     2.4  extern void SDL_GL_DeduceMaxSupportedESProfile(int* major, int* minor);
     2.5  
     2.6  extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
     2.7 +extern SDL_bool SDL_HasWindows();
     2.8  
     2.9  extern void SDL_OnWindowShown(SDL_Window * window);
    2.10  extern void SDL_OnWindowHidden(SDL_Window * window);
     3.1 --- a/src/video/SDL_video.c	Sat Aug 12 17:01:14 2017 -0700
     3.2 +++ b/src/video/SDL_video.c	Sat Aug 12 17:41:59 2017 -0700
     3.3 @@ -1606,6 +1606,12 @@
     3.4      return 0;
     3.5  }
     3.6  
     3.7 +SDL_bool
     3.8 +SDL_HasWindows()
     3.9 +{
    3.10 +    return (_this && _this->windows != NULL);
    3.11 +}
    3.12 +
    3.13  Uint32
    3.14  SDL_GetWindowID(SDL_Window * window)
    3.15  {