mirror of
https://github.com/libsdl-org/SDL.git
synced 2025-09-30 15:08:31 +00:00
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.
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
#include "../SDL_hints_c.h"
|
||||
#include "SDL_gamepad_c.h"
|
||||
#include "SDL_joystick_c.h"
|
||||
#include "SDL_steam_virtual_gamepad.h"
|
||||
|
||||
#ifndef SDL_EVENTS_DISABLED
|
||||
#include "../events/SDL_events_c.h"
|
||||
@@ -624,6 +625,8 @@ int SDL_InitJoysticks(void)
|
||||
SDL_AddHintCallback(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS,
|
||||
SDL_JoystickAllowBackgroundEventsChanged, NULL);
|
||||
|
||||
SDL_InitSteamVirtualGamepadInfo();
|
||||
|
||||
status = -1;
|
||||
for (i = 0; i < SDL_arraysize(SDL_joystick_drivers); ++i) {
|
||||
if (SDL_joystick_drivers[i]->Init() >= 0) {
|
||||
@@ -696,6 +699,19 @@ SDL_JoystickID *SDL_GetJoysticks(int *count)
|
||||
return joysticks;
|
||||
}
|
||||
|
||||
const SDL_SteamVirtualGamepadInfo *SDL_GetJoystickInstanceVirtualGamepadInfo(SDL_JoystickID instance_id)
|
||||
{
|
||||
SDL_JoystickDriver *driver;
|
||||
int device_index;
|
||||
const SDL_SteamVirtualGamepadInfo *info = NULL;
|
||||
|
||||
if (SDL_SteamVirtualGamepadEnabled() &&
|
||||
SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) {
|
||||
info = SDL_GetSteamVirtualGamepadInfo(driver->GetDeviceSteamVirtualGamepadSlot(device_index));
|
||||
}
|
||||
return info;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get the implementation dependent name of a joystick
|
||||
*/
|
||||
@@ -704,9 +720,13 @@ const char *SDL_GetJoystickInstanceName(SDL_JoystickID instance_id)
|
||||
SDL_JoystickDriver *driver;
|
||||
int device_index;
|
||||
const char *name = NULL;
|
||||
const SDL_SteamVirtualGamepadInfo *info;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
if (SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) {
|
||||
info = SDL_GetJoystickInstanceVirtualGamepadInfo(instance_id);
|
||||
if (info) {
|
||||
name = info->name;
|
||||
} else if (SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) {
|
||||
name = driver->GetDeviceName(device_index);
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
@@ -993,6 +1013,7 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
|
||||
const char *joystickpath = NULL;
|
||||
SDL_JoystickPowerLevel initial_power_level;
|
||||
SDL_bool invert_sensors = SDL_FALSE;
|
||||
const SDL_SteamVirtualGamepadInfo *info;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
|
||||
@@ -1076,6 +1097,12 @@ SDL_Joystick *SDL_OpenJoystick(SDL_JoystickID instance_id)
|
||||
|
||||
joystick->is_gamepad = SDL_IsGamepad(instance_id);
|
||||
|
||||
/* Get the Steam Input API handle */
|
||||
info = SDL_GetJoystickInstanceVirtualGamepadInfo(instance_id);
|
||||
if (info) {
|
||||
joystick->steam_handle = info->handle;
|
||||
}
|
||||
|
||||
/* Use system gyro and accelerometer if the gamepad doesn't have built-in sensors */
|
||||
if (ShouldAttemptSensorFusion(joystick, &invert_sensors)) {
|
||||
AttemptSensorFusion(joystick, invert_sensors);
|
||||
@@ -1491,15 +1518,20 @@ SDL_PropertiesID SDL_GetJoystickProperties(SDL_Joystick *joystick)
|
||||
const char *SDL_GetJoystickName(SDL_Joystick *joystick)
|
||||
{
|
||||
const char *retval;
|
||||
const SDL_SteamVirtualGamepadInfo *info;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
{
|
||||
info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id);
|
||||
if (info) {
|
||||
retval = info->name;
|
||||
} else {
|
||||
CHECK_JOYSTICK_MAGIC(joystick, NULL);
|
||||
|
||||
retval = joystick->name;
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
/* FIXME: Really we should reference count this name so it doesn't go away after unlock */
|
||||
return retval;
|
||||
}
|
||||
|
||||
@@ -1823,6 +1855,8 @@ void SDL_QuitJoysticks(void)
|
||||
SDL_QuitSubSystem(SDL_INIT_EVENTS);
|
||||
#endif
|
||||
|
||||
SDL_QuitSteamVirtualGamepadInfo();
|
||||
|
||||
SDL_DelHintCallback(SDL_HINT_JOYSTICK_ALLOW_BACKGROUND_EVENTS,
|
||||
SDL_JoystickAllowBackgroundEventsChanged, NULL);
|
||||
|
||||
@@ -1921,7 +1955,10 @@ void SDL_PrivateJoystickAdded(SDL_JoystickID instance_id)
|
||||
SDL_joystick_being_added = SDL_TRUE;
|
||||
|
||||
if (SDL_GetDriverAndJoystickIndex(instance_id, &driver, &device_index)) {
|
||||
player_index = driver->GetDevicePlayerIndex(device_index);
|
||||
player_index = driver->GetDeviceSteamVirtualGamepadSlot(device_index);
|
||||
if (player_index < 0) {
|
||||
player_index = driver->GetDevicePlayerIndex(device_index);
|
||||
}
|
||||
}
|
||||
if (player_index < 0 && SDL_IsGamepad(instance_id)) {
|
||||
player_index = SDL_FindFreePlayerIndex();
|
||||
@@ -2200,6 +2237,43 @@ int SDL_SendJoystickButton(Uint64 timestamp, SDL_Joystick *joystick, Uint8 butto
|
||||
return posted;
|
||||
}
|
||||
|
||||
static void SendSteamHandleUpdateEvents(void)
|
||||
{
|
||||
SDL_Joystick *joystick;
|
||||
const SDL_SteamVirtualGamepadInfo *info;
|
||||
|
||||
/* Check to see if any Steam handles changed */
|
||||
for (joystick = SDL_joysticks; joystick; joystick = joystick->next) {
|
||||
SDL_bool changed = SDL_FALSE;
|
||||
|
||||
if (!joystick->is_gamepad) {
|
||||
continue;
|
||||
}
|
||||
|
||||
info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id);
|
||||
if (info) {
|
||||
if (joystick->steam_handle != info->handle) {
|
||||
joystick->steam_handle = info->handle;
|
||||
changed = SDL_TRUE;
|
||||
}
|
||||
} else {
|
||||
if (joystick->steam_handle != 0) {
|
||||
joystick->steam_handle = 0;
|
||||
changed = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
SDL_Event event;
|
||||
|
||||
SDL_zero(event);
|
||||
event.type = SDL_EVENT_GAMEPAD_STEAM_HANDLE_UPDATED;
|
||||
event.common.timestamp = 0;
|
||||
event.gdevice.which = joystick->instance_id;
|
||||
SDL_PushEvent(&event);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SDL_UpdateJoysticks(void)
|
||||
{
|
||||
int i;
|
||||
@@ -2212,6 +2286,10 @@ void SDL_UpdateJoysticks(void)
|
||||
|
||||
SDL_LockJoysticks();
|
||||
|
||||
if (SDL_UpdateSteamVirtualGamepadInfo()) {
|
||||
SendSteamHandleUpdateEvents();
|
||||
}
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
/* Special function for HIDAPI devices, as a single device can provide multiple SDL_Joysticks */
|
||||
HIDAPI_UpdateDevices();
|
||||
@@ -3083,18 +3161,38 @@ SDL_JoystickGUID SDL_GetJoystickInstanceGUID(SDL_JoystickID instance_id)
|
||||
Uint16 SDL_GetJoystickInstanceVendor(SDL_JoystickID instance_id)
|
||||
{
|
||||
Uint16 vendor;
|
||||
SDL_JoystickGUID guid = SDL_GetJoystickInstanceGUID(instance_id);
|
||||
const SDL_SteamVirtualGamepadInfo *info;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
info = SDL_GetJoystickInstanceVirtualGamepadInfo(instance_id);
|
||||
if (info) {
|
||||
vendor = info->vendor_id;
|
||||
} else {
|
||||
SDL_JoystickGUID guid = SDL_GetJoystickInstanceGUID(instance_id);
|
||||
|
||||
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL);
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL);
|
||||
return vendor;
|
||||
}
|
||||
|
||||
Uint16 SDL_GetJoystickInstanceProduct(SDL_JoystickID instance_id)
|
||||
{
|
||||
Uint16 product;
|
||||
SDL_JoystickGUID guid = SDL_GetJoystickInstanceGUID(instance_id);
|
||||
const SDL_SteamVirtualGamepadInfo *info;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
info = SDL_GetJoystickInstanceVirtualGamepadInfo(instance_id);
|
||||
if (info) {
|
||||
product = info->product_id;
|
||||
} else {
|
||||
SDL_JoystickGUID guid = SDL_GetJoystickInstanceGUID(instance_id);
|
||||
|
||||
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL);
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL);
|
||||
return product;
|
||||
}
|
||||
|
||||
@@ -3141,18 +3239,38 @@ SDL_JoystickGUID SDL_GetJoystickGUID(SDL_Joystick *joystick)
|
||||
Uint16 SDL_GetJoystickVendor(SDL_Joystick *joystick)
|
||||
{
|
||||
Uint16 vendor;
|
||||
SDL_JoystickGUID guid = SDL_GetJoystickGUID(joystick);
|
||||
const SDL_SteamVirtualGamepadInfo *info;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id);
|
||||
if (info) {
|
||||
vendor = info->vendor_id;
|
||||
} else {
|
||||
SDL_JoystickGUID guid = SDL_GetJoystickGUID(joystick);
|
||||
|
||||
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL);
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
SDL_GetJoystickGUIDInfo(guid, &vendor, NULL, NULL, NULL);
|
||||
return vendor;
|
||||
}
|
||||
|
||||
Uint16 SDL_GetJoystickProduct(SDL_Joystick *joystick)
|
||||
{
|
||||
Uint16 product;
|
||||
SDL_JoystickGUID guid = SDL_GetJoystickGUID(joystick);
|
||||
const SDL_SteamVirtualGamepadInfo *info;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
info = SDL_GetJoystickInstanceVirtualGamepadInfo(joystick->instance_id);
|
||||
if (info) {
|
||||
product = info->product_id;
|
||||
} else {
|
||||
SDL_JoystickGUID guid = SDL_GetJoystickGUID(joystick);
|
||||
|
||||
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL);
|
||||
}
|
||||
SDL_UnlockJoysticks();
|
||||
|
||||
SDL_GetJoystickGUIDInfo(guid, NULL, &product, NULL, NULL);
|
||||
return product;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user