More tweaks (work around the old problem where lingering analog values biased the digital input)

This commit is contained in:
Henrik Rydgård 2023-03-31 20:27:30 +02:00
parent 48993f4f4b
commit 9804a905c8
2 changed files with 27 additions and 2 deletions

View file

@ -155,6 +155,15 @@ static int RotatePSPKeyCode(int x) {
}
}
// Used to decay analog values when clashing with digital ones.
static float ReduceMagnitude(float value) {
value *= 0.75f;
if ((value > 0.0f && value < 0.05f) || (value < 0.0f && value > -0.05f)) {
value = 0.0f;
}
return value;
}
// Can only be called from Key or Axis.
bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) {
// Instead of taking an input key and finding what it outputs, we loop through the OUTPUTS and
@ -262,6 +271,20 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) {
continue;
}
// Small values from analog inputs like gamepad sticks can linger around, which is bad here because we sum
// up before applying deadzone etc. This means that it can be impossible to reach the min/max values with digital input!
// So if non-analog events clash with analog ones mapped to the same input, decay the analog input,
// which will quickly get things back to normal, while if it's intentional to use both at the same time for some reason,
// that still works, though a bit weaker. We could also zero here, but you never know who relies on such strange tricks..
// Note: This is an old problem, it didn't appear with the refactoring.
if (!changedMapping.IsAxis()) {
for (auto &mapping : inputMappings) {
if (mapping.IsAxis()) {
curInput_[mapping] = ReduceMagnitude(curInput_[mapping]);
}
}
}
value = clamp_value(value, 0.0f, 1.0f);
// Derive bools from the floats using the device's threshold.
@ -440,7 +463,7 @@ void ControlMapper::GetDebugString(char *buffer, size_t bufSize) const {
}
for (int i = 0; i < ARRAY_SIZE(virtKeys_); i++) {
int vkId = VIRTKEY_FIRST + i;
if ((vkId >= VIRTKEY_AXIS_X_MIN && vkId <= VIRTKEY_AXIS_Y_MAX) || vkId == VIRTKEY_ANALOG_LIGHTLY) {
if ((vkId >= VIRTKEY_AXIS_X_MIN && vkId <= VIRTKEY_AXIS_Y_MAX) || vkId == VIRTKEY_ANALOG_LIGHTLY || vkId == VIRTKEY_SPEED_ANALOG) {
str << KeyMap::GetPspButtonName(vkId) << ": " << virtKeys_[i] << std::endl;
}
}

View file

@ -771,7 +771,9 @@ void EmuScreen::onVKeyAnalog(int virtualKeyCode, float value) {
// We only handle VIRTKEY_SPEED_ANALOG here.
static constexpr float DEADZONE_THRESHOLD = 0.15f;
// Xbox controllers need a pretty big deadzone here to not leave behind small values
// on occasion when releasing the trigger. Still feels right.
static constexpr float DEADZONE_THRESHOLD = 0.20f;
static constexpr float DEADZONE_SCALE = 1.0f / (1.0f - DEADZONE_THRESHOLD);
FPSLimit &limitMode = PSP_CoreParameter().fpsLimit;