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 */