Add Steam Input-style advanced deadzone controls to analog calibration

This commit is contained in:
David Cottingham
2026-05-16 19:09:25 -10:00
parent fa50bb1976
commit 043b0a437c
5 changed files with 198 additions and 10 deletions
+34 -2
View File
@@ -551,9 +551,34 @@ void AnalogCalibrationScreen::CreateSettingsViews(UI::ViewGroup *scrollContents)
scrollContents->Add(new PopupSliderChoiceFloat(&g_Config.fAnalogDeadzone, 0.0f, 0.5f, 0.15f, co->T("Deadzone radius"), 0.01f, screenManager(), "/ 1.0"));
scrollContents->Add(new PopupSliderChoiceFloat(&g_Config.fAnalogInverseDeadzone, 0.0f, 1.0f, 0.0f, co->T("Low end radius"), 0.01f, screenManager(), "/ 1.0"));
scrollContents->Add(new PopupSliderChoiceFloat(&g_Config.fAnalogSensitivity, 0.0f, 2.0f, 1.1f, co->T("Sensitivity (scale)", "Sensitivity"), 0.01f, screenManager(), "x"));
// TODO: This should probably be a slider.
scrollContents->Add(new CheckBox(&g_Config.bAnalogIsCircular, co->T("Circular stick input")));
// Legacy circular toggle. Disabled when deadzone shape is set to Circle, since that already provides circular behavior.
CheckBox *circularCheck = scrollContents->Add(new CheckBox(&g_Config.bAnalogIsCircular, co->T("Circular stick input")));
circularCheck->SetEnabledFunc([] {
return g_Config.iAnalogDeadzoneShape != 0; // Disabled when shape is Circle (redundant)
});
scrollContents->Add(new PopupSliderChoiceFloat(&g_Config.fAnalogAutoRotSpeed, 0.1f, 20.0f, 8.0f, co->T("Auto-rotation speed"), 1.0f, screenManager()));
// Advanced deadzone settings (Steam Input-style).
scrollContents->Add(new ItemHeader(co->T("Advanced Deadzone Settings")));
static const char *deadzoneShapes[] = { "Circle", "Square", "Cross" };
scrollContents->Add(new PopupMultiChoice(&g_Config.iAnalogDeadzoneShape, co->T("Deadzone shape"), deadzoneShapes, 0, ARRAY_SIZE(deadzoneShapes), I18NCat::CONTROLS, screenManager()));
PopupSliderChoiceFloat *axialDZ = scrollContents->Add(new PopupSliderChoiceFloat(&g_Config.fAnalogAxialDeadzone, 0.0f, 0.5f, 0.0f, co->T("Axial anti-deadzone"), 0.01f, screenManager(), "/ 1.0"));
axialDZ->SetEnabledFunc([] {
return g_Config.iAnalogDeadzoneShape == 2; // Only enabled for Cross shape
});
scrollContents->Add(new PopupSliderChoiceFloat(&g_Config.fAnalogOuterDeadzone, 0.0f, 0.3f, 0.0f, co->T("Outer deadzone"), 0.01f, screenManager(), "/ 1.0"));
scrollContents->Add(new PopupSliderChoiceFloat(&g_Config.fAnalogOutputAntiDeadzone, 0.0f, 0.5f, 0.0f, co->T("Output anti-deadzone"), 0.01f, screenManager(), "/ 1.0"));
PopupSliderChoiceFloat *adBuffer = scrollContents->Add(new PopupSliderChoiceFloat(&g_Config.fAnalogOutputAntiDeadzoneBuffer, 0.0f, 0.2f, 0.0f, co->T("Anti-deadzone buffer"), 0.01f, screenManager(), "/ 1.0"));
adBuffer->SetEnabledFunc([] {
return g_Config.fAnalogOutputAntiDeadzone > 0.0f; // Buffer only makes sense with anti-deadzone active
});
static const char *responseCurves[] = { "Linear", "Aggressive", "Relaxed", "Wide" };
scrollContents->Add(new PopupMultiChoice(&g_Config.iAnalogResponseCurve, co->T("Response curve"), responseCurves, 0, ARRAY_SIZE(responseCurves), I18NCat::CONTROLS, screenManager()));
scrollContents->Add(new Choice(co->T("Reset to defaults")))->OnClick.Handle(this, &AnalogCalibrationScreen::OnResetToDefaults);
}
@@ -576,6 +601,13 @@ void AnalogCalibrationScreen::OnResetToDefaults(UI::EventParams &e) {
g_Config.fAnalogSensitivity = 1.1f;
g_Config.bAnalogIsCircular = false;
g_Config.fAnalogAutoRotSpeed = 8.0f;
// Advanced settings
g_Config.iAnalogDeadzoneShape = 1; // Square (matches legacy default)
g_Config.fAnalogAxialDeadzone = 0.0f;
g_Config.fAnalogOuterDeadzone = 0.0f;
g_Config.fAnalogOutputAntiDeadzone = 0.0f;
g_Config.fAnalogOutputAntiDeadzoneBuffer = 0.0f;
g_Config.iAnalogResponseCurve = 0;
}
class Backplate : public UI::InertView {