summaryrefslogtreecommitdiff
path: root/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp')
-rw-r--r--Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp72
1 files changed, 57 insertions, 15 deletions
diff --git a/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp
index c687bef856..2bc924bf41 100644
--- a/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp
+++ b/Source/Core/InputCommon/Src/ControllerInterface/XInput/XInput.cpp
@@ -48,14 +48,60 @@ static const char* const named_motors[] =
"Motor R"
};
+static HMODULE hXInput = nullptr;
+
+typedef decltype(&XInputGetCapabilities) XInputGetCapabilities_t;
+typedef decltype(&XInputSetState) XInputSetState_t;
+typedef decltype(&XInputGetState) XInputGetState_t;
+
+static XInputGetCapabilities_t PXInputGetCapabilities = nullptr;
+static XInputSetState_t PXInputSetState = nullptr;
+static XInputGetState_t PXInputGetState = nullptr;
+
void Init(std::vector<Core::Device*>& devices)
{
+ if (!hXInput)
+ {
+ // Try for the most recent version we were compiled against (will only work if running on Win8+)
+ hXInput = ::LoadLibrary(XINPUT_DLL);
+ if (!hXInput)
+ {
+ // Drop back to DXSDK June 2010 version. Requires DX June 2010 redist.
+ hXInput = ::LoadLibrary(TEXT("xinput1_3.dll"));
+ if (!hXInput)
+ {
+ return;
+ }
+ }
+
+ PXInputGetCapabilities = (XInputGetCapabilities_t)::GetProcAddress(hXInput, "XInputGetCapabilities");
+ PXInputSetState = (XInputSetState_t)::GetProcAddress(hXInput, "XInputSetState");
+ PXInputGetState = (XInputGetState_t)::GetProcAddress(hXInput, "XInputGetState");
+ if (!PXInputGetCapabilities ||
+ !PXInputSetState ||
+ !PXInputGetState)
+ {
+ ::FreeLibrary(hXInput);
+ hXInput = nullptr;
+ return;
+ }
+ }
+
XINPUT_CAPABILITIES caps;
for (int i = 0; i != 4; ++i)
- if (ERROR_SUCCESS == XInputGetCapabilities(i, 0, &caps))
+ if (ERROR_SUCCESS == PXInputGetCapabilities(i, 0, &caps))
devices.push_back(new Device(caps, i));
}
+void DeInit()
+{
+ if (hXInput)
+ {
+ ::FreeLibrary(hXInput);
+ hXInput = nullptr;
+ }
+}
+
Device::Device(const XINPUT_CAPABILITIES& caps, u8 index)
: m_index(index), m_subtype(caps.SubType)
{
@@ -112,20 +158,16 @@ void Device::ClearInputState()
std::string Device::GetName() const
{
- // why aren't these defined
- // subtype doesn't seem to work, I tested with 2 different arcade sticks, both were shown as gamepad
- // I'll leave it in anyway, maybe m$ will fix it
-
switch (m_subtype)
{
- case XINPUT_DEVSUBTYPE_GAMEPAD : return "Gamepad"; break;
- case 0x02 /*XINPUT_DEVSUBTYPE_WHEEL*/ : return "Wheel"; break;
- case 0x03 /*XINPUT_DEVSUBTYPE_ARCADE_STICK*/ : return "Arcade Stick"; break;
- case 0x04 /*XINPUT_DEVSUBTYPE_FLIGHT_STICK*/ : return "Flight Stick"; break;
- case 0x05 /*XINPUT_DEVSUBTYPE_DANCE_PAD*/ : return "Dance Pad"; break;
- case 0x06 /*XINPUT_DEVSUBTYPE_GUITAR*/ : return "Guitar"; break;
- case 0x08 /*XINPUT_DEVSUBTYPE_DRUM_KIT*/ : return "Drum Kit"; break;
- default : return "Device"; break;
+ case XINPUT_DEVSUBTYPE_GAMEPAD: return "Gamepad"; break;
+ case XINPUT_DEVSUBTYPE_WHEEL: return "Wheel"; break;
+ case XINPUT_DEVSUBTYPE_ARCADE_STICK: return "Arcade Stick"; break;
+ case XINPUT_DEVSUBTYPE_FLIGHT_STICK: return "Flight Stick"; break;
+ case XINPUT_DEVSUBTYPE_DANCE_PAD: return "Dance Pad"; break;
+ case XINPUT_DEVSUBTYPE_GUITAR: return "Guitar"; break;
+ case XINPUT_DEVSUBTYPE_DRUM_KIT: return "Drum Kit"; break;
+ default: return "Device"; break;
}
}
@@ -143,7 +185,7 @@ std::string Device::GetSource() const
bool Device::UpdateInput()
{
- return (ERROR_SUCCESS == XInputGetState(m_index, &m_state_in));
+ return (ERROR_SUCCESS == PXInputGetState(m_index, &m_state_in));
}
bool Device::UpdateOutput()
@@ -153,7 +195,7 @@ bool Device::UpdateOutput()
if (memcmp(&m_state_out, &m_current_state_out, sizeof(m_state_out)))
{
m_current_state_out = m_state_out;
- return (ERROR_SUCCESS == XInputSetState(m_index, &m_state_out));
+ return (ERROR_SUCCESS == PXInputSetState(m_index, &m_state_out));
}
else
{