Skip to content

Commit

Permalink
Tilt: Add back inverse deadzone (low end radius). Allow choosing circ…
Browse files Browse the repository at this point in the history
…ular or per-axis.
  • Loading branch information
hrydgard committed May 22, 2023
1 parent d5dfef8 commit 2ceb994
Show file tree
Hide file tree
Showing 4 changed files with 29 additions and 1 deletion.
1 change: 1 addition & 0 deletions Core/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -681,6 +681,7 @@ static const ConfigSetting controlSettings[] = {
ConfigSetting("TiltSensitivityX", &g_Config.iTiltSensitivityX, 60, CfgFlag::PER_GAME),
ConfigSetting("TiltSensitivityY", &g_Config.iTiltSensitivityY, 60, CfgFlag::PER_GAME),
ConfigSetting("TiltAnalogDeadzoneRadius", &g_Config.fTiltAnalogDeadzoneRadius, 0.0f, CfgFlag::PER_GAME),
ConfigSetting("TiltInverseDeadzone", &g_Config.fTiltInverseDeadzone, 0.0f, CfgFlag::PER_GAME),
ConfigSetting("TiltInputType", &g_Config.iTiltInputType, 0, CfgFlag::PER_GAME),
#endif

Expand Down
2 changes: 2 additions & 0 deletions Core/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ struct Config {
int iTiltSensitivityY;
// The deadzone radius of the tilt. Only used in the analog mapping.
float fTiltAnalogDeadzoneRadius;
float fTiltInverseDeadzone; // An inverse deadzone for the output, counteracting excessive deadzones applied by games. See #17483.
bool bTiltCircularInverseDeadzone;
// Type of tilt input currently selected: Defined in TiltEventProcessor.h
// 0 - no tilt, 1 - analog stick, 2 - D-Pad, 3 - Action Buttons (Tri, Cross, Square, Circle)
int iTiltInputType;
Expand Down
25 changes: 24 additions & 1 deletion Core/TiltEventProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,24 @@ inline float ApplyDeadzone(float x, float deadzone) {
}
}

// Also clamps to -1.0..1.0.
// This applies a (circular if desired) inverse deadzone.
inline void ApplyInverseDeadzone(float x, float y, float *outX, float *outY, float inverseDeadzone, bool circular) {
if (inverseDeadzone == 0.0f) {
*outX = Clamp(x, -1.0f, 1.0f);
*outY = Clamp(y, -1.0f, 1.0f);
}
if (circular) {
float magnitude = sqrtf(x * x + y * y);
magnitude = (magnitude + inverseDeadzone) / magnitude;
*outX = Clamp(x * magnitude, -1.0f, 1.0f);
*outY = Clamp(y * magnitude, -1.0f, 1.0f);
} else {
*outX = Clamp(x + copysignf(inverseDeadzone, x), -1.0f, 1.0f);
*outY = Clamp(y + copysignf(inverseDeadzone, y), -1.0f, 1.0f);
}
}

void ProcessTilt(bool landscape, float calibrationAngle, float x, float y, float z, bool invertX, bool invertY, float xSensitivity, float ySensitivity) {
if (g_Config.iTiltInputType == TILT_NULL) {
// Turned off - nothing to do.
Expand Down Expand Up @@ -79,9 +97,14 @@ void ProcessTilt(bool landscape, float calibrationAngle, float x, float y, float

if (g_Config.iTiltInputType == TILT_ANALOG) {
// Only analog mappings use the deadzone.

float adjustedTiltX = ApplyDeadzone(tiltX, g_Config.fTiltAnalogDeadzoneRadius);
float adjustedTiltY = ApplyDeadzone(tiltY, g_Config.fTiltAnalogDeadzoneRadius);

// Unlike regular deadzone, where per-axis is okay, inverse deadzone (to compensate for game deadzones) really needs to be
// applied on the two axes together.
// TODO: Share this code with the joystick code. For now though, we keep it separate.
ApplyInverseDeadzone(adjustedTiltX, adjustedTiltY, &adjustedTiltX, &adjustedTiltY, g_Config.fTiltInverseDeadzone, g_Config.bTiltCircularInverseDeadzone);

rawTiltAnalogX = adjustedTiltX;
rawTiltAnalogY = adjustedTiltY;
GenerateAnalogStickEvent(adjustedTiltX, adjustedTiltY);
Expand Down
2 changes: 2 additions & 0 deletions UI/TiltAnalogSettingsScreen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ void TiltAnalogSettingsScreen::CreateViews() {
settings->Add(new ItemHeader(co->T("Sensitivity")));
if (g_Config.iTiltInputType == 1) {
settings->Add(new PopupSliderChoiceFloat(&g_Config.fTiltAnalogDeadzoneRadius, 0.0f, 0.8f, 0.0f, co->T("Deadzone radius"), 0.01f, screenManager(), "/ 1.0"))->SetEnabledFunc(enabledFunc);
settings->Add(new PopupSliderChoiceFloat(&g_Config.fTiltInverseDeadzone, 0.0f, 0.8f, 0.0f, co->T("Low end radius"), 0.0f, screenManager(), "/ 1.0"))->SetEnabledFunc(enabledFunc);
settings->Add(new CheckBox(&g_Config.bTiltCircularInverseDeadzone, co->T("Circular low end radius")))->SetEnabledFunc(enabledFunc);
}
settings->Add(new PopupSliderChoice(&g_Config.iTiltSensitivityX, 0, 100, 60, co->T("Tilt Sensitivity along X axis"), screenManager(), "%"))->SetEnabledFunc(enabledFunc);
settings->Add(new PopupSliderChoice(&g_Config.iTiltSensitivityY, 0, 100, 60, co->T("Tilt Sensitivity along Y axis"), screenManager(), "%"))->SetEnabledFunc(enabledFunc);
Expand Down

0 comments on commit 2ceb994

Please sign in to comment.