diff --git a/Src/OSD/Windows/DirectInputSystem.cpp b/Src/OSD/Windows/DirectInputSystem.cpp
index 7e447bd..352633c 100644
--- a/Src/OSD/Windows/DirectInputSystem.cpp
+++ b/Src/OSD/Windows/DirectInputSystem.cpp
@@ -27,8 +27,10 @@
  */
 
 #include "DirectInputSystem.h"
+#include "Util/Format.h"
 #include "Supermodel.h"
 
+#include <array>
 #include <algorithm>
 
 #include <wbemidl.h>
@@ -38,27 +40,12 @@
 #include <SDL_syswm.h>
 
 /*
- * MinGW compatibility: the XInput.h distributed with MinGW is missing these
- * definitions. I've copied them from the Microsoft DirectX SDK. If a proper
- * header file appears, this hack should be removed.
+ * There seem to be three versions of XInput floating around, all of which
+ * ought to provide the functionality we need. We try them all in sequence,
+ * in order of newest/most feature-laden first.
  */
-#if !defined(XINPUT_DLL_A)
-
-#ifndef XINPUT_USE_9_1_0
-#define XINPUT_DLL_A  "xinput1_3.dll"
-#define XINPUT_DLL_W L"xinput1_3.dll"
-#else
-#define XINPUT_DLL_A  "xinput9_1_0.dll"
-#define XINPUT_DLL_W L"xinput9_1_0.dll"
-#endif
-#ifdef UNICODE
-    #define XINPUT_DLL XINPUT_DLL_W
-#else
-    #define XINPUT_DLL XINPUT_DLL_A
-#endif 
-
-#endif	// XINPUT_DLL_A
-
+static std::array<const char *, 3> s_xinput_dlls = { TEXT("xinput1_4.dll"), TEXT("xinput1_3.dll"), TEXT("xinput9_1_0.dll") };
+static std::array<const char *, 3> s_xinput_dlls_a = { "xinput1_4.dll", "xinput1_3.dll", "xinput9_1_0.dll" };
 
 // TODO - need to double check these all correct and see if can fill in any missing codes (although most just don't exist)
 DIKeyMapStruct CDirectInputSystem::s_keyMap[] = 
@@ -1541,6 +1528,33 @@ HRESULT CDirectInputSystem::CreateJoystickEffect(LPDIRECTINPUTDEVICE8 joystick,
 	return S_OK;
 }
 
+void CDirectInputSystem::LoadXInputDLL()
+{
+  // Try each of the XInput DLLs
+  HMODULE xInput = NULL;
+  for (auto filename: s_xinput_dlls)
+  {
+    xInput = LoadLibrary(filename);
+    if (xInput != NULL)
+      break;
+  }
+  if (xInput != NULL)
+  {
+	  m_xiGetCapabilitiesPtr = (XInputGetCapabilitiesPtr)GetProcAddress(xInput, "XInputGetCapabilities");
+		m_xiGetStatePtr = (XInputGetStatePtr)GetProcAddress(xInput, "XInputGetState");
+		m_xiSetStatePtr = (XInputSetStatePtr)GetProcAddress(xInput, "XInputSetState");
+		m_useXInput = m_xiGetCapabilitiesPtr != NULL && m_xiGetStatePtr != NULL && m_xiSetStatePtr != NULL;
+	}
+	else
+		m_useXInput = false;
+
+	if (!m_useXInput)
+  {
+    ErrorLog("XInput not found. Tried: %s.", Util::Format(", ").Join(s_xinput_dlls_a).str().c_str());
+    ErrorLog("Falling back on DirectInput.");
+  }
+}
+
 bool CDirectInputSystem::InitializeSystem()
 {
 	if (m_useRawInput)
@@ -1577,19 +1591,8 @@ bool CDirectInputSystem::InitializeSystem()
 	if (m_useXInput)
 	{
 		// Dynamically load XInput API
-		HMODULE xInput = LoadLibrary(TEXT(XINPUT_DLL_A));
-		if (xInput != NULL)
-		{
-			m_xiGetCapabilitiesPtr = (XInputGetCapabilitiesPtr)GetProcAddress(xInput, "XInputGetCapabilities");
-			m_xiGetStatePtr = (XInputGetStatePtr)GetProcAddress(xInput, "XInputGetState");
-			m_xiSetStatePtr = (XInputSetStatePtr)GetProcAddress(xInput, "XInputSetState");
-			m_useXInput = m_xiGetCapabilitiesPtr != NULL && m_xiGetStatePtr != NULL && m_xiSetStatePtr != NULL;
-		}
-		else
-			m_useXInput = false;
-
-		if (!m_useXInput)
-			ErrorLog("Unable to initialize XInput API (" XINPUT_DLL_A " not found) - switching to DirectInput.\n");
+		LoadXInputDLL();//LoadLibrary(TEXT(XINPUT_DLL_A));
+		
 	}
 
 	// Dynamically create DirectInput8 via COM, rather than statically linking to dinput8.dll
diff --git a/Src/OSD/Windows/DirectInputSystem.h b/Src/OSD/Windows/DirectInputSystem.h
index cd7876d..3ebf3a8 100644
--- a/Src/OSD/Windows/DirectInputSystem.h
+++ b/Src/OSD/Windows/DirectInputSystem.h
@@ -187,6 +187,8 @@ private:
 
 	HRESULT CreateJoystickEffect(LPDIRECTINPUTDEVICE8 di8Joystick, int axisNum, ForceFeedbackCmd ffCmd, LPDIRECTINPUTEFFECT *di8Effect);
 
+	void LoadXInputDLL();
+
 protected:
 	/*
 	 * Initializes the DirectInput input system.