mirror of
https://github.com/libsdl-org/SDL.git
synced 2026-06-13 15:13:54 +00:00
Use the Microsoft provided GameInputCreate() function (#15797)
It does better version checking and has better compatibility. This also fixes a crash in GameInputRedist.dll when attempting to load v3 when v2 is installed on the system. In this case, a thread is created in GameInputCreate() which is not cleaned up when the object is released, and can crash later with a NULL pointer dereference.
This commit is contained in:
20
.github/workflows/create-test-plan.py
vendored
20
.github/workflows/create-test-plan.py
vendored
@@ -12,7 +12,6 @@ from typing import Optional
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
WINDOWS_GAMEINPUT_VERSION = "v3.3.195.0 "
|
||||
|
||||
class AppleArch(Enum):
|
||||
Aarch64 = "aarch64"
|
||||
@@ -222,7 +221,8 @@ class JobDetails:
|
||||
msys2_packages: list[str] = dataclasses.field(default_factory=list)
|
||||
cygwin_packages: list[str] = dataclasses.field(default_factory=list)
|
||||
werror: bool = True
|
||||
microsoft_gameinput_version: str = ""
|
||||
microsoft_gameinput: bool = False
|
||||
microsoft_gameinput_arch: str = ""
|
||||
msvc_vcvars_arch: str = ""
|
||||
msvc_vcvars_sdk: str = ""
|
||||
msvc_project: str = ""
|
||||
@@ -293,7 +293,8 @@ class JobDetails:
|
||||
"android-mk": self.android_mk,
|
||||
"werror": self.werror,
|
||||
"sudo": self.sudo,
|
||||
"microsoft-gameinput-version": self.microsoft_gameinput_version,
|
||||
"microsoft-gameinput": self.microsoft_gameinput,
|
||||
"microsoft-gameinput-arch": self.microsoft_gameinput_arch,
|
||||
"msvc-vcvars-arch": self.msvc_vcvars_arch,
|
||||
"msvc-vcvars-sdk": self.msvc_vcvars_sdk,
|
||||
"msvc-project": self.msvc_project,
|
||||
@@ -445,9 +446,14 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool, ctest_args
|
||||
job.setup_libusb_arch = "x86"
|
||||
case MsvcArch.X64:
|
||||
job.setup_libusb_arch = "x64"
|
||||
job.microsoft_gameinput_version = WINDOWS_GAMEINPUT_VERSION
|
||||
job.cflags.append("-I$GAMEINPUT_INCLUDE")
|
||||
job.cxxflags.append("-I$GAMEINPUT_INCLUDE")
|
||||
job.microsoft_gameinput = True
|
||||
match spec.msvc_arch:
|
||||
case MsvcArch.X64:
|
||||
job.microsoft_gameinput_arch = "x64"
|
||||
case MsvcArch.Arm64:
|
||||
job.microsoft_gameinput_arch = "arm64"
|
||||
job.cflags.append("-I$GAMEINPUT_INCLUDE")
|
||||
job.cxxflags.append("-I$GAMEINPUT_INCLUDE")
|
||||
case SdlPlatform.Linux:
|
||||
if spec.name.startswith("Ubuntu"):
|
||||
assert spec.os.value.startswith("ubuntu-")
|
||||
@@ -775,7 +781,7 @@ def spec_to_job(spec: JobSpec, key: str, trackmem_symbol_names: bool, ctest_args
|
||||
job.msys2_packages.append(f"{msys2_env}-clang-tools-extra")
|
||||
if job.ccache:
|
||||
job.msys2_packages.append(f"{msys2_env}-ccache")
|
||||
job.microsoft_gameinput_version = WINDOWS_GAMEINPUT_VERSION
|
||||
job.microsoft_gameinput = True
|
||||
job.cflags.append("-I$GAMEINPUT_INCLUDE")
|
||||
job.cxxflags.append("-I$GAMEINPUT_INCLUDE")
|
||||
case SdlPlatform.Cygwin:
|
||||
|
||||
13
.github/workflows/generic.yml
vendored
13
.github/workflows/generic.yml
vendored
@@ -173,14 +173,12 @@ jobs:
|
||||
done
|
||||
done
|
||||
- name: 'Set up Microsoft.GameInput headers'
|
||||
if: ${{ matrix.platform.microsoft-gameinput-version != '' }}
|
||||
if: ${{ !!matrix.platform.microsoft-gameinput }}
|
||||
run: |
|
||||
python build-scripts/download-gameinput-headers.py \
|
||||
--version ${{ matrix.platform.microsoft-gameinput-version }} \
|
||||
-o $HOME/gameinput
|
||||
echo "GAMEINPUT_INCLUDE=$(cygpath -w "$HOME/gameinput")" >>$GITHUB_ENV
|
||||
echo "INCLUDE=$INCLUDE;$(cygpath -w "$HOME/gameinput")" >>$GITHUB_ENV
|
||||
|
||||
python build-scripts/download-gameinput-sdk.py -o $HOME/gameinput
|
||||
echo "GAMEINPUT_INCLUDE=$(cygpath -w "$HOME/gameinput/include")" >>$GITHUB_ENV
|
||||
echo "INCLUDE=$(cygpath -w "$HOME/gameinput/include");$INCLUDE" >>$GITHUB_ENV
|
||||
${{ (!!matrix.platform.microsoft-gameinput-arch && format('echo "LIB=$(cygpath -w "$HOME/gameinput/lib/{0}");$LIB" >>$GITHUB_ENV', matrix.platform.microsoft-gameinput-arch)) || '' }}
|
||||
- name: 'Calculate ccache key'
|
||||
if: ${{ matrix.platform.ccache }}
|
||||
id: prepare-restore-ccache
|
||||
@@ -439,6 +437,7 @@ jobs:
|
||||
path: |
|
||||
build/dist/SDL3*
|
||||
build/include*
|
||||
build/CMakeFiles/CMakeConfigureLog.yaml
|
||||
- name: 'Upload minidumps'
|
||||
uses: actions/upload-artifact@v7
|
||||
continue-on-error: true
|
||||
|
||||
@@ -938,7 +938,7 @@ if(SDL_ASSEMBLY)
|
||||
}]==] COMPILER_SUPPORTS_ARMSVE2)
|
||||
if(COMPILER_SUPPORTS_ARMSVE2)
|
||||
# IMPORTANT: As not all AArch64 processors support SVE2, we only
|
||||
# attach the following compilation option to SVE
|
||||
# attach the following compilation option to SVE
|
||||
# dedicated source files.
|
||||
set(SVE2_MARCH_FLAG "-march=armv8-a+sve2")
|
||||
set(HAVE_ARMSVE2 TRUE)
|
||||
@@ -2313,12 +2313,42 @@ elseif(WINDOWS OR CYGWIN)
|
||||
static __x_ABI_CWindows_CGaming_CInput_CIGamepadStatics2 *s2;
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_WINDOWS_GAMING_INPUT_H
|
||||
)
|
||||
|
||||
check_cxx_source_compiles("
|
||||
#include <stdbool.h>
|
||||
#define COBJMACROS
|
||||
#include <gameinput.h>
|
||||
int main(int argc, char **argv) { return 0; }" HAVE_GAMEINPUT_H
|
||||
)
|
||||
if(HAVE_GAMEINPUT_H)
|
||||
set(SDL_GAMEINPUT_DYNAMIC 1)
|
||||
find_library(GAMEINPUT_LIB NAMES "gameinput.lib")
|
||||
if(GAMEINPUT_LIB)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_LIBRARIES "${GAMEINPUT_LIB}")
|
||||
check_cxx_source_compiles("
|
||||
#include <windows.h>
|
||||
#include <gameinput.h>
|
||||
#if defined(GAMEINPUT_API_VERSION) && GAMEINPUT_API_VERSION > 0
|
||||
#define STR_JOIN2(A, B) A##B
|
||||
#define STR_JOIN(A, B) STR_JOIN2(A, B)
|
||||
using namespace GameInput::STR_JOIN(v, GAMEINPUT_API_VERSION);
|
||||
#endif
|
||||
int main(int argc, char **argv) {
|
||||
IGameInput *gameInput;
|
||||
HRESULT hr = GameInputCreate(&gameInput);
|
||||
if (SUCCEEDED(hr)) {
|
||||
gameInput->Release();
|
||||
}
|
||||
(void) argc; (void) argv;
|
||||
return 0;
|
||||
}" HAVE_GAMEINPUT_LIB
|
||||
)
|
||||
if(HAVE_GAMEINPUT_LIB)
|
||||
sdl_link_dependency(gameinput LIBS gameinput.lib PKG_CONFIG_LINK_OPTIONS -lgameinput)
|
||||
set(SDL_GAMEINPUT_DYNAMIC 0)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
check_include_file(dxgi1_5.h HAVE_DXGI1_5_H)
|
||||
check_include_file(dxgi1_6.h HAVE_DXGI1_6_H)
|
||||
check_include_file(tpcshrd.h HAVE_TPCSHRD_H)
|
||||
|
||||
@@ -132,7 +132,7 @@
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;vcruntimed.lib;msvcrtd.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gameinput.lib;setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;vcruntimed.lib;msvcrtd.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
@@ -161,7 +161,7 @@
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_xs.lib;uuid.lib;vcruntimed.lib;msvcrtd.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gameinput.lib;setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_xs.lib;uuid.lib;vcruntimed.lib;msvcrtd.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
@@ -199,7 +199,7 @@
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_x.lib;uuid.lib;vcruntimed.lib;msvcrtd.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gameinput.lib;setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_x.lib;uuid.lib;vcruntimed.lib;msvcrtd.lib;ucrtd.lib;msvcprtd.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<IgnoreAllDefaultLibraries>true</IgnoreAllDefaultLibraries>
|
||||
@@ -238,7 +238,7 @@
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;vcruntime.lib;msvcrt.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gameinput.lib;setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;vcruntime.lib;msvcrt.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
@@ -268,7 +268,7 @@
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_xs.lib;uuid.lib;vcruntime.lib;msvcrt.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gameinput.lib;setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_xs.lib;uuid.lib;vcruntime.lib;msvcrt.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
@@ -307,7 +307,7 @@
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
</ResourceCompile>
|
||||
<Link>
|
||||
<AdditionalDependencies>setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_x.lib;uuid.lib;vcruntime.lib;msvcrt.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies>gameinput.lib;setupapi.lib;winmm.lib;imm32.lib;version.lib;xgameruntime.lib;d3d12_x.lib;uuid.lib;vcruntime.lib;msvcrt.lib;ucrt.lib;msvcprt.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
|
||||
@@ -175,7 +175,7 @@ class VisualStudio:
|
||||
assert msbuild_path.is_file(), "MSBuild.exe does not exist"
|
||||
return msbuild_path
|
||||
|
||||
def build(self, arch_platform: VsArchPlatformConfig, projects: list[Path], include_paths: list[str]):
|
||||
def build(self, arch_platform: VsArchPlatformConfig, projects: list[Path], include_paths: list[str], lib_paths: list[str]):
|
||||
assert projects, "Need at least one project to build"
|
||||
|
||||
vsdev_cmd_str = f"\"{self.vsdevcmd}\" -arch={arch_platform.arch}"
|
||||
@@ -183,7 +183,10 @@ class VisualStudio:
|
||||
include_contents = "%INCLUDE%"
|
||||
if include_paths:
|
||||
include_contents = f"{';'.join(str(p) for p in include_paths)};" + include_contents
|
||||
bat_contents = textwrap.dedent(f"{vsdev_cmd_str} && set INCLUDE={include_contents} && {msbuild_cmd_str}")
|
||||
lib_contents = "%LIB%"
|
||||
if lib_paths:
|
||||
lib_contents = f"{';'.join(str(p) for p in lib_paths)};" + lib_contents
|
||||
bat_contents = textwrap.dedent(f"{vsdev_cmd_str} && set INCLUDE={include_contents} && set LIB={lib_paths} && {msbuild_cmd_str}")
|
||||
bat_path = Path(tempfile.gettempdir()) / "cmd.bat"
|
||||
with bat_path.open("w") as f:
|
||||
f.write(bat_contents)
|
||||
@@ -1218,9 +1221,12 @@ class Releaser:
|
||||
def _build_msvc_msbuild(self, arch_platform: VsArchPlatformConfig, vs: VisualStudio):
|
||||
platform_context = self.get_context(arch_platform.extra_context())
|
||||
include_paths = []
|
||||
lib_paths = []
|
||||
for dep in self.release_info.get("dependencies", {}):#release_info["msvc"].get("dependencies", {}).items():
|
||||
if "command" in self.release_info["dependencies"][dep]:
|
||||
include_paths.append(self.deps_path / dep / "include")
|
||||
lib_paths.append(self.deps_path / dep / "lib")
|
||||
lib_paths.append(self.deps_path / dep / "lib" / arch_platform.arch)
|
||||
continue
|
||||
depinfo = self.release_info["msvc"]["dependencies"][dep]
|
||||
msvc_zip = self.deps_path / glob.glob(depinfo["artifact"], root_dir=self.deps_path)[0]
|
||||
@@ -1270,7 +1276,7 @@ class Releaser:
|
||||
shutil.copy(src=src, dst=dir_b_props)
|
||||
|
||||
with self.section_printer.group(f"Build {arch_platform.arch} VS binary"):
|
||||
vs.build(arch_platform=arch_platform, projects=projects, include_paths=include_paths)
|
||||
vs.build(arch_platform=arch_platform, projects=projects, include_paths=include_paths, lib_paths=lib_paths)
|
||||
|
||||
if self.dry:
|
||||
for b in built_paths:
|
||||
|
||||
@@ -7,24 +7,27 @@ import urllib.request
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
def download_headers(tag: str, lowercase: bool, output: Path):
|
||||
DEFAULT_GAMEINPUT_VERSION = "v3.3.195.0"
|
||||
|
||||
def download_sdk(tag: str, lowercase: bool, output: Path):
|
||||
base_url = f"https://raw.githubusercontent.com/microsoftconnect/GameInput/refs/tags/{tag}/"
|
||||
url_relpaths = (
|
||||
"include/GameInput.h",
|
||||
"include/v0/GameInput.h",
|
||||
"include/v1/GameInput.h",
|
||||
"include/v2/GameInput.h",
|
||||
"lib/arm64/GameInput.lib",
|
||||
"lib/x64/GameInput.lib",
|
||||
)
|
||||
remove_prefix = "include/"
|
||||
for url_relpath in url_relpaths:
|
||||
url = base_url + url_relpath
|
||||
local_relpath = url_relpath.removeprefix(remove_prefix)
|
||||
local_relpath = url_relpath
|
||||
if lowercase:
|
||||
local_relpath = local_relpath.lower()
|
||||
local_path = output / local_relpath
|
||||
|
||||
local_dirpath = local_path.parent
|
||||
local_dirpath.mkdir(parents=False, exist_ok=True)
|
||||
local_dirpath.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
logger.info("Downloading %s to %s...", url, local_path)
|
||||
urllib.request.urlretrieve(url, local_path)
|
||||
@@ -33,12 +36,12 @@ def download_headers(tag: str, lowercase: bool, output: Path):
|
||||
def main():
|
||||
logging.basicConfig(level=logging.INFO)
|
||||
|
||||
parser = argparse.ArgumentParser(description="Download Microsoft.GameInput headers", allow_abbrev=False)
|
||||
parser.add_argument("--version", required=True, help="GameInput release tag (see https://github.com/microsoftconnect/GameInput/tags)")
|
||||
parser.add_argument("--no-lowercase", action="store_false", dest="lowercase", help="Don't lowercase downloaded headers")
|
||||
parser.add_argument("-o", "--output", type=Path, default=Path.cwd(), help="Headers will be stored here (subdirectories created as ")
|
||||
parser = argparse.ArgumentParser(description="Download Microsoft.GameInput SDK", allow_abbrev=False)
|
||||
parser.add_argument("--version", help="GameInput release tag (see https://github.com/microsoftconnect/GameInput/tags)", default=DEFAULT_GAMEINPUT_VERSION)
|
||||
parser.add_argument("--no-lowercase", action="store_false", dest="lowercase", help="Don't lowercase downloaded files")
|
||||
parser.add_argument("-o", "--output", type=Path, default=Path.cwd(), help="SDK will be stored here (in include and lib subdirectories)")
|
||||
args = parser.parse_args()
|
||||
download_headers(tag=args.version, lowercase=args.lowercase, output=args.output)
|
||||
download_sdk(tag=args.version, lowercase=args.lowercase, output=args.output)
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
@@ -3,7 +3,7 @@
|
||||
"remote": "libsdl-org/SDL",
|
||||
"dependencies": {
|
||||
"gameinput": {
|
||||
"command": "build-scripts/download-gameinput-headers.py -o @<@DEPS_PATH@>@/include --version v3.3.195.0",
|
||||
"command": "build-scripts/download-gameinput-sdk.py -o @<@DEPS_PATH@>@",
|
||||
"artifact": "gameinput/include/gameinput.h"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -65,11 +65,12 @@ endfunction()
|
||||
# - LIBS: list of libraries to link to (cmake and pkg-config)
|
||||
# - LINK_OPTIONS: list of link options (also used in pc file, unless PKG_CONFIG_LINK_OPTION is used)
|
||||
function(sdl_generic_link_dependency ID)
|
||||
cmake_parse_arguments(ARGS "" "COLLECTOR" "SHARED_TARGETS;STATIC_TARGETS;INCLUDES;PKG_CONFIG_LINK_OPTIONS;PKG_CONFIG_LIBS;PKG_CONFIG_PREFIX;PKG_CONFIG_SPECS;CMAKE_MODULE;LIBS;LINK_OPTIONS" ${ARGN})
|
||||
cmake_parse_arguments(ARGS "" "COLLECTOR" "SHARED_TARGETS;STATIC_TARGETS;INCLUDES;PKG_CONFIG_LINK_OPTIONS;PKG_CONFIG_LIBS;PKG_CONFIG_PREFIX;PKG_CONFIG_SPECS;CMAKE_MODULE;PUBLIC_LIBS;LIBS;LINK_OPTIONS" ${ARGN})
|
||||
foreach(target IN LISTS ARGS_SHARED_TARGETS)
|
||||
if(TARGET ${target})
|
||||
target_include_directories(${target} SYSTEM PRIVATE ${ARGS_INCLUDES})
|
||||
target_link_libraries(${target} PRIVATE ${ARGS_LIBS})
|
||||
target_link_libraries(${target} PUBLIC ${ARGS_PUBLIC_LIBS})
|
||||
target_link_options(${target} PRIVATE ${ARGS_LINK_OPTIONS})
|
||||
endif()
|
||||
endforeach()
|
||||
@@ -77,6 +78,7 @@ function(sdl_generic_link_dependency ID)
|
||||
if(TARGET ${target})
|
||||
target_include_directories(${target} SYSTEM PRIVATE ${ARGS_INCLUDES})
|
||||
target_link_libraries(${target} PRIVATE ${ARGS_LIBS})
|
||||
target_link_libraries(${target} PUBLIC ${ARGS_PUBLIC_LIBS})
|
||||
target_link_options(${target} INTERFACE ${ARGS_LINK_OPTIONS})
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
@@ -231,6 +231,7 @@
|
||||
#cmakedefine HAVE_XINPUT_H 1
|
||||
#cmakedefine HAVE_WINDOWS_GAMING_INPUT_H 1
|
||||
#cmakedefine HAVE_GAMEINPUT_H 1
|
||||
#cmakedefine SDL_GAMEINPUT_DYNAMIC 1
|
||||
#cmakedefine HAVE_DXGI_H 1
|
||||
#cmakedefine HAVE_DXGI1_5_H 1
|
||||
#cmakedefine HAVE_DXGI1_6_H 1
|
||||
|
||||
@@ -25,6 +25,13 @@
|
||||
|
||||
#ifdef HAVE_GAMEINPUT_H
|
||||
|
||||
#ifndef SDL_GAMEINPUT_DYNAMIC
|
||||
#define USE_GAMEINPUT_LIB
|
||||
#ifdef _MSC_VER
|
||||
#pragma comment(lib, "gameinput.lib")
|
||||
#endif
|
||||
#endif // !SDL_GAMEINPUT_DYNAMIC
|
||||
|
||||
static SDL_SharedObject *g_hGameInputDLL;
|
||||
static IGameInput *g_pGameInput;
|
||||
static int g_nGameInputRefCount;
|
||||
@@ -33,6 +40,32 @@ static int g_nGameInputRefCount;
|
||||
bool SDL_InitGameInput(IGameInput **ppGameInput)
|
||||
{
|
||||
if (g_nGameInputRefCount == 0) {
|
||||
#ifdef USE_GAMEINPUT_LIB
|
||||
// This is recommended, as Microsoft's GameInputCreate() is robust
|
||||
// and better handles various GameInput installations
|
||||
HRESULT hr = GameInputCreate(&g_pGameInput);
|
||||
if (FAILED(hr)) {
|
||||
return WIN_SetErrorFromHRESULT("GameInputCreate failed", hr);
|
||||
}
|
||||
#elif GAMEINPUT_API_VERSION > 0
|
||||
g_hGameInputDLL = SDL_LoadObject("gameinputredist.dll");
|
||||
if (!g_hGameInputDLL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
typedef HRESULT (WINAPI *pfnGameInputInitialize)(REFIID riid, void **ppvObject);
|
||||
pfnGameInputInitialize pGameInputInitialize = (pfnGameInputInitialize)SDL_LoadFunction(g_hGameInputDLL, "GameInputInitialize");
|
||||
if (!pGameInputInitialize) {
|
||||
SDL_UnloadObject(g_hGameInputDLL);
|
||||
return false;
|
||||
}
|
||||
|
||||
HRESULT hr = pGameInputInitialize(IID_IGameInput, (void **)&g_pGameInput);
|
||||
if (FAILED(hr)) {
|
||||
SDL_UnloadObject(g_hGameInputDLL);
|
||||
return WIN_SetErrorFromHRESULT("GameInputInitialize failed", hr);
|
||||
}
|
||||
#else
|
||||
g_hGameInputDLL = SDL_LoadObject("gameinput.dll");
|
||||
if (!g_hGameInputDLL) {
|
||||
return false;
|
||||
@@ -45,29 +78,12 @@ bool SDL_InitGameInput(IGameInput **ppGameInput)
|
||||
return false;
|
||||
}
|
||||
|
||||
IGameInput *pGameInput = NULL;
|
||||
HRESULT hr = pGameInputCreate(&pGameInput);
|
||||
HRESULT hr = pGameInputCreate(&g_pGameInput);
|
||||
if (FAILED(hr)) {
|
||||
SDL_UnloadObject(g_hGameInputDLL);
|
||||
return WIN_SetErrorFromHRESULT("GameInputCreate failed", hr);
|
||||
}
|
||||
|
||||
#ifdef SDL_PLATFORM_WIN32
|
||||
#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
|
||||
g_pGameInput = pGameInput;
|
||||
#endif
|
||||
#endif // USE_GAMEINPUT_LIB
|
||||
}
|
||||
++g_nGameInputRefCount;
|
||||
|
||||
|
||||
@@ -40,12 +40,11 @@
|
||||
#define GAMEINPUT_API_VERSION 0
|
||||
#endif
|
||||
|
||||
#if GAMEINPUT_API_VERSION == 3
|
||||
using namespace GameInput::v3;
|
||||
#elif GAMEINPUT_API_VERSION == 2
|
||||
using namespace GameInput::v2;
|
||||
#elif GAMEINPUT_API_VERSION == 1
|
||||
using namespace GameInput::v1;
|
||||
#if GAMEINPUT_API_VERSION > 0
|
||||
// Use the namespace of the current GameInput version
|
||||
#define STR_JOIN2(A, B) A##B
|
||||
#define STR_JOIN(A, B) STR_JOIN2(A, B)
|
||||
using namespace GameInput::STR_JOIN(v, GAMEINPUT_API_VERSION);
|
||||
#endif
|
||||
|
||||
// Default value for SDL_HINT_JOYSTICK_GAMEINPUT
|
||||
|
||||
Reference in New Issue
Block a user