diff --git a/SDL/SDLJoystick.cpp b/SDL/SDLJoystick.cpp index bcaf616c7ded..d9d064434096 100644 --- a/SDL/SDLJoystick.cpp +++ b/SDL/SDLJoystick.cpp @@ -182,15 +182,28 @@ void SDLJoystick::ProcessInput(const SDL_Event &event){ } break; case SDL_CONTROLLERAXISMOTION: - AxisInput axis; - // TODO: Can we really cast axis events like that? Do they match? - axis.axisId = (InputAxis)event.caxis.axis; - axis.value = event.caxis.value / 32767.0f; - if (axis.value > 1.0f) axis.value = 1.0f; - if (axis.value < -1.0f) axis.value = -1.0f; - axis.deviceId = DEVICE_ID_PAD_0 + getDeviceIndex(event.caxis.which); - NativeAxis(&axis, 1); + { + InputDeviceID deviceId = DEVICE_ID_PAD_0 + getDeviceIndex(event.caxis.which); + // TODO: Can we really cast axis IDs like that? Do they match? + InputAxis axisId = (InputAxis)event.caxis.axis; + float value = event.caxis.value * (1.f / 32767.f); + if (value > 1.0f) value = 1.0f; + if (value < -1.0f) value = -1.0f; + // Filter duplicate axis values. + auto key = std::pair(deviceId, axisId); + auto iter = prevAxisValue_.find(key); + if (iter == prevAxisValue_.end()) { + prevAxisValue_[key] = value; + } else if (iter->second != value) { + iter->second = value; + AxisInput axis; + axis.axisId = axisId; + axis.value = value; + axis.deviceId = deviceId; + NativeAxis(&axis, 1); + } // else ignore event. break; + } case SDL_CONTROLLERDEVICEREMOVED: // for removal events, "which" is the instance ID for SDL_CONTROLLERDEVICEREMOVED for (auto it = controllers.begin(); it != controllers.end(); ++it) { diff --git a/SDL/SDLJoystick.h b/SDL/SDLJoystick.h index e91bfd0b5cfd..50cc43c4c7f3 100644 --- a/SDL/SDLJoystick.h +++ b/SDL/SDLJoystick.h @@ -27,7 +27,11 @@ class SDLJoystick{ void setUpControllers(); InputKeyCode getKeycodeForButton(SDL_GameControllerButton button); int getDeviceIndex(int instanceId); + bool registeredAsEventHandler; std::vector controllers; std::map controllerDeviceMap; + + // Deduplicate axis events. Pair is device, axis. + std::map, float> prevAxisValue_; };