diff --git a/VisualC-GDK/SDL/SDL.vcxproj b/VisualC-GDK/SDL/SDL.vcxproj index cec3972f0..9d4ecf0da 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj +++ b/VisualC-GDK/SDL/SDL.vcxproj @@ -425,6 +425,7 @@ + @@ -438,7 +439,6 @@ - @@ -646,6 +646,7 @@ + @@ -690,10 +691,6 @@ CompileAsCpp CompileAsCpp - - $(IntDir)$(TargetName)_cpp.pch - $(IntDir)$(TargetName)_cpp.pch - diff --git a/VisualC-GDK/SDL/SDL.vcxproj.filters b/VisualC-GDK/SDL/SDL.vcxproj.filters index f5d648fe7..c59af5d0a 100644 --- a/VisualC-GDK/SDL/SDL.vcxproj.filters +++ b/VisualC-GDK/SDL/SDL.vcxproj.filters @@ -52,6 +52,7 @@ + @@ -319,6 +320,7 @@ + diff --git a/VisualC/SDL/SDL.vcxproj b/VisualC/SDL/SDL.vcxproj index 45415212d..c5a508b82 100644 --- a/VisualC/SDL/SDL.vcxproj +++ b/VisualC/SDL/SDL.vcxproj @@ -347,6 +347,7 @@ + @@ -520,6 +521,7 @@ + diff --git a/VisualC/SDL/SDL.vcxproj.filters b/VisualC/SDL/SDL.vcxproj.filters index 807300481..679a2bc55 100644 --- a/VisualC/SDL/SDL.vcxproj.filters +++ b/VisualC/SDL/SDL.vcxproj.filters @@ -88,6 +88,9 @@ {d008487d-6ed0-4251-848b-79a68e3c1459} + + {c9e8273e-13ae-47dc-bef8-8ad8e64c9a3e} + {c9e8273e-13ae-47dc-bef8-8ad8e64c9a3d} @@ -546,6 +549,9 @@ haptic\windows + + joystick\gdk + joystick\hidapi @@ -1063,6 +1069,9 @@ joystick\dummy + + joystick\gdk + joystick\hidapi diff --git a/include/build_config/SDL_build_config_windows.h b/include/build_config/SDL_build_config_windows.h index 52c2df725..68664c5ba 100644 --- a/include/build_config/SDL_build_config_windows.h +++ b/include/build_config/SDL_build_config_windows.h @@ -238,6 +238,7 @@ typedef unsigned int uintptr_t; /* Enable various input drivers */ #define SDL_JOYSTICK_DINPUT 1 +/*#define SDL_JOYSTICK_GAMEINPUT 1*/ #define SDL_JOYSTICK_HIDAPI 1 #ifndef SDL_PLATFORM_WINRT #define SDL_JOYSTICK_RAWINPUT 1 diff --git a/src/core/windows/SDL_xinput.c b/src/core/windows/SDL_xinput.c index fdeed7085..13c06bde4 100644 --- a/src/core/windows/SDL_xinput.c +++ b/src/core/windows/SDL_xinput.c @@ -20,8 +20,6 @@ */ #include "SDL_internal.h" -#ifndef SDL_JOYSTICK_GAMEINPUT - #include "SDL_xinput.h" /* Set up for C function definitions, even when using C++ */ @@ -144,5 +142,3 @@ void WIN_UnloadXInputDLL(void) #ifdef __cplusplus } #endif - -#endif /* !SDL_JOYSTICK_GAMEINPUT */ diff --git a/src/joystick/gdk/SDL_gameinputjoystick.cpp b/src/joystick/gdk/SDL_gameinputjoystick.c similarity index 82% rename from src/joystick/gdk/SDL_gameinputjoystick.cpp rename to src/joystick/gdk/SDL_gameinputjoystick.c index 1b4223d6e..230f5c96f 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick.cpp +++ b/src/joystick/gdk/SDL_gameinputjoystick.c @@ -18,6 +18,8 @@ misrepresented as being the original software. 3. This notice may not be removed or altered from any source distribution. */ +#include "SDL_internal.h" + #include "SDL_gameinputjoystick_c.h" #if defined(SDL_JOYSTICK_GAMEINPUT) && SDL_JOYSTICK_GAMEINPUT @@ -39,9 +41,9 @@ typedef struct GAMEINPUT_InternalDevice SDL_JoystickGUID joystickGuid; /* generated by SDL. */ SDL_JoystickID instanceId; /* generated by SDL. */ int playerIndex; - Uint32 caps; + GameInputRumbleMotors supportedRumbleMotors; char devicePath[(APP_LOCAL_DEVICE_ID_SIZE * 2) + 1]; - bool isAdded, isDeleteRequested; + SDL_bool isAdded, isDeleteRequested; } GAMEINPUT_InternalDevice; typedef struct GAMEINPUT_InternalList @@ -59,6 +61,7 @@ typedef struct joystick_hwdata static GAMEINPUT_InternalList g_GameInputList = { NULL }; +static void *g_hGameInputDLL = NULL; static IGameInput *g_pGameInput = NULL; static GameInputCallbackToken g_GameInputCallbackToken = GAMEINPUT_INVALID_CALLBACK_TOKEN_VALUE; @@ -75,7 +78,7 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) return SDL_SetError("GAMEINPUT_InternalAddOrFind argument pDevice cannot be NULL"); } - devinfo = pDevice->GetDeviceInfo(); + devinfo = IGameInputDevice_GetDeviceInfo(pDevice); if (!devinfo) { return SDL_SetError("GAMEINPUT_InternalAddOrFind GetDeviceInfo returned NULL"); } @@ -95,8 +98,8 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) /* generate a device name */ for (idx = 0; idx < APP_LOCAL_DEVICE_ID_SIZE; ++idx) { - (void)SDL_snprintf(tmpbuff, SDL_arraysize(tmpbuff), "%02hhX", devinfo->deviceId.value[idx]); - (void)strncat_s(elem->devicePath, tmpbuff, SDL_arraysize(tmpbuff)); + SDL_snprintf(tmpbuff, SDL_arraysize(tmpbuff), "%02hhX", devinfo->deviceId.value[idx]); + SDL_strlcat(elem->devicePath, tmpbuff, SDL_arraysize(tmpbuff)); } devicelist = (GAMEINPUT_InternalDevice **)SDL_realloc(g_GameInputList.devices, sizeof(elem) * (g_GameInputList.count + 1LL)); @@ -106,16 +109,10 @@ static int GAMEINPUT_InternalAddOrFind(IGameInputDevice *pDevice) } g_GameInputList.devices = devicelist; - pDevice->AddRef(); + IGameInputDevice_AddRef(pDevice); elem->device = pDevice; elem->deviceName = "GameInput Gamepad"; - elem->caps = 0; - if (devinfo->supportedRumbleMotors & (GameInputRumbleLowFrequency | GameInputRumbleHighFrequency)) { - elem->caps |= SDL_JOYSTICK_CAP_RUMBLE; - } - if (devinfo->supportedRumbleMotors & (GameInputRumbleLeftTrigger | GameInputRumbleRightTrigger)) { - elem->caps |= SDL_JOYSTICK_CAP_TRIGGER_RUMBLE; - } + elem->supportedRumbleMotors = devinfo->supportedRumbleMotors; elem->joystickGuid = SDL_CreateJoystickGUID( SDL_HARDWARE_BUS_BLUETOOTH, USB_VENDOR_MICROSOFT, @@ -142,7 +139,7 @@ static int GAMEINPUT_InternalRemoveByIndex(int idx) return SDL_SetError("GAMEINPUT_InternalRemoveByIndex argument idx %d is out of range", idx); } - g_GameInputList.devices[idx]->device->Release(); + IGameInputDevice_Release(g_GameInputList.devices[idx]->device); if (g_GameInputList.devices[idx]) { SDL_free(g_GameInputList.devices[idx]); @@ -199,7 +196,7 @@ static void CALLBACK GAMEINPUT_InternalJoystickDeviceCallback( elem = g_GameInputList.devices[idx]; if (elem && elem->device == device) { /* will be deleted on the next Detect call */ - elem->isDeleteRequested = true; + elem->isDeleteRequested = SDL_TRUE; break; } } @@ -212,29 +209,40 @@ static int GAMEINPUT_JoystickInit(void) { HRESULT hR; + if (!g_hGameInputDLL) { + g_hGameInputDLL = SDL_LoadObject("gameinput.dll"); + if (!g_hGameInputDLL) { + return -1; + } + } + if (!g_pGameInput) { - hR = GameInputCreate(&g_pGameInput); + typedef HRESULT (WINAPI *GameInputCreate_t)(IGameInput * *gameInput); + GameInputCreate_t GameInputCreateFunc = (GameInputCreate_t)SDL_LoadFunction(g_hGameInputDLL, "GameInputCreate"); + if (!GameInputCreateFunc) { + return -1; + } + + hR = GameInputCreateFunc(&g_pGameInput); if (FAILED(hR)) { return SDL_SetError("GameInputCreate failure with HRESULT of %08X", hR); } } - hR = g_pGameInput->RegisterDeviceCallback( - nullptr, - GameInputKindGamepad, - GameInputDeviceConnected, - GameInputBlockingEnumeration, - nullptr, - GAMEINPUT_InternalJoystickDeviceCallback, - &g_GameInputCallbackToken - ); + hR = IGameInput_RegisterDeviceCallback(g_pGameInput, + NULL, + GameInputKindGamepad, + GameInputDeviceConnected, + GameInputBlockingEnumeration, + NULL, + GAMEINPUT_InternalJoystickDeviceCallback, + &g_GameInputCallbackToken); if (FAILED(hR)) { return SDL_SetError("IGameInput::RegisterDeviceCallback failure with HRESULT of %08X", hR); } GAMEINPUT_JoystickDetect(); - /* no need to free IGameInput on failure. */ return 0; } @@ -256,10 +264,10 @@ static void GAMEINPUT_JoystickDetect(void) if (!elem->isAdded) { SDL_PrivateJoystickAdded(elem->instanceId); - elem->isAdded = true; + elem->isAdded = SDL_TRUE; } - if (elem->isDeleteRequested || !(elem->device->GetDeviceStatus() & GameInputDeviceConnected)) { + if (elem->isDeleteRequested || !(IGameInputDevice_GetDeviceStatus(elem->device) & GameInputDeviceConnected)) { SDL_PrivateJoystickRemoved(elem->instanceId); GAMEINPUT_InternalRemoveByIndex(idx--); } @@ -332,8 +340,8 @@ static SDL_JoystickGUID GAMEINPUT_JoystickGetDeviceGUID(int device_index) GAMEINPUT_InternalDevice *elem = GAMEINPUT_InternalFindByIndex(device_index); if (!elem) { - /* empty guid */ - return { { 0 } }; + static SDL_JoystickGUID emptyGUID; + return emptyGUID; } return elem->joystickGuid; @@ -371,6 +379,13 @@ static int GAMEINPUT_JoystickOpen(SDL_Joystick *joystick, int device_index) joystick->nbuttons = 11; joystick->nhats = 1; + if (elem->supportedRumbleMotors & (GameInputRumbleLowFrequency | GameInputRumbleHighFrequency)) { + SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_RUMBLE_BOOLEAN, SDL_TRUE); + } + if (elem->supportedRumbleMotors & (GameInputRumbleLeftTrigger | GameInputRumbleRightTrigger)) { + SDL_SetBooleanProperty(SDL_GetJoystickProperties(joystick), SDL_PROP_JOYSTICK_CAP_TRIGGER_RUMBLE_BOOLEAN, SDL_TRUE); + } + return 0; } @@ -381,7 +396,7 @@ static int GAMEINPUT_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency GameInputRumbleParams *params = &hwdata->rumbleParams; params->lowFrequency = (float)low_frequency_rumble / (float)SDL_MAX_UINT16; params->highFrequency = (float)high_frequency_rumble / (float)SDL_MAX_UINT16; - hwdata->devref->device->SetRumbleState(params); + IGameInputDevice_SetRumbleState(hwdata->devref->device, params); return 0; } @@ -392,15 +407,10 @@ static int 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; - hwdata->devref->device->SetRumbleState(params); + IGameInputDevice_SetRumbleState(hwdata->devref->device, params); return 0; } -static Uint32 GAMEINPUT_JoystickGetCapabilities(SDL_Joystick *joystick) -{ - return joystick->hwdata->devref->caps; -} - static int GAMEINPUT_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) { return SDL_Unsupported(); @@ -418,7 +428,7 @@ static int GAMEINPUT_JoystickSendEffect(SDL_Joystick *joystick, const void *data effect = (const GAMEINPUT_JoystickEffectData *)data; if (effect->type == GAMEINPUT_JoystickEffectDataType_HapticFeedback) { - hR = hwdata->devref->device->SetHapticMotorState( + hR = IGameInputDevice_SetHapticMotorState(hwdata->devref->device, effect->hapticFeedbackMotorIndex, &effect->hapticFeedbackParams ); @@ -450,7 +460,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) IGameInputReading *reading = NULL; uint64_t ts = 0; GameInputGamepadState state; - HRESULT hR = g_pGameInput->GetCurrentReading( + HRESULT hR = IGameInput_GetCurrentReading(g_pGameInput, GameInputKindGamepad, device, &reading @@ -463,9 +473,9 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) /* GDKX private docs for GetTimestamp: "The microsecond timestamp describing when the input was made." */ /* SDL expects a nanosecond timestamp, so I guess US_TO_NS should be used here? */ - ts = SDL_US_TO_NS(reading->GetTimestamp()); + ts = SDL_US_TO_NS(IGameInputReading_GetTimestamp(reading)); - if (((!hwdata->lastTimestamp) || (ts != hwdata->lastTimestamp)) && reading->GetGamepadState(&state)) { + if (((!hwdata->lastTimestamp) || (ts != hwdata->lastTimestamp)) && IGameInputReading_GetGamepadState(reading, &state)) { /* `state` is now valid */ #define tosint16(_TheValue) ((Sint16)(((_TheValue) < 0.0f) ? ((_TheValue) * 32768.0f) : ((_TheValue) * 32767.0f))) @@ -507,7 +517,7 @@ static void GAMEINPUT_JoystickUpdate(SDL_Joystick *joystick) hwdata->lastTimestamp = ts; } - reading->Release(); + IGameInputReading_Release(reading); } static void GAMEINPUT_JoystickClose(SDL_Joystick* joystick) @@ -520,26 +530,29 @@ static void GAMEINPUT_JoystickQuit(void) { int idx; - if (!g_pGameInput) { - return; + if (g_pGameInput) { + /* free the callback */ + IGameInput_UnregisterCallback(g_pGameInput, g_GameInputCallbackToken, /*timeoutInUs:*/ 10000); + g_GameInputCallbackToken = GAMEINPUT_INVALID_CALLBACK_TOKEN_VALUE; + + /* free the list */ + for (idx = 0; idx < g_GameInputList.count; ++idx) { + IGameInputDevice_Release(g_GameInputList.devices[idx]->device); + SDL_free(g_GameInputList.devices[idx]); + g_GameInputList.devices[idx] = NULL; + } + SDL_free(g_GameInputList.devices); + g_GameInputList.devices = NULL; + g_GameInputList.count = 0; + + IGameInput_Release(g_pGameInput); + g_pGameInput = NULL; } - /* free the callback */ - g_pGameInput->UnregisterCallback(g_GameInputCallbackToken, /*timeoutInUs:*/ 10000); - g_GameInputCallbackToken = GAMEINPUT_INVALID_CALLBACK_TOKEN_VALUE; - - /* free the list */ - for (idx = 0; idx < g_GameInputList.count; ++idx) { - g_GameInputList.devices[idx]->device->Release(); - SDL_free(g_GameInputList.devices[idx]); - g_GameInputList.devices[idx] = NULL; + if (g_hGameInputDLL) { + SDL_UnloadObject(g_hGameInputDLL); + g_hGameInputDLL = NULL; } - SDL_free(g_GameInputList.devices); - g_GameInputList.devices = NULL; - g_GameInputList.count = 0; - - g_pGameInput->Release(); - g_pGameInput = NULL; } static SDL_bool GAMEINPUT_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out) @@ -563,7 +576,6 @@ SDL_JoystickDriver SDL_GAMEINPUT_JoystickDriver = GAMEINPUT_JoystickOpen, GAMEINPUT_JoystickRumble, GAMEINPUT_JoystickRumbleTriggers, - GAMEINPUT_JoystickGetCapabilities, GAMEINPUT_JoystickSetLED, GAMEINPUT_JoystickSendEffect, GAMEINPUT_JoystickSetSensorsEnabled, diff --git a/src/joystick/gdk/SDL_gameinputjoystick_c.h b/src/joystick/gdk/SDL_gameinputjoystick_c.h index 03bc1c059..0b3bc51a6 100644 --- a/src/joystick/gdk/SDL_gameinputjoystick_c.h +++ b/src/joystick/gdk/SDL_gameinputjoystick_c.h @@ -23,14 +23,10 @@ #if defined(SDL_JOYSTICK_GAMEINPUT) && SDL_JOYSTICK_GAMEINPUT -/* include this file in C++ */ +#include +#define COBJMACROS #include -/* Set up for C function definitions, even when using C++ */ -#ifdef __cplusplus -extern "C" { -#endif - typedef enum GAMEINPUT_JoystickEffectDataType { GAMEINPUT_JoystickEffectDataType_HapticFeedback @@ -50,9 +46,4 @@ typedef struct GAMEINPUT_JoystickEffectData }; } GAMEINPUT_JoystickEffectData; -/* Ends C function definitions when using C++ */ -#ifdef __cplusplus -} -#endif - #endif /* defined(SDL_JOYSTICK_GAMEINPUT) && SDL_JOYSTICK_GAMEINPUT */