From 644ee910dfa7d221555618f1f79f6b1ba9f52e1b Mon Sep 17 00:00:00 2001 From: "Wilson E. Alvarez" Date: Fri, 3 May 2024 12:06:09 -0400 Subject: [PATCH] Expose joypad `vendor_id` and `product_id` in Windows --- platform/windows/joypad_windows.cpp | 17 +++++++++++++++-- platform/windows/joypad_windows.h | 11 +++++++++++ 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/platform/windows/joypad_windows.cpp b/platform/windows/joypad_windows.cpp index 60edb00dd284..4a804334c671 100644 --- a/platform/windows/joypad_windows.cpp +++ b/platform/windows/joypad_windows.cpp @@ -200,8 +200,12 @@ bool JoypadWindows::setup_dinput_joypad(const DIDEVICEINSTANCE *instance) { joy->di_joy->EnumObjects(objectsCallback, this, 0); joy->joy_axis.sort(); + Dictionary joypad_info; + joypad_info["vendor_id"] = (int64_t)LOWORD(guid.Data1); + joypad_info["product_id"] = (int64_t)HIWORD(guid.Data1); + joy->guid = instance->guidInstance; - input->joy_connection_changed(num, true, instance->tszProductName, uid); + input->joy_connection_changed(num, true, instance->tszProductName, uid, joypad_info); joy->attached = true; joy->id = num; attached_joypads[num] = true; @@ -322,6 +326,13 @@ void JoypadWindows::probe_joypads() { attached_joypads[id] = true; Dictionary joypad_info; joypad_info["xinput_index"] = (int)i; + if (XInputGetCapabilitiesEx) { + xinput_capabilities_ex xcapex; + if (XInputGetCapabilitiesEx(1, i, 0, &xcapex) == ERROR_SUCCESS) { + joypad_info["product_id"] = (int64_t)xcapex.productId; + joypad_info["vendor_id"] = (int64_t)xcapex.vendorId; + } + } input->joy_connection_changed(id, true, "XInput Gamepad", "__XINPUT_DEVICE__", joypad_info); } } else if (x_joypads[i].attached) { @@ -536,7 +547,9 @@ void JoypadWindows::load_xinput() { xinput_set_state = &_xinput_set_state; bool legacy_xinput = false; xinput_dll = LoadLibrary("XInput1_4.dll"); - if (!xinput_dll) { + if (xinput_dll) { + XInputGetCapabilitiesEx = (_XInputGetCapabilitiesEx)GetProcAddress((HMODULE)xinput_dll, (char *)108); + } else { xinput_dll = LoadLibrary("XInput1_3.dll"); if (!xinput_dll) { xinput_dll = LoadLibrary("XInput9_1_0.dll"); diff --git a/platform/windows/joypad_windows.h b/platform/windows/joypad_windows.h index cfddbcc8dc0d..5ccf5fc22e29 100644 --- a/platform/windows/joypad_windows.h +++ b/platform/windows/joypad_windows.h @@ -104,8 +104,19 @@ class JoypadWindows { uint64_t ff_end_timestamp = 0; }; + struct xinput_capabilities_ex { + XINPUT_CAPABILITIES Capabilities; + WORD vendorId; + WORD productId; + WORD revisionId; + DWORD a4; // unknown + }; + typedef DWORD(WINAPI *XInputGetState_t)(DWORD dwUserIndex, XINPUT_STATE *pState); typedef DWORD(WINAPI *XInputSetState_t)(DWORD dwUserIndex, XINPUT_VIBRATION *pVibration); + typedef DWORD(_stdcall *_XInputGetCapabilitiesEx)(DWORD a1, DWORD dwUserIndex, DWORD dwFlags, xinput_capabilities_ex *pCapabilities); + + _XInputGetCapabilitiesEx XInputGetCapabilitiesEx = nullptr; HWND *hWnd = nullptr; HANDLE xinput_dll;