DInput/XInput: Deadzone fixes & Sensitivity

* DInput Deadzone & Deadzone Inverter now function correctly
* Added analog Sensitivity options to DInput and XInput
This commit is contained in:
Josh Palmer 2015-02-05 05:30:39 +00:00
parent 918b96500c
commit 6856709b1d
5 changed files with 51 additions and 28 deletions

View File

@ -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),

View File

@ -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

View File

@ -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)

View File

@ -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);

View File

@ -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;