Path: blob/master/thirdparty/sdl/core/windows/SDL_xinput.c
9905 views
/*1Simple DirectMedia Layer2Copyright (C) 1997-2025 Sam Lantinga <[email protected]>34This software is provided 'as-is', without any express or implied5warranty. In no event will the authors be held liable for any damages6arising from the use of this software.78Permission is granted to anyone to use this software for any purpose,9including commercial applications, and to alter it and redistribute it10freely, subject to the following restrictions:11121. The origin of this software must not be misrepresented; you must not13claim that you wrote the original software. If you use this software14in a product, an acknowledgment in the product documentation would be15appreciated but is not required.162. Altered source versions must be plainly marked as such, and must not be17misrepresented as being the original software.183. This notice may not be removed or altered from any source distribution.19*/20#include "SDL_internal.h"2122#include "SDL_xinput.h"2324// Set up for C function definitions, even when using C++25#ifdef __cplusplus26extern "C" {27#endif2829XInputGetState_t SDL_XInputGetState = NULL;30XInputSetState_t SDL_XInputSetState = NULL;31XInputGetCapabilities_t SDL_XInputGetCapabilities = NULL;32XInputGetCapabilitiesEx_t SDL_XInputGetCapabilitiesEx = NULL;33XInputGetBatteryInformation_t SDL_XInputGetBatteryInformation = NULL;34DWORD SDL_XInputVersion = 0;3536static HMODULE s_pXInputDLL = NULL;37static int s_XInputDLLRefCount = 0;3839#if defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES)4041bool WIN_LoadXInputDLL(void)42{43/* Getting handles to system dlls (via LoadLibrary and its variants) is not44* supported on Xbox, thus, pointers to XInput's functions can't be45* retrieved via GetProcAddress.46*47* When on Xbox, assume that XInput is already loaded, and directly map48* its XInput.h-declared functions to the SDL_XInput* set of function49* pointers.50*/51SDL_XInputGetState = (XInputGetState_t)XInputGetState;52SDL_XInputSetState = (XInputSetState_t)XInputSetState;53SDL_XInputGetCapabilities = (XInputGetCapabilities_t)XInputGetCapabilities;54SDL_XInputGetBatteryInformation = (XInputGetBatteryInformation_t)XInputGetBatteryInformation;5556// XInput 1.4 ships with Windows 8 and 8.1:57SDL_XInputVersion = (1 << 16) | 4;5859return true;60}6162void WIN_UnloadXInputDLL(void)63{64}6566#else // !(defined(SDL_PLATFORM_XBOXONE) || defined(SDL_PLATFORM_XBOXSERIES))6768bool WIN_LoadXInputDLL(void)69{70DWORD version = 0;7172if (s_pXInputDLL) {73SDL_assert(s_XInputDLLRefCount > 0);74s_XInputDLLRefCount++;75return true; // already loaded76}7778/* NOTE: Don't load XinputUap.dll79* This is XInput emulation over Windows.Gaming.Input, and has all the80* limitations of that API (no devices at startup, no background input, etc.)81*/82version = (1 << 16) | 4;83s_pXInputDLL = LoadLibrary(TEXT("XInput1_4.dll")); // 1.4 Ships with Windows 8.84if (!s_pXInputDLL) {85version = (1 << 16) | 3;86s_pXInputDLL = LoadLibrary(TEXT("XInput1_3.dll")); // 1.3 can be installed as a redistributable component.87}88if (!s_pXInputDLL) {89s_pXInputDLL = LoadLibrary(TEXT("bin\\XInput1_3.dll"));90}91if (!s_pXInputDLL) {92// "9.1.0" Ships with Vista and Win7, and is more limited than 1.3+ (e.g. XInputGetStateEx is not available.)93s_pXInputDLL = LoadLibrary(TEXT("XInput9_1_0.dll"));94}95if (!s_pXInputDLL) {96return false;97}9899SDL_assert(s_XInputDLLRefCount == 0);100SDL_XInputVersion = version;101s_XInputDLLRefCount = 1;102103// 100 is the ordinal for _XInputGetStateEx, which returns the same struct as XinputGetState, but with extra data in wButtons for the guide button, we think...104SDL_XInputGetState = (XInputGetState_t)GetProcAddress(s_pXInputDLL, (LPCSTR)100);105if (!SDL_XInputGetState) {106SDL_XInputGetState = (XInputGetState_t)GetProcAddress(s_pXInputDLL, "XInputGetState");107}108SDL_XInputSetState = (XInputSetState_t)GetProcAddress(s_pXInputDLL, "XInputSetState");109SDL_XInputGetCapabilities = (XInputGetCapabilities_t)GetProcAddress(s_pXInputDLL, "XInputGetCapabilities");110// 108 is the ordinal for _XInputGetCapabilitiesEx, which additionally returns VID/PID of the controller.111SDL_XInputGetCapabilitiesEx = (XInputGetCapabilitiesEx_t)GetProcAddress(s_pXInputDLL, (LPCSTR)108);112SDL_XInputGetBatteryInformation = (XInputGetBatteryInformation_t)GetProcAddress(s_pXInputDLL, "XInputGetBatteryInformation");113if (!SDL_XInputGetState || !SDL_XInputSetState || !SDL_XInputGetCapabilities) {114WIN_UnloadXInputDLL();115return false;116}117118return true;119}120121void WIN_UnloadXInputDLL(void)122{123if (s_pXInputDLL) {124SDL_assert(s_XInputDLLRefCount > 0);125if (--s_XInputDLLRefCount == 0) {126FreeLibrary(s_pXInputDLL);127s_pXInputDLL = NULL;128}129} else {130SDL_assert(s_XInputDLLRefCount == 0);131}132}133134#endif135136// Ends C function definitions when using C++137#ifdef __cplusplus138}139#endif140141142