SDL: Check for wine_get_version() to detect Wine/Proton (f36d6)

From f36d683b610857c4382a6b241a2038199d371243 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Wed, 12 Nov 2025 21:40:05 -0800
Subject: [PATCH] Check for wine_get_version() to detect Wine/Proton

If this application is being run under Wine but Steam doesn't know that, Steam won't set STEAM_COMPAT_PROTON. So we'll use wine_get_version() to detect that we're running under Wine instead.

(cherry picked from commit e2e8f86076a815303836514bb4ba661a84532d24)
---
 src/core/windows/SDL_windows.c    | 18 ++++++++++++++++++
 src/core/windows/SDL_windows.h    |  3 +++
 src/joystick/SDL_gamecontroller.c |  6 +++++-
 3 files changed, 26 insertions(+), 1 deletion(-)

diff --git a/src/core/windows/SDL_windows.c b/src/core/windows/SDL_windows.c
index c4e760be33bd1..ee730b8c2b4bf 100644
--- a/src/core/windows/SDL_windows.c
+++ b/src/core/windows/SDL_windows.c
@@ -199,6 +199,24 @@ static BOOL IsWindowsVersionOrGreater(WORD wMajorVersion, WORD wMinorVersion, WO
 }
 #endif
 
+BOOL WIN_IsWine(void)
+{
+    static SDL_bool checked;
+    static SDL_bool is_wine;
+
+    if (!checked) {
+        HMODULE ntdll = LoadLibrary(TEXT("ntdll.dll"));
+        if (ntdll) {
+            if (GetProcAddress(ntdll, "wine_get_version") != NULL) {
+                is_wine = SDL_TRUE;
+            }
+            FreeLibrary(ntdll);
+        }
+        checked = SDL_TRUE;
+    }
+    return is_wine;
+}
+
 BOOL WIN_IsWindowsVistaOrGreater(void)
 {
 #if defined(__WINRT__) || defined(__XBOXONE__) || defined(__XBOXSERIES__)
diff --git a/src/core/windows/SDL_windows.h b/src/core/windows/SDL_windows.h
index 33581a95a68ad..997c0ab4accba 100644
--- a/src/core/windows/SDL_windows.h
+++ b/src/core/windows/SDL_windows.h
@@ -136,6 +136,9 @@ extern void WIN_CoUninitialize(void);
 extern HRESULT WIN_RoInitialize(void);
 extern void WIN_RoUninitialize(void);
 
+/* Returns true if we're running on Wine */
+extern BOOL WIN_IsWine(void);
+
 /* Returns SDL_TRUE if we're running on Windows Vista and newer */
 extern BOOL WIN_IsWindowsVistaOrGreater(void);
 
diff --git a/src/joystick/SDL_gamecontroller.c b/src/joystick/SDL_gamecontroller.c
index adc8dd3e88e69..146dc332b4cc4 100644
--- a/src/joystick/SDL_gamecontroller.c
+++ b/src/joystick/SDL_gamecontroller.c
@@ -37,6 +37,10 @@
 #include "../events/SDL_events_c.h"
 #endif
 
+#if defined(__WIN32__)
+#include "../core/windows/SDL_windows.h"
+#endif
+
 #if defined(__ANDROID__)
 #include "SDL_system.h"
 #endif
@@ -2130,7 +2134,7 @@ SDL_bool SDL_ShouldIgnoreGameController(const char *name, SDL_JoystickGUID guid)
 
 #ifdef __WIN32__
     if (SDL_GetHintBoolean("SDL_GAMECONTROLLER_ALLOW_STEAM_VIRTUAL_GAMEPAD", SDL_FALSE) &&
-        SDL_GetHintBoolean("STEAM_COMPAT_PROTON", SDL_FALSE)) {
+        WIN_IsWine()) {
         /* We are launched by Steam and running under Proton
          * We can't tell whether this controller is a Steam Virtual Gamepad,
          * so assume that Proton is doing the appropriate filtering of controllers