Skip to content

Commit 3671160

Browse files
committed
Added Steam Input API support for game controllers
Added support for getting the real controller info, as well as the function SDL_GetGamepadSteamHandle() to get the Steam Input API handle, from the virtual gamepads provided by Steam. Also added an event SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED which is triggered when a controller's API handle changes, e.g. the controllers were reassigned slots in the Steam UI.
1 parent 9d13be7 commit 3671160

40 files changed

+721
-23
lines changed

Diff for: VisualC-GDK/SDL/SDL.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@
407407
<ClInclude Include="..\..\src\joystick\SDL_gamepad_c.h" />
408408
<ClInclude Include="..\..\src\joystick\SDL_gamepad_db.h" />
409409
<ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
410+
<ClInclude Include="..\..\src\joystick\SDL_steam_virtual_gamepad.h" />
410411
<ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
411412
<ClInclude Include="..\..\src\joystick\usb_ids.h" />
412413
<ClInclude Include="..\..\src\joystick\virtual\SDL_virtualjoystick_c.h" />
@@ -634,6 +635,7 @@
634635
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
635636
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
636637
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
638+
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />
637639
<ClCompile Include="..\..\src\joystick\virtual\SDL_virtualjoystick.c" />
638640
<ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
639641
<ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />

Diff for: VisualC-GDK/SDL/SDL.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -507,6 +507,9 @@
507507
<ClInclude Include="..\..\src\joystick\SDL_joystick_c.h">
508508
<Filter>joystick</Filter>
509509
</ClInclude>
510+
<ClInclude Include="..\..\src\joystick\SDL_steam_virtual_gamepad.h">
511+
<Filter>joystick</Filter>
512+
</ClInclude>
510513
<ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h">
511514
<Filter>joystick</Filter>
512515
</ClInclude>
@@ -964,6 +967,9 @@
964967
<ClCompile Include="..\..\src\joystick\SDL_joystick.c">
965968
<Filter>joystick</Filter>
966969
</ClCompile>
970+
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c">
971+
<Filter>joystick</Filter>
972+
</ClCompile>
967973
<ClCompile Include="..\..\src\libm\e_atan2.c">
968974
<Filter>libm</Filter>
969975
</ClCompile>

Diff for: VisualC-WinRT/SDL-UWP.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@
127127
<ClInclude Include="..\src\joystick\SDL_gamepad_c.h" />
128128
<ClInclude Include="..\src\joystick\SDL_gamepad_db.h" />
129129
<ClInclude Include="..\src\joystick\SDL_joystick_c.h" />
130+
<ClInclude Include="..\src\joystick\SDL_steam_virtual_gamepad.h" />
130131
<ClInclude Include="..\src\joystick\SDL_sysjoystick.h" />
131132
<ClInclude Include="..\src\joystick\virtual\SDL_virtualjoystick_c.h" />
132133
<ClInclude Include="..\src\joystick\windows\SDL_dinputjoystick_c.h" />
@@ -331,6 +332,7 @@
331332
<ClCompile Include="..\src\joystick\controller_type.c" />
332333
<ClCompile Include="..\src\joystick\SDL_gamepad.c" />
333334
<ClCompile Include="..\src\joystick\SDL_joystick.c" />
335+
<ClCompile Include="..\src\joystick\SDL_steam_virtual_gamepad.c" />
334336
<ClCompile Include="..\src\joystick\virtual\SDL_virtualjoystick.c" />
335337
<ClCompile Include="..\src\joystick\windows\SDL_dinputjoystick.c" />
336338
<ClCompile Include="..\src\joystick\windows\SDL_windowsjoystick.c" />

Diff for: VisualC-WinRT/SDL-UWP.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -261,6 +261,9 @@
261261
<ClInclude Include="..\src\joystick\SDL_joystick_c.h">
262262
<Filter>Source Files</Filter>
263263
</ClInclude>
264+
<ClInclude Include="..\src\joystick\SDL_steam_virtual_gamepad.h">
265+
<Filter>Source Files</Filter>
266+
</ClInclude>
264267
<ClInclude Include="..\src\joystick\SDL_sysjoystick.h">
265268
<Filter>Source Files</Filter>
266269
</ClInclude>
@@ -585,6 +588,9 @@
585588
<ClCompile Include="..\src\joystick\SDL_joystick.c">
586589
<Filter>Source Files</Filter>
587590
</ClCompile>
591+
<ClCompile Include="..\src\joystick\SDL_steam_virtual_gamepad.c">
592+
<Filter>Source Files</Filter>
593+
</ClCompile>
588594
<ClCompile Include="..\src\joystick\virtual\SDL_virtualjoystick.c">
589595
<Filter>Source Files</Filter>
590596
</ClCompile>

Diff for: VisualC/SDL/SDL.vcxproj

+2
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@
357357
<ClInclude Include="..\..\src\joystick\SDL_gamepad_c.h" />
358358
<ClInclude Include="..\..\src\joystick\SDL_gamepad_db.h" />
359359
<ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
360+
<ClInclude Include="..\..\src\joystick\SDL_steam_virtual_gamepad.h" />
360361
<ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
361362
<ClInclude Include="..\..\src\joystick\usb_ids.h" />
362363
<ClInclude Include="..\..\src\joystick\virtual\SDL_virtualjoystick_c.h" />
@@ -537,6 +538,7 @@
537538
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
538539
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
539540
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
541+
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />
540542
<ClCompile Include="..\..\src\joystick\virtual\SDL_virtualjoystick.c" />
541543
<ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
542544
<ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />

Diff for: VisualC/SDL/SDL.vcxproj.filters

+6
Original file line numberDiff line numberDiff line change
@@ -501,6 +501,9 @@
501501
<ClInclude Include="..\..\src\joystick\SDL_joystick_c.h">
502502
<Filter>joystick</Filter>
503503
</ClInclude>
504+
<ClInclude Include="..\..\src\joystick\SDL_steam_virtual_gamepad.h">
505+
<Filter>joystick</Filter>
506+
</ClInclude>
504507
<ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h">
505508
<Filter>joystick</Filter>
506509
</ClInclude>
@@ -945,6 +948,9 @@
945948
<ClCompile Include="..\..\src\joystick\SDL_joystick.c">
946949
<Filter>joystick</Filter>
947950
</ClCompile>
951+
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c">
952+
<Filter>joystick</Filter>
953+
</ClCompile>
948954
<ClCompile Include="..\..\src\libm\e_atan2.c">
949955
<Filter>libm</Filter>
950956
</ClCompile>

Diff for: include/SDL3/SDL_events.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ typedef enum
170170
SDL_EVENT_GAMEPAD_TOUCHPAD_UP, /**< Gamepad touchpad finger was lifted */
171171
SDL_EVENT_GAMEPAD_SENSOR_UPDATE, /**< Gamepad sensor was updated */
172172
SDL_EVENT_GAMEPAD_UPDATE_COMPLETE, /**< Gamepad update is complete */
173+
SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED, /**< Gamepad Steam handle has changed */
173174

174175
/* Touch events */
175176
SDL_EVENT_FINGER_DOWN = 0x700,
@@ -457,7 +458,7 @@ typedef struct SDL_GamepadButtonEvent
457458
*/
458459
typedef struct SDL_GamepadDeviceEvent
459460
{
460-
Uint32 type; /**< ::SDL_EVENT_GAMEPAD_ADDED, ::SDL_EVENT_GAMEPAD_REMOVED, or ::SDL_EVENT_GAMEPAD_REMAPPED or ::SDL_EVENT_GAMEPAD_UPDATE_COMPLETE */
461+
Uint32 type; /**< ::SDL_EVENT_GAMEPAD_ADDED, ::SDL_EVENT_GAMEPAD_REMOVED, or ::SDL_EVENT_GAMEPAD_REMAPPED, ::SDL_EVENT_GAMEPAD_UPDATE_COMPLETE or ::SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED */
461462
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
462463
SDL_JoystickID which; /**< The joystick instance id */
463464
} SDL_GamepadDeviceEvent;

Diff for: include/SDL3/SDL_gamepad.h

+13
Original file line numberDiff line numberDiff line change
@@ -758,6 +758,19 @@ extern DECLSPEC Uint16 SDLCALL SDL_GetGamepadFirmwareVersion(SDL_Gamepad *gamepa
758758
*/
759759
extern DECLSPEC const char * SDLCALL SDL_GetGamepadSerial(SDL_Gamepad *gamepad);
760760

761+
/**
762+
* Get the Steam Input handle of an opened gamepad, if available.
763+
*
764+
* Returns an InputHandle_t for the gamepad that can be used with Steam Input API:
765+
* https://partner.steamgames.com/doc/api/ISteamInput
766+
*
767+
* \param gamepad the gamepad object to query.
768+
* \returns the gamepad handle, or 0 if unavailable.
769+
*
770+
* \since This function is available since SDL 3.0.0.
771+
*/
772+
extern DECLSPEC Uint64 SDLCALL SDL_GetGamepadSteamHandle(SDL_Gamepad *gamepad);
773+
761774
/**
762775
* Get the battery level of a gamepad, if available.
763776
*

Diff for: src/dynapi/SDL_dynapi.sym

+1
Original file line numberDiff line numberDiff line change
@@ -965,6 +965,7 @@ SDL3_0.0.0 {
965965
SDL_SyncWindow;
966966
SDL_SetSurfaceScaleMode;
967967
SDL_GetSurfaceScaleMode;
968+
SDL_GetGamepadSteamHandle;
968969
# extra symbols go here (don't modify this line)
969970
local: *;
970971
};

Diff for: src/dynapi/SDL_dynapi_overrides.h

+1
Original file line numberDiff line numberDiff line change
@@ -990,3 +990,4 @@
990990
#define SDL_SyncWindow SDL_SyncWindow_REAL
991991
#define SDL_SetSurfaceScaleMode SDL_SetSurfaceScaleMode_REAL
992992
#define SDL_GetSurfaceScaleMode SDL_GetSurfaceScaleMode_REAL
993+
#define SDL_GetGamepadSteamHandle SDL_GetGamepadSteamHandle_REAL

Diff for: src/dynapi/SDL_dynapi_procs.h

+1
Original file line numberDiff line numberDiff line change
@@ -1015,3 +1015,4 @@ SDL_DYNAPI_PROC(wchar_t*,SDL_wcsnstr,(const wchar_t *a, const wchar_t *b, size_t
10151015
SDL_DYNAPI_PROC(int,SDL_SyncWindow,(SDL_Window *a),(a),return)
10161016
SDL_DYNAPI_PROC(int,SDL_SetSurfaceScaleMode,(SDL_Surface *a, SDL_ScaleMode b),(a,b),return)
10171017
SDL_DYNAPI_PROC(int,SDL_GetSurfaceScaleMode,(SDL_Surface *a, SDL_ScaleMode *b),(a,b),return)
1018+
SDL_DYNAPI_PROC(Uint64,SDL_GetGamepadSteamHandle,(SDL_Gamepad *a),(a),return)

Diff for: src/events/SDL_events.c

+3
Original file line numberDiff line numberDiff line change
@@ -433,6 +433,9 @@ static void SDL_LogEvent(const SDL_Event *event)
433433
SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_REMAPPED)
434434
PRINT_GAMEPADDEV_EVENT(event);
435435
break;
436+
SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED)
437+
PRINT_GAMEPADDEV_EVENT(event);
438+
break;
436439
#undef PRINT_GAMEPADDEV_EVENT
437440

438441
#define PRINT_CTOUCHPAD_EVENT(event) \

Diff for: src/joystick/SDL_gamepad.c

+40-3
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "../SDL_utils_c.h"
2626
#include "SDL_sysjoystick.h"
2727
#include "SDL_joystick_c.h"
28+
#include "SDL_steam_virtual_gamepad.h"
2829
#include "SDL_gamepad_c.h"
2930
#include "SDL_gamepad_db.h"
3031
#include "controller_type.h"
@@ -2411,7 +2412,21 @@ SDL_GamepadType SDL_GetGamepadInstanceType(SDL_JoystickID instance_id)
24112412

24122413
SDL_GamepadType SDL_GetRealGamepadInstanceType(SDL_JoystickID instance_id)
24132414
{
2414-
return SDL_GetGamepadTypeFromGUID(SDL_GetJoystickInstanceGUID(instance_id), SDL_GetJoystickInstanceName(instance_id));
2415+
SDL_GamepadType type = SDL_GAMEPAD_TYPE_UNKNOWN;
2416+
const SDL_SteamVirtualGamepadInfo *info;
2417+
2418+
SDL_LockJoysticks();
2419+
{
2420+
info = SDL_GetJoystickInstanceVirtualGamepadInfo(instance_id);
2421+
if (info) {
2422+
type = info->type;
2423+
} else {
2424+
type = SDL_GetGamepadTypeFromGUID(SDL_GetJoystickInstanceGUID(instance_id), SDL_GetJoystickInstanceName(instance_id));
2425+
}
2426+
}
2427+
SDL_UnlockJoysticks();
2428+
2429+
return type;
24152430
}
24162431

24172432
char *SDL_GetGamepadInstanceMapping(SDL_JoystickID instance_id)
@@ -3190,7 +3205,8 @@ const char *SDL_GetGamepadName(SDL_Gamepad *gamepad)
31903205
{
31913206
CHECK_GAMEPAD_MAGIC(gamepad, NULL);
31923207

3193-
if (SDL_strcmp(gamepad->name, "*") == 0) {
3208+
if (SDL_strcmp(gamepad->name, "*") == 0 ||
3209+
gamepad->joystick->steam_handle != 0) {
31943210
retval = SDL_GetJoystickName(gamepad->joystick);
31953211
} else {
31963212
retval = gamepad->name;
@@ -3214,12 +3230,18 @@ const char *SDL_GetGamepadPath(SDL_Gamepad *gamepad)
32143230
SDL_GamepadType SDL_GetGamepadType(SDL_Gamepad *gamepad)
32153231
{
32163232
SDL_GamepadType type;
3233+
const SDL_SteamVirtualGamepadInfo *info;
32173234

32183235
SDL_LockJoysticks();
32193236
{
32203237
CHECK_GAMEPAD_MAGIC(gamepad, SDL_GAMEPAD_TYPE_UNKNOWN);
32213238

3222-
type = gamepad->type;
3239+
info = SDL_GetJoystickInstanceVirtualGamepadInfo(gamepad->joystick->instance_id);
3240+
if (info) {
3241+
type = info->type;
3242+
} else {
3243+
type = gamepad->type;
3244+
}
32233245
}
32243246
SDL_UnlockJoysticks();
32253247

@@ -3310,6 +3332,21 @@ const char * SDL_GetGamepadSerial(SDL_Gamepad *gamepad)
33103332
return SDL_GetJoystickSerial(joystick);
33113333
}
33123334

3335+
Uint64 SDL_GetGamepadSteamHandle(SDL_Gamepad *gamepad)
3336+
{
3337+
Uint64 handle = 0;
3338+
3339+
SDL_LockJoysticks();
3340+
{
3341+
CHECK_GAMEPAD_MAGIC(gamepad, 0);
3342+
3343+
handle = gamepad->joystick->steam_handle;
3344+
}
3345+
SDL_UnlockJoysticks();
3346+
3347+
return handle;
3348+
}
3349+
33133350
SDL_JoystickPowerLevel SDL_GetGamepadPowerLevel(SDL_Gamepad *gamepad)
33143351
{
33153352
SDL_Joystick *joystick = SDL_GetGamepadJoystick(gamepad);

0 commit comments

Comments
 (0)