From 13bb7cf30aacd7cabcc0147d66d70f92721a2fbd Mon Sep 17 00:00:00 2001 From: Jonathan Li Date: Mon, 29 Feb 2016 00:46:48 +0000 Subject: [PATCH] xpad: Support both XInput 1.3 and 1.4 --- plugins/xpad/xpad.cpp | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/plugins/xpad/xpad.cpp b/plugins/xpad/xpad.cpp index f75dd5389..eb390bf8a 100644 --- a/plugins/xpad/xpad.cpp +++ b/plugins/xpad/xpad.cpp @@ -21,8 +21,13 @@ #include "stdafx.h" #include "xpad.h" +#include static HMODULE s_hModule; +static HMODULE s_xInputDll; +static decltype(&XInputEnable) pXInputEnable; +static decltype(&XInputGetState) pXInputGetState; +static decltype(&XInputSetState) pXInputSetState; BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) { @@ -133,7 +138,7 @@ public: { memset(&m_state, 0, sizeof(m_state)); - m_connected = XInputGetState(m_pad, &m_state) == S_OK; // ERROR_DEVICE_NOT_CONNECTED is not an error, SUCCEEDED(...) won't work here + m_connected = pXInputGetState(m_pad, &m_state) == S_OK; // ERROR_DEVICE_NOT_CONNECTED is not an error, SUCCEEDED(...) won't work here m_lastpoll = now; } @@ -147,7 +152,7 @@ public: { if(m_vibration.wLeftMotorSpeed != vibration.wLeftMotorSpeed || m_vibration.wRightMotorSpeed != vibration.wRightMotorSpeed) { - XInputSetState(m_pad, &vibration); + pXInputSetState(m_pad, &vibration); m_vibration = vibration; } @@ -634,16 +639,41 @@ LRESULT WINAPI PADwndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) EXPORT_C_(UINT32) PADinit(UINT32 flags) { + DWORD loadFlags = LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32; + + s_xInputDll = LoadLibraryEx(L"xinput1_3.dll", nullptr, loadFlags); + if (s_xInputDll == nullptr && IsWindows8OrGreater()) + { + s_xInputDll = LoadLibraryEx(L"XInput1_4.dll", nullptr, loadFlags); + } + if (s_xInputDll == nullptr) + { + return 1; + } + + if (!(pXInputEnable = reinterpret_cast(GetProcAddress(s_xInputDll, "XInputEnable"))) + || !(pXInputSetState = reinterpret_cast(GetProcAddress(s_xInputDll, "XInputSetState"))) + || !(pXInputGetState = reinterpret_cast(GetProcAddress(s_xInputDll, "XInputGetState")))) + { + FreeLibrary(s_xInputDll); + s_xInputDll = nullptr; + return 1; + } return 0; } EXPORT_C PADshutdown() { + if (s_xInputDll) + { + FreeLibrary(s_xInputDll); + s_xInputDll = nullptr; + } } EXPORT_C_(UINT32) PADopen(void* pDsp) { - XInputEnable(TRUE); + pXInputEnable(TRUE); if(s_nRefs == 0) { @@ -671,7 +701,7 @@ EXPORT_C PADclose() } } - XInputEnable(FALSE); + pXInputEnable(FALSE); } EXPORT_C_(UINT32) CALLBACK PADquery()