From 8aaf945b2fd7a1125deeb6626215219180a041a1 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Thu, 28 Nov 2019 11:44:15 -0800 Subject: [PATCH] Fixed mapping controllers that have axes that start at -32768 and then snap to 0 at the first input report --- src/joystick/SDL_joystick.c | 34 ++++++++++++++++++++-------------- src/joystick/SDL_sysjoystick.h | 1 + test/controllermap.c | 14 ++++---------- 3 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/joystick/SDL_joystick.c b/src/joystick/SDL_joystick.c index ba6d2b3bf..96a3b8991 100644 --- a/src/joystick/SDL_joystick.c +++ b/src/joystick/SDL_joystick.c @@ -833,43 +833,49 @@ int SDL_PrivateJoystickAxis(SDL_Joystick * joystick, Uint8 axis, Sint16 value) { int posted; + SDL_JoystickAxisInfo *info; /* Make sure we're not getting garbage or duplicate events */ if (axis >= joystick->naxes) { 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; + + info = &joystick->axes[axis]; + if (!info->has_initial_value || + (!info->has_second_value && info->initial_value == -32768 && value == 0)) { + info->initial_value = value; + info->value = value; + info->zero = value; + info->has_initial_value = SDL_TRUE; + } else { + info->has_second_value = SDL_TRUE; } - if (value == joystick->axes[axis].value) { + if (value == info->value) { return 0; } - if (!joystick->axes[axis].sent_initial_value) { + if (!info->sent_initial_value) { /* Make sure we don't send motion until there's real activity on this axis */ const int MAX_ALLOWED_JITTER = SDL_JOYSTICK_AXIS_MAX / 80; /* ShanWan PS3 controller needed 96 */ - if (SDL_abs(value - joystick->axes[axis].value) <= MAX_ALLOWED_JITTER) { + if (SDL_abs(value - info->value) <= MAX_ALLOWED_JITTER) { return 0; } - joystick->axes[axis].sent_initial_value = SDL_TRUE; - joystick->axes[axis].value = value; /* Just so we pass the check above */ - SDL_PrivateJoystickAxis(joystick, axis, joystick->axes[axis].initial_value); + info->sent_initial_value = SDL_TRUE; + info->value = value; /* Just so we pass the check above */ + SDL_PrivateJoystickAxis(joystick, axis, info->initial_value); } /* We ignore events if we don't have keyboard focus, except for centering * events. */ if (SDL_PrivateJoystickShouldIgnoreEvent()) { - if ((value > joystick->axes[axis].zero && value >= joystick->axes[axis].value) || - (value < joystick->axes[axis].zero && value <= joystick->axes[axis].value)) { + if ((value > info->zero && value >= info->value) || + (value < info->zero && value <= info->value)) { return 0; } } /* Update internal joystick state */ - joystick->axes[axis].value = value; + info->value = value; /* Post the event, if desired */ posted = 0; diff --git a/src/joystick/SDL_sysjoystick.h b/src/joystick/SDL_sysjoystick.h index 8f5752326..4ea0c80fd 100644 --- a/src/joystick/SDL_sysjoystick.h +++ b/src/joystick/SDL_sysjoystick.h @@ -35,6 +35,7 @@ typedef struct _SDL_JoystickAxisInfo 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 has_second_value; /* Whether we've seen a second value on the axis yet */ SDL_bool sent_initial_value; /* Whether we've sent the initial axis value */ } SDL_JoystickAxisInfo; diff --git a/test/controllermap.c b/test/controllermap.c index 40c3518d2..0f7de702b 100644 --- a/test/controllermap.c +++ b/test/controllermap.c @@ -413,13 +413,6 @@ WatchJoystick(SDL_Joystick * joystick) s_nNumAxes = SDL_JoystickNumAxes(joystick); s_arrAxisState = (AxisState *)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) { @@ -472,9 +465,10 @@ WatchJoystick(SDL_Joystick * joystick) int nValue = event.jaxis.value; int nCurrentDistance, nFarthestDistance; if (!pAxisState->m_bMoving) { - pAxisState->m_bMoving = SDL_TRUE; - pAxisState->m_nStartingValue = nValue; - pAxisState->m_nFarthestValue = nValue; + Sint16 nInitialValue; + pAxisState->m_bMoving = SDL_JoystickGetAxisInitialState(joystick, event.jaxis.axis, &nInitialValue); + pAxisState->m_nStartingValue = nInitialValue; + pAxisState->m_nFarthestValue = nInitialValue; } nCurrentDistance = SDL_abs(nValue - pAxisState->m_nStartingValue); nFarthestDistance = SDL_abs(pAxisState->m_nFarthestValue - pAxisState->m_nStartingValue);