Windows: Check for devices on Windows events only.

A user reported stuttering after the periodic checks, and devices failing
until unplug/replug.  Presumably, this is caused by poor drivers reacting
badly to periodic DirectInput queries, so less queries should help.
This commit is contained in:
Unknown W. Brackets 2018-11-01 21:42:12 -07:00
parent 5ea935f4bf
commit d30d75ab38
3 changed files with 14 additions and 2 deletions

View File

@ -39,6 +39,7 @@
unsigned int DinputDevice::pInstances = 0; unsigned int DinputDevice::pInstances = 0;
LPDIRECTINPUT8 DinputDevice::pDI = NULL; LPDIRECTINPUT8 DinputDevice::pDI = NULL;
std::vector<DIDEVICEINSTANCE> DinputDevice::devices; std::vector<DIDEVICEINSTANCE> DinputDevice::devices;
bool DinputDevice::needsCheck_ = true;
// In order from 0. There can be 128, but most controllers do not have that many. // In order from 0. There can be 128, but most controllers do not have that many.
static const int dinput_buttons[] = { static const int dinput_buttons[] = {
@ -120,7 +121,7 @@ BOOL CALLBACK DinputDevice::DevicesCallback(
void DinputDevice::getDevices(bool refresh) void DinputDevice::getDevices(bool refresh)
{ {
if (devices.empty() || refresh) if (refresh)
{ {
getPDI()->EnumDevices(DI8DEVCLASS_GAMECTRL, &DinputDevice::DevicesCallback, NULL, DIEDFL_ATTACHEDONLY); getPDI()->EnumDevices(DI8DEVCLASS_GAMECTRL, &DinputDevice::DevicesCallback, NULL, DIEDFL_ATTACHEDONLY);
} }
@ -368,6 +369,7 @@ void DinputDevice::ApplyButtons(DIJOYSTATE2 &state) {
size_t DinputDevice::getNumPads() size_t DinputDevice::getNumPads()
{ {
getDevices(true); getDevices(needsCheck_);
needsCheck_ = false;
return devices.size(); return devices.size();
} }

View File

@ -35,6 +35,10 @@ public:
virtual int UpdateState(); virtual int UpdateState();
virtual bool IsPad() { return true; } virtual bool IsPad() { return true; }
static size_t getNumPads(); static size_t getNumPads();
static void CheckDevices() {
needsCheck_ = true;
}
private: private:
void ApplyButtons(DIJOYSTATE2 &state); void ApplyButtons(DIJOYSTATE2 &state);
//unfortunate and unclean way to keep only one DirectInput instance around //unfortunate and unclean way to keep only one DirectInput instance around
@ -52,6 +56,7 @@ private:
static unsigned int pInstances; static unsigned int pInstances;
static std::vector<DIDEVICEINSTANCE> devices; static std::vector<DIDEVICEINSTANCE> devices;
static LPDIRECTINPUT8 pDI; static LPDIRECTINPUT8 pDI;
static bool needsCheck_;
int pDevNum; int pDevNum;
LPDIRECTINPUTDEVICE8 pJoystick; LPDIRECTINPUTDEVICE8 pJoystick;
DIJOYSTATE2 pPrevState; DIJOYSTATE2 pPrevState;

View File

@ -54,6 +54,7 @@
#include "Windows/GEDebugger/GEDebugger.h" #include "Windows/GEDebugger/GEDebugger.h"
#include "Windows/main.h" #include "Windows/main.h"
#include "Windows/DinputDevice.h"
#include "Windows/EmuThread.h" #include "Windows/EmuThread.h"
#include "Windows/resource.h" #include "Windows/resource.h"
@ -814,6 +815,10 @@ namespace MainWindow
case WM_CHAR: case WM_CHAR:
return WindowsRawInput::ProcessChar(hWnd, wParam, lParam); return WindowsRawInput::ProcessChar(hWnd, wParam, lParam);
case WM_DEVICECHANGE:
DinputDevice::CheckDevices();
return DefWindowProc(hWnd, message, wParam, lParam);
case WM_VERYSLEEPY_MSG: case WM_VERYSLEEPY_MSG:
switch (wParam) { switch (wParam) {
case VERYSLEEPY_WPARAM_SUPPORTED: case VERYSLEEPY_WPARAM_SUPPORTED: