Collect DInput devices in a meta device

This commit is contained in:
Henrik Rydgård committed 2025-06-28 13:57:04 +02:00
1 parent ce64ae2f7b
commit 66785a724b
4 files changed
+45 -42

No files matched your search

+32 -10
View File
@@ -241,7 +241,7 @@ int DinputDevice::UpdateState() {
|| js.lVX != 0 || js.lVY != 0 || js.lVZ != 0 || js.lVRx != 0 || js.lVRy != 0 || js.lVRz != 0)
{
pPrevState = js;
return UPDATESTATE_SKIP_PAD;
return InputDevice::UPDATESTATE_SKIP_PAD;
}
return -1;
}
@@ -312,12 +312,6 @@ size_t DinputDevice::getNumPads()
static std::set<u32> DetectXInputVIDPIDs() {
std::set<u32> xinputVidPids;
/*
if (FAILED(CoInitializeEx(nullptr, COINIT_MULTITHREADED))) {
return xinputVidPids;
}
*/
IWbemLocator* pIWbemLocator = nullptr;
if (FAILED(CoCreateInstance(__uuidof(WbemLocator), nullptr, CLSCTX_INPROC_SERVER,
__uuidof(IWbemLocator), (void**)&pIWbemLocator)))
@@ -340,10 +334,10 @@ static std::set<u32> DetectXInputVIDPIDs() {
return xinputVidPids;
}
IWbemClassObject* pDevices[20] = { 0 };
IWbemClassObject* pDevices[32] = { 0 };
ULONG uReturned = 0;
while (SUCCEEDED(pEnumDevices->Next(10000, 20, pDevices, &uReturned)) && uReturned > 0) {
while (SUCCEEDED(pEnumDevices->Next(10000, 32, pDevices, &uReturned)) && uReturned > 0) {
for (ULONG i = 0; i < uReturned; i++) {
VARIANT var;
if (SUCCEEDED(pDevices[i]->Get(L"DeviceID", 0, &var, nullptr, nullptr)))
@@ -369,7 +363,35 @@ static std::set<u32> DetectXInputVIDPIDs() {
pEnumDevices->Release();
pIWbemServices->Release();
pIWbemLocator->Release();
// CoUninitialize();
return xinputVidPids;
}
DInputMetaDevice::DInputMetaDevice() {
//find all connected DInput devices of class GamePad
numDinputDevices_ = DinputDevice::getNumPads();
for (size_t i = 0; i < numDinputDevices_; i++) {
devices_.push_back(std::make_unique<DinputDevice>(static_cast<int>(i)));
}
}
int DInputMetaDevice::UpdateState() {
static const int CHECK_FREQUENCY = 71; // Just an arbitrary prime to try to not collide with other periodic checks.
if (checkCounter_++ > CHECK_FREQUENCY) {
const size_t newCount = DinputDevice::getNumPads();
if (newCount > numDinputDevices_) {
INFO_LOG(Log::System, "New controller device detected");
for (size_t i = numDinputDevices_; i < newCount; i++) {
devices_.push_back(std::make_unique<DinputDevice>(static_cast<int>(i)));
}
numDinputDevices_ = newCount;
}
checkCounter_ = 0;
}
for (const auto &device : devices_) {
if (device->UpdateState() == InputDevice::UPDATESTATE_SKIP_PAD)
return InputDevice::UPDATESTATE_SKIP_PAD;
}
return 0;
}
+12 -4
View File
@@ -28,15 +28,13 @@
// TODO: This needs a major refactor into a DinputManager and individual devices inside.
class DinputDevice final :
public InputDevice
{
class DinputDevice {
public:
//instantiates device number devnum as explored by the first call to
//getDevices(), enumerates all devices if not done yet
DinputDevice(int devnum);
~DinputDevice();
int UpdateState() override;
int UpdateState();
static size_t getNumPads();
static void CheckDevices() {
needsCheck_ = true;
@@ -76,3 +74,13 @@ private:
int last_lRy_;
int last_lRz_;
};
struct DInputMetaDevice : public InputDevice {
public:
DInputMetaDevice();
int UpdateState() override;
private:
std::vector<std::unique_ptr<DinputDevice>> devices_;
size_t numDinputDevices_ = 0;
int checkCounter_ = 0;
};
+1 -25
View File
@@ -41,9 +41,7 @@
#include "Windows/WindowsHost.h"
#include "Windows/MainWindow.h"
#ifndef _M_ARM
#include "Windows/DinputDevice.h"
#endif
#include "Windows/XinputDevice.h"
#include "Windows/main.h"
@@ -51,32 +49,10 @@
void WindowsInputManager::Init() {
//add first XInput device to respond
input.push_back(std::make_unique<XinputDevice>());
#ifndef _M_ARM
//find all connected DInput devices of class GamePad
numDinputDevices_ = DinputDevice::getNumPads();
for (size_t i = 0; i < numDinputDevices_; i++) {
input.push_back(std::make_unique<DinputDevice>(static_cast<int>(i)));
}
#endif
input.push_back(std::make_unique<DInputMetaDevice>());
}
void WindowsInputManager::PollControllers() {
static const int CHECK_FREQUENCY = 71; // Just an arbitrary prime to try to not collide with other periodic checks.
if (checkCounter_++ > CHECK_FREQUENCY) {
#ifndef _M_ARM
size_t newCount = DinputDevice::getNumPads();
if (newCount > numDinputDevices_) {
INFO_LOG(Log::System, "New controller device detected");
for (size_t i = numDinputDevices_; i < newCount; i++) {
input.push_back(std::make_unique<DinputDevice>(static_cast<int>(i)));
}
numDinputDevices_ = newCount;
}
#endif
checkCounter_ = 0;
}
for (const auto &device : input) {
if (device->UpdateState() == InputDevice::UPDATESTATE_SKIP_PAD)
break;
-3
View File
@@ -27,13 +27,10 @@ public:
void PollControllers();
private:
size_t numDinputDevices_ = 0;
std::list<std::unique_ptr<InputDevice>> input;
float mouseDeltaX_ = 0;
float mouseDeltaY_ = 0;
int checkCounter_ = 0;
};
extern WindowsInputManager g_inputManager;