From 918b96500c2aee18c0690ac680d7933dacef9cd9 Mon Sep 17 00:00:00 2001 From: Josh Palmer Date: Sat, 17 Jan 2015 16:47:19 +0000 Subject: [PATCH 1/4] DInput/XInput: Configurable deadzone + inverter * Add configurable shared deadzone for all DInput axes * Add configurable separate deadzones for left & right XInput sticks * Add configurable deadzone inverter for DInput X/Y axes * Add configurable deadzone inverter for XInput sticks --- Core/Config.cpp | 13 ++++++++ Core/Config.h | 13 ++++++++ UI/GameSettingsScreen.cpp | 17 +++++++++++ Windows/DinputDevice.cpp | 42 ++++++++++++++++++++++++-- Windows/XinputDevice.cpp | 62 ++++++++++++++++++++++++++++++++------- 5 files changed, 135 insertions(+), 12 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 60e96feed7..7b30a19d04 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -562,6 +562,19 @@ static ConfigSetting controlSettings[] = { ConfigSetting("AnalogStickX", &g_Config.fAnalogStickX, -1.0f, true, true), ConfigSetting("AnalogStickY", &g_Config.fAnalogStickY, -1.0f, true, true), ConfigSetting("AnalogStickScale", &g_Config.fAnalogStickScale, defaultControlScale, true, true), +#ifdef _WIN32 + ConfigSetting("DInputAnalogDeadzone", &g_Config.fDInputAnalogDeadzone, 0.1f, true, true), + ConfigSetting("DInputAnalogInverseDeadzone", &g_Config.fDInputAnalogInverseDeadzone, 0.0f, true, true), + + ConfigSetting("XInputLeftAnalogDeadzone", &g_Config.fXInputLeftAnalogDeadzone, 0.24f, true, true), + ConfigSetting("XInputRightAnalogDeadzone", &g_Config.fXInputRightAnalogDeadzone, 0.27f, true, true), + + ConfigSetting("XInputLeftAnalogInverseMode", &g_Config.iXInputLeftAnalogInverseMode, 0, true, true), + ConfigSetting("XInputLeftAnalogInverseDeadzone", &g_Config.fXInputLeftAnalogInverseDeadzone, 0.0f, true, true), + + ConfigSetting("XInputRightAnalogInverseMode", &g_Config.iXInputRightAnalogInverseMode, 0, true, true), + ConfigSetting("XInputRightAnalogInverseDeadzone", &g_Config.fXInputRightAnalogInverseDeadzone, 0.0f, true, true), +#endif ConfigSetting("AnalogLimiterDeadzone", &g_Config.fAnalogLimiterDeadzone, 0.6f, true, true), ConfigSetting(false), diff --git a/Core/Config.h b/Core/Config.h index db12106ba8..ea836ea109 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -276,6 +276,19 @@ public: bool bHapticFeedback; + float fDInputAnalogDeadzone; + int iDInputAnalogInverseMode; + float fDInputAnalogInverseDeadzone; + + float fXInputLeftAnalogDeadzone; + float fXInputRightAnalogDeadzone; + + int iXInputLeftAnalogInverseMode; + float fXInputLeftAnalogInverseDeadzone; + + int iXInputRightAnalogInverseMode; + float fXInputRightAnalogInverseDeadzone; + float fAnalogLimiterDeadzone; // GLES backend-specific hacks. Not saved to the ini file, do not add checkboxes. Will be made into // proper options when good enough. diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 2b1e61f949..c383c26e1e 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -372,6 +372,23 @@ void GameSettingsScreen::CreateViews() { View *style = controlsSettings->Add(new PopupMultiChoice(&g_Config.iTouchButtonStyle, c->T("Button style"), touchControlStyles, 0, ARRAY_SIZE(touchControlStyles), c, screenManager())); style->SetEnabledPtr(&g_Config.bShowTouchControls); + static const char *inverseDeadzoneModes[] = { "Off", "X", "Y", "X + Y" }; + + controlsSettings->Add(new ItemHeader(c->T("DInput Analog Settings", "DInput Analog Settings"))); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone"), screenManager())); + controlsSettings->Add(new PopupMultiChoice(&g_Config.iDInputAnalogInverseMode, c->T("Inverse Dead Zone Mode"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size"), screenManager())); + + controlsSettings->Add(new ItemHeader(c->T("XInput Analog Settings", "XInput Analog Settings"))); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputLeftAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone (Left Stick)"), screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputRightAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone (Right Stick)"), screenManager())); + + controlsSettings->Add(new PopupMultiChoice(&g_Config.iXInputLeftAnalogInverseMode, c->T("Inverse Dead Zone Mode (Left Stick)"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputLeftAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size (Left Stick)"), screenManager())); + + controlsSettings->Add(new PopupMultiChoice(&g_Config.iXInputRightAnalogInverseMode, c->T("Inverse Dead Zone Mode (Right Stick)"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputRightAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size (Right Stick)"), screenManager())); + controlsSettings->Add(new ItemHeader(c->T("Keyboard", "Keyboard Control Settings"))); #if defined(USING_WIN_UI) controlsSettings->Add(new CheckBox(&g_Config.bIgnoreWindowsKey, c->T("Ignore Windows Key"))); diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index 3050518dd2..44b80b954f 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -177,8 +177,8 @@ DinputDevice::DinputDevice(int devnum) { dipw.diph.dwHeaderSize = sizeof(DIPROPHEADER); dipw.diph.dwHow = DIPH_DEVICE; dipw.diph.dwObj = 0; - // dwData 1000 is deadzone(0% - 10%) - dipw.dwData = 1000; + // dwData 10000 is deadzone(0% - 100%), multiply by config scalar + dipw.dwData = (int)(g_Config.fDInputAnalogDeadzone * 10000); analog |= FAILED(pJoystick->SetProperty(DIPROP_DEADZONE, &dipw.diph)) ? false : true; } @@ -214,6 +214,14 @@ void SendNativeAxis(int deviceId, short value, short &lastValue, int axisId) { lastValue = value; } +inline float Signf(float val) { + return (0.0f < val) - (val < 0.0f); +} + +inline float LinearMapf(float val, float a0, float a1, float b0, float b1) { + return b0 + (((val - a0) * (b1 - b0)) / (a1 - a0)); +} + int DinputDevice::UpdateState(InputState &input_state) { if (!pJoystick) return -1; @@ -232,6 +240,36 @@ int DinputDevice::UpdateState(InputState &input_state) { if (analog) { AxisInput axis; axis.deviceId = DEVICE_ID_PAD_0 + pDevNum; + + // Linear range mapping (used to invert deadzones) + float dz = g_Config.fDInputAnalogDeadzone; + int idzm = g_Config.iDInputAnalogInverseMode; + float idz = g_Config.fDInputAnalogInverseDeadzone; + float md = std::max(dz, idz); + + float magnitude = sqrtf(js.lX * js.lX + js.lY * js.lY); + if (idzm == 1) + { + float xSign = Signf(js.lX); + if (xSign != 0.0f) { + js.lX = LinearMapf(js.lX, xSign * dz, xSign, xSign * md, xSign); + } + } + else if (idzm == 2) + { + float ySign = Signf(js.lY); + if (ySign != 0.0f) { + js.lY = LinearMapf(js.lY, ySign * dz, ySign, ySign * md, ySign); + } + } + else if (idzm == 3) + { + float xNorm = js.lX / magnitude; + float yNorm = js.lY / magnitude; + float mapMag = LinearMapf(magnitude, dz, 1.0, md, 1.0); + js.lX = xNorm * mapMag; + js.lY = yNorm * mapMag; + } SendNativeAxis(DEVICE_ID_PAD_0 + pDevNum, js.lX, last_lX_, JOYSTICK_AXIS_X); SendNativeAxis(DEVICE_ID_PAD_0 + pDevNum, js.lY, last_lY_, JOYSTICK_AXIS_Y); diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index 5452bb0096..fbecfebe04 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -120,12 +120,20 @@ inline float Clampf(float val, float min, float max) { return val; } -static Stick NormalizedDeadzoneFilter(short x, short y, short thresh) { - static const float DEADZONE = (float)thresh / 32767.0f; +inline float Signf(float val) { + return (0.0f < val) - (val < 0.0f); +} + +inline float LinearMapf(float val, float a0, float a1, float b0, float b1) { + return b0 + (((val - a0) * (b1 - b0)) / (a1 - a0)); +} + +static Stick NormalizedDeadzoneFilter(short x, short y, float dz, int idzm, float idz) { Stick s(x, y, 1.0 / 32767.0f); float magnitude = sqrtf(s.x * s.x + s.y * s.y); - if (magnitude > DEADZONE) { + if (magnitude > dz) { + // Circle to square mapping (the PSP stick outputs the full -1..1 square of values) #if 1 // Looks way better than the old one, below, in the axis tester. @@ -140,6 +148,33 @@ static Stick NormalizedDeadzoneFilter(short x, short y, short thresh) { s.y *= 1.41421f; } #endif + + // Linear range mapping (used to invert deadzones) + float md = std::max(dz, idz); + + if (idzm == 1) + { + float xSign = Signf(s.x); + if (xSign != 0.0f) { + s.x = LinearMapf(s.x, xSign * dz, xSign, xSign * md, xSign); + } + } + else if (idzm == 2) + { + float ySign = Signf(s.y); + if (ySign != 0.0f) { + s.y = LinearMapf(s.y, ySign * dz, ySign, ySign * md, ySign); + } + } + else if (idzm == 3) + { + float xNorm = s.x / magnitude; + float yNorm = s.y / magnitude; + float mapMag = LinearMapf(magnitude, dz, 1.0, md, 1.0); + s.x = xNorm * mapMag; + s.y = yNorm * mapMag; + } + s.x = Clampf(s.x, -1.0f, 1.0f); s.y = Clampf(s.y, -1.0f, 1.0f); } else { @@ -149,14 +184,13 @@ static Stick NormalizedDeadzoneFilter(short x, short y, short thresh) { return s; } -bool NormalizedDeadzoneDiffers(short x1, short y1, short x2, short y2, const short thresh) { - static const float DEADZONE = (float)thresh / 32767.0f; +bool NormalizedDeadzoneDiffers(short x1, short y1, short x2, short y2, const float dz) { Stick s1(x1, y1, 1.0 / 32767.0f); Stick s2(x2, y2, 1.0 / 32767.0f); float magnitude1 = sqrtf(s1.x * s1.x + s1.y * s1.y); float magnitude2 = sqrtf(s2.x * s2.x + s2.y * s2.y); - if (magnitude1 > DEADZONE || magnitude2 > DEADZONE) { + if (magnitude1 > dz || magnitude2 > dz) { return x1 != x2 || y1 != y2; } return false; @@ -201,8 +235,12 @@ int XinputDevice::UpdateState(InputState &input_state) { } ApplyButtons(state, input_state); - if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbLX, prevState.Gamepad.sThumbLY, state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)) { - Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE); + const float LEFT_STICK_DEADZONE = g_Config.fXInputLeftAnalogDeadzone; + const int LEFT_STICK_INV_MODE = g_Config.iXInputLeftAnalogInverseMode; + const float LEFT_STICK_INV_DEADZONE = g_Config.fXInputLeftAnalogInverseDeadzone; + + if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbLX, prevState.Gamepad.sThumbLY, state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, LEFT_STICK_DEADZONE)) { + Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, LEFT_STICK_DEADZONE, LEFT_STICK_INV_MODE, LEFT_STICK_INV_DEADZONE); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; @@ -218,8 +256,12 @@ int XinputDevice::UpdateState(InputState &input_state) { } } - if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbRX, prevState.Gamepad.sThumbRY, state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE)) { - Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE); + const float RIGHT_STICK_DEADZONE = g_Config.fXInputRightAnalogDeadzone; + const int RIGHT_STICK_INV_MODE = g_Config.iXInputRightAnalogInverseMode; + const float RIGHT_STICK_INV_DEADZONE = g_Config.fXInputRightAnalogInverseDeadzone; + + if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbRX, prevState.Gamepad.sThumbRY, state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, RIGHT_STICK_DEADZONE)) { + Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, RIGHT_STICK_DEADZONE, RIGHT_STICK_INV_MODE, LEFT_STICK_INV_DEADZONE); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; From 6856709b1dc1c0adcc44502143b3f66f19c11cbf Mon Sep 17 00:00:00 2001 From: Josh Palmer Date: Thu, 5 Feb 2015 05:30:39 +0000 Subject: [PATCH 2/4] DInput/XInput: Deadzone fixes & Sensitivity * DInput Deadzone & Deadzone Inverter now function correctly * Added analog Sensitivity options to DInput and XInput --- Core/Config.cpp | 6 +++++ Core/Config.h | 3 +++ UI/GameSettingsScreen.cpp | 3 +++ Windows/DinputDevice.cpp | 53 +++++++++++++++++++++++---------------- Windows/XinputDevice.cpp | 14 ++++++----- 5 files changed, 51 insertions(+), 28 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 7b30a19d04..ee1b5f5141 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -565,15 +565,21 @@ static ConfigSetting controlSettings[] = { #ifdef _WIN32 ConfigSetting("DInputAnalogDeadzone", &g_Config.fDInputAnalogDeadzone, 0.1f, true, true), ConfigSetting("DInputAnalogInverseDeadzone", &g_Config.fDInputAnalogInverseDeadzone, 0.0f, true, true), + ConfigSetting("DInputAnalogSensitivity", &g_Config.fDInputAnalogSensitivity, 1.0f, true, true), + + ConfigSetting("DInputAnalogInverseMode", &g_Config.iDInputAnalogInverseMode, 0, true, true), + ConfigSetting("DInputAnalogInverseDeadzone", &g_Config.fDInputAnalogInverseDeadzone, 0.0f, true, true), ConfigSetting("XInputLeftAnalogDeadzone", &g_Config.fXInputLeftAnalogDeadzone, 0.24f, true, true), ConfigSetting("XInputRightAnalogDeadzone", &g_Config.fXInputRightAnalogDeadzone, 0.27f, true, true), ConfigSetting("XInputLeftAnalogInverseMode", &g_Config.iXInputLeftAnalogInverseMode, 0, true, true), ConfigSetting("XInputLeftAnalogInverseDeadzone", &g_Config.fXInputLeftAnalogInverseDeadzone, 0.0f, true, true), + ConfigSetting("XInputLeftAnalogSensitivity", &g_Config.fXInputLeftAnalogSensitivity, 1.0f, true, true), ConfigSetting("XInputRightAnalogInverseMode", &g_Config.iXInputRightAnalogInverseMode, 0, true, true), ConfigSetting("XInputRightAnalogInverseDeadzone", &g_Config.fXInputRightAnalogInverseDeadzone, 0.0f, true, true), + ConfigSetting("XInputRightAnalogSensitivity", &g_Config.fXInputRightAnalogSensitivity, 1.0f, true, true), #endif ConfigSetting("AnalogLimiterDeadzone", &g_Config.fAnalogLimiterDeadzone, 0.6f, true, true), diff --git a/Core/Config.h b/Core/Config.h index ea836ea109..efff6df126 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -279,15 +279,18 @@ public: float fDInputAnalogDeadzone; int iDInputAnalogInverseMode; float fDInputAnalogInverseDeadzone; + float fDInputAnalogSensitivity; float fXInputLeftAnalogDeadzone; float fXInputRightAnalogDeadzone; int iXInputLeftAnalogInverseMode; float fXInputLeftAnalogInverseDeadzone; + float fXInputLeftAnalogSensitivity; int iXInputRightAnalogInverseMode; float fXInputRightAnalogInverseDeadzone; + float fXInputRightAnalogSensitivity; float fAnalogLimiterDeadzone; // GLES backend-specific hacks. Not saved to the ini file, do not add checkboxes. Will be made into diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index c383c26e1e..24fda800db 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -378,6 +378,7 @@ void GameSettingsScreen::CreateViews() { controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone"), screenManager())); controlsSettings->Add(new PopupMultiChoice(&g_Config.iDInputAnalogInverseMode, c->T("Inverse Dead Zone Mode"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size"), screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogSensitivity, 0.0f, 10.0f, c->T("Sensitivity"), screenManager())); controlsSettings->Add(new ItemHeader(c->T("XInput Analog Settings", "XInput Analog Settings"))); controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputLeftAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone (Left Stick)"), screenManager())); @@ -385,9 +386,11 @@ void GameSettingsScreen::CreateViews() { controlsSettings->Add(new PopupMultiChoice(&g_Config.iXInputLeftAnalogInverseMode, c->T("Inverse Dead Zone Mode (Left Stick)"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputLeftAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size (Left Stick)"), screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputLeftAnalogSensitivity, 0.0f, 10.0f, c->T("Sensitivity (Left Stick)"), screenManager())); controlsSettings->Add(new PopupMultiChoice(&g_Config.iXInputRightAnalogInverseMode, c->T("Inverse Dead Zone Mode (Right Stick)"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputRightAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size (Right Stick)"), screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputRightAnalogSensitivity, 0.0f, 10.0f, c->T("Sensitivity (Right Stick)"), screenManager())); controlsSettings->Add(new ItemHeader(c->T("Keyboard", "Keyboard Control Settings"))); #if defined(USING_WIN_UI) diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index 44b80b954f..5d5205c3fa 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -208,17 +208,18 @@ void SendNativeAxis(int deviceId, short value, short &lastValue, int axisId) { AxisInput axis; axis.deviceId = deviceId; axis.axisId = axisId; - axis.value = NormalizedDeadzoneFilter(value); + //axis.value = NormalizedDeadzoneFilter(value); + axis.value = (float)value / 10000.0f; NativeAxis(axis); lastValue = value; } -inline float Signf(float val) { - return (0.0f < val) - (val < 0.0f); +inline float Signs(short val) { + return (0 < val) - (val < 0); } -inline float LinearMapf(float val, float a0, float a1, float b0, float b1) { +inline float LinearMaps(short val, short a0, short a1, short b0, short b1) { return b0 + (((val - a0) * (b1 - b0)) / (a1 - a0)); } @@ -246,29 +247,37 @@ int DinputDevice::UpdateState(InputState &input_state) { int idzm = g_Config.iDInputAnalogInverseMode; float idz = g_Config.fDInputAnalogInverseDeadzone; float md = std::max(dz, idz); + float st = g_Config.fDInputAnalogSensitivity; float magnitude = sqrtf(js.lX * js.lX + js.lY * js.lY); - if (idzm == 1) - { - float xSign = Signf(js.lX); - if (xSign != 0.0f) { - js.lX = LinearMapf(js.lX, xSign * dz, xSign, xSign * md, xSign); + if (magnitude > dz * 10000.0f) { + if (idzm == 1) + { + short xSign = Signs(js.lX); + if (xSign != 0.0f) { + js.lX = LinearMaps(js.lX, xSign * (short)(dz * 10000), xSign * 10000, xSign * (short)(md * 10000), (xSign * 10000 * st) - (short)(md * 10000) ); + } + } + else if (idzm == 2) + { + short ySign = Signs(js.lY); + if (ySign != 0.0f) { + js.lY = LinearMaps(js.lY, ySign * (short)(dz * 10000.0f), ySign * 10000, ySign * (short)(md * 10000.0f), (ySign * 10000 * st) - (short)(md * 10000)); + } + } + else if (idzm == 3) + { + float xNorm = (float)js.lX / magnitude; + float yNorm = (float)js.lY / magnitude; + float mapMag = LinearMaps(magnitude, dz * 10000.0f, 10000.0f, md * 10000.0f, (10000.0f * st) - (short)(md * 10000)); + js.lX = (short)(xNorm * mapMag); + js.lY = (short)(yNorm * mapMag); } } - else if (idzm == 2) + else { - float ySign = Signf(js.lY); - if (ySign != 0.0f) { - js.lY = LinearMapf(js.lY, ySign * dz, ySign, ySign * md, ySign); - } - } - else if (idzm == 3) - { - float xNorm = js.lX / magnitude; - float yNorm = js.lY / magnitude; - float mapMag = LinearMapf(magnitude, dz, 1.0, md, 1.0); - js.lX = xNorm * mapMag; - js.lY = yNorm * mapMag; + js.lX = 0; + js.lY = 0; } SendNativeAxis(DEVICE_ID_PAD_0 + pDevNum, js.lX, last_lX_, JOYSTICK_AXIS_X); diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index fbecfebe04..dd5bc6e350 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -128,7 +128,7 @@ inline float LinearMapf(float val, float a0, float a1, float b0, float b1) { return b0 + (((val - a0) * (b1 - b0)) / (a1 - a0)); } -static Stick NormalizedDeadzoneFilter(short x, short y, float dz, int idzm, float idz) { +static Stick NormalizedDeadzoneFilter(short x, short y, float dz, int idzm, float idz, float st) { Stick s(x, y, 1.0 / 32767.0f); float magnitude = sqrtf(s.x * s.x + s.y * s.y); @@ -156,21 +156,21 @@ static Stick NormalizedDeadzoneFilter(short x, short y, float dz, int idzm, floa { float xSign = Signf(s.x); if (xSign != 0.0f) { - s.x = LinearMapf(s.x, xSign * dz, xSign, xSign * md, xSign); + s.x = LinearMapf(s.x, xSign * dz, xSign, xSign * md, (xSign * st) - md); } } else if (idzm == 2) { float ySign = Signf(s.y); if (ySign != 0.0f) { - s.y = LinearMapf(s.y, ySign * dz, ySign, ySign * md, ySign); + s.y = LinearMapf(s.y, ySign * dz, ySign, ySign * md, (ySign * st) - md); } } else if (idzm == 3) { float xNorm = s.x / magnitude; float yNorm = s.y / magnitude; - float mapMag = LinearMapf(magnitude, dz, 1.0, md, 1.0); + float mapMag = LinearMapf(magnitude, dz, 1.0f, md, (1.0f * st) - md); s.x = xNorm * mapMag; s.y = yNorm * mapMag; } @@ -238,9 +238,10 @@ int XinputDevice::UpdateState(InputState &input_state) { const float LEFT_STICK_DEADZONE = g_Config.fXInputLeftAnalogDeadzone; const int LEFT_STICK_INV_MODE = g_Config.iXInputLeftAnalogInverseMode; const float LEFT_STICK_INV_DEADZONE = g_Config.fXInputLeftAnalogInverseDeadzone; + const float LEFT_STICK_SENSITIVITY = g_Config.fXInputLeftAnalogSensitivity; if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbLX, prevState.Gamepad.sThumbLY, state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, LEFT_STICK_DEADZONE)) { - Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, LEFT_STICK_DEADZONE, LEFT_STICK_INV_MODE, LEFT_STICK_INV_DEADZONE); + Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, LEFT_STICK_DEADZONE, LEFT_STICK_INV_MODE, LEFT_STICK_INV_DEADZONE, LEFT_STICK_SENSITIVITY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; @@ -259,9 +260,10 @@ int XinputDevice::UpdateState(InputState &input_state) { const float RIGHT_STICK_DEADZONE = g_Config.fXInputRightAnalogDeadzone; const int RIGHT_STICK_INV_MODE = g_Config.iXInputRightAnalogInverseMode; const float RIGHT_STICK_INV_DEADZONE = g_Config.fXInputRightAnalogInverseDeadzone; + const float RIGHT_STICK_SENSITIVITY = g_Config.fXInputRightAnalogSensitivity; if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbRX, prevState.Gamepad.sThumbRY, state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, RIGHT_STICK_DEADZONE)) { - Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, RIGHT_STICK_DEADZONE, RIGHT_STICK_INV_MODE, LEFT_STICK_INV_DEADZONE); + Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, RIGHT_STICK_DEADZONE, RIGHT_STICK_INV_MODE, RIGHT_STICK_INV_DEADZONE, RIGHT_STICK_SENSITIVITY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; From 4c6410cd0d1d5eb10d031724c3844d49405ba990 Mon Sep 17 00:00:00 2001 From: Josh Palmer Date: Thu, 5 Feb 2015 05:48:29 +0000 Subject: [PATCH 3/4] DInput/XInput: Further fixes & improvements * Remove redundant second analog settings for XInput * Replace DInput circle->square mapping with improved XInput version --- Core/Config.cpp | 18 +++++------------- Core/Config.h | 14 ++++---------- UI/GameSettingsScreen.cpp | 14 ++++---------- Windows/DinputDevice.cpp | 22 +++++++++++----------- Windows/XinputDevice.cpp | 21 ++++++++------------- 5 files changed, 32 insertions(+), 57 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index ee1b5f5141..53c5e131c1 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -564,22 +564,14 @@ static ConfigSetting controlSettings[] = { ConfigSetting("AnalogStickScale", &g_Config.fAnalogStickScale, defaultControlScale, true, true), #ifdef _WIN32 ConfigSetting("DInputAnalogDeadzone", &g_Config.fDInputAnalogDeadzone, 0.1f, true, true), + ConfigSetting("DInputAnalogInverseMode", &g_Config.iDInputAnalogInverseMode, 0, true, true), ConfigSetting("DInputAnalogInverseDeadzone", &g_Config.fDInputAnalogInverseDeadzone, 0.0f, true, true), ConfigSetting("DInputAnalogSensitivity", &g_Config.fDInputAnalogSensitivity, 1.0f, true, true), - ConfigSetting("DInputAnalogInverseMode", &g_Config.iDInputAnalogInverseMode, 0, true, true), - ConfigSetting("DInputAnalogInverseDeadzone", &g_Config.fDInputAnalogInverseDeadzone, 0.0f, true, true), - - ConfigSetting("XInputLeftAnalogDeadzone", &g_Config.fXInputLeftAnalogDeadzone, 0.24f, true, true), - ConfigSetting("XInputRightAnalogDeadzone", &g_Config.fXInputRightAnalogDeadzone, 0.27f, true, true), - - ConfigSetting("XInputLeftAnalogInverseMode", &g_Config.iXInputLeftAnalogInverseMode, 0, true, true), - ConfigSetting("XInputLeftAnalogInverseDeadzone", &g_Config.fXInputLeftAnalogInverseDeadzone, 0.0f, true, true), - ConfigSetting("XInputLeftAnalogSensitivity", &g_Config.fXInputLeftAnalogSensitivity, 1.0f, true, true), - - ConfigSetting("XInputRightAnalogInverseMode", &g_Config.iXInputRightAnalogInverseMode, 0, true, true), - ConfigSetting("XInputRightAnalogInverseDeadzone", &g_Config.fXInputRightAnalogInverseDeadzone, 0.0f, true, true), - ConfigSetting("XInputRightAnalogSensitivity", &g_Config.fXInputRightAnalogSensitivity, 1.0f, true, true), + ConfigSetting("XInputAnalogDeadzone", &g_Config.fXInputAnalogDeadzone, 0.24f, true, true), + ConfigSetting("XInputAnalogInverseMode", &g_Config.iXInputAnalogInverseMode, 0, true, true), + ConfigSetting("XInputAnalogInverseDeadzone", &g_Config.fXInputAnalogInverseDeadzone, 0.0f, true, true), + ConfigSetting("XInputAnalogSensitivity", &g_Config.fXInputAnalogSensitivity, 1.0f, true, true), #endif ConfigSetting("AnalogLimiterDeadzone", &g_Config.fAnalogLimiterDeadzone, 0.6f, true, true), diff --git a/Core/Config.h b/Core/Config.h index efff6df126..bd3079dd32 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -281,16 +281,10 @@ public: float fDInputAnalogInverseDeadzone; float fDInputAnalogSensitivity; - float fXInputLeftAnalogDeadzone; - float fXInputRightAnalogDeadzone; - - int iXInputLeftAnalogInverseMode; - float fXInputLeftAnalogInverseDeadzone; - float fXInputLeftAnalogSensitivity; - - int iXInputRightAnalogInverseMode; - float fXInputRightAnalogInverseDeadzone; - float fXInputRightAnalogSensitivity; + float fXInputAnalogDeadzone; + int iXInputAnalogInverseMode; + float fXInputAnalogInverseDeadzone; + float fXInputAnalogSensitivity; float fAnalogLimiterDeadzone; // GLES backend-specific hacks. Not saved to the ini file, do not add checkboxes. Will be made into diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 24fda800db..8dd9337886 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -381,16 +381,10 @@ void GameSettingsScreen::CreateViews() { controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogSensitivity, 0.0f, 10.0f, c->T("Sensitivity"), screenManager())); controlsSettings->Add(new ItemHeader(c->T("XInput Analog Settings", "XInput Analog Settings"))); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputLeftAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone (Left Stick)"), screenManager())); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputRightAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone (Right Stick)"), screenManager())); - - controlsSettings->Add(new PopupMultiChoice(&g_Config.iXInputLeftAnalogInverseMode, c->T("Inverse Dead Zone Mode (Left Stick)"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputLeftAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size (Left Stick)"), screenManager())); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputLeftAnalogSensitivity, 0.0f, 10.0f, c->T("Sensitivity (Left Stick)"), screenManager())); - - controlsSettings->Add(new PopupMultiChoice(&g_Config.iXInputRightAnalogInverseMode, c->T("Inverse Dead Zone Mode (Right Stick)"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputRightAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size (Right Stick)"), screenManager())); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputRightAnalogSensitivity, 0.0f, 10.0f, c->T("Sensitivity (Right Stick)"), screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone"), screenManager())); + controlsSettings->Add(new PopupMultiChoice(&g_Config.iXInputAnalogInverseMode, c->T("Inverse Dead Zone Mode"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size"), screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputAnalogSensitivity, 0.0f, 10.0f, c->T("Sensitivity"), screenManager())); controlsSettings->Add(new ItemHeader(c->T("Keyboard", "Keyboard Control Settings"))); #if defined(USING_WIN_UI) diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index 5d5205c3fa..d98b8b97a7 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -208,8 +208,7 @@ void SendNativeAxis(int deviceId, short value, short &lastValue, int axisId) { AxisInput axis; axis.deviceId = deviceId; axis.axisId = axisId; - //axis.value = NormalizedDeadzoneFilter(value); - axis.value = (float)value / 10000.0f; + axis.value = (float)value / 10000.0f; // Convert axis to normalised float NativeAxis(axis); lastValue = value; @@ -241,6 +240,13 @@ int DinputDevice::UpdateState(InputState &input_state) { if (analog) { AxisInput axis; axis.deviceId = DEVICE_ID_PAD_0 + pDevNum; + + // Circle to Square mapping, cribbed from XInputDevice + float sx = js.lX; + float sy = js.lY; + float scaleFactor = sqrtf((sx * sx + sy * sy) / std::max(sx * sx, sy * sy)); + js.lX = (short)(sx * scaleFactor); + js.lY = (short)(sy * scaleFactor); // Linear range mapping (used to invert deadzones) float dz = g_Config.fDInputAnalogDeadzone; @@ -280,6 +286,9 @@ int DinputDevice::UpdateState(InputState &input_state) { js.lY = 0; } + js.lX = (short)std::min(10000.0f, std::max((float)js.lX, -10000.0f)); + js.lY = (short)std::min(10000.0f, std::max((float)js.lY, -10000.0f)); + SendNativeAxis(DEVICE_ID_PAD_0 + pDevNum, js.lX, last_lX_, JOYSTICK_AXIS_X); SendNativeAxis(DEVICE_ID_PAD_0 + pDevNum, js.lY, last_lY_, JOYSTICK_AXIS_Y); SendNativeAxis(DEVICE_ID_PAD_0 + pDevNum, js.lZ, last_lZ_, JOYSTICK_AXIS_Z); @@ -300,15 +309,6 @@ int DinputDevice::UpdateState(InputState &input_state) { return -1; } -static float NormalizedDeadzoneFilter(short value) { - float result = (float)value / 10000.0f; - - // Expand and clamp. Hack to let us reach the corners on most pads. - result = std::min(1.0f, std::max(result * 1.2f, -1.0f)); - - return result; -} - void DinputDevice::ApplyButtons(DIJOYSTATE2 &state, InputState &input_state) { BYTE *buttons = state.rgbButtons; u32 downMask = 0x80; diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index dd5bc6e350..a3ea140ae7 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -235,13 +235,13 @@ int XinputDevice::UpdateState(InputState &input_state) { } ApplyButtons(state, input_state); - const float LEFT_STICK_DEADZONE = g_Config.fXInputLeftAnalogDeadzone; - const int LEFT_STICK_INV_MODE = g_Config.iXInputLeftAnalogInverseMode; - const float LEFT_STICK_INV_DEADZONE = g_Config.fXInputLeftAnalogInverseDeadzone; - const float LEFT_STICK_SENSITIVITY = g_Config.fXInputLeftAnalogSensitivity; + const float STICK_DEADZONE = g_Config.fXInputAnalogDeadzone; + const int STICK_INV_MODE = g_Config.iXInputAnalogInverseMode; + const float STICK_INV_DEADZONE = g_Config.fXInputAnalogInverseDeadzone; + const float STICK_SENSITIVITY = g_Config.fXInputAnalogSensitivity; - if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbLX, prevState.Gamepad.sThumbLY, state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, LEFT_STICK_DEADZONE)) { - Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, LEFT_STICK_DEADZONE, LEFT_STICK_INV_MODE, LEFT_STICK_INV_DEADZONE, LEFT_STICK_SENSITIVITY); + if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbLX, prevState.Gamepad.sThumbLY, state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, STICK_DEADZONE)) { + Stick left = NormalizedDeadzoneFilter(state.Gamepad.sThumbLX, state.Gamepad.sThumbLY, STICK_DEADZONE, STICK_INV_MODE, STICK_INV_DEADZONE, STICK_SENSITIVITY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; @@ -257,13 +257,8 @@ int XinputDevice::UpdateState(InputState &input_state) { } } - const float RIGHT_STICK_DEADZONE = g_Config.fXInputRightAnalogDeadzone; - const int RIGHT_STICK_INV_MODE = g_Config.iXInputRightAnalogInverseMode; - const float RIGHT_STICK_INV_DEADZONE = g_Config.fXInputRightAnalogInverseDeadzone; - const float RIGHT_STICK_SENSITIVITY = g_Config.fXInputRightAnalogSensitivity; - - if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbRX, prevState.Gamepad.sThumbRY, state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, RIGHT_STICK_DEADZONE)) { - Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, RIGHT_STICK_DEADZONE, RIGHT_STICK_INV_MODE, RIGHT_STICK_INV_DEADZONE, RIGHT_STICK_SENSITIVITY); + if (NormalizedDeadzoneDiffers(prevState.Gamepad.sThumbRX, prevState.Gamepad.sThumbRY, state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, STICK_DEADZONE)) { + Stick right = NormalizedDeadzoneFilter(state.Gamepad.sThumbRX, state.Gamepad.sThumbRY, STICK_DEADZONE, STICK_INV_MODE, STICK_INV_DEADZONE, STICK_SENSITIVITY); AxisInput axis; axis.deviceId = DEVICE_ID_X360_0; From 929866edd362fa775721c84e5ff5c9ebc12e3be4 Mon Sep 17 00:00:00 2001 From: Josh Palmer Date: Thu, 5 Feb 2015 06:30:29 +0000 Subject: [PATCH 4/4] XInput/DInput: Rename settings, fix sensitivity * Change deadzone inverter naming convention to 'analog mapper' * Remove hokey mathematics from sensitivity calculations --- UI/GameSettingsScreen.cpp | 12 ++++++------ Windows/DinputDevice.cpp | 6 +++--- Windows/XinputDevice.cpp | 6 +++--- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 8dd9337886..09828e6aa1 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -376,15 +376,15 @@ void GameSettingsScreen::CreateViews() { controlsSettings->Add(new ItemHeader(c->T("DInput Analog Settings", "DInput Analog Settings"))); controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone"), screenManager())); - controlsSettings->Add(new PopupMultiChoice(&g_Config.iDInputAnalogInverseMode, c->T("Inverse Dead Zone Mode"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size"), screenManager())); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogSensitivity, 0.0f, 10.0f, c->T("Sensitivity"), screenManager())); + controlsSettings->Add(new PopupMultiChoice(&g_Config.iDInputAnalogInverseMode, c->T("Analog Mapper Mode"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Analog Mapper Low End (Inverse Deadzone)"), screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fDInputAnalogSensitivity, 0.0f, 10.0f, c->T("Analog Mapper High End (Axis Sensitivity)"), screenManager())); controlsSettings->Add(new ItemHeader(c->T("XInput Analog Settings", "XInput Analog Settings"))); controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputAnalogDeadzone, 0.0f, 1.0f, c->T("Dead Zone"), screenManager())); - controlsSettings->Add(new PopupMultiChoice(&g_Config.iXInputAnalogInverseMode, c->T("Inverse Dead Zone Mode"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Inverse Dead Zone Size"), screenManager())); - controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputAnalogSensitivity, 0.0f, 10.0f, c->T("Sensitivity"), screenManager())); + controlsSettings->Add(new PopupMultiChoice(&g_Config.iXInputAnalogInverseMode, c->T("Analog Mapper Mode"), inverseDeadzoneModes, 0, ARRAY_SIZE(inverseDeadzoneModes), c, screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputAnalogInverseDeadzone, 0.0f, 1.0f, c->T("Analog Mapper Low End (Inverse Deadzone)"), screenManager())); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fXInputAnalogSensitivity, 0.0f, 10.0f, c->T("Analog Mapper High End (Axis Sensitivity)"), screenManager())); controlsSettings->Add(new ItemHeader(c->T("Keyboard", "Keyboard Control Settings"))); #if defined(USING_WIN_UI) diff --git a/Windows/DinputDevice.cpp b/Windows/DinputDevice.cpp index d98b8b97a7..77476c0bb9 100644 --- a/Windows/DinputDevice.cpp +++ b/Windows/DinputDevice.cpp @@ -261,21 +261,21 @@ int DinputDevice::UpdateState(InputState &input_state) { { short xSign = Signs(js.lX); if (xSign != 0.0f) { - js.lX = LinearMaps(js.lX, xSign * (short)(dz * 10000), xSign * 10000, xSign * (short)(md * 10000), (xSign * 10000 * st) - (short)(md * 10000) ); + js.lX = LinearMaps(js.lX, xSign * (short)(dz * 10000), xSign * 10000, xSign * (short)(md * 10000), xSign * 10000 * st); } } else if (idzm == 2) { short ySign = Signs(js.lY); if (ySign != 0.0f) { - js.lY = LinearMaps(js.lY, ySign * (short)(dz * 10000.0f), ySign * 10000, ySign * (short)(md * 10000.0f), (ySign * 10000 * st) - (short)(md * 10000)); + js.lY = LinearMaps(js.lY, ySign * (short)(dz * 10000.0f), ySign * 10000, ySign * (short)(md * 10000.0f), ySign * 10000 * st); } } else if (idzm == 3) { float xNorm = (float)js.lX / magnitude; float yNorm = (float)js.lY / magnitude; - float mapMag = LinearMaps(magnitude, dz * 10000.0f, 10000.0f, md * 10000.0f, (10000.0f * st) - (short)(md * 10000)); + float mapMag = LinearMaps(magnitude, dz * 10000.0f, 10000.0f, md * 10000.0f, 10000.0f * st); js.lX = (short)(xNorm * mapMag); js.lY = (short)(yNorm * mapMag); } diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index a3ea140ae7..deae4fc882 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -156,21 +156,21 @@ static Stick NormalizedDeadzoneFilter(short x, short y, float dz, int idzm, floa { float xSign = Signf(s.x); if (xSign != 0.0f) { - s.x = LinearMapf(s.x, xSign * dz, xSign, xSign * md, (xSign * st) - md); + s.x = LinearMapf(s.x, xSign * dz, xSign, xSign * md, xSign * st); } } else if (idzm == 2) { float ySign = Signf(s.y); if (ySign != 0.0f) { - s.y = LinearMapf(s.y, ySign * dz, ySign, ySign * md, (ySign * st) - md); + s.y = LinearMapf(s.y, ySign * dz, ySign, ySign * md, ySign * st); } } else if (idzm == 3) { float xNorm = s.x / magnitude; float yNorm = s.y / magnitude; - float mapMag = LinearMapf(magnitude, dz, 1.0f, md, (1.0f * st) - md); + float mapMag = LinearMapf(magnitude, dz, 1.0f, md, st); s.x = xNorm * mapMag; s.y = yNorm * mapMag; }