From 4938c5054e16ebbd5e666d0dcb3d406dbfc10313 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Wed, 4 Jan 2017 10:28:07 -0800 Subject: [PATCH] Added SDL_JoystickGetAxisInitialState() to get a joystick axis' initial value. This is useful for controller mapping programs to determine an axis' zero state --- include/SDL_joystick.h | 12 ++++++++++++ src/dynapi/SDL_dynapi_overrides.h | 1 + src/dynapi/SDL_dynapi_procs.h | 1 + src/joystick/SDL_joystick.c | 23 +++++++++++++++++++++-- src/joystick/SDL_sysjoystick.h | 3 ++- test/controllermap.c | 8 ++++++++ 6 files changed, 45 insertions(+), 3 deletions(-) diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h index af7f7810b91c3..a15fbb539443b 100644 --- a/include/SDL_joystick.h +++ b/include/SDL_joystick.h @@ -244,6 +244,18 @@ extern DECLSPEC int SDLCALL SDL_JoystickEventState(int state); extern DECLSPEC Sint16 SDLCALL SDL_JoystickGetAxis(SDL_Joystick * joystick, int axis); +/** + * Get the initial state of an axis control on a joystick. + * + * The state is a value ranging from -32768 to 32767. + * + * The axis indices start at index 0. + * + * \return SDL_TRUE if this axis has any initial value, or SDL_FALSE if not. + */ +extern DECLSPEC SDL_bool SDLCALL SDL_JoystickGetAxisInitialState(SDL_Joystick * joystick, + int axis, Sint16 *state); + /** * \name Hat positions */ diff --git a/src/dynapi/SDL_dynapi_overrides.h b/src/dynapi/SDL_dynapi_overrides.h index 7daf37966ebe8..3fe4b86da94b5 100644 --- a/src/dynapi/SDL_dynapi_overrides.h +++ b/src/dynapi/SDL_dynapi_overrides.h @@ -624,3 +624,4 @@ #define SDL_HasNEON SDL_HasNEON_REAL #define SDL_GameControllerNumMappings SDL_GameControllerNumMappings_REAL #define SDL_GameControllerMappingForIndex SDL_GameControllerMappingForIndex_REAL +#define SDL_JoystickGetAxisInitialState SDL_JoystickGetAxisInitialState_REAL diff --git a/src/dynapi/SDL_dynapi_procs.h b/src/dynapi/SDL_dynapi_procs.h index c06c9a2a3fd7d..e416b4a64e718 100644 --- a/src/dynapi/SDL_dynapi_procs.h +++ b/src/dynapi/SDL_dynapi_procs.h @@ -656,3 +656,4 @@ SDL_DYNAPI_PROC(Uint16,SDL_GameControllerGetProductVersion,(SDL_GameController * SDL_DYNAPI_PROC(SDL_bool,SDL_HasNEON,(void),(),return) SDL_DYNAPI_PROC(int,SDL_GameControllerNumMappings,(void),(),return) SDL_DYNAPI_PROC(char*,SDL_GameControllerMappingForIndex,(int a),(a),return) +SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickGetAxisInitialState,(SDL_Joystick *a, int b, Sint16 *c),(a,b,c),return) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index 457747d1ff798..e9c4001c9759c 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -334,6 +334,25 @@ SDL_JoystickGetAxis(SDL_Joystick * joystick, int axis) return (state); } +/* + * Get the initial state of an axis control on a joystick + */ +SDL_bool +SDL_JoystickGetAxisInitialState(SDL_Joystick * joystick, int axis, Sint16 *state) +{ + if (!SDL_PrivateJoystickValid(joystick)) { + return SDL_FALSE; + } + if (axis >= joystick->naxes) { + SDL_SetError("Joystick only has %d axes", joystick->naxes); + return SDL_FALSE; + } + if (state) { + *state = joystick->axes[axis].initial_value; + } + return joystick->axes[axis].has_initial_value; +} + /* * Get the current state of a hat on a joystick */ @@ -646,6 +665,7 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) return 0; } if (!joystick->axes[axis].has_initial_value) { + joystick->axes[axis].initial_value = value; joystick->axes[axis].value = value; joystick->axes[axis].zero = value; joystick->axes[axis].has_initial_value = SDL_TRUE; @@ -654,10 +674,9 @@ SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) return 0; } if (!joystick->axes[axis].sent_initial_value) { - int initial_value = joystick->axes[axis].value; joystick->axes[axis].sent_initial_value = SDL_TRUE; joystick->axes[axis].value = value; /* Just so we pass the check above */ - SDL_PrivateJoystickAxis(joystick, axis, initial_value); + SDL_PrivateJoystickAxis(joystick, axis, joystick->axes[axis].initial_value); } /* We ignore events if we don't have keyboard focus, except for centering diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 09b7e58928b18..53a7ff75909ca 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -31,7 +31,8 @@ /* The SDL joystick structure */ typedef struct _SDL_JoystickAxisInfo { - Sint16 value; /* Current axis states */ + Sint16 initial_value; /* Initial axis state */ + Sint16 value; /* Current axis state */ Sint16 zero; /* Zero point on the axis (-32768 for triggers) */ SDL_bool has_initial_value; /* Whether we've seen a value on the axis yet */ SDL_bool sent_initial_value; /* Whether we've sent the initial axis value */ diff --git a/test/controllermap.c b/test/controllermap.c index f0a01f0619c2e..d5f1f2205397c 100644 --- a/test/controllermap.c +++ b/test/controllermap.c @@ -337,6 +337,7 @@ WatchJoystick(SDL_Joystick * joystick) Uint8 alpha=200, alpha_step = -1; Uint32 alpha_ticks = 0; SDL_JoystickID nJoystickID; + int iIndex; /* Create a window to display joystick axis position */ window = SDL_CreateWindow("Game Controller Map", SDL_WINDOWPOS_CENTERED, @@ -383,6 +384,13 @@ WatchJoystick(SDL_Joystick * joystick) s_nNumAxes = SDL_JoystickNumAxes(joystick); s_arrAxisState = SDL_calloc(s_nNumAxes, sizeof(*s_arrAxisState)); + for (iIndex = 0; iIndex < s_nNumAxes; ++iIndex) { + AxisState *pAxisState = &s_arrAxisState[iIndex]; + Sint16 nInitialValue; + pAxisState->m_bMoving = SDL_JoystickGetAxisInitialState(joystick, iIndex, &nInitialValue); + pAxisState->m_nStartingValue = nInitialValue; + pAxisState->m_nFarthestValue = nInitialValue; + } /* Loop, getting joystick events! */ while (!done && !s_bBindingComplete) {