From 3895cfff749da38ab0795fa7155e1d427b44b355 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Thu, 28 Dec 2023 13:36:03 +0100 Subject: [PATCH] Add "Analog trigger threshold" setting, for conversion of analog trigger inputs to digital button inputs. --- Core/Config.cpp | 1 + Core/Config.h | 3 +++ Core/ControlMapper.cpp | 26 ++++++++++++++++++++------ Core/ControlMapper.h | 1 + Core/KeyMap.cpp | 21 ++++++++++++++++++++- Core/KeyMap.h | 13 +++++++++---- GPU/Common/TextureReplacer.cpp | 1 + UI/ControlMappingScreen.cpp | 4 ++++ UI/GameSettingsScreen.cpp | 1 + 9 files changed, 60 insertions(+), 11 deletions(-) diff --git a/Core/Config.cpp b/Core/Config.cpp index 1d97f59050..750ab894c3 100644 --- a/Core/Config.cpp +++ b/Core/Config.cpp @@ -827,6 +827,7 @@ static const ConfigSetting controlSettings[] = { ConfigSetting("AnalogAutoRotSpeed", &g_Config.fAnalogAutoRotSpeed, 8.0f, CfgFlag::PER_GAME), ConfigSetting("AnalogLimiterDeadzone", &g_Config.fAnalogLimiterDeadzone, 0.6f, CfgFlag::DEFAULT), + ConfigSetting("AnalogTriggerThreshold", &g_Config.fAnalogTriggerThreshold, 0.75f, CfgFlag::DEFAULT), ConfigSetting("AllowMappingCombos", &g_Config.bAllowMappingCombos, false, CfgFlag::DEFAULT), diff --git a/Core/Config.h b/Core/Config.h index 798fb7bc33..eacd1ecfa0 100644 --- a/Core/Config.h +++ b/Core/Config.h @@ -396,6 +396,9 @@ public: // Sets up how much the analog limiter button restricts digital->analog input. float fAnalogLimiterDeadzone; + // Trigger configuration + float fAnalogTriggerThreshold; + // Sets whether combo mapping is enabled. bool bAllowMappingCombos; diff --git a/Core/ControlMapper.cpp b/Core/ControlMapper.cpp index dc4dd4afa3..a8746afc08 100644 --- a/Core/ControlMapper.cpp +++ b/Core/ControlMapper.cpp @@ -15,9 +15,23 @@ using KeyMap::MultiInputMapping; -// TODO: Possibly make these thresholds configurable? -static float GetDeviceAxisThreshold(int device) { - return device == DEVICE_ID_MOUSE ? AXIS_BIND_THRESHOLD_MOUSE : AXIS_BIND_THRESHOLD; +const float AXIS_BIND_THRESHOLD = 0.75f; +const float AXIS_BIND_THRESHOLD_MOUSE = 0.01f; + +float GetDeviceAxisThreshold(int device, const InputMapping &mapping) { + if (device == DEVICE_ID_MOUSE) { + return AXIS_BIND_THRESHOLD_MOUSE; + } + if (mapping.IsAxis()) { + switch (KeyMap::GetAxisType((InputAxis)mapping.Axis(nullptr))) { + case KeyMap::AxisType::TRIGGER: + return g_Config.fAnalogTriggerThreshold; + default: + return AXIS_BIND_THRESHOLD; + } + } else { + return AXIS_BIND_THRESHOLD; + } } static int GetOppositeVKey(int vkey) { @@ -311,7 +325,7 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping, double no } else { curTime = iter->second.timestamp; } - bool down = iter->second.value > GetDeviceAxisThreshold(iter->first.deviceId); + bool down = iter->second.value > GetDeviceAxisThreshold(iter->first.deviceId, mapping); if (!down) all = false; } @@ -364,7 +378,7 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping, double no } if (mapping.IsAxis()) { - threshold = GetDeviceAxisThreshold(iter->first.deviceId); + threshold = GetDeviceAxisThreshold(iter->first.deviceId, mapping); float value = MapAxisValue(iter->second.value, idForMapping, mapping, changedMapping, &touchedByMapping); product *= value; } else { @@ -510,7 +524,7 @@ void ControlMapper::ToggleSwapAxes() { void ControlMapper::UpdateCurInputAxis(const InputMapping &mapping, float value, double timestamp) { InputSample &input = curInput_[mapping]; input.value = value; - if (value > GetDeviceAxisThreshold(mapping.deviceId)) { + if (value >= GetDeviceAxisThreshold(mapping.deviceId, mapping)) { if (input.timestamp == 0.0) { input.timestamp = time_now_d(); } diff --git a/Core/ControlMapper.h b/Core/ControlMapper.h index 60d975070e..1df1f39244 100644 --- a/Core/ControlMapper.h +++ b/Core/ControlMapper.h @@ -93,3 +93,4 @@ private: }; void ConvertAnalogStick(float x, float y, float *outX, float *outY); +float GetDeviceAxisThreshold(int device, const InputMapping &mapping); diff --git a/Core/KeyMap.cpp b/Core/KeyMap.cpp index 34a92313f4..980329ee41 100644 --- a/Core/KeyMap.cpp +++ b/Core/KeyMap.cpp @@ -48,6 +48,25 @@ std::set g_seenPads; std::map g_padNames; std::set g_seenDeviceIds; +AxisType GetAxisType(InputAxis input) { + switch (input) { + case JOYSTICK_AXIS_GAS: + case JOYSTICK_AXIS_BRAKE: + case JOYSTICK_AXIS_LTRIGGER: + case JOYSTICK_AXIS_RTRIGGER: + return AxisType::TRIGGER; + case JOYSTICK_AXIS_X: + case JOYSTICK_AXIS_Y: + case JOYSTICK_AXIS_Z: + case JOYSTICK_AXIS_RX: + case JOYSTICK_AXIS_RY: + case JOYSTICK_AXIS_RZ: + return AxisType::STICK; + default: + return AxisType::OTHER; + } +} + // Utility for UI navigation void SingleInputMappingFromPspButton(int btn, std::vector *mappings, bool ignoreMouse) { std::vector multiMappings; @@ -874,7 +893,7 @@ bool HasChanged(int &prevGeneration) { return false; } -static const char *g_vKeyNames[] = { +static const char * const g_vKeyNames[] = { "AXIS_X_MIN", "AXIS_Y_MIN", "AXIS_X_MAX", diff --git a/Core/KeyMap.h b/Core/KeyMap.h index 00a75befd5..de9334d32e 100644 --- a/Core/KeyMap.h +++ b/Core/KeyMap.h @@ -78,10 +78,6 @@ enum { VIRTKEY_COUNT = VIRTKEY_LAST - VIRTKEY_FIRST }; -const float AXIS_BIND_THRESHOLD = 0.75f; -const float AXIS_BIND_RELEASE_THRESHOLD = 0.35f; // Used during mapping only to detect a "key-up" reliably. -const float AXIS_BIND_THRESHOLD_MOUSE = 0.01f; - struct MappedAnalogAxis { int axisId; int direction; @@ -224,4 +220,13 @@ namespace KeyMap { bool IsKeyMapped(InputDeviceID device, int key); bool HasChanged(int &prevGeneration); + + // Used for setting thresholds. Technically we could allow a setting per axis, but this is a reasonable compromise. + enum class AxisType { + TRIGGER, + STICK, + OTHER, + }; + + AxisType GetAxisType(InputAxis axis); } // namespace KeyMap diff --git a/GPU/Common/TextureReplacer.cpp b/GPU/Common/TextureReplacer.cpp index a17789b542..f11c287608 100644 --- a/GPU/Common/TextureReplacer.cpp +++ b/GPU/Common/TextureReplacer.cpp @@ -600,6 +600,7 @@ ReplacedTexture *TextureReplacer::FindReplacement(u64 cachekey, u32 hash, int w, desc.hashfiles = hashfiles; } + _dbg_assert_(!hashfiles.empty()); // OK, we might already have a matching texture, we use hashfiles as a key. Look it up in the level cache. auto iter = levelCache_.find(hashfiles); if (iter != levelCache_.end()) { diff --git a/UI/ControlMappingScreen.cpp b/UI/ControlMappingScreen.cpp index 1e07aa4506..cf4f75d8ff 100644 --- a/UI/ControlMappingScreen.cpp +++ b/UI/ControlMappingScreen.cpp @@ -441,6 +441,10 @@ bool KeyMappingNewMouseKeyDialog::key(const KeyInput &key) { return true; } +// Only used during the bind process. In other places, it's configurable for some types of axis, like trigger. +const float AXIS_BIND_THRESHOLD = 0.75f; +const float AXIS_BIND_RELEASE_THRESHOLD = 0.35f; // Used during mapping only to detect a "key-up" reliably. + void KeyMappingNewKeyDialog::axis(const AxisInput &axis) { if (time_now_d() < delayUntil_) return; diff --git a/UI/GameSettingsScreen.cpp b/UI/GameSettingsScreen.cpp index 4ef735fe8a..b26af2382f 100644 --- a/UI/GameSettingsScreen.cpp +++ b/UI/GameSettingsScreen.cpp @@ -669,6 +669,7 @@ void GameSettingsScreen::CreateControlsSettings(UI::ViewGroup *controlsSettings) controlsSettings->Add(new ItemHeader(ms->T("Controls"))); controlsSettings->Add(new Choice(co->T("Control Mapping")))->OnClick.Handle(this, &GameSettingsScreen::OnControlMapping); controlsSettings->Add(new Choice(co->T("Calibrate Analog Stick")))->OnClick.Handle(this, &GameSettingsScreen::OnCalibrateAnalogs); + controlsSettings->Add(new PopupSliderChoiceFloat(&g_Config.fAnalogTriggerThreshold, 0.25f, 0.98f, 0.75f, co->T("Analog trigger threshold"), screenManager())); #if defined(USING_WIN_UI) || (PPSSPP_PLATFORM(LINUX) && !PPSSPP_PLATFORM(ANDROID)) controlsSettings->Add(new CheckBox(&g_Config.bSystemControls, co->T("Enable standard shortcut keys")));