Properly fix the analog limiter feature ("lightly").

This commit is contained in:
Henrik Rydgård 2023-04-15 17:36:55 +02:00
parent 2ac73bd830
commit 9612bff2ac
5 changed files with 37 additions and 8 deletions

View File

@ -680,7 +680,7 @@ static const ConfigSetting controlSettings[] = {
ConfigSetting("AnalogIsCircular", &g_Config.bAnalogIsCircular, false, CfgFlag::PER_GAME),
ConfigSetting("AnalogAutoRotSpeed", &g_Config.fAnalogAutoRotSpeed, 8.0f, CfgFlag::PER_GAME),
ConfigSetting("AnalogLimiterDeadzone", &g_Config.fAnalogLimiterDeadzone, 0.25f, CfgFlag::DEFAULT),
ConfigSetting("AnalogLimiterDeadzone", &g_Config.fAnalogLimiterDeadzone, 0.6f, CfgFlag::DEFAULT),
ConfigSetting("LeftStickHeadScale", &g_Config.fLeftStickHeadScale, 1.0f, CfgFlag::PER_GAME),
ConfigSetting("RightStickHeadScale", &g_Config.fRightStickHeadScale, 1.0f, CfgFlag::PER_GAME),

View File

@ -387,6 +387,7 @@ public:
// Auto rotation speed
float fAnalogAutoRotSpeed;
// Sets up how much the analog limiter button restricts digital->analog input.
float fAnalogLimiterDeadzone;
bool bMouseControl;

View File

@ -136,14 +136,23 @@ void ControlMapper::SetPSPAxis(int device, int stick, char axis, float value) {
if (!ignore) {
history_[stick][axisId] = value;
float x, y;
ConvertAnalogStick(history_[stick][0], history_[stick][1], &x, &y);
converted_[stick][0] = x;
converted_[stick][1] = y;
setPSPAnalog_(stick, x, y);
UpdateAnalogOutput(stick);
}
}
void ControlMapper::UpdateAnalogOutput(int stick) {
float x, y;
ConvertAnalogStick(history_[stick][0], history_[stick][1], &x, &y);
if (virtKeyOn_[VIRTKEY_ANALOG_LIGHTLY - VIRTKEY_FIRST]) {
x *= g_Config.fAnalogLimiterDeadzone;
y *= g_Config.fAnalogLimiterDeadzone;
}
converted_[stick][0] = x;
converted_[stick][1] = y;
setPSPAnalog_(stick, x, y);
}
static int RotatePSPKeyCode(int x) {
switch (x) {
case CTRL_UP: return CTRL_RIGHT;
@ -249,6 +258,7 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) {
updatePSPButtons_(buttonMask & changedButtonMask, (~buttonMask) & changedButtonMask);
bool keyInputUsed = changedButtonMask != 0;
bool updateAnalogSticks = false;
// OK, handle all the virtual keys next. For these we need to do deltas here and send events.
for (int i = 0; i < VIRTKEY_COUNT; i++) {
@ -322,12 +332,28 @@ bool ControlMapper::UpdatePSPState(const InputMapping &changedMapping) {
if (!bPrevValue && bValue) {
// INFO_LOG(G3D, "vkeyon %s", KeyMap::GetVirtKeyName(vkId));
onVKey(vkId, true);
virtKeyOn_[vkId - VIRTKEY_FIRST] = true;
if (vkId == VIRTKEY_ANALOG_LIGHTLY) {
updateAnalogSticks = true;
}
} else if (bPrevValue && !bValue) {
// INFO_LOG(G3D, "vkeyoff %s", KeyMap::GetVirtKeyName(vkId));
onVKey(vkId, false);
virtKeyOn_[vkId - VIRTKEY_FIRST] = false;
if (vkId == VIRTKEY_ANALOG_LIGHTLY) {
updateAnalogSticks = true;
}
}
}
if (updateAnalogSticks) {
// If "lightly" (analog limiter) was toggled, we need to update both computed stick outputs.
UpdateAnalogOutput(0);
UpdateAnalogOutput(1);
}
return keyInputUsed;
}

View File

@ -39,12 +39,14 @@ private:
float MapAxisValue(float value, int vkId, const InputMapping &mapping, const InputMapping &changedMapping, bool *oppositeTouched);
void SetPSPAxis(int deviceId, int stick, char axis, float value);
void UpdateAnalogOutput(int stick);
void onVKey(int vkey, bool down);
void onVKeyAnalog(int deviceId, int vkey, float value);
// To track mappable virtual keys. We can have as many as we want.
float virtKeys_[VIRTKEY_COUNT]{};
bool virtKeyOn_[VIRTKEY_COUNT]{}; // Track boolean output separaately since thresholds may differ.
int lastNonDeadzoneDeviceID_[2]{};

View File

@ -769,8 +769,8 @@ void EmuScreen::onVKeyAnalog(int virtualKeyCode, float value) {
// Xbox controllers need a pretty big deadzone here to not leave behind small values
// on occasion when releasing the trigger. Still feels right.
float DEADZONE_THRESHOLD = g_Config.fAnalogLimiterDeadzone;
float DEADZONE_SCALE = 1.0f / (1.0f - DEADZONE_THRESHOLD);
static constexpr float DEADZONE_THRESHOLD = 0.2f;
static constexpr float DEADZONE_SCALE = 1.0f / (1.0f - DEADZONE_THRESHOLD);
FPSLimit &limitMode = PSP_CoreParameter().fpsLimit;
// If we're using an alternate speed already, let that win.