From 9d0927fa51f138f4382a4739d78867c789f5528b Mon Sep 17 00:00:00 2001 From: LunaMoo Date: Mon, 13 Apr 2020 16:50:28 +0200 Subject: [PATCH] Add a timer check to avoid XInputSetState freezing. --- Windows/XinputDevice.cpp | 29 +++++++++++++++++++---------- Windows/XinputDevice.h | 2 +- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/Windows/XinputDevice.cpp b/Windows/XinputDevice.cpp index d20b0378aa..8dee2e71f8 100644 --- a/Windows/XinputDevice.cpp +++ b/Windows/XinputDevice.cpp @@ -13,6 +13,7 @@ #include "XinputDevice.h" #include "Core/Core.h" #include "Core/HLE/sceCtrl.h" +#include "Common/Timer.h" // Utilities to dynamically load XInput. Adapted from SDL. @@ -26,6 +27,7 @@ static XInputSetState_t PPSSPP_XInputSetState = NULL; static DWORD PPSSPP_XInputVersion = 0; static HMODULE s_pXInputDLL = 0; static int s_XInputDLLRefCount = 0; +static int newVibrationTime = 0; static void UnloadXInputDLL(); @@ -361,17 +363,24 @@ void XinputDevice::ApplyButtons(int pad, const XINPUT_STATE &state) { void XinputDevice::ApplyVibration(int pad, XINPUT_VIBRATION &vibration) { if (PSP_IsInited()) { - if (GetUIState() == UISTATE_INGAME) { - vibration.wLeftMotorSpeed = sceCtrlGetLeftVibration(); // use any value between 0-65535 here - vibration.wRightMotorSpeed = sceCtrlGetRightVibration(); // use any value between 0-65535 here - } else { - vibration.wLeftMotorSpeed = 0; - vibration.wRightMotorSpeed = 0; - } + newVibrationTime = Common::Timer::GetTimeMs() >> 6; + // We have to run PPSSPP_XInputSetState at time intervals + // since it bugs otherwise with very high unthrottle speeds + // and freezes at constant vibration or no vibration at all. + if (abs(newVibrationTime - prevVibrationTime) >= 1) { + if (GetUIState() == UISTATE_INGAME) { + vibration.wLeftMotorSpeed = sceCtrlGetLeftVibration(); // use any value between 0-65535 here + vibration.wRightMotorSpeed = sceCtrlGetRightVibration(); // use any value between 0-65535 here + } else { + vibration.wLeftMotorSpeed = 0; + vibration.wRightMotorSpeed = 0; + } - if (prevVibration[pad].wLeftMotorSpeed != vibration.wLeftMotorSpeed || prevVibration[pad].wRightMotorSpeed != vibration.wRightMotorSpeed) { - PPSSPP_XInputSetState(pad, &vibration); - prevVibration[pad] = vibration; + if ((prevVibration[pad].wLeftMotorSpeed != vibration.wLeftMotorSpeed || prevVibration[pad].wRightMotorSpeed != vibration.wRightMotorSpeed)) { + PPSSPP_XInputSetState(pad, &vibration); + prevVibration[pad] = vibration; + } + prevVibrationTime = newVibrationTime; } } else { DWORD dwResult = PPSSPP_XInputSetState(pad, &vibration); diff --git a/Windows/XinputDevice.h b/Windows/XinputDevice.h index c1cac28887..40cb973b25 100644 --- a/Windows/XinputDevice.h +++ b/Windows/XinputDevice.h @@ -17,6 +17,6 @@ private: int check_delay[4]{}; XINPUT_STATE prevState[4]{}; XINPUT_VIBRATION prevVibration[4]{}; - + int prevVibrationTime = 0; u32 prevButtons[4]{}; };