mirror of
https://github.com/libsdl-org/SDL.git
synced 2024-11-23 02:43:30 +08:00
Added support for pairing controllers to the Steam Controller dongle
This commit is contained in:
parent
e4778d53d3
commit
b71151a697
@ -22,11 +22,14 @@
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI
|
||||
|
||||
#include "../../SDL_hints_c.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "SDL_hidapijoystick_c.h"
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_STEAM
|
||||
|
||||
#define SDL_HINT_JOYSTICK_HIDAPI_STEAM_PAIRING_ENABLED "SDL_JOYSTICK_HIDAPI_STEAM_PAIRING_ENABLED"
|
||||
|
||||
#if defined(SDL_PLATFORM_ANDROID) || defined(SDL_PLATFORM_IOS) || defined(SDL_PLATFORM_TVOS)
|
||||
// This requires prompting for Bluetooth permissions, so make sure the application really wants it
|
||||
#define SDL_HINT_JOYSTICK_HIDAPI_STEAM_DEFAULT false
|
||||
@ -620,6 +623,31 @@ static int ReadSteamController(SDL_hid_device *dev, uint8_t *pData, int nDataSiz
|
||||
return SDL_hid_read(dev, pData, nDataSize);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Set Steam Controller pairing state
|
||||
//---------------------------------------------------------------------------
|
||||
static void SetPairingState(SDL_HIDAPI_Device *dev, bool bEnablePairing)
|
||||
{
|
||||
unsigned char buf[65];
|
||||
SDL_memset(buf, 0, 65);
|
||||
buf[1] = ID_ENABLE_PAIRING;
|
||||
buf[2] = 2; // 2 payload bytes: bool + timeout
|
||||
buf[3] = bEnablePairing ? 1 : 0;
|
||||
buf[4] = bEnablePairing ? 60 : 0;
|
||||
SetFeatureReport(dev, buf, 5);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Commit Steam Controller pairing
|
||||
//---------------------------------------------------------------------------
|
||||
static void CommitPairing(SDL_HIDAPI_Device *dev)
|
||||
{
|
||||
unsigned char buf[65];
|
||||
SDL_memset(buf, 0, 65);
|
||||
buf[1] = ID_DONGLE_COMMIT_DEVICE;
|
||||
SetFeatureReport(dev, buf, 2);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Close a Steam Controller
|
||||
//---------------------------------------------------------------------------
|
||||
@ -967,6 +995,7 @@ static bool UpdateSteamControllerState(const uint8_t *pData, int nDataSize, Stea
|
||||
|
||||
typedef struct
|
||||
{
|
||||
SDL_HIDAPI_Device *device;
|
||||
bool connected;
|
||||
bool report_sensors;
|
||||
uint32_t update_rate_in_us;
|
||||
@ -977,6 +1006,11 @@ typedef struct
|
||||
SteamControllerStateInternal_t m_last_state;
|
||||
} SDL_DriverSteam_Context;
|
||||
|
||||
static bool IsDongle(Uint16 product_id)
|
||||
{
|
||||
return (product_id == USB_PRODUCT_VALVE_STEAM_CONTROLLER_DONGLE);
|
||||
}
|
||||
|
||||
static void HIDAPI_DriverSteam_RegisterHints(SDL_HintCallback callback, void *userdata)
|
||||
{
|
||||
SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM, callback, userdata);
|
||||
@ -997,6 +1031,45 @@ static bool HIDAPI_DriverSteam_IsSupportedDevice(SDL_HIDAPI_Device *device, cons
|
||||
return SDL_IsJoystickSteamController(vendor_id, product_id);
|
||||
}
|
||||
|
||||
static void HIDAPI_DriverSteam_SetPairingState(SDL_DriverSteam_Context *ctx, bool enabled)
|
||||
{
|
||||
// Only have one dongle in pairing mode at a time
|
||||
static SDL_DriverSteam_Context *s_PairingContext = NULL;
|
||||
|
||||
if (enabled && s_PairingContext != NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!enabled && s_PairingContext != ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->connected) {
|
||||
return;
|
||||
}
|
||||
|
||||
SetPairingState(ctx->device, enabled);
|
||||
|
||||
if (enabled) {
|
||||
s_PairingContext = ctx;
|
||||
} else {
|
||||
s_PairingContext = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void HIDAPI_DriverSteam_CommitPairing(SDL_DriverSteam_Context *ctx)
|
||||
{
|
||||
CommitPairing(ctx->device);
|
||||
}
|
||||
|
||||
static void SDLCALL SDL_PairingEnabledHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
|
||||
{
|
||||
SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)userdata;
|
||||
bool enabled = SDL_GetStringBoolean(hint, false);
|
||||
|
||||
HIDAPI_DriverSteam_SetPairingState(ctx, enabled);
|
||||
}
|
||||
|
||||
static bool HIDAPI_DriverSteam_InitDevice(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
SDL_DriverSteam_Context *ctx;
|
||||
@ -1005,6 +1078,7 @@ static bool HIDAPI_DriverSteam_InitDevice(SDL_HIDAPI_Device *device)
|
||||
if (!ctx) {
|
||||
return false;
|
||||
}
|
||||
ctx->device = device;
|
||||
device->context = ctx;
|
||||
|
||||
#ifdef SDL_PLATFORM_WIN32
|
||||
@ -1018,7 +1092,7 @@ static bool HIDAPI_DriverSteam_InitDevice(SDL_HIDAPI_Device *device)
|
||||
HIDAPI_SetDeviceName(device, "Steam Controller");
|
||||
|
||||
// If this is a wireless dongle, request a wireless state update
|
||||
if (device->product_id == USB_PRODUCT_VALVE_STEAM_CONTROLLER_DONGLE) {
|
||||
if (IsDongle(device->product_id)) {
|
||||
unsigned char buf[65];
|
||||
int res;
|
||||
|
||||
@ -1029,6 +1103,9 @@ static bool HIDAPI_DriverSteam_InitDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_SetError("Failed to send ID_DONGLE_GET_WIRELESS_STATE request");
|
||||
}
|
||||
|
||||
SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM_PAIRING_ENABLED,
|
||||
SDL_PairingEnabledHintChanged, ctx);
|
||||
|
||||
// We will enumerate any attached controllers in UpdateDevice()
|
||||
return true;
|
||||
} else {
|
||||
@ -1255,6 +1332,9 @@ static bool HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return false;
|
||||
}
|
||||
|
||||
// We'll automatically accept this controller if we're in pairing mode
|
||||
HIDAPI_DriverSteam_CommitPairing(ctx);
|
||||
|
||||
joystick = SDL_GetJoystickFromID(device->joysticks[0]);
|
||||
ctx->connected = true;
|
||||
}
|
||||
@ -1277,6 +1357,14 @@ static void HIDAPI_DriverSteam_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joys
|
||||
|
||||
static void HIDAPI_DriverSteam_FreeDevice(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context;
|
||||
|
||||
if (IsDongle(device->product_id)) {
|
||||
SDL_RemoveHintCallback(SDL_HINT_JOYSTICK_HIDAPI_STEAM_PAIRING_ENABLED,
|
||||
SDL_PairingEnabledHintChanged, ctx);
|
||||
|
||||
HIDAPI_DriverSteam_SetPairingState(ctx, false);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam = {
|
||||
|
Loading…
Reference in New Issue
Block a user