Commit 766d81ec866086f172e6c25687ed23d072fd2b93

Dimitriy Ryazantcev 2021-06-10T14:01:04

Rewrite SDL_DINPUT_JoystickPresent method to avoid costly IDirectInput8_CreateDevice calls

diff --git a/src/joystick/windows/SDL_dinputjoystick.c b/src/joystick/windows/SDL_dinputjoystick.c
index d2170c5..8552d9f 100644
--- a/src/joystick/windows/SDL_dinputjoystick.c
+++ b/src/joystick/windows/SDL_dinputjoystick.c
@@ -537,60 +537,28 @@ SDL_DINPUT_JoystickDetect(JoyStick_DeviceData **pContext)
     IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoysticksCallback, pContext, DIEDFL_ATTACHEDONLY);
 }
 
-typedef struct
-{
-    Uint16 vendor;
-    Uint16 product;
-    Uint16 version;
-    SDL_bool present;
-} EnumJoystickPresentData;
-
-static BOOL CALLBACK
-EnumJoystickPresentCallback(LPCDIDEVICEINSTANCE pDeviceInstance, LPVOID pContext)
+SDL_bool
+SDL_DINPUT_JoystickPresent(Uint16 vendor_id, Uint16 product_id, Uint16 version_number)
 {
-#define CHECK(exp) { if(!(exp)) goto err; }
-    EnumJoystickPresentData *data = (EnumJoystickPresentData *)pContext;
+    JoyStick_DeviceData* joystick = SYS_Joystick;
     Uint16 vendor = 0;
     Uint16 product = 0;
-    LPDIRECTINPUTDEVICE8 device = NULL;
-    BOOL ret = DIENUM_CONTINUE;
-
-    /* We are only supporting HID devices. */
-    CHECK((pDeviceInstance->dwDevType & DIDEVTYPE_HID) != 0);
-
-    CHECK(SUCCEEDED(IDirectInput8_CreateDevice(dinput, &pDeviceInstance->guidInstance, &device, NULL)));
-    CHECK(QueryDeviceInfo(device, &vendor, &product));
-
-    CHECK(data->vendor == vendor && data->product == product);
-
-    data->present = SDL_TRUE;
-    ret = DIENUM_STOP;
-
-err:
-    if (device) {
-        IDirectInputDevice8_Release(device);
-    }
+    Uint16 version = 0;
 
-    return ret;
-#undef CHECK
-}
+    while (joystick) {
+        SDL_GetJoystickGUIDInfo(joystick->guid, &vendor, &product, &version);
 
-SDL_bool
-SDL_DINPUT_JoystickPresent(Uint16 vendor, Uint16 product, Uint16 version)
-{
-    EnumJoystickPresentData data;
+        if (!joystick->bXInputDevice &&
+            vendor == vendor_id &&
+            product == product_id &&
+            version == version_number) {
+            return SDL_TRUE;
+        }
 
-    if (dinput == NULL) {
-        return SDL_FALSE;
+        joystick = joystick->pNext;
     }
 
-    data.vendor = vendor;
-    data.product = product;
-    data.version = version;
-    data.present = SDL_FALSE;
-    IDirectInput8_EnumDevices(dinput, DI8DEVCLASS_GAMECTRL, EnumJoystickPresentCallback, &data, DIEDFL_ATTACHEDONLY);
-
-    return data.present;
+    return SDL_FALSE;
 }
 
 static BOOL CALLBACK