From 8a57c83ff9b44d5529146bb4408c2d4d8ab062b0 Mon Sep 17 00:00:00 2001
From: Sam Lantinga <[EMAIL REDACTED]>
Date: Fri, 11 Apr 2025 11:58:12 -0700
Subject: [PATCH] Updated to GameInput v1.1
The biggest change is that the C API is no longer available.
Here are more details:
https://www.nuget.org/packages/Microsoft.GameInput
Fixes https://github.com/libsdl-org/SDL/issues/12802
---
.github/workflows/create-test-plan.py | 2 +
CMakeLists.txt | 5 +-
VisualC-GDK/SDL/SDL.vcxproj | 6 +-
VisualC-GDK/SDL/SDL.vcxproj.filters | 6 +-
VisualC/SDL/SDL.vcxproj | 31 ++++-
VisualC/SDL/SDL.vcxproj.filters | 20 ++--
.../{SDL_gameinput.c => SDL_gameinput.cpp} | 21 ++--
src/core/windows/SDL_gameinput.h | 9 +-
...utjoystick.c => SDL_gameinputjoystick.cpp} | 111 +++++++++++-------
...wsgameinput.c => SDL_windowsgameinput.cpp} | 111 +++++++++---------
src/video/windows/SDL_windowsgameinput.h | 9 ++
src/video/windows/SDL_windowsvideo.h | 2 +
12 files changed, 201 insertions(+), 132 deletions(-)
rename src/core/windows/{SDL_gameinput.c => SDL_gameinput.cpp} (85%)
rename src/joystick/gdk/{SDL_gameinputjoystick.c => SDL_gameinputjoystick.cpp} (89%)
rename src/video/windows/{SDL_windowsgameinput.c => SDL_windowsgameinput.cpp} (81%)
diff --git a/.github/workflows/create-test-plan.py b/.github/workflows/create-test-plan.py
index a137889c81a7d..8048e2bc3229f 100755
--- a/.github/workflows/create-test-plan.py
+++ b/.github/workflows/create-test-plan.py
@@ -381,9 +381,11 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool) -> JobDeta
match spec.msvc_arch:
case MsvcArch.X86:
job.cflags.append("/clang:-m32")
+ job.cxxflags.append("/clang:-m32")
job.ldflags.append("/MACHINE:X86")
case MsvcArch.X64:
job.cflags.append("/clang:-m64")
+ job.cxxflags.append("/clang:-m64")
job.ldflags.append("/MACHINE:X64")
case _:
raise ValueError(f"Unsupported clang-cl architecture (arch={spec.msvc_arch})")
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 364cb5c0fd359..0db59b3eec21c 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1893,11 +1893,13 @@ elseif(UNIX AND NOT APPLE AND NOT RISCOS AND NOT HAIKU)
set (USE_POSIX_SPAWN 1)
endif()
elseif(WINDOWS)
+ enable_language(CXX)
check_c_source_compiles("
#include <windows.h>
int main(int argc, char **argv) { return 0; }" HAVE_WIN32_CC)
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/windows/*.c")
+ sdl_glob_sources("${SDL3_SOURCE_DIR}/src/core/windows/*.cpp")
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/main/windows/*.c")
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/io/windows/*.c")
@@ -2008,6 +2010,7 @@ elseif(WINDOWS)
if(SDL_VIDEO)
set(SDL_VIDEO_DRIVER_WINDOWS 1)
sdl_glob_sources("${SDL3_SOURCE_DIR}/src/video/windows/*.c")
+ sdl_glob_sources("${SDL3_SOURCE_DIR}/src/video/windows/*.cpp")
CheckOpenVR()
@@ -2135,7 +2138,7 @@ elseif(WINDOWS)
set(SDL_JOYSTICK_WGI 1)
endif()
if(HAVE_GAMEINPUT_H)
- sdl_glob_sources("${SDL3_SOURCE_DIR}/src/joystick/gdk/*.c")
+ sdl_glob_sources("${SDL3_SOURCE_DIR}/src/joystick/gdk/*.cpp")
set(SDL_JOYSTICK_GAMEINPUT 1)
endif()
set(HAVE_SDL_JOYSTICK TRUE)
diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj
index d15619c802ee2..baa2fffe2c2af 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj
+++ b/VisualC-GDK/SDL/SDL.vcxproj
@@ -645,7 +645,7 @@
<ClCompile Include="..\..\src\audio\SDL_wave.c" />
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c" />
- <ClCompile Include="..\..\src\core\windows\SDL_gameinput.c"/>
+ <ClCompile Include="..\..\src\core\windows\SDL_gameinput.cpp"/>
<ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
<ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
@@ -710,7 +710,7 @@
<ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="..\..\src\joystick\controller_type.c" />
<ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
- <ClCompile Include="..\..\src\joystick\gdk\SDL_gameinputjoystick.c" />
+ <ClCompile Include="..\..\src\joystick\gdk\SDL_gameinputjoystick.cpp" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapijoystick.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_8bitdo.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_combined.c" />
@@ -891,7 +891,7 @@
<ClCompile Include="..\..\src\video\windows\SDL_windowsevents.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsframebuffer.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowskeyboard.c" />
- <ClCompile Include="..\..\src\video\windows\SDL_windowsgameinput.c" />
+ <ClCompile Include="..\..\src\video\windows\SDL_windowsgameinput.cpp" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsmessagebox.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsmodes.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsmouse.c" />
diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters
index 03b5a6a8f817d..26f228826c966 100644
--- a/VisualC-GDK/SDL/SDL.vcxproj.filters
+++ b/VisualC-GDK/SDL/SDL.vcxproj.filters
@@ -27,7 +27,7 @@
<ClCompile Include="..\..\src\audio\SDL_wave.c" />
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c" />
- <ClCompile Include="..\..\src\core\windows\SDL_gameinput.c" />
+ <ClCompile Include="..\..\src\core\windows\SDL_gameinput.cpp" />
<ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
<ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
@@ -61,7 +61,7 @@
<ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="..\..\src\joystick\controller_type.c" />
<ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
- <ClCompile Include="..\..\src\joystick\gdk\SDL_gameinputjoystick.c" />
+ <ClCompile Include="..\..\src\joystick\gdk\SDL_gameinputjoystick.cpp" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapijoystick.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_8bitdo.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_combined.c" />
@@ -193,7 +193,7 @@
<ClCompile Include="..\..\src\video\windows\SDL_windowsevents.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsframebuffer.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowskeyboard.c" />
- <ClCompile Include="..\..\src\video\windows\SDL_windowsgameinput.c" />
+ <ClCompile Include="..\..\src\video\windows\SDL_windowsgameinput.cpp" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsmessagebox.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsmodes.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsmouse.c" />
diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj
index 738a4110fbc8f..c0a4d8643665d 100644
--- a/VisualC/SDL/SDL.vcxproj
+++ b/VisualC/SDL/SDL.vcxproj
@@ -424,6 +424,16 @@
<ClCompile Include="..\..\src\camera\dummy\SDL_camera_dummy.c" />
<ClCompile Include="..\..\src\camera\mediafoundation\SDL_camera_mediafoundation.c" />
<ClCompile Include="..\..\src\camera\SDL_camera.c" />
+ <ClCompile Include="..\..\src\core\windows\pch_cpp.cpp">
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ </ClCompile>
<ClCompile Include="..\..\src\dialog\SDL_dialog.c" />
<ClCompile Include="..\..\src\dialog\SDL_dialog_utils.c" />
<ClCompile Include="..\..\src\filesystem\SDL_filesystem.c" />
@@ -543,7 +553,12 @@
<ClCompile Include="..\..\src\audio\SDL_wave.c" />
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c" />
- <ClCompile Include="..\..\src\core\windows\SDL_gameinput.c" />
+ <ClCompile Include="..\..\src\core\windows\SDL_gameinput.cpp">
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ </ClCompile>
<ClCompile Include="..\..\src\core\windows\SDL_hid.c" />
<ClCompile Include="..\..\src\core\windows\SDL_immdevice.c" />
<ClCompile Include="..\..\src\core\windows\SDL_windows.c" />
@@ -580,7 +595,12 @@
<ClCompile Include="..\..\src\hidapi\SDL_hidapi.c" />
<ClCompile Include="..\..\src\joystick\controller_type.c" />
<ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c" />
- <ClCompile Include="..\..\src\joystick\gdk\SDL_gameinputjoystick.c" />
+ <ClCompile Include="..\..\src\joystick\gdk\SDL_gameinputjoystick.cpp">
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ </ClCompile>
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapijoystick.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_8bitdo.c" />
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_combined.c" />
@@ -726,7 +746,12 @@
<ClCompile Include="..\..\src\video\windows\SDL_windowsevents.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsframebuffer.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowskeyboard.c" />
- <ClCompile Include="..\..\src\video\windows\SDL_windowsgameinput.c" />
+ <ClCompile Include="..\..\src\video\windows\SDL_windowsgameinput.cpp">
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ <PrecompiledHeaderOutputFile Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(IntDir)$(TargetName)_cpp.pch</PrecompiledHeaderOutputFile>
+ </ClCompile>
<ClCompile Include="..\..\src\video\windows\SDL_windowsmessagebox.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsmodes.c" />
<ClCompile Include="..\..\src\video\windows\SDL_windowsmouse.c" />
diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters
index a5b201ed6d5e2..2583c9f3791ea 100644
--- a/VisualC/SDL/SDL.vcxproj.filters
+++ b/VisualC/SDL/SDL.vcxproj.filters
@@ -537,9 +537,6 @@
<ClInclude Include="..\..\src\events\SDL_events_c.h">
<Filter>events</Filter>
</ClInclude>
- <ClInclude Include="..\..\src\events\SDL_eventfilter_c.h">
- <Filter>events</Filter>
- </ClInclude>
<ClInclude Include="..\..\src\events\SDL_keyboard_c.h">
<Filter>events</Filter>
</ClInclude>
@@ -962,6 +959,7 @@
<ClInclude Include="..\..\include\SDL3\SDL_storage.h" />
<ClInclude Include="..\..\include\SDL3\SDL_time.h" />
<ClInclude Include="..\..\src\events\SDL_categories_c.h" />
+ <ClInclude Include="..\..\src\events\SDL_eventwatch_c.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\audio\wasapi\SDL_wasapi.c" />
@@ -1049,7 +1047,7 @@
<ClCompile Include="..\..\src\core\SDL_core_unsupported.c">
<Filter>core</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\core\windows\SDL_gameinput.c">
+ <ClCompile Include="..\..\src\core\windows\SDL_gameinput.cpp">
<Filter>core\windows</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\windows\SDL_hid.c">
@@ -1088,9 +1086,6 @@
<ClCompile Include="..\..\src\events\SDL_events.c">
<Filter>events</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\events\SDL_eventfilter.c">
- <Filter>events</Filter>
- </ClCompile>
<ClCompile Include="..\..\src\events\SDL_keyboard.c">
<Filter>events</Filter>
</ClCompile>
@@ -1184,7 +1179,7 @@
<ClCompile Include="..\..\src\joystick\dummy\SDL_sysjoystick.c">
<Filter>joystick\dummy</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\joystick\gdk\SDL_gameinputjoystick.c">
+ <ClCompile Include="..\..\src\joystick\gdk\SDL_gameinputjoystick.cpp">
<Filter>joystick\gdk</Filter>
</ClCompile>
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_8bitdo.c">
@@ -1367,7 +1362,7 @@
<ClCompile Include="..\..\src\video\windows\SDL_windowskeyboard.c">
<Filter>video\windows</Filter>
</ClCompile>
- <ClCompile Include="..\..\src\video\windows\SDL_windowsgameinput.c">
+ <ClCompile Include="..\..\src\video\windows\SDL_windowsgameinput.cpp">
<Filter>video\windows</Filter>
</ClCompile>
<ClCompile Include="..\..\src\video\windows\SDL_windowsmessagebox.c">
@@ -1606,11 +1601,12 @@
<ClCompile Include="..\..\src\storage\generic\SDL_genericstorage.c" />
<ClCompile Include="..\..\src\storage\steam\SDL_steamstorage.c" />
<ClCompile Include="..\..\src\storage\SDL_storage.c" />
+ <ClCompile Include="..\..\src\events\SDL_eventwatch.c" />
+ <ClCompile Include="..\..\src\core\windows\pch_cpp.cpp">
+ <Filter>core\windows</Filter>
+ </ClCompile>
</ItemGroup>
<ItemGroup>
<ResourceCompile Include="..\..\src\core\windows\version.rc" />
</ItemGroup>
- <ItemGroup>
- <MASM Include="..\..\src\stdlib\SDL_mslibc_x64.masm" />
- </ItemGroup>
</Project>
diff --git a/src/core/windows/SDL_gameinput.c b/src/core/windows/SDL_gameinput.cpp
similarity index 85%
rename from src/core/windows/SDL_gameinput.c
rename to src/core/windows/SDL_gameinput.cpp
index 9ac5912db9d06..e2ea3fb4ab285 100644
--- a/src/core/windows/SDL_gameinput.c
+++ b/src/core/windows/SDL_gameinput.cpp
@@ -25,16 +25,11 @@
#include "SDL_windows.h"
#include "SDL_gameinput.h"
-#ifdef SDL_PLATFORM_WIN32
-#include <initguid.h>
-// {11BE2A7E-4254-445A-9C09-FFC40F006918}
-DEFINE_GUID(SDL_IID_GameInput, 0x11BE2A7E, 0x4254, 0x445A, 0x9C, 0x09, 0xFF, 0xC4, 0x0F, 0x00, 0x69, 0x18);
-#endif
-
static SDL_SharedObject *g_hGameInputDLL;
static IGameInput *g_pGameInput;
static int g_nGameInputRefCount;
+
bool SDL_InitGameInput(IGameInput **ppGameInput)
{
if (g_nGameInputRefCount == 0) {
@@ -43,7 +38,7 @@ bool SDL_InitGameInput(IGameInput **ppGameInput)
return false;
}
- typedef HRESULT (WINAPI *GameInputCreate_t)(IGameInput * *gameInput);
+ typedef HRESULT (WINAPI *GameInputCreate_t)(IGameInput **gameInput);
GameInputCreate_t GameInputCreateFunc = (GameInputCreate_t)SDL_LoadFunction(g_hGameInputDLL, "GameInputCreate");
if (!GameInputCreateFunc) {
SDL_UnloadObject(g_hGameInputDLL);
@@ -58,15 +53,19 @@ bool SDL_InitGameInput(IGameInput **ppGameInput)
}
#ifdef SDL_PLATFORM_WIN32
- hr = IGameInput_QueryInterface(pGameInput, &SDL_IID_GameInput, (void **)&g_pGameInput);
- IGameInput_Release(pGameInput);
+#if GAMEINPUT_API_VERSION >= 1
+ hr = pGameInput->QueryInterface(IID_IGameInput, (void **)&g_pGameInput);
+#else
+ // We require GameInput v1.1 or newer
+ hr = E_NOINTERFACE;
+#endif
+ pGameInput->Release();
if (FAILED(hr)) {
SDL_UnloadObject(g_hGameInputDLL);
return WIN_SetErrorFromHRESULT("GameInput QueryInterface failed", hr);
}
#else
// Assume that the version we get is compatible with the current SDK
- // If that isn't the case, define the correct GUID for SDL_IID_GameInput above
g_pGameInput = pGameInput;
#endif
}
@@ -85,7 +84,7 @@ void SDL_QuitGameInput(void)
--g_nGameInputRefCount;
if (g_nGameInputRefCount == 0) {
if (g_pGameInput) {
- IGameInput_Release(g_pGameInput);
+ g_pGameInput->Release();
g_pGameInput = NULL;
}
if (g_hGameInputDLL) {
diff --git a/src/core/windows/SDL_gameinput.h b/src/core/windows/SDL_gameinput.h
index 0022c0bdde163..4d2beb5647005 100644
--- a/src/core/windows/SDL_gameinput.h
+++ b/src/core/windows/SDL_gameinput.h
@@ -25,9 +25,16 @@
#ifdef HAVE_GAMEINPUT_H
-#define COBJMACROS
#include <gameinput.h>
+#ifndef GAMEINPUT_API_VERSION
+#define GAMEINPUT_API_VERSION 0
+#endif
+
+#if GAMEINPUT_API_VERSION == 1
+using namespace GameInput::v1;
+#endif
+
extern bool SDL_InitGameInput(IGameInput **ppGameInput);
extern void SDL_QuitGameInput(void);
diff --git a/src/joystick/gdk/SDL_gameinputjoystick.c b/src/joystick/gdk/SDL_gameinputjoystick.cpp
similarity index 89%
rename from src/joystick/gdk/SDL_gameinputjoystick.c
rename to src/joystick/gdk/SDL_gameinputjoystick.cpp
index 6cf0a902b7f17..46d4ecc5f117a 100644
--- a/src/joystick/gdk/SDL_gameinputjoystick.c
+++ b/src/joystick/gdk/SDL_gameinputjoystick.cpp
@@ -24,6 +24,7 @@
#include "../SDL_sysjoystick.h"
#include "../usb_ids.h"
+#include "../../core/windows/SDL_windows.h"
#include "../../core/windows/SDL_gameinput.h"
// Default value for SDL_HINT_JOYSTICK_GAMEINPUT
@@ -66,7 +67,7 @@ typedef struct joystick_hwdata
static GAMEINPUT_InternalList g_GameInputList = { NULL };
static IGameInput *g_pGameInput = NULL;
-static GameInputCallbackToken g_GameInputCallbackToken = GAMEINPUT_INVALID_CALLBACK_TOKEN_VALUE;
+static GameInputCallbackToken g_GameInputCallbackToken = 0;
static Uint64 g_GameInputTimestampOffset;
static bool GAMEINPUT_InternalIsGamepad(const GameInputDeviceInfo *info)
@@ -93,15 +94,22 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice)
SDL_AssertJoysticksLocked();
- info = IGameInputDevice_GetDeviceInfo(pDevice);
- if (info->capabilities & GameInputDeviceCapabilityWireless) {
+#if GAMEINPUT_API_VERSION >= 1
+ HRESULT hr = pDevice->GetDeviceInfo(&info);
+ if (FAILED(hr)) {
+ return WIN_SetErrorFromHRESULT("IGameInputDevice::GetDeviceInfo", hr);
+ }
+#else
+ info = pDevice->GetDeviceInfo();
+#endif
+ if (false /*info->capabilities & GameInputDeviceCapabilityWireless*/) {
bus = SDL_HARDWARE_BUS_BLUETOOTH;
} else {
bus = SDL_HARDWARE_BUS_USB;
}
vendor = info->vendorId;
product = info->productId;
- version = (info->firmwareVersion.major << 8) | info->firmwareVersion.minor;
+ //version = (info->firmwareVersion.major << 8) | info->firmwareVersion.minor;
if (SDL_JoystickHandledByAnotherDriver(&SDL_GAMEINPUT_JoystickDriver, vendor, product, version, "")) {
return true;
@@ -130,18 +138,20 @@ static bool GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice)
// Generate a device path
for (idx = 0; idx < APP_LOCAL_DEVICE_ID_SIZE; ++idx) {
SDL_snprintf(tmp, SDL_arraysize(tmp), "%02hhX", info->deviceId.value[idx]);
- SDL_strlcat(elem->path, tmp, SDL_arraysize(tmp));
+ SDL_strlcat(elem->path, tmp, SDL_arraysize(elem->path));
}
- if (info->deviceStrings) {
- // In theory we could get the manufacturer and product strings here, but they're NULL for all the controllers I've tested
+#if GAMEINPUT_API_VERSION >= 1
+ if (info->displayName) {
+ product_string = info->displayName;
}
-
+#else
if (info->displayName) {
- // This could give us a product string, but it's NULL for all the controllers I've tested
+ product_string = info->displayName->data;
}
+#endif
- IGameInputDevice_AddRef(pDevice);
+ pDevice->AddRef();
elem->device = pDevice;
elem->name = SDL_CreateJoystickName(vendor, product, manufacturer_string, product_string);
elem->guid = SDL_CreateJoystickGUID(bus, vendor, product, version, manufacturer_string, product_string, 'g', 0);
@@ -168,7 +178,7 @@ static bool GAMEINPUT_InternalRemoveByIndex(int idx)
elem = g_GameInputList.devices[idx];
if (elem) {
- IGameInputDevice_Release(elem->device);
+ elem->device->Release();
SDL_free(elem->name);
SDL_free(elem);
}
@@ -232,10 +242,11 @@ static void CALLBACK GAMEINPUT_InternalJoystickDeviceCallback(
}
static void GAMEINPUT_JoystickDetect(void);
+static void GAMEINPUT_JoystickQuit(void);
static bool GAMEINPUT_JoystickInit(void)
{
- HRESULT hR;
+ HRESULT hr;
if (!SDL_GetHintBoolean(SDL_HINT_JOYSTICK_GAMEINPUT, SDL_GAMEINPUT_DEFAULT)) {
return true;
@@ -245,21 +256,21 @@ static bool GAMEINPUT_JoystickInit(void)
return false;
}
- hR = IGameInput_RegisterDeviceCallback(g_pGameInput,
- NULL,
+ hr = g_pGameInput->RegisterDeviceCallback(NULL,
GameInputKindController,
GameInputDeviceConnected,
GameInputBlockingEnumeration,
NULL,
GAMEINPUT_InternalJoystickDeviceCallback,
&g_GameInputCallbackToken);
- if (FAILED(hR)) {
- return SDL_SetError("IGameInput::RegisterDeviceCallback failure with HRESULT of %08lX", hR);
+ if (FAILED(hr)) {
+ GAMEINPUT_JoystickQuit();
+ return WIN_SetErrorFromHRESULT("IGameInput::RegisterDeviceCallback", hr);
}
// Calculate the relative offset between SDL timestamps and GameInput timestamps
Uint64 now = SDL_GetTicksNS();
- uint64_t timestampUS = IGameInput_GetCurrentTimestamp(g_pGameInput);
+ uint64_t timestampUS = g_pGameInput->GetCurrentTimestamp();
g_GameInputTimestampOffset = (SDL_NS_TO_US(now) - timestampUS);
GAMEINPUT_JoystickDetect();
@@ -292,7 +303,7 @@ static void GAMEINPUT_JoystickDetect(void)
elem->isAdded = true;
}
- if (elem->isDeleteRequested || !(IGameInputDevice_GetDeviceStatus(elem->device) & GameInputDeviceConnected)) {
+ if (elem->isDeleteRequested || !(elem->device->GetDeviceStatus() & GameInputDeviceConnected)) {
SDL_PrivateJoystickRemoved(elem->device_instance);
GAMEINPUT_InternalRemoveByIndex(idx--);
}
@@ -357,6 +368,7 @@ static SDL_JoystickID GAMEINPUT_JoystickGetDeviceInstanceID(int device_index)
static void GAMEINPUT_UpdatePowerInfo(SDL_Joystick *joystick, IGameInputDevice *device)
{
+#if 0
GameInputBatteryState battery_state;
SDL_PowerState state;
int percent = 0;
@@ -385,10 +397,10 @@ static void GAMEINPUT_UpdatePowerInfo(SDL_Joystick *joystick, IGameInputDevice *
percent = (int)SDL_roundf((battery_state.remainingCapacity / battery_state.fullChargeCapacity) * 100.0f);
}
SDL_SendJoystickPowerInfo(joystick, state, percent);
+#endif
}
-#ifdef IGameInput_RegisterSystemButtonCallback
-
+#if GAMEINPUT_API_VERSION >= 1
static void CALLBACK GAMEINPUT_InternalSystemButtonCallback(
_In_ GameInputCallbackToken callbackToken,
_In_ void * context,
@@ -415,8 +427,7 @@ static void CALLBACK GAMEINPUT_InternalSystemButtonCallback(
SDL_UnlockJoysticks();
}
}
-
-#endif // IGameInput_RegisterSystemButtonCallback
+#endif // GAMEINPUT_API_VERSION >= 1
static bool GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
{
@@ -441,19 +452,15 @@ static bool GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
joystick->nbuttons = 11;
joystick->nhats = 1;
-#ifdef IGameInput_RegisterSystemButtonCallback
+#if GAMEINPUT_API_VERSION >= 1
if (info->supportedSystemButtons != GameInputSystemButtonNone) {
if (info->supportedSystemButtons & GameInputSystemButtonShare) {
++joystick->nbuttons;
}
-#if 1 // The C macro in GameInput.h version 10.0.26100 refers to a focus policy which I guess has been removed from the final API?
-#undef IGameInput_RegisterSystemButtonCallback
-#define IGameInput_RegisterSystemButtonCallback(This, device, buttonFilter, context, callbackFunc, callbackToken) ((This)->lpVtbl->RegisterSystemButtonCallback(This, device, buttonFilter, context, callbackFunc, callbackToken))
-#endif
- IGameInput_RegisterSystemButtonCallback(g_pGameInput, elem->device, (GameInputSystemButtonGuide | GameInputSystemButtonShare), joystick, GAMEINPUT_InternalSystemButtonCallback, &hwdata->system_button_callback_token);
+ g_pGameInput->RegisterSystemButtonCallback(elem->device, (GameInputSystemButtonGuide | GameInputSystemButtonShare), joystick, GAMEINPUT_InternalSystemButtonCallback, &hwdata->system_button_callback_token);
}
-#endif // IGameInput_RegisterSystemButtonCallback
+#endif // GAMEINPUT_API_VERSION >= 1
} else {
joystick->naxes = info->controllerAxisCount;
joystick->nbuttons = info->controllerButtonCount;
@@ -467,6 +474,7 @@ static bool GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN, true);
}
+#if 0
if (info->supportedInput & GameInputKindTouch) {
SDL_PrivateJoystickAddTouchpad(joystick, info->touchPointCount);
}
@@ -482,6 +490,7 @@ static bool GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index)
} else {
joystick->connection_state = SDL_JOYSTICK_CONNECTION_WIRED;
}
+#endif
return true;
}
@@ -492,7 +501,7 @@ static bool GAMEINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequenc
GameInputRumbleParams *params = &hwdata->rumbleParams;
params->lowFrequency = (float)low_frequency_rumble / (float)SDL_MAX_UINT16;
params->highFrequency = (float)high_frequency_rumble / (float)SDL_MAX_UINT16;
- IGameInputDevice_SetRumbleState(hwdata->devref->device, params);
+ hwdata->devref->device->SetRumbleState(params);
return true;
}
@@ -503,7 +512,7 @@ static bool GAMEINPUT_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left
GameInputRumbleParams *params = &hwdata->rumbleParams;
params->leftTrigger = (float)left_rumble / (float)SDL_MAX_UINT16;
params->rightTrigger = (float)right_rumble / (float)SDL_MAX_UINT16;
- IGameInputDevice_SetRumbleState(hwdata->devref->device, params);
+ hwdata->devref->device->SetRumbleState(params);
return true;
}
@@ -531,15 +540,15 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
IGameInputReading *reading = NULL;
Uint64 timestamp;
GameInputGamepadState state;
- HRESULT hR;
+ HRESULT hr;
- hR = IGameInput_GetCurrentReading(g_pGameInput, info->supportedInput, device, &reading);
- if (FAILED(hR)) {
+ hr = g_pGameInput->GetCurrentReading(info->supportedInput, device, &reading);
+ if (FAILED(hr)) {
// don't SetError here since there can be a legitimate case when there's no reading avail
return;
}
- timestamp = SDL_US_TO_NS(IGameInputReading_GetTimestamp(reading) + g_GameInputTimestampOffset);
+ timestamp = SDL_US_TO_NS(reading->GetTimestamp() + g_GameInputTimestampOffset);
if (GAMEINPUT_InternalIsGamepad(info)) {
static WORD s_XInputButtons[] = {
@@ -557,7 +566,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
};
Uint8 btnidx = 0, hat = 0;
- if (IGameInputReading_GetGamepadState(reading, &state)) {
+ if (reading->GetGamepadState(&state)) {
for (btnidx = 0; btnidx < SDL_arraysize(s_XInputButtons); ++btnidx) {
WORD button_mask = s_XInputButtons[btnidx];
if (!button_mask) {
@@ -599,7 +608,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
if (button_state) {
uint32_t i;
- uint32_t button_count = IGameInputReading_GetControllerButtonState(reading, info->controllerButtonCount, button_state);
+ uint32_t button_count = reading->GetControllerButtonState(info->controllerButtonCount, button_state);
for (i = 0; i < button_count; ++i) {
SDL_SendJoystickButton(timestamp, joystick, (Uint8)i, button_state[i]);
}
@@ -609,7 +618,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
#define CONVERT_AXIS(v) (Sint16)((v)*65535.0f - 32768.0f)
if (axis_state) {
uint32_t i;
- uint32_t axis_count = IGameInputReading_GetControllerAxisState(reading, info->controllerAxisCount, axis_state);
+ uint32_t axis_count = reading->GetControllerAxisState(info->controllerAxisCount, axis_state);
for (i = 0; i < axis_count; ++i) {
SDL_SendJoystickAxis(timestamp, joystick, (Uint8)i, CONVERT_AXIS(axis_state[i]));
}
@@ -619,7 +628,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick)
if (switch_state) {
uint32_t i;
- uint32_t switch_count = IGameInputReading_GetControllerSwitchState(reading, info->controllerSwitchCount, switch_state);
+ uint32_t switch_count = reading->GetControllerSwitchState(info->controllerSwitchCount, switch_state);
for (i = 0; i < switch_count; ++i) {
Uint8 hat;
switch (switch_state[
(Patch may be truncated, please check the link at the top of this post.)