Commit 4938c5054e16ebbd5e666d0dcb3d406dbfc10313

Sam Lantinga 2017-01-04T10:28:07

Added SDL_JoystickGetAxisInitialState() to get a joystick axis' initial value. This is useful for controller mapping programs to determine an axis' zero state

diff --git a/include/SDL_joystick.h b/include/SDL_joystick.h
index af7f781..a15fbb5 100644
--- a/include/SDL_joystick.h
+++ b/include/SDL_joystick.h
@@ -245,6 +245,18 @@ 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 7daf379..3fe4b86 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 c06c9a2..e416b4a 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 457747d..e9c4001 100644
--- a/src/joystick/SDL_joystick.c
+++ b/src/joystick/SDL_joystick.c
@@ -335,6 +335,25 @@ SDL_JoystickGetAxis(SDL_Joystick * joystick, int axis)
 }
 
 /*
+ * 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
  */
 Uint8
@@ -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 09b7e58..53a7ff7 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 f0a01f0..d5f1f22 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) {