Skip to content

Commit

Permalink
Added Steam Input API support for game controllers
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
slouken committed Dec 20, 2023
1 parent 9d13be7 commit 54b7fcd
Show file tree
Hide file tree
Showing 40 changed files with 723 additions and 23 deletions.
2 changes: 2 additions & 0 deletions VisualC-GDK/SDL/SDL.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -407,6 +407,7 @@
<ClInclude Include="..\..\src\joystick\SDL_gamepad_c.h" />
<ClInclude Include="..\..\src\joystick\SDL_gamepad_db.h" />
<ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
<ClInclude Include="..\..\src\joystick\SDL_steam_virtual_gamepad.h" />
<ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
<ClInclude Include="..\..\src\joystick\usb_ids.h" />
<ClInclude Include="..\..\src\joystick\virtual\SDL_virtualjoystick_c.h" />
Expand Down Expand Up @@ -634,6 +635,7 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />
<ClCompile Include="..\..\src\joystick\virtual\SDL_virtualjoystick.c" />
<ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
<ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />
Expand Down
6 changes: 6 additions & 0 deletions VisualC-GDK/SDL/SDL.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,9 @@
<ClInclude Include="..\..\src\joystick\SDL_joystick_c.h">
<Filter>joystick</Filter>
</ClInclude>
<ClInclude Include="..\..\src\joystick\SDL_steam_virtual_gamepad.h">
<Filter>joystick</Filter>
</ClInclude>
<ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h">
<Filter>joystick</Filter>
</ClInclude>
Expand Down Expand Up @@ -964,6 +967,9 @@
<ClCompile Include="..\..\src\joystick\SDL_joystick.c">
<Filter>joystick</Filter>
</ClCompile>
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c">
<Filter>joystick</Filter>
</ClCompile>
<ClCompile Include="..\..\src\libm\e_atan2.c">
<Filter>libm</Filter>
</ClCompile>
Expand Down
2 changes: 2 additions & 0 deletions VisualC-WinRT/SDL-UWP.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,7 @@
<ClInclude Include="..\src\joystick\SDL_gamepad_c.h" />
<ClInclude Include="..\src\joystick\SDL_gamepad_db.h" />
<ClInclude Include="..\src\joystick\SDL_joystick_c.h" />
<ClInclude Include="..\src\joystick\SDL_steam_virtual_gamepad.h" />
<ClInclude Include="..\src\joystick\SDL_sysjoystick.h" />
<ClInclude Include="..\src\joystick\virtual\SDL_virtualjoystick_c.h" />
<ClInclude Include="..\src\joystick\windows\SDL_dinputjoystick_c.h" />
Expand Down Expand Up @@ -331,6 +332,7 @@
<ClCompile Include="..\src\joystick\controller_type.c" />
<ClCompile Include="..\src\joystick\SDL_gamepad.c" />
<ClCompile Include="..\src\joystick\SDL_joystick.c" />
<ClCompile Include="..\src\joystick\SDL_steam_virtual_gamepad.c" />
<ClCompile Include="..\src\joystick\virtual\SDL_virtualjoystick.c" />
<ClCompile Include="..\src\joystick\windows\SDL_dinputjoystick.c" />
<ClCompile Include="..\src\joystick\windows\SDL_windowsjoystick.c" />
Expand Down
6 changes: 6 additions & 0 deletions VisualC-WinRT/SDL-UWP.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,9 @@
<ClInclude Include="..\src\joystick\SDL_joystick_c.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\joystick\SDL_steam_virtual_gamepad.h">
<Filter>Source Files</Filter>
</ClInclude>
<ClInclude Include="..\src\joystick\SDL_sysjoystick.h">
<Filter>Source Files</Filter>
</ClInclude>
Expand Down Expand Up @@ -585,6 +588,9 @@
<ClCompile Include="..\src\joystick\SDL_joystick.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\joystick\SDL_steam_virtual_gamepad.c">
<Filter>Source Files</Filter>
</ClCompile>
<ClCompile Include="..\src\joystick\virtual\SDL_virtualjoystick.c">
<Filter>Source Files</Filter>
</ClCompile>
Expand Down
2 changes: 2 additions & 0 deletions VisualC/SDL/SDL.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@
<ClInclude Include="..\..\src\joystick\SDL_gamepad_c.h" />
<ClInclude Include="..\..\src\joystick\SDL_gamepad_db.h" />
<ClInclude Include="..\..\src\joystick\SDL_joystick_c.h" />
<ClInclude Include="..\..\src\joystick\SDL_steam_virtual_gamepad.h" />
<ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h" />
<ClInclude Include="..\..\src\joystick\usb_ids.h" />
<ClInclude Include="..\..\src\joystick\virtual\SDL_virtualjoystick_c.h" />
Expand Down Expand Up @@ -537,6 +538,7 @@
<ClCompile Include="..\..\src\joystick\hidapi\SDL_hidapi_xboxone.c" />
<ClCompile Include="..\..\src\joystick\SDL_gamepad.c" />
<ClCompile Include="..\..\src\joystick\SDL_joystick.c" />
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c" />
<ClCompile Include="..\..\src\joystick\virtual\SDL_virtualjoystick.c" />
<ClCompile Include="..\..\src\joystick\windows\SDL_dinputjoystick.c" />
<ClCompile Include="..\..\src\joystick\windows\SDL_rawinputjoystick.c" />
Expand Down
6 changes: 6 additions & 0 deletions VisualC/SDL/SDL.vcxproj.filters
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,9 @@
<ClInclude Include="..\..\src\joystick\SDL_joystick_c.h">
<Filter>joystick</Filter>
</ClInclude>
<ClInclude Include="..\..\src\joystick\SDL_steam_virtual_gamepad.h">
<Filter>joystick</Filter>
</ClInclude>
<ClInclude Include="..\..\src\joystick\SDL_sysjoystick.h">
<Filter>joystick</Filter>
</ClInclude>
Expand Down Expand Up @@ -945,6 +948,9 @@
<ClCompile Include="..\..\src\joystick\SDL_joystick.c">
<Filter>joystick</Filter>
</ClCompile>
<ClCompile Include="..\..\src\joystick\SDL_steam_virtual_gamepad.c">
<Filter>joystick</Filter>
</ClCompile>
<ClCompile Include="..\..\src\libm\e_atan2.c">
<Filter>libm</Filter>
</ClCompile>
Expand Down
3 changes: 2 additions & 1 deletion include/SDL3/SDL_events.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ typedef enum
SDL_EVENT_GAMEPAD_TOUCHPAD_UP, /**< Gamepad touchpad finger was lifted */
SDL_EVENT_GAMEPAD_SENSOR_UPDATE, /**< Gamepad sensor was updated */
SDL_EVENT_GAMEPAD_UPDATE_COMPLETE, /**< Gamepad update is complete */
SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED, /**< Gamepad Steam handle has changed */

/* Touch events */
SDL_EVENT_FINGER_DOWN = 0x700,
Expand Down Expand Up @@ -457,7 +458,7 @@ typedef struct SDL_GamepadButtonEvent
*/
typedef struct SDL_GamepadDeviceEvent
{
Uint32 type; /**< ::SDL_EVENT_GAMEPAD_ADDED, ::SDL_EVENT_GAMEPAD_REMOVED, or ::SDL_EVENT_GAMEPAD_REMAPPED or ::SDL_EVENT_GAMEPAD_UPDATE_COMPLETE */
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 */
Uint64 timestamp; /**< In nanoseconds, populated using SDL_GetTicksNS() */
SDL_JoystickID which; /**< The joystick instance id */
} SDL_GamepadDeviceEvent;
Expand Down
13 changes: 13 additions & 0 deletions include/SDL3/SDL_gamepad.h
Original file line number Diff line number Diff line change
Expand Up @@ -758,6 +758,19 @@ extern DECLSPEC Uint16 SDLCALL SDL_GetGamepadFirmwareVersion(SDL_Gamepad *gamepa
*/
extern DECLSPEC const char * SDLCALL SDL_GetGamepadSerial(SDL_Gamepad *gamepad);

/**
* Get the Steam Input handle of an opened gamepad, if available.
*
* Returns an InputHandle_t for the gamepad that can be used with Steam Input API:
* https://partner.steamgames.com/doc/api/ISteamInput
*
* \param gamepad the gamepad object to query.
* \returns the gamepad handle, or 0 if unavailable.
*
* \since This function is available since SDL 3.0.0.
*/
extern DECLSPEC Uint64 SDLCALL SDL_GetGamepadSteamHandle(SDL_Gamepad *gamepad);

/**
* Get the battery level of a gamepad, if available.
*
Expand Down
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi.sym
Original file line number Diff line number Diff line change
Expand Up @@ -965,6 +965,7 @@ SDL3_0.0.0 {
SDL_SyncWindow;
SDL_SetSurfaceScaleMode;
SDL_GetSurfaceScaleMode;
SDL_GetGamepadSteamHandle;
# extra symbols go here (don't modify this line)
local: *;
};
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Original file line number Diff line number Diff line change
Expand Up @@ -990,3 +990,4 @@
#define SDL_SyncWindow SDL_SyncWindow_REAL
#define SDL_SetSurfaceScaleMode SDL_SetSurfaceScaleMode_REAL
#define SDL_GetSurfaceScaleMode SDL_GetSurfaceScaleMode_REAL
#define SDL_GetGamepadSteamHandle SDL_GetGamepadSteamHandle_REAL
1 change: 1 addition & 0 deletions src/dynapi/SDL_dynapi_procs.h
Original file line number Diff line number Diff line change
Expand Up @@ -1015,3 +1015,4 @@ SDL_DYNAPI_PROC(wchar_t*,SDL_wcsnstr,(const wchar_t *a, const wchar_t *b, size_t
SDL_DYNAPI_PROC(int,SDL_SyncWindow,(SDL_Window *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_SetSurfaceScaleMode,(SDL_Surface *a, SDL_ScaleMode b),(a,b),return)
SDL_DYNAPI_PROC(int,SDL_GetSurfaceScaleMode,(SDL_Surface *a, SDL_ScaleMode *b),(a,b),return)
SDL_DYNAPI_PROC(Uint64,SDL_GetGamepadSteamHandle,(SDL_Gamepad *a),(a),return)
3 changes: 3 additions & 0 deletions src/events/SDL_events.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,9 @@ static void SDL_LogEvent(const SDL_Event *event)
SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_REMAPPED)
PRINT_GAMEPADDEV_EVENT(event);
break;
SDL_EVENT_CASE(SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED)
PRINT_GAMEPADDEV_EVENT(event);
break;
#undef PRINT_GAMEPADDEV_EVENT

#define PRINT_CTOUCHPAD_EVENT(event) \
Expand Down
43 changes: 40 additions & 3 deletions src/joystick/SDL_gamepad.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "../SDL_utils_c.h"
#include "SDL_sysjoystick.h"
#include "SDL_joystick_c.h"
#include "SDL_steam_virtual_gamepad.h"
#include "SDL_gamepad_c.h"
#include "SDL_gamepad_db.h"
#include "controller_type.h"
Expand Down Expand Up @@ -2411,7 +2412,21 @@ SDL_GamepadType SDL_GetGamepadInstanceType(SDL_JoystickID instance_id)

SDL_GamepadType SDL_GetRealGamepadInstanceType(SDL_JoystickID instance_id)
{
return SDL_GetGamepadTypeFromGUID(SDL_GetJoystickInstanceGUID(instance_id), SDL_GetJoystickInstanceName(instance_id));
SDL_GamepadType type = SDL_GAMEPAD_TYPE_UNKNOWN;
const SDL_SteamVirtualGamepadInfo *info;

SDL_LockJoysticks();
{
info = SDL_GetJoystickInstanceVirtualGamepadInfo(instance_id);
if (info) {
type = info->type;
} else {
type = SDL_GetGamepadTypeFromGUID(SDL_GetJoystickInstanceGUID(instance_id), SDL_GetJoystickInstanceName(instance_id));
}
}
SDL_UnlockJoysticks();

return type;
}

char *SDL_GetGamepadInstanceMapping(SDL_JoystickID instance_id)
Expand Down Expand Up @@ -3190,7 +3205,8 @@ const char *SDL_GetGamepadName(SDL_Gamepad *gamepad)
{
CHECK_GAMEPAD_MAGIC(gamepad, NULL);

if (SDL_strcmp(gamepad->name, "*") == 0) {
if (SDL_strcmp(gamepad->name, "*") == 0 ||
gamepad->joystick->steam_handle != 0) {
retval = SDL_GetJoystickName(gamepad->joystick);
} else {
retval = gamepad->name;
Expand All @@ -3214,12 +3230,18 @@ const char *SDL_GetGamepadPath(SDL_Gamepad *gamepad)
SDL_GamepadType SDL_GetGamepadType(SDL_Gamepad *gamepad)
{
SDL_GamepadType type;
const SDL_SteamVirtualGamepadInfo *info;

SDL_LockJoysticks();
{
CHECK_GAMEPAD_MAGIC(gamepad, SDL_GAMEPAD_TYPE_UNKNOWN);

type = gamepad->type;
info = SDL_GetJoystickInstanceVirtualGamepadInfo(gamepad->joystick->instance_id);
if (info) {
type = info->type;
} else {
type = gamepad->type;
}
}
SDL_UnlockJoysticks();

Expand Down Expand Up @@ -3310,6 +3332,21 @@ const char * SDL_GetGamepadSerial(SDL_Gamepad *gamepad)
return SDL_GetJoystickSerial(joystick);
}

Uint64 SDL_GetGamepadSteamHandle(SDL_Gamepad *gamepad)
{
Uint64 handle = 0;

SDL_LockJoysticks();
{
CHECK_GAMEPAD_MAGIC(gamepad, 0);

handle = gamepad->joystick->steam_handle;
}
SDL_UnlockJoysticks();

return handle;
}

SDL_JoystickPowerLevel SDL_GetGamepadPowerLevel(SDL_Gamepad *gamepad)
{
SDL_Joystick *joystick = SDL_GetGamepadJoystick(gamepad);
Expand Down
Loading

0 comments on commit 54b7fcd

Please sign in to comment.