From 72164985b0ea6428c98308dfd108865762ac79a7 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 7 Oct 2016 16:04:15 -0700 Subject: [PATCH] Fixed bug 2823 - Release events for triggers receive wrong centered value Ryochan7 I have been using SDL 2 for a little project that I have been developing for a while. My project is called antimicro and it takes gamepad input and then translates gamepad events into keyboard and mouse events. SDL is used to read the input from an XInput gamepad and it works great for the most part. However, there is one glaring problem that I have encountered. When a device is unplugged and SDL sends the centered value release events for all axes, buttons, and hats, SDL does not use the proper centered value for the triggers. It pushes an SDL_JOYAXISMOTION event onto the queue with a value of 0 for all axes. That value is converted to around 16,000 for a Game Controller. That value is incorrect for triggers and, in my program, that causes any bindings that are assigned to the triggers to get activated. With most profiles, that will typically mean that a mouse right click and left click will be activated before the device is finally seen as removed and then those bindings are released by antimicro. --- src/joystick/SDL_gamecontroller.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c index ccecb80d5..4bcb69a34 100644 --- a/src/joystick/SDL_gamecontroller.c +++ b/src/joystick/SDL_gamecontroller.c @@ -156,8 +156,17 @@ int SDL_GameControllerEventWatcher(void *userdata, SDL_Event * event) switch (axis) { case SDL_CONTROLLER_AXIS_TRIGGERLEFT: case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: - /* Shift it to be 0 - 32767. */ - value = value / 2 + 16384; + /* Shift it to be 0 - 32767 */ + if (controllerlist->joystick->force_recentering) { + int triggerMapping = controllerlist->mapping.axes[axis]; + if (triggerMapping >= 0) { + controllerlist->joystick->axes[triggerMapping] = (Sint16)-32768; + } + value = 0; + } else { + value = value / 2 + 16384; + } + break; default: break; } @@ -1003,6 +1012,18 @@ SDL_GameControllerOpen(int device_index) SDL_PrivateLoadButtonMapping(&gamecontroller->mapping, pSupportedController->guid, pSupportedController->name, pSupportedController->mapping); + /* The triggers are mapped from -32768 to 32767, where -32768 is the 'unpressed' value */ + { + int leftTriggerMapping = gamecontroller->mapping.axes[SDL_CONTROLLER_AXIS_TRIGGERLEFT]; + int rightTriggerMapping = gamecontroller->mapping.axes[SDL_CONTROLLER_AXIS_TRIGGERRIGHT]; + if (leftTriggerMapping >= 0) { + gamecontroller->joystick->axes[leftTriggerMapping] = (Sint16)-32768; + } + if (rightTriggerMapping >= 0) { + gamecontroller->joystick->axes[rightTriggerMapping] = (Sint16)-32768; + } + } + /* Add joystick to list */ ++gamecontroller->ref_count; /* Link the joystick in the list */ @@ -1039,7 +1060,7 @@ SDL_GameControllerGetAxis(SDL_GameController * gamecontroller, SDL_GameControlle switch (axis) { case SDL_CONTROLLER_AXIS_TRIGGERLEFT: case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: - /* Shift it to be 0 - 32767. */ + /* Shift it to be 0 - 32767 */ value = value / 2 + 16384; default: break;