diff --git a/pcsx2/USB/usb-pad/dx/dinput-config.cpp b/pcsx2/USB/usb-pad/dx/dinput-config.cpp index a3d49dddba..36adc14060 100644 --- a/pcsx2/USB/usb-pad/dx/dinput-config.cpp +++ b/pcsx2/USB/usb-pad/dx/dinput-config.cpp @@ -53,6 +53,10 @@ namespace usb_pad int32_t FFMULTI[2][1]; int32_t INVERTFORCES[2]{}; + // FFB test + bool ffbTestRunning = false; + unsigned int ffbTestStage = 0; + bool dialogOpen = false; HWND hKey; @@ -685,6 +689,14 @@ namespace usb_pad EndPaint(hWnd, &Ps); } + void EndFFBTest() + { + if (std::exchange(ffbTestRunning, false)) + { + KillTimer(hWnd, 23); + } + } + INT_PTR CALLBACK StaticProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) { (*pFnPrevFunc)(hDlg, uMsg, wParam, lParam); @@ -890,6 +902,16 @@ namespace usb_pad ControlTest(s->port); break; } + case 23: + { + s = (DXDlgSettings*)GetWindowLongPtr(hDlg, GWLP_USERDATA); + if (!UpdateTestForce(s->port, ffbTestStage++)) + { + EndTestForce(s->port); + EndFFBTest(); + } + break; + } } break; } @@ -933,6 +955,7 @@ namespace usb_pad //SendMessage(hWnd, WM_CLOSE, 0, 0); //return TRUE; dialogOpen = false; + EndFFBTest(); FreeDirectInput(); EndDialog(hWnd, TRUE); return TRUE; @@ -943,6 +966,7 @@ namespace usb_pad //Seems to create some dead locks //SendMessage(hWnd, WM_CLOSE, 0, 0); dialogOpen = false; + EndFFBTest(); FreeDirectInput(); EndDialog(hWnd, FALSE); return TRUE; @@ -950,9 +974,20 @@ namespace usb_pad break; case IDC_BUTTON1: { - //MessageBeep(MB_ICONEXCLAMATION); - ApplySettings(s->port); - TestForce(s->port); + if (!ffbTestRunning) + { + ApplySettings(s->port); + if (StartTestForce(s->port)) + { + if (UpdateTestForce(s->port, 0)) + { + // Start a timer to "tick" the FFB test every 500ms + ffbTestStage = 1; + SetTimer(hWnd, 23, 500, nullptr); + ffbTestRunning = true; + } + } + } } break; @@ -1179,6 +1214,7 @@ namespace usb_pad case WM_CLOSE: { dialogOpen = false; + EndFFBTest(); FreeDirectInput(); EndDialog(hWnd, 0); } diff --git a/pcsx2/USB/usb-pad/dx/dinput.cpp b/pcsx2/USB/usb-pad/dx/dinput.cpp index 2e4f723f4e..7c02bbe631 100644 --- a/pcsx2/USB/usb-pad/dx/dinput.cpp +++ b/pcsx2/USB/usb-pad/dx/dinput.cpp @@ -429,13 +429,13 @@ namespace usb_pad } } - void UpdateFFBSettings(int port, LPDIRECTINPUTDEVICE8 device) + bool UpdateFFBSettings(int port, LPDIRECTINPUTDEVICE8 device) { DIPROPDWORD prop { sizeof(prop), sizeof(prop.diph) }; prop.diph.dwObj = 0; prop.diph.dwHow = DIPH_DEVICE; prop.dwData = std::clamp(GAINZ[port][0], 0, DI_FFNOMINALMAX); - device->SetProperty(DIPROP_FFGAIN, &prop.diph); + return SUCCEEDED(device->SetProperty(DIPROP_FFGAIN, &prop.diph)); } BOOL CALLBACK EnumJoysticksCallback(const DIDEVICEINSTANCE* pdidInstance, @@ -1019,7 +1019,7 @@ namespace usb_pad return g_pEffectConstant[port]->SetParameters(&eff, DIEP_TYPESPECIFICPARAMS | DIEP_START); } - void TestForce(int port) + bool StartTestForce(int port) { InputMapped im; LPDIRECTINPUTDEVICE8 dev = nullptr; @@ -1027,23 +1027,36 @@ namespace usb_pad dev = g_pJoysticks[im.index]->GetDevice(); // Gain value may have changed, so update it for the constant force effect - UpdateFFBSettings(port, dev); + return UpdateFFBSettings(port, dev); + } - if (FAILED(SetConstantForce(port, DI_FFNOMINALMAX / 3))) - return; - Sleep(500); - SetConstantForce(port, -DI_FFNOMINALMAX / 3); - Sleep(1000); - SetConstantForce(port, DI_FFNOMINALMAX / 3); - Sleep(500); - SetConstantForce(port, 0); - - if (dev) - { //FIXME actually center, maybe - AutoCenter(dev, true); - Sleep(1500); - AutoCenter(dev, false); + bool UpdateTestForce(int port, unsigned int stage) + { + // FFB test ticks every 500ms and goes as follows: + // Turn right, wait 500ms, turn left, wait 1000ms, turn right, wait 500ms, end + if (stage == 0) + { + return SUCCEEDED(SetConstantForce(port, DI_FFNOMINALMAX / 3)); } + if (stage == 1) + { + return SUCCEEDED(SetConstantForce(port, -DI_FFNOMINALMAX / 3)); + } + if (stage == 2) + { + // Do nothing, as we wait 1000ms + return true; + } + if (stage == 3) + { + return SUCCEEDED(SetConstantForce(port, DI_FFNOMINALMAX / 3)); + } + return false; + } + + bool EndTestForce(int port) + { + return SUCCEEDED(SetConstantForce(port, 0)); } } // namespace dx diff --git a/pcsx2/USB/usb-pad/dx/dx.h b/pcsx2/USB/usb-pad/dx/dx.h index 0821ef8ba5..57ff3c0f11 100644 --- a/pcsx2/USB/usb-pad/dx/dx.h +++ b/pcsx2/USB/usb-pad/dx/dx.h @@ -204,13 +204,17 @@ namespace usb_pad float ReadAxis(const InputMapped& im); float ReadAxis(int port, int axisid); float FilterControl(float input, LONG linear, LONG offset, LONG dead); - void TestForce(int port); + + bool StartTestForce(int port); + bool UpdateTestForce(int port, unsigned int stage); + bool EndTestForce(int port); + LONG GetAxisValueFromOffset(int axis, const DIJOYSTATE2& j); bool GetControl(int port, int id); float GetAxisControl(int port, ControlID id); void CreateFFB(int port, LPDIRECTINPUTDEVICE8 device, DWORD axis); bool FindFFDevice(int port); - void UpdateFFBSettings(int port, LPDIRECTINPUTDEVICE8 device); + bool UpdateFFBSettings(int port, LPDIRECTINPUTDEVICE8 device); void AddInputMap(int port, int cid, const InputMapped& im); void RemoveInputMap(int port, int cid);