early-access version 2281
This commit is contained in:
@@ -32,7 +32,7 @@
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "SDL_hidapijoystick_c.h"
|
||||
#include "SDL_hidapi_rumble.h"
|
||||
#include "../../hidapi/SDL_hidapi.h"
|
||||
#include "../../hidapi/SDL_hidapi_c.h"
|
||||
|
||||
|
||||
#ifdef SDL_JOYSTICK_HIDAPI_GAMECUBE
|
||||
@@ -129,7 +129,7 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -154,7 +154,7 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
|
||||
}
|
||||
} else {
|
||||
/* This is all that's needed to initialize the device. Really! */
|
||||
if (hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) {
|
||||
if (SDL_hid_write(device->dev, &initMagic, sizeof(initMagic)) != sizeof(initMagic)) {
|
||||
SDL_SetError("Couldn't initialize WUP-028");
|
||||
goto error;
|
||||
}
|
||||
@@ -163,7 +163,7 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
|
||||
SDL_Delay(10);
|
||||
|
||||
/* Add all the applicable joysticks */
|
||||
while ((size = hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
|
||||
#ifdef DEBUG_GAMECUBE_PROTOCOL
|
||||
HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size);
|
||||
#endif
|
||||
@@ -204,7 +204,7 @@ error:
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
if (device->context) {
|
||||
@@ -389,7 +389,7 @@ HIDAPI_DriverGameCube_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
int size;
|
||||
|
||||
/* Read input packet */
|
||||
while ((size = hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, packet, sizeof(packet), 0)) > 0) {
|
||||
#ifdef DEBUG_GAMECUBE_PROTOCOL
|
||||
//HIDAPI_DumpPacket("Nintendo GameCube packet: size = %d", packet, size);
|
||||
#endif
|
||||
@@ -464,10 +464,26 @@ HIDAPI_DriverGameCube_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joys
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverGameCube_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverGameCube_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (!ctx->pc_mode) {
|
||||
Uint8 i;
|
||||
|
||||
for (i = 0; i < MAX_CONTROLLERS; i += 1) {
|
||||
if (joystick->instance_id == ctx->joysticks[i]) {
|
||||
if (!ctx->wireless[i] && ctx->rumbleAllowed[i]) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -510,7 +526,7 @@ HIDAPI_DriverGameCube_FreeDevice(SDL_HIDAPI_Device *device)
|
||||
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -523,6 +539,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_GAMECUBE,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverGameCube_IsSupportedDevice,
|
||||
HIDAPI_DriverGameCube_GetDeviceName,
|
||||
HIDAPI_DriverGameCube_InitDevice,
|
||||
@@ -532,7 +549,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
|
||||
HIDAPI_DriverGameCube_OpenJoystick,
|
||||
HIDAPI_DriverGameCube_RumbleJoystick,
|
||||
HIDAPI_DriverGameCube_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverGameCube_HasJoystickLED,
|
||||
HIDAPI_DriverGameCube_GetJoystickCapabilities,
|
||||
HIDAPI_DriverGameCube_SetJoystickLED,
|
||||
HIDAPI_DriverGameCube_SendJoystickEffect,
|
||||
HIDAPI_DriverGameCube_SetJoystickSensorsEnabled,
|
||||
|
@@ -87,7 +87,7 @@ HIDAPI_DriverLuna_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
SDL_free(ctx);
|
||||
@@ -132,10 +132,16 @@ HIDAPI_DriverLuna_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverLuna_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverLuna_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (device->product_id == BLUETOOTH_PRODUCT_LUNA_CONTROLLER) {
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -386,7 +392,7 @@ HIDAPI_DriverLuna_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_LUNA_PROTOCOL
|
||||
HIDAPI_DumpPacket("Amazon Luna packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -413,7 +419,7 @@ HIDAPI_DriverLuna_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
|
||||
@@ -432,6 +438,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_LUNA,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverLuna_IsSupportedDevice,
|
||||
HIDAPI_DriverLuna_GetDeviceName,
|
||||
HIDAPI_DriverLuna_InitDevice,
|
||||
@@ -441,7 +448,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverLuna =
|
||||
HIDAPI_DriverLuna_OpenJoystick,
|
||||
HIDAPI_DriverLuna_RumbleJoystick,
|
||||
HIDAPI_DriverLuna_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverLuna_HasJoystickLED,
|
||||
HIDAPI_DriverLuna_GetJoystickCapabilities,
|
||||
HIDAPI_DriverLuna_SetJoystickLED,
|
||||
HIDAPI_DriverLuna_SendJoystickEffect,
|
||||
HIDAPI_DriverLuna_SetJoystickSensorsEnabled,
|
||||
|
@@ -163,11 +163,11 @@ HIDAPI_DriverPS4_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
{
|
||||
SDL_memset(report, 0, length);
|
||||
report[0] = report_id;
|
||||
return hid_get_feature_report(dev, report, length);
|
||||
return SDL_hid_get_feature_report(dev, report, length);
|
||||
}
|
||||
|
||||
static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id)
|
||||
@@ -415,7 +415,7 @@ HIDAPI_DriverPS4_TickleBluetooth(SDL_HIDAPI_Device *device)
|
||||
/* This is just a dummy packet that should have no effect, since we don't set the CRC */
|
||||
Uint8 data[78];
|
||||
|
||||
SDL_zero(data);
|
||||
SDL_zeroa(data);
|
||||
|
||||
data[0] = k_EPS4ReportIdBluetoothEffects;
|
||||
data[1] = 0xC0; /* Magic value HID + CRC */
|
||||
@@ -479,7 +479,7 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
ctx->joystick = joystick;
|
||||
ctx->last_packet = SDL_GetTicks();
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -511,7 +511,7 @@ HIDAPI_DriverPS4_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
ctx->is_bluetooth = SDL_TRUE;
|
||||
|
||||
/* Read a report to see if we're in enhanced mode */
|
||||
size = hid_read_timeout(device->dev, data, sizeof(data), 16);
|
||||
size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16);
|
||||
#ifdef DEBUG_PS4_PROTOCOL
|
||||
if (size > 0) {
|
||||
HIDAPI_DumpPacket("PS4 first packet: size = %d", data, size);
|
||||
@@ -598,10 +598,17 @@ HIDAPI_DriverPS4_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverPS4_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverPS4_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_TRUE;
|
||||
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (ctx->enhanced_mode && ctx->effects_supported) {
|
||||
result |= SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -632,7 +639,7 @@ HIDAPI_DriverPS4_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||
HIDAPI_DriverPS4_SetEnhancedMode(device, joystick);
|
||||
}
|
||||
|
||||
SDL_zero(data);
|
||||
SDL_zeroa(data);
|
||||
|
||||
if (ctx->is_bluetooth) {
|
||||
data[0] = k_EPS4ReportIdBluetoothEffects;
|
||||
@@ -684,7 +691,7 @@ HIDAPI_DriverPS4_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joysti
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet)
|
||||
HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS4_Context *ctx, PS4StatePacket_t *packet)
|
||||
{
|
||||
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
|
||||
static const float TOUCHPAD_SCALEY = 1.0f / 920; /* This is noted as being 944 resolution, but 920 feels better */
|
||||
@@ -846,7 +853,7 @@ HIDAPI_DriverPS4_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_PS4_PROTOCOL
|
||||
HIDAPI_DumpPacket("PS4 packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -908,7 +915,7 @@ HIDAPI_DriverPS4_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick
|
||||
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -926,6 +933,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_PS4,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverPS4_IsSupportedDevice,
|
||||
HIDAPI_DriverPS4_GetDeviceName,
|
||||
HIDAPI_DriverPS4_InitDevice,
|
||||
@@ -935,7 +943,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
|
||||
HIDAPI_DriverPS4_OpenJoystick,
|
||||
HIDAPI_DriverPS4_RumbleJoystick,
|
||||
HIDAPI_DriverPS4_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverPS4_HasJoystickLED,
|
||||
HIDAPI_DriverPS4_GetJoystickCapabilities,
|
||||
HIDAPI_DriverPS4_SetJoystickLED,
|
||||
HIDAPI_DriverPS4_SendJoystickEffect,
|
||||
HIDAPI_DriverPS4_SetJoystickSensorsEnabled,
|
||||
|
@@ -192,11 +192,11 @@ HIDAPI_DriverPS5_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ReadFeatureReport(hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
static int ReadFeatureReport(SDL_hid_device *dev, Uint8 report_id, Uint8 *report, size_t length)
|
||||
{
|
||||
SDL_memset(report, 0, length);
|
||||
report[0] = report_id;
|
||||
return hid_get_feature_report(dev, report, length);
|
||||
return SDL_hid_get_feature_report(dev, report, length);
|
||||
}
|
||||
|
||||
static void
|
||||
@@ -471,7 +471,7 @@ HIDAPI_DriverPS5_TickleBluetooth(SDL_HIDAPI_Device *device)
|
||||
/* This is just a dummy packet that should have no effect, since we don't set the CRC */
|
||||
Uint8 data[78];
|
||||
|
||||
SDL_zero(data);
|
||||
SDL_zeroa(data);
|
||||
|
||||
data[0] = k_EPS5ReportIdBluetoothEffects;
|
||||
data[1] = 0x02; /* Magic value */
|
||||
@@ -553,7 +553,7 @@ HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
ctx->joystick = joystick;
|
||||
ctx->last_packet = SDL_GetTicks();
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -562,7 +562,7 @@ HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
device->context = ctx;
|
||||
|
||||
/* Read a report to see what mode we're in */
|
||||
size = hid_read_timeout(device->dev, data, sizeof(data), 16);
|
||||
size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 16);
|
||||
#ifdef DEBUG_PS5_PROTOCOL
|
||||
if (size > 0) {
|
||||
HIDAPI_DumpPacket("PS5 first packet: size = %d", data, size);
|
||||
@@ -663,10 +663,17 @@ HIDAPI_DriverPS5_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverPS5_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverPS5_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_TRUE;
|
||||
SDL_DriverPS5_Context *ctx = (SDL_DriverPS5_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (ctx->enhanced_mode) {
|
||||
result |= SDL_JOYCAP_LED | SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -696,7 +703,7 @@ HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||
HIDAPI_DriverPS5_SetEnhancedMode(device, joystick);
|
||||
}
|
||||
|
||||
SDL_zero(data);
|
||||
SDL_zeroa(data);
|
||||
|
||||
if (ctx->is_bluetooth) {
|
||||
data[0] = k_EPS5ReportIdBluetoothEffects;
|
||||
@@ -761,7 +768,7 @@ HIDAPI_DriverPS5_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joysti
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS5_Context *ctx, PS5SimpleStatePacket_t *packet)
|
||||
HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5SimpleStatePacket_t *packet)
|
||||
{
|
||||
Sint16 axis;
|
||||
|
||||
@@ -855,7 +862,7 @@ HIDAPI_DriverPS5_HandleSimpleStatePacket(SDL_Joystick *joystick, hid_device *dev
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet)
|
||||
HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverPS5_Context *ctx, PS5StatePacket_t *packet)
|
||||
{
|
||||
static const float TOUCHPAD_SCALEX = 1.0f / 1920;
|
||||
static const float TOUCHPAD_SCALEY = 1.0f / 1070;
|
||||
@@ -1010,7 +1017,7 @@ HIDAPI_DriverPS5_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_PS5_PROTOCOL
|
||||
HIDAPI_DumpPacket("PS5 packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -1071,7 +1078,7 @@ HIDAPI_DriverPS5_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick
|
||||
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -1089,6 +1096,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_PS5,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverPS5_IsSupportedDevice,
|
||||
HIDAPI_DriverPS5_GetDeviceName,
|
||||
HIDAPI_DriverPS5_InitDevice,
|
||||
@@ -1098,7 +1106,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS5 =
|
||||
HIDAPI_DriverPS5_OpenJoystick,
|
||||
HIDAPI_DriverPS5_RumbleJoystick,
|
||||
HIDAPI_DriverPS5_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverPS5_HasJoystickLED,
|
||||
HIDAPI_DriverPS5_GetJoystickCapabilities,
|
||||
HIDAPI_DriverPS5_SetJoystickLED,
|
||||
HIDAPI_DriverPS5_SendJoystickEffect,
|
||||
HIDAPI_DriverPS5_SetJoystickSensorsEnabled,
|
||||
|
@@ -80,7 +80,7 @@ static int SDL_HIDAPI_RumbleThread(void *data)
|
||||
#ifdef DEBUG_RUMBLE
|
||||
HIDAPI_DumpPacket("Rumble packet: size = %d", request->data, request->size);
|
||||
#endif
|
||||
hid_write(request->device->dev, request->data, request->size);
|
||||
SDL_hid_write(request->device->dev, request->data, request->size);
|
||||
}
|
||||
SDL_UnlockMutex(request->device->dev_lock);
|
||||
(void)SDL_AtomicDecRef(&request->device->rumble_pending);
|
||||
|
@@ -88,7 +88,7 @@ HIDAPI_DriverStadia_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
SDL_free(ctx);
|
||||
@@ -126,10 +126,10 @@ HIDAPI_DriverStadia_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joysti
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverStadia_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverStadia_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
return SDL_FALSE;
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -267,7 +267,7 @@ HIDAPI_DriverStadia_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_STADIA_PROTOCOL
|
||||
HIDAPI_DumpPacket("Google Stadia packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -287,7 +287,7 @@ HIDAPI_DriverStadia_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
|
||||
@@ -306,6 +306,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_STADIA,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverStadia_IsSupportedDevice,
|
||||
HIDAPI_DriverStadia_GetDeviceName,
|
||||
HIDAPI_DriverStadia_InitDevice,
|
||||
@@ -315,7 +316,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverStadia =
|
||||
HIDAPI_DriverStadia_OpenJoystick,
|
||||
HIDAPI_DriverStadia_RumbleJoystick,
|
||||
HIDAPI_DriverStadia_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverStadia_HasJoystickLED,
|
||||
HIDAPI_DriverStadia_GetJoystickCapabilities,
|
||||
HIDAPI_DriverStadia_SetJoystickLED,
|
||||
HIDAPI_DriverStadia_SendJoystickEffect,
|
||||
HIDAPI_DriverStadia_SetJoystickSensorsEnabled,
|
||||
|
219
externals/SDL/src/joystick/hidapi/SDL_hidapi_steam.c
vendored
219
externals/SDL/src/joystick/hidapi/SDL_hidapi_steam.c
vendored
@@ -190,7 +190,7 @@ typedef struct
|
||||
|
||||
|
||||
// Wireless firmware quirk: the firmware intentionally signals "failure" when performing
|
||||
// SET_FEATURE / GET_FEATURE when it actually means "pending radio round-trip". The only
|
||||
// SET_FEATURE / GET_FEATURE when it actually means "pending radio roundtrip". The only
|
||||
// way to make SET_FEATURE / GET_FEATURE work is to loop several times with a sleep. If
|
||||
// it takes more than 50ms to get the response for SET_FEATURE / GET_FEATURE, we assume
|
||||
// that the controller has failed.
|
||||
@@ -220,7 +220,7 @@ static void hexdump( const uint8_t *ptr, int len )
|
||||
|
||||
static void ResetSteamControllerPacketAssembler( SteamControllerPacketAssembler *pAssembler )
|
||||
{
|
||||
memset( pAssembler->uBuffer, 0, sizeof( pAssembler->uBuffer ) );
|
||||
SDL_memset( pAssembler->uBuffer, 0, sizeof( pAssembler->uBuffer ) );
|
||||
pAssembler->nExpectedSegmentNumber = 0;
|
||||
}
|
||||
|
||||
@@ -239,6 +239,9 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
{
|
||||
if ( pAssembler->bIsBle )
|
||||
{
|
||||
uint8_t uSegmentHeader = pSegment[ 1 ];
|
||||
int nSegmentNumber = uSegmentHeader & 0x07;
|
||||
|
||||
HEXDUMP( pSegment, nSegmentLength );
|
||||
|
||||
if ( pSegment[ 0 ] != BLE_REPORT_NUMBER )
|
||||
@@ -255,7 +258,6 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t uSegmentHeader = pSegment[ 1 ];
|
||||
DPRINTF("GOT PACKET HEADER = 0x%x\n", uSegmentHeader);
|
||||
|
||||
if ( ( uSegmentHeader & REPORT_SEGMENT_DATA_FLAG ) == 0 )
|
||||
@@ -264,7 +266,6 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
return 0;
|
||||
}
|
||||
|
||||
int nSegmentNumber = uSegmentHeader & 0x07;
|
||||
if ( nSegmentNumber != pAssembler->nExpectedSegmentNumber )
|
||||
{
|
||||
ResetSteamControllerPacketAssembler( pAssembler );
|
||||
@@ -278,7 +279,7 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
}
|
||||
}
|
||||
|
||||
memcpy( pAssembler->uBuffer + nSegmentNumber * MAX_REPORT_SEGMENT_PAYLOAD_SIZE,
|
||||
SDL_memcpy( pAssembler->uBuffer + nSegmentNumber * MAX_REPORT_SEGMENT_PAYLOAD_SIZE,
|
||||
pSegment + 2, // ignore header and report number
|
||||
MAX_REPORT_SEGMENT_PAYLOAD_SIZE );
|
||||
|
||||
@@ -293,7 +294,7 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
else
|
||||
{
|
||||
// Just pass through
|
||||
memcpy( pAssembler->uBuffer,
|
||||
SDL_memcpy( pAssembler->uBuffer,
|
||||
pSegment,
|
||||
nSegmentLength );
|
||||
return nSegmentLength;
|
||||
@@ -304,22 +305,23 @@ static int WriteSegmentToSteamControllerPacketAssembler( SteamControllerPacketAs
|
||||
|
||||
#define BLE_MAX_READ_RETRIES 8
|
||||
|
||||
static int SetFeatureReport( hid_device *dev, unsigned char uBuffer[65], int nActualDataLen )
|
||||
static int SetFeatureReport( SDL_hid_device *dev, unsigned char uBuffer[65], int nActualDataLen )
|
||||
{
|
||||
DPRINTF("SetFeatureReport %p %p %d\n", dev, uBuffer, nActualDataLen);
|
||||
int nRet = -1;
|
||||
bool bBle = true; // only wireless/BLE for now, though macOS could do wired in the future
|
||||
|
||||
DPRINTF("SetFeatureReport %p %p %d\n", dev, uBuffer, nActualDataLen);
|
||||
|
||||
if ( bBle )
|
||||
{
|
||||
int nSegmentNumber = 0;
|
||||
uint8_t uPacketBuffer[ MAX_REPORT_SEGMENT_SIZE ];
|
||||
unsigned char *pBufferPtr = uBuffer + 1;
|
||||
|
||||
if ( nActualDataLen < 1 )
|
||||
return -1;
|
||||
|
||||
int nSegmentNumber = 0;
|
||||
uint8_t uPacketBuffer[ MAX_REPORT_SEGMENT_SIZE ];
|
||||
|
||||
// Skip report number in data
|
||||
unsigned char *pBufferPtr = uBuffer + 1;
|
||||
nActualDataLen--;
|
||||
|
||||
while ( nActualDataLen > 0 )
|
||||
@@ -329,15 +331,15 @@ static int SetFeatureReport( hid_device *dev, unsigned char uBuffer[65], int nAc
|
||||
nActualDataLen -= nBytesInPacket;
|
||||
|
||||
// Construct packet
|
||||
memset( uPacketBuffer, 0, sizeof( uPacketBuffer ) );
|
||||
SDL_memset( uPacketBuffer, 0, sizeof( uPacketBuffer ) );
|
||||
uPacketBuffer[ 0 ] = BLE_REPORT_NUMBER;
|
||||
uPacketBuffer[ 1 ] = GetSegmentHeader( nSegmentNumber, nActualDataLen == 0 );
|
||||
memcpy( &uPacketBuffer[ 2 ], pBufferPtr, nBytesInPacket );
|
||||
SDL_memcpy( &uPacketBuffer[ 2 ], pBufferPtr, nBytesInPacket );
|
||||
|
||||
pBufferPtr += nBytesInPacket;
|
||||
nSegmentNumber++;
|
||||
|
||||
nRet = hid_send_feature_report( dev, uPacketBuffer, sizeof( uPacketBuffer ) );
|
||||
nRet = SDL_hid_send_feature_report( dev, uPacketBuffer, sizeof( uPacketBuffer ) );
|
||||
DPRINTF("SetFeatureReport() ret = %d\n", nRet);
|
||||
}
|
||||
}
|
||||
@@ -345,24 +347,26 @@ static int SetFeatureReport( hid_device *dev, unsigned char uBuffer[65], int nAc
|
||||
return nRet;
|
||||
}
|
||||
|
||||
static int GetFeatureReport( hid_device *dev, unsigned char uBuffer[65] )
|
||||
static int GetFeatureReport( SDL_hid_device *dev, unsigned char uBuffer[65] )
|
||||
{
|
||||
DPRINTF("GetFeatureReport( %p %p )\n", dev, uBuffer );
|
||||
int nRet = -1;
|
||||
bool bBle = true;
|
||||
|
||||
DPRINTF("GetFeatureReport( %p %p )\n", dev, uBuffer );
|
||||
|
||||
if ( bBle )
|
||||
{
|
||||
int nRetries = 0;
|
||||
uint8_t uSegmentBuffer[ MAX_REPORT_SEGMENT_SIZE ];
|
||||
|
||||
SteamControllerPacketAssembler assembler;
|
||||
InitializeSteamControllerPacketAssembler( &assembler );
|
||||
|
||||
int nRetries = 0;
|
||||
uint8_t uSegmentBuffer[ MAX_REPORT_SEGMENT_SIZE ];
|
||||
while( nRetries < BLE_MAX_READ_RETRIES )
|
||||
{
|
||||
memset( uSegmentBuffer, 0, sizeof( uSegmentBuffer ) );
|
||||
SDL_memset( uSegmentBuffer, 0, sizeof( uSegmentBuffer ) );
|
||||
uSegmentBuffer[ 0 ] = BLE_REPORT_NUMBER;
|
||||
nRet = hid_get_feature_report( dev, uSegmentBuffer, sizeof( uSegmentBuffer ) );
|
||||
nRet = SDL_hid_get_feature_report( dev, uSegmentBuffer, sizeof( uSegmentBuffer ) );
|
||||
DPRINTF( "GetFeatureReport ble ret=%d\n", nRet );
|
||||
HEXDUMP( uSegmentBuffer, nRet );
|
||||
|
||||
@@ -382,7 +386,7 @@ static int GetFeatureReport( hid_device *dev, unsigned char uBuffer[65] )
|
||||
{
|
||||
// Leave space for "report number"
|
||||
uBuffer[ 0 ] = 0;
|
||||
memcpy( uBuffer + 1, assembler.uBuffer, nPacketLength );
|
||||
SDL_memcpy( uBuffer + 1, assembler.uBuffer, nPacketLength );
|
||||
return nPacketLength;
|
||||
}
|
||||
}
|
||||
@@ -396,11 +400,12 @@ static int GetFeatureReport( hid_device *dev, unsigned char uBuffer[65] )
|
||||
return nRet;
|
||||
}
|
||||
|
||||
static int ReadResponse( hid_device *dev, uint8_t uBuffer[65], int nExpectedResponse )
|
||||
static int ReadResponse( SDL_hid_device *dev, uint8_t uBuffer[65], int nExpectedResponse )
|
||||
{
|
||||
DPRINTF("ReadResponse( %p %p %d )\n", dev, uBuffer, nExpectedResponse );
|
||||
int nRet = GetFeatureReport( dev, uBuffer );
|
||||
|
||||
DPRINTF("ReadResponse( %p %p %d )\n", dev, uBuffer, nExpectedResponse );
|
||||
|
||||
if ( nRet < 0 )
|
||||
return nRet;
|
||||
|
||||
@@ -416,13 +421,18 @@ static int ReadResponse( hid_device *dev, uint8_t uBuffer[65], int nExpectedResp
|
||||
//---------------------------------------------------------------------------
|
||||
// Reset steam controller (unmap buttons and pads) and re-fetch capability bits
|
||||
//---------------------------------------------------------------------------
|
||||
static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
|
||||
static bool ResetSteamController( SDL_hid_device *dev, bool bSuppressErrorSpew, uint32_t *punUpdateRateUS )
|
||||
{
|
||||
DPRINTF( "ResetSteamController hid=%p\n", dev );
|
||||
// Firmware quirk: Set Feature and Get Feature requests always require a 65-byte buffer.
|
||||
unsigned char buf[65];
|
||||
int res = -1;
|
||||
int res = -1, i;
|
||||
int nSettings = 0;
|
||||
int nAttributesLength;
|
||||
FeatureReportMsg *msg;
|
||||
uint32_t unUpdateRateUS = 9000; // Good default rate
|
||||
|
||||
DPRINTF( "ResetSteamController hid=%p\n", dev );
|
||||
|
||||
buf[0] = 0;
|
||||
buf[1] = ID_GET_ATTRIBUTES_VALUES;
|
||||
res = SetFeatureReport( dev, buf, 2 );
|
||||
@@ -444,14 +454,40 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
|
||||
return false;
|
||||
}
|
||||
|
||||
int nAttributesLength = buf[ 2 ];
|
||||
nAttributesLength = buf[ 2 ];
|
||||
if ( nAttributesLength > res )
|
||||
{
|
||||
if ( !bSuppressErrorSpew )
|
||||
printf( "Bad GET_ATTRIBUTES_VALUES response for controller %p\n", dev );
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
msg = (FeatureReportMsg *)&buf[1];
|
||||
for ( i = 0; i < (int)msg->header.length / sizeof( ControllerAttribute ); ++i )
|
||||
{
|
||||
uint8_t unAttribute = msg->payload.getAttributes.attributes[i].attributeTag;
|
||||
uint32_t unValue = msg->payload.getAttributes.attributes[i].attributeValue;
|
||||
|
||||
switch ( unAttribute )
|
||||
{
|
||||
case ATTRIB_UNIQUE_ID:
|
||||
break;
|
||||
case ATTRIB_PRODUCT_ID:
|
||||
break;
|
||||
case ATTRIB_CAPABILITIES:
|
||||
break;
|
||||
case ATTRIB_CONNECTION_INTERVAL_IN_US:
|
||||
unUpdateRateUS = unValue;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ( punUpdateRateUS )
|
||||
{
|
||||
*punUpdateRateUS = unUpdateRateUS;
|
||||
}
|
||||
|
||||
// Clear digital button mappings
|
||||
buf[0] = 0;
|
||||
buf[1] = ID_CLEAR_DIGITAL_MAPPINGS;
|
||||
@@ -464,7 +500,7 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
|
||||
}
|
||||
|
||||
// Reset the default settings
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_LOAD_DEFAULT_SETTINGS;
|
||||
buf[2] = 0;
|
||||
res = SetFeatureReport( dev, buf, 3 );
|
||||
@@ -476,14 +512,13 @@ static bool ResetSteamController( hid_device *dev, bool bSuppressErrorSpew )
|
||||
}
|
||||
|
||||
// Apply custom settings - clear trackpad modes (cancel mouse emulation), etc
|
||||
int nSettings = 0;
|
||||
#define ADD_SETTING(SETTING, VALUE) \
|
||||
buf[3+nSettings*3] = SETTING; \
|
||||
buf[3+nSettings*3+1] = ((uint16_t)VALUE)&0xFF; \
|
||||
buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \
|
||||
++nSettings;
|
||||
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_SETTINGS_VALUES;
|
||||
ADD_SETTING( SETTING_WIRELESS_PACKET_VERSION, 2 );
|
||||
ADD_SETTING( SETTING_LEFT_TRACKPAD_MODE, TRACKPAD_NONE );
|
||||
@@ -512,7 +547,7 @@ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \
|
||||
int iRetry;
|
||||
for ( iRetry = 0; iRetry < 2; ++iRetry )
|
||||
{
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_GET_DIGITAL_MAPPINGS;
|
||||
buf[2] = 1; // one byte - requesting from index 0
|
||||
buf[3] = 0;
|
||||
@@ -545,7 +580,7 @@ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \
|
||||
}
|
||||
|
||||
// Set our new mappings
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_DIGITAL_MAPPINGS;
|
||||
buf[2] = 6; // 2 settings x 3 bytes
|
||||
buf[3] = IO_DIGITAL_BUTTON_RIGHT_TRIGGER;
|
||||
@@ -571,36 +606,36 @@ buf[3+nSettings*3+2] = ((uint16_t)VALUE)>>8; \
|
||||
//---------------------------------------------------------------------------
|
||||
// Read from a Steam Controller
|
||||
//---------------------------------------------------------------------------
|
||||
static int ReadSteamController( hid_device *dev, uint8_t *pData, int nDataSize )
|
||||
static int ReadSteamController( SDL_hid_device *dev, uint8_t *pData, int nDataSize )
|
||||
{
|
||||
memset( pData, 0, nDataSize );
|
||||
SDL_memset( pData, 0, nDataSize );
|
||||
pData[ 0 ] = BLE_REPORT_NUMBER; // hid_read will also overwrite this with the same value, 0x03
|
||||
return hid_read( dev, pData, nDataSize );
|
||||
return SDL_hid_read( dev, pData, nDataSize );
|
||||
}
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Close a Steam Controller
|
||||
//---------------------------------------------------------------------------
|
||||
static void CloseSteamController( hid_device *dev )
|
||||
static void CloseSteamController( SDL_hid_device *dev )
|
||||
{
|
||||
// Switch the Steam Controller back to lizard mode so it works with the OS
|
||||
unsigned char buf[65];
|
||||
int nSettings = 0;
|
||||
|
||||
// Reset digital button mappings
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_DEFAULT_DIGITAL_MAPPINGS;
|
||||
SetFeatureReport( dev, buf, 2 );
|
||||
|
||||
// Reset the default settings
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_LOAD_DEFAULT_SETTINGS;
|
||||
buf[2] = 0;
|
||||
SetFeatureReport( dev, buf, 3 );
|
||||
|
||||
// Reset mouse mode for lizard mode
|
||||
memset( buf, 0, 65 );
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_SETTINGS_VALUES;
|
||||
ADD_SETTING( SETTING_RIGHT_TRACKPAD_MODE, TRACKPAD_ABSOLUTE_MOUSE );
|
||||
buf[2] = nSettings*3;
|
||||
@@ -651,14 +686,23 @@ static void RotatePadShort( short *pX, short *pY, float flAngleInRad )
|
||||
//---------------------------------------------------------------------------
|
||||
static void FormatStatePacketUntilGyro( SteamControllerStateInternal_t *pState, ValveControllerStatePacket_t *pStatePacket )
|
||||
{
|
||||
memset(pState, 0, offsetof(SteamControllerStateInternal_t, sBatteryLevel));
|
||||
int nLeftPadX;
|
||||
int nLeftPadY;
|
||||
int nRightPadX;
|
||||
int nRightPadY;
|
||||
int nPadOffset;
|
||||
|
||||
// 15 degrees in rad
|
||||
const float flRotationAngle = 0.261799f;
|
||||
|
||||
SDL_memset(pState, 0, offsetof(SteamControllerStateInternal_t, sBatteryLevel));
|
||||
|
||||
//pState->eControllerType = m_eControllerType;
|
||||
pState->eControllerType = 2; // k_eControllerType_SteamController;
|
||||
pState->unPacketNum = pStatePacket->unPacketNum;
|
||||
|
||||
// We have a chunk of trigger data in the packet format here, so zero it out afterwards
|
||||
memcpy(&pState->ulButtons, &pStatePacket->ButtonTriggerData.ulButtons, 8);
|
||||
SDL_memcpy(&pState->ulButtons, &pStatePacket->ButtonTriggerData.ulButtons, 8);
|
||||
pState->ulButtons &= ~0xFFFF000000LL;
|
||||
|
||||
// The firmware uses this bit to tell us what kind of data is packed into the left two axises
|
||||
@@ -735,18 +779,14 @@ static void FormatStatePacketUntilGyro( SteamControllerStateInternal_t *pState,
|
||||
pState->sRightPadX = pStatePacket->sRightPadX;
|
||||
pState->sRightPadY = pStatePacket->sRightPadY;
|
||||
|
||||
int nLeftPadX = pState->sLeftPadX;
|
||||
int nLeftPadY = pState->sLeftPadY;
|
||||
int nRightPadX = pState->sRightPadX;
|
||||
int nRightPadY = pState->sRightPadY;
|
||||
|
||||
// 15 degrees in rad
|
||||
const float flRotationAngle = 0.261799f;
|
||||
nLeftPadX = pState->sLeftPadX;
|
||||
nLeftPadY = pState->sLeftPadY;
|
||||
nRightPadX = pState->sRightPadX;
|
||||
nRightPadY = pState->sRightPadY;
|
||||
|
||||
RotatePad(&nLeftPadX, &nLeftPadY, -flRotationAngle);
|
||||
RotatePad(&nRightPadX, &nRightPadY, flRotationAngle);
|
||||
|
||||
int nPadOffset;
|
||||
if (pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK)
|
||||
nPadOffset = 1000;
|
||||
else
|
||||
@@ -782,7 +822,7 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize,
|
||||
ucOptionDataMask |= (uint32_t)(*pData++) << 8;
|
||||
if ( ucOptionDataMask & k_EBLEButtonChunk1 )
|
||||
{
|
||||
memcpy( &pState->ulButtons, pData, 3 );
|
||||
SDL_memcpy( &pState->ulButtons, pData, 3 );
|
||||
pData += 3;
|
||||
}
|
||||
if ( ucOptionDataMask & k_EBLEButtonChunk2 )
|
||||
@@ -804,14 +844,14 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize,
|
||||
// This doesn't handle any of the special headcrab stuff for raw joystick which is OK for now since that FW doesn't support
|
||||
// this protocol yet either
|
||||
int nLength = sizeof( pState->sLeftStickX ) + sizeof( pState->sLeftStickY );
|
||||
memcpy( &pState->sLeftStickX, pData, nLength );
|
||||
SDL_memcpy( &pState->sLeftStickX, pData, nLength );
|
||||
pData += nLength;
|
||||
}
|
||||
if ( ucOptionDataMask & k_EBLELeftTrackpadChunk )
|
||||
{
|
||||
int nLength = sizeof( pState->sLeftPadX ) + sizeof( pState->sLeftPadY );
|
||||
int nPadOffset;
|
||||
memcpy( &pState->sLeftPadX, pData, nLength );
|
||||
SDL_memcpy( &pState->sLeftPadX, pData, nLength );
|
||||
if ( pState->ulButtons & STEAM_LEFTPAD_FINGERDOWN_MASK )
|
||||
nPadOffset = 1000;
|
||||
else
|
||||
@@ -827,7 +867,7 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize,
|
||||
int nLength = sizeof( pState->sRightPadX ) + sizeof( pState->sRightPadY );
|
||||
int nPadOffset = 0;
|
||||
|
||||
memcpy( &pState->sRightPadX, pData, nLength );
|
||||
SDL_memcpy( &pState->sRightPadX, pData, nLength );
|
||||
|
||||
if ( pState->ulButtons & STEAM_RIGHTPAD_FINGERDOWN_MASK )
|
||||
nPadOffset = 1000;
|
||||
@@ -842,19 +882,19 @@ static bool UpdateBLESteamControllerState( const uint8_t *pData, int nDataSize,
|
||||
if ( ucOptionDataMask & k_EBLEIMUAccelChunk )
|
||||
{
|
||||
int nLength = sizeof( pState->sAccelX ) + sizeof( pState->sAccelY ) + sizeof( pState->sAccelZ );
|
||||
memcpy( &pState->sAccelX, pData, nLength );
|
||||
SDL_memcpy( &pState->sAccelX, pData, nLength );
|
||||
pData += nLength;
|
||||
}
|
||||
if ( ucOptionDataMask & k_EBLEIMUGyroChunk )
|
||||
{
|
||||
int nLength = sizeof( pState->sAccelX ) + sizeof( pState->sAccelY ) + sizeof( pState->sAccelZ );
|
||||
memcpy( &pState->sGyroX, pData, nLength );
|
||||
SDL_memcpy( &pState->sGyroX, pData, nLength );
|
||||
pData += nLength;
|
||||
}
|
||||
if ( ucOptionDataMask & k_EBLEIMUQuatChunk )
|
||||
{
|
||||
int nLength = sizeof( pState->sGyroQuatW ) + sizeof( pState->sGyroQuatX ) + sizeof( pState->sGyroQuatY ) + sizeof( pState->sGyroQuatZ );
|
||||
memcpy( &pState->sGyroQuatW, pData, nLength );
|
||||
SDL_memcpy( &pState->sGyroQuatW, pData, nLength );
|
||||
pData += nLength;
|
||||
}
|
||||
return true;
|
||||
@@ -950,6 +990,7 @@ static bool UpdateSteamControllerState( const uint8_t *pData, int nDataSize, Ste
|
||||
/*****************************************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
SDL_bool report_sensors;
|
||||
SteamControllerPacketAssembler m_assembler;
|
||||
SteamControllerStateInternal_t m_state;
|
||||
SteamControllerStateInternal_t m_last_state;
|
||||
@@ -989,6 +1030,8 @@ static SDL_bool
|
||||
HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
SDL_DriverSteam_Context *ctx;
|
||||
uint32_t update_rate_in_us = 0;
|
||||
float update_rate_in_hz = 0.0f;
|
||||
|
||||
ctx = (SDL_DriverSteam_Context *)SDL_calloc(1, sizeof(*ctx));
|
||||
if (!ctx) {
|
||||
@@ -997,15 +1040,20 @@ HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
|
||||
}
|
||||
device->context = ctx;
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
goto error;
|
||||
}
|
||||
SDL_hid_set_nonblocking(device->dev, 1);
|
||||
|
||||
if (!ResetSteamController(device->dev, false)) {
|
||||
if (!ResetSteamController(device->dev, false, &update_rate_in_us)) {
|
||||
SDL_SetError("Couldn't reset controller");
|
||||
goto error;
|
||||
}
|
||||
if (update_rate_in_us > 0) {
|
||||
update_rate_in_hz = 1000000.0f / update_rate_in_us;
|
||||
}
|
||||
|
||||
InitializeSteamControllerPacketAssembler(&ctx->m_assembler);
|
||||
|
||||
@@ -1013,13 +1061,16 @@ HIDAPI_DriverSteam_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
|
||||
joystick->nbuttons = 17;
|
||||
joystick->naxes = SDL_CONTROLLER_AXIS_MAX;
|
||||
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_GYRO, update_rate_in_hz);
|
||||
SDL_PrivateJoystickAddSensor(joystick, SDL_SENSOR_ACCEL, update_rate_in_hz);
|
||||
|
||||
return SDL_TRUE;
|
||||
|
||||
error:
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
if (device->context) {
|
||||
@@ -1044,11 +1095,11 @@ HIDAPI_DriverSteam_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystic
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverSteam_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverSteam_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* You should use the full Steam Input API for LED support */
|
||||
return SDL_FALSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1067,8 +1118,25 @@ HIDAPI_DriverSteam_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *j
|
||||
static int
|
||||
HIDAPI_DriverSteam_SetSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled)
|
||||
{
|
||||
/* You should use the full Steam Input API for sensor support */
|
||||
return SDL_Unsupported();
|
||||
SDL_DriverSteam_Context *ctx = (SDL_DriverSteam_Context *)device->context;
|
||||
unsigned char buf[65];
|
||||
int nSettings = 0;
|
||||
|
||||
SDL_memset( buf, 0, 65 );
|
||||
buf[1] = ID_SET_SETTINGS_VALUES;
|
||||
if (enabled) {
|
||||
ADD_SETTING( SETTING_GYRO_MODE, 0x18 /* SETTING_GYRO_SEND_RAW_ACCEL | SETTING_GYRO_MODE_SEND_RAW_GYRO */ );
|
||||
} else {
|
||||
ADD_SETTING( SETTING_GYRO_MODE, 0x00 /* SETTING_GYRO_MODE_OFF */ );
|
||||
}
|
||||
buf[2] = nSettings*3;
|
||||
if (SetFeatureReport( device->dev, buf, 3+nSettings*3 ) < 0) {
|
||||
return SDL_SetError("Couldn't write feature report");
|
||||
}
|
||||
|
||||
ctx->report_sensors = enabled;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
@@ -1165,6 +1233,20 @@ HIDAPI_DriverSteam_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, ctx->m_state.sRightPadX);
|
||||
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~ctx->m_state.sRightPadY);
|
||||
|
||||
if (ctx->report_sensors) {
|
||||
float values[3];
|
||||
|
||||
values[0] = (ctx->m_state.sGyroX / 32768.0f) * (2000.0f * (M_PI / 180.0f));
|
||||
values[1] = (ctx->m_state.sGyroZ / 32768.0f) * (2000.0f * (M_PI / 180.0f));
|
||||
values[2] = (ctx->m_state.sGyroY / 32768.0f) * (2000.0f * (M_PI / 180.0f));
|
||||
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_GYRO, values, 3);
|
||||
|
||||
values[0] = (ctx->m_state.sAccelX / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
|
||||
values[1] = (ctx->m_state.sAccelZ / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
|
||||
values[2] = (-ctx->m_state.sAccelY / 32768.0f) * 2.0f * SDL_STANDARD_GRAVITY;
|
||||
SDL_PrivateJoystickSensor(joystick, SDL_SENSOR_ACCEL, values, 3);
|
||||
}
|
||||
|
||||
ctx->m_last_state = ctx->m_state;
|
||||
}
|
||||
|
||||
@@ -1184,7 +1266,7 @@ HIDAPI_DriverSteam_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
||||
{
|
||||
CloseSteamController(device->dev);
|
||||
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -1202,6 +1284,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_STEAM,
|
||||
SDL_TRUE,
|
||||
SDL_FALSE,
|
||||
HIDAPI_DriverSteam_IsSupportedDevice,
|
||||
HIDAPI_DriverSteam_GetDeviceName,
|
||||
HIDAPI_DriverSteam_InitDevice,
|
||||
@@ -1211,7 +1294,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam =
|
||||
HIDAPI_DriverSteam_OpenJoystick,
|
||||
HIDAPI_DriverSteam_RumbleJoystick,
|
||||
HIDAPI_DriverSteam_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverSteam_HasJoystickLED,
|
||||
HIDAPI_DriverSteam_GetJoystickCapabilities,
|
||||
HIDAPI_DriverSteam_SetJoystickLED,
|
||||
HIDAPI_DriverSteam_SendJoystickEffect,
|
||||
HIDAPI_DriverSteam_SetSensorsEnabled,
|
||||
|
@@ -346,13 +346,13 @@ static int ReadInput(SDL_DriverSwitch_Context *ctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
return hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0);
|
||||
return SDL_hid_read_timeout(ctx->device->dev, ctx->m_rgucReadBuffer, sizeof(ctx->m_rgucReadBuffer), 0);
|
||||
}
|
||||
|
||||
static int WriteOutput(SDL_DriverSwitch_Context *ctx, const Uint8 *data, int size)
|
||||
{
|
||||
#ifdef SWITCH_SYNCHRONOUS_WRITES
|
||||
return hid_write(ctx->device->dev, data, size);
|
||||
return SDL_hid_write(ctx->device->dev, data, size);
|
||||
#else
|
||||
/* Use the rumble thread for general asynchronous writes */
|
||||
if (SDL_HIDAPI_LockRumble() < 0) {
|
||||
@@ -418,7 +418,7 @@ static void ConstructSubcommand(SDL_DriverSwitch_Context *ctx, ESwitchSubcommand
|
||||
outPacket->commonData.ucPacketType = k_eSwitchOutputReportIDs_RumbleAndSubcommand;
|
||||
outPacket->commonData.ucPacketNumber = ctx->m_nCommandNumber;
|
||||
|
||||
SDL_memcpy(&outPacket->commonData.rumbleData, &ctx->m_RumblePacket.rumbleData, sizeof(ctx->m_RumblePacket.rumbleData));
|
||||
SDL_memcpy(outPacket->commonData.rumbleData, ctx->m_RumblePacket.rumbleData, sizeof(ctx->m_RumblePacket.rumbleData));
|
||||
|
||||
outPacket->ucSubcommandID = ucCommandID;
|
||||
SDL_memcpy(outPacket->rgucSubcommandData, pBuf, ucLen);
|
||||
@@ -621,7 +621,7 @@ static SDL_bool BReadDeviceInfo(SDL_DriverSwitch_Context *ctx)
|
||||
ctx->m_eControllerType = (ESwitchDeviceInfoControllerType)reply->deviceInfo.ucDeviceType;
|
||||
|
||||
// Bytes 4-9: MAC address (big-endian)
|
||||
memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress));
|
||||
SDL_memcpy(ctx->m_rgucMACAddress, reply->deviceInfo.rgucMACAddress, sizeof(ctx->m_rgucMACAddress));
|
||||
|
||||
return SDL_TRUE;
|
||||
}
|
||||
@@ -856,7 +856,7 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
||||
ctx->device = device;
|
||||
device->context = ctx;
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
goto error;
|
||||
@@ -936,10 +936,13 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
|
||||
|
||||
/* Set the LED state */
|
||||
if (ctx->m_bHasHomeLED) {
|
||||
if (SDL_GetHintBoolean(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED, SDL_TRUE)) {
|
||||
SetHomeLED(ctx, 100);
|
||||
} else {
|
||||
SetHomeLED(ctx, 0);
|
||||
const char *hint = SDL_GetHint(SDL_HINT_JOYSTICK_HIDAPI_SWITCH_HOME_LED);
|
||||
if (hint && *hint) {
|
||||
if (SDL_GetStringBoolean(hint, SDL_TRUE)) {
|
||||
SetHomeLED(ctx, 100);
|
||||
} else {
|
||||
SetHomeLED(ctx, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
SetSlotLED(ctx, (joystick->instance_id % 4));
|
||||
@@ -983,7 +986,7 @@ error:
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
if (device->context) {
|
||||
@@ -1103,11 +1106,18 @@ HIDAPI_DriverSwitch_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joysti
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverSwitch_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverSwitch_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return true here */
|
||||
return SDL_FALSE;
|
||||
SDL_DriverSwitch_Context *ctx = (SDL_DriverSwitch_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (!ctx->m_bInputOnly) {
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -1527,7 +1537,7 @@ HIDAPI_DriverSwitch_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -1545,6 +1555,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_SWITCH,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverSwitch_IsSupportedDevice,
|
||||
HIDAPI_DriverSwitch_GetDeviceName,
|
||||
HIDAPI_DriverSwitch_InitDevice,
|
||||
@@ -1554,7 +1565,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
|
||||
HIDAPI_DriverSwitch_OpenJoystick,
|
||||
HIDAPI_DriverSwitch_RumbleJoystick,
|
||||
HIDAPI_DriverSwitch_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverSwitch_HasJoystickLED,
|
||||
HIDAPI_DriverSwitch_GetJoystickCapabilities,
|
||||
HIDAPI_DriverSwitch_SetJoystickLED,
|
||||
HIDAPI_DriverSwitch_SendJoystickEffect,
|
||||
HIDAPI_DriverSwitch_SetJoystickSensorsEnabled,
|
||||
|
@@ -88,14 +88,14 @@ HIDAPI_DriverXbox360_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static SDL_bool SetSlotLED(hid_device *dev, Uint8 slot)
|
||||
static SDL_bool SetSlotLED(SDL_hid_device *dev, Uint8 slot)
|
||||
{
|
||||
const SDL_bool blink = SDL_FALSE;
|
||||
Uint8 mode = (blink ? 0x02 : 0x06) + slot;
|
||||
Uint8 led_packet[] = { 0x01, 0x03, 0x00 };
|
||||
|
||||
led_packet[2] = mode;
|
||||
if (hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
@@ -136,7 +136,7 @@ HIDAPI_DriverXbox360_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
SDL_free(ctx);
|
||||
@@ -203,11 +203,11 @@ HIDAPI_DriverXbox360_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joyst
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverXbox360_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverXbox360_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return true here */
|
||||
return SDL_FALSE;
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -296,7 +296,7 @@ HIDAPI_DriverXbox360_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
HIDAPI_DumpPacket("Xbox 360 packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -318,7 +318,7 @@ HIDAPI_DriverXbox360_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
if (device->dev) {
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
}
|
||||
|
||||
@@ -337,6 +337,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_XBOX,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverXbox360_IsSupportedDevice,
|
||||
HIDAPI_DriverXbox360_GetDeviceName,
|
||||
HIDAPI_DriverXbox360_InitDevice,
|
||||
@@ -346,7 +347,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
|
||||
HIDAPI_DriverXbox360_OpenJoystick,
|
||||
HIDAPI_DriverXbox360_RumbleJoystick,
|
||||
HIDAPI_DriverXbox360_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverXbox360_HasJoystickLED,
|
||||
HIDAPI_DriverXbox360_GetJoystickCapabilities,
|
||||
HIDAPI_DriverXbox360_SetJoystickLED,
|
||||
HIDAPI_DriverXbox360_SendJoystickEffect,
|
||||
HIDAPI_DriverXbox360_SetJoystickSensorsEnabled,
|
||||
|
@@ -62,14 +62,14 @@ HIDAPI_DriverXbox360W_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
|
||||
return "Xbox 360 Wireless Controller";
|
||||
}
|
||||
|
||||
static SDL_bool SetSlotLED(hid_device *dev, Uint8 slot)
|
||||
static SDL_bool SetSlotLED(SDL_hid_device *dev, Uint8 slot)
|
||||
{
|
||||
const SDL_bool blink = SDL_FALSE;
|
||||
Uint8 mode = (blink ? 0x02 : 0x06) + slot;
|
||||
Uint8 led_packet[] = { 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
led_packet[3] = 0x40 + (mode % 0x0e);
|
||||
if (hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
if (SDL_hid_write(dev, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
return SDL_FALSE;
|
||||
}
|
||||
return SDL_TRUE;
|
||||
@@ -105,7 +105,7 @@ HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device)
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -113,7 +113,7 @@ HIDAPI_DriverXbox360W_InitDevice(SDL_HIDAPI_Device *device)
|
||||
}
|
||||
device->context = ctx;
|
||||
|
||||
if (hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) {
|
||||
if (SDL_hid_write(device->dev, init_packet, sizeof(init_packet)) != sizeof(init_packet)) {
|
||||
SDL_SetError("Couldn't write init packet");
|
||||
return SDL_FALSE;
|
||||
}
|
||||
@@ -173,11 +173,11 @@ HIDAPI_DriverXbox360W_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joys
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverXbox360W_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverXbox360W_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return true here */
|
||||
return SDL_FALSE;
|
||||
/* Doesn't have an RGB LED, so don't return SDL_JOYCAP_LED here */
|
||||
return SDL_JOYCAP_RUMBLE;
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -199,7 +199,7 @@ HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_J
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size)
|
||||
HIDAPI_DriverXbox360W_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev, SDL_DriverXbox360W_Context *ctx, Uint8 *data, int size)
|
||||
{
|
||||
Sint16 axis;
|
||||
const SDL_bool invert_y_axes = SDL_TRUE;
|
||||
@@ -259,7 +259,7 @@ HIDAPI_DriverXbox360W_UpdateDevice(SDL_HIDAPI_Device *device)
|
||||
joystick = SDL_JoystickFromInstanceID(device->joysticks[0]);
|
||||
}
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
HIDAPI_DumpPacket("Xbox 360 wireless packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -321,7 +321,7 @@ HIDAPI_DriverXbox360W_FreeDevice(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -334,6 +334,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_XBOX,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverXbox360W_IsSupportedDevice,
|
||||
HIDAPI_DriverXbox360W_GetDeviceName,
|
||||
HIDAPI_DriverXbox360W_InitDevice,
|
||||
@@ -343,7 +344,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
|
||||
HIDAPI_DriverXbox360W_OpenJoystick,
|
||||
HIDAPI_DriverXbox360W_RumbleJoystick,
|
||||
HIDAPI_DriverXbox360W_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverXbox360W_HasJoystickLED,
|
||||
HIDAPI_DriverXbox360W_GetJoystickCapabilities,
|
||||
HIDAPI_DriverXbox360W_SetJoystickLED,
|
||||
HIDAPI_DriverXbox360W_SendJoystickEffect,
|
||||
HIDAPI_DriverXbox360W_SetJoystickSensorsEnabled,
|
||||
|
@@ -44,33 +44,23 @@
|
||||
#define CONTROLLER_PREPARE_INPUT_TIMEOUT_MS 50
|
||||
|
||||
|
||||
/* Connect controller */
|
||||
/* Start controller */
|
||||
static const Uint8 xboxone_init0[] = {
|
||||
0x04, 0x20, 0x00, 0x00
|
||||
};
|
||||
/* Start controller - extended? */
|
||||
static const Uint8 xboxone_init1[] = {
|
||||
0x05, 0x20, 0x00, 0x0F, 0x06, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x55, 0x53, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00
|
||||
};
|
||||
/* Start controller with input */
|
||||
static const Uint8 xboxone_init2[] = {
|
||||
0x05, 0x20, 0x03, 0x01, 0x00
|
||||
};
|
||||
/* Enable LED */
|
||||
static const Uint8 xboxone_init3[] = {
|
||||
static const Uint8 xboxone_init1[] = {
|
||||
0x0A, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
|
||||
};
|
||||
/* Start input reports? */
|
||||
static const Uint8 xboxone_init4[] = {
|
||||
0x06, 0x20, 0x00, 0x02, 0x01, 0x00
|
||||
};
|
||||
/* Start rumble? */
|
||||
static const Uint8 xboxone_init5[] = {
|
||||
/* Setup rumble (not needed for Microsoft controllers, but it doesn't hurt) */
|
||||
static const Uint8 xboxone_init2[] = {
|
||||
0x09, 0x00, 0x00, 0x09, 0x00, 0x0F, 0x00, 0x00,
|
||||
0x00, 0x00, 0xFF, 0x00, 0xEB
|
||||
};
|
||||
/* This controller passed security check */
|
||||
static const Uint8 security_passed_packet[] = {
|
||||
0x06, 0x20, 0x00, 0x02, 0x01, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* This specifies the selection of init packets that a gamepad
|
||||
@@ -90,16 +80,11 @@ typedef struct {
|
||||
|
||||
|
||||
static const SDL_DriverXboxOne_InitPacket xboxone_init_packets[] = {
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x04, 0xb0 } },
|
||||
/* The PDP Rock Candy controller doesn't start sending input until it gets this packet */
|
||||
{ 0x0e6f, 0x0246, 0x0000, 0x0000, security_passed_packet, sizeof(security_passed_packet), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init0, sizeof(xboxone_init0), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init1, sizeof(xboxone_init1), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init2, sizeof(xboxone_init2), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x0000, 0x0000, xboxone_init3, sizeof(xboxone_init3), { 0x00, 0x00 } },
|
||||
|
||||
/* These next packets are required for third party controllers (PowerA, PDP, HORI),
|
||||
but aren't the correct protocol for Microsoft Xbox controllers.
|
||||
*/
|
||||
{ 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init4, sizeof(xboxone_init4), { 0x00, 0x00 } },
|
||||
{ 0x0000, 0x0000, 0x045e, 0x0000, xboxone_init5, sizeof(xboxone_init5), { 0x00, 0x00 } },
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
@@ -120,6 +105,7 @@ typedef struct {
|
||||
Uint32 send_time;
|
||||
Uint8 last_state[USB_PACKET_LENGTH];
|
||||
SDL_bool has_guide_packet;
|
||||
SDL_bool has_color_led;
|
||||
SDL_bool has_paddles;
|
||||
SDL_bool has_trigger_rumble;
|
||||
SDL_bool has_share_button;
|
||||
@@ -129,6 +115,12 @@ typedef struct {
|
||||
Uint8 right_trigger_rumble;
|
||||
} SDL_DriverXboxOne_Context;
|
||||
|
||||
static SDL_bool
|
||||
ControllerHasColorLED(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
return (vendor_id == USB_VENDOR_MICROSOFT && product_id == USB_PRODUCT_XBOX_ONE_ELITE_SERIES_2);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
@@ -138,7 +130,7 @@ ControllerHasPaddles(Uint16 vendor_id, Uint16 product_id)
|
||||
static SDL_bool
|
||||
ControllerHasTriggerRumble(Uint16 vendor_id, Uint16 product_id)
|
||||
{
|
||||
// All the Microsoft Xbox One controllers have trigger rumble
|
||||
/* All the Microsoft Xbox One controllers have trigger rumble */
|
||||
return (vendor_id == USB_VENDOR_MICROSOFT);
|
||||
}
|
||||
|
||||
@@ -178,7 +170,10 @@ SendAckIfNeeded(SDL_HIDAPI_Device *device, Uint8 *data, int size)
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
HIDAPI_DumpPacket("Xbox One sending ACK packet: size = %d", ack_packet, sizeof(ack_packet));
|
||||
#endif
|
||||
hid_write(device->dev, ack_packet, sizeof(ack_packet));
|
||||
if (SDL_HIDAPI_LockRumble() < 0 ||
|
||||
SDL_HIDAPI_SendRumbleAndUnlock(device, ack_packet, sizeof(ack_packet)) != sizeof(ack_packet)) {
|
||||
SDL_SetError("Couldn't send ack packet");
|
||||
}
|
||||
}
|
||||
#endif /* __WIN32__ */
|
||||
}
|
||||
@@ -322,7 +317,7 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
return SDL_FALSE;
|
||||
}
|
||||
|
||||
device->dev = hid_open_path(device->path, 0);
|
||||
device->dev = SDL_hid_open_path(device->path, 0);
|
||||
if (!device->dev) {
|
||||
SDL_free(ctx);
|
||||
SDL_SetError("Couldn't open %s", device->path);
|
||||
@@ -335,6 +330,7 @@ HIDAPI_DriverXboxOne_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
|
||||
ctx->bluetooth = SDL_IsJoystickBluetoothXboxOne(device->vendor_id, device->product_id);
|
||||
ctx->start_time = SDL_GetTicks();
|
||||
ctx->sequence = 1;
|
||||
ctx->has_color_led = ControllerHasColorLED(ctx->vendor_id, ctx->product_id);
|
||||
ctx->has_paddles = ControllerHasPaddles(ctx->vendor_id, ctx->product_id);
|
||||
ctx->has_trigger_rumble = ControllerHasTriggerRumble(ctx->vendor_id, ctx->product_id);
|
||||
ctx->has_share_button = ControllerHasShareButton(ctx->vendor_id, ctx->product_id);
|
||||
@@ -426,17 +422,44 @@ HIDAPI_DriverXboxOne_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joyst
|
||||
return HIDAPI_DriverXboxOne_UpdateRumble(device);
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_DriverXboxOne_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_DriverXboxOne_GetJoystickCapabilities(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
|
||||
{
|
||||
/* Doesn't have an RGB LED, so don't return true here */
|
||||
return SDL_FALSE;
|
||||
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
|
||||
Uint32 result = 0;
|
||||
|
||||
result |= SDL_JOYCAP_RUMBLE;
|
||||
if (ctx->has_trigger_rumble) {
|
||||
result |= SDL_JOYCAP_RUMBLE_TRIGGERS;
|
||||
}
|
||||
|
||||
if (ctx->has_color_led) {
|
||||
result |= SDL_JOYCAP_LED;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static int
|
||||
HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
|
||||
{
|
||||
return SDL_Unsupported();
|
||||
SDL_DriverXboxOne_Context *ctx = (SDL_DriverXboxOne_Context *)device->context;
|
||||
|
||||
if (ctx->has_color_led) {
|
||||
Uint8 led_packet[] = { 0x0E, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
|
||||
led_packet[5] = 0x00; /* Whiteness? Sets white intensity when RGB is 0, seems additive */
|
||||
led_packet[6] = red;
|
||||
led_packet[7] = green;
|
||||
led_packet[8] = blue;
|
||||
|
||||
if (SDL_HIDAPI_SendRumble(device, led_packet, sizeof(led_packet)) != sizeof(led_packet)) {
|
||||
return SDL_SetError("Couldn't send LED packet");
|
||||
}
|
||||
return 0;
|
||||
} else {
|
||||
return SDL_Unsupported();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
@@ -508,12 +531,16 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
|
||||
Paddle bits:
|
||||
P3: 0x01 (A) P1: 0x02 (B)
|
||||
P4: 0x04 (X) P2: 0x08 (Y)
|
||||
Xbox One Elite Series 2 report is 38 bytes, paddles in data[18], mode in data[19], mode 0 has no mapped paddles by default
|
||||
Xbox One Elite Series 2 4.x firmware report is 38 bytes, paddles in data[18], mode in data[19], mode 0 has no mapped paddles by default
|
||||
Paddle bits:
|
||||
P3: 0x04 (A) P1: 0x01 (B)
|
||||
P4: 0x08 (X) P2: 0x02 (Y)
|
||||
Xbox One Elite Series 2 5.x firmware report is 50 bytes, paddles in data[22], mode in data[23], mode 0 has no mapped paddles by default
|
||||
Paddle bits:
|
||||
P3: 0x04 (A) P1: 0x01 (B)
|
||||
P4: 0x08 (X) P2: 0x02 (Y)
|
||||
*/
|
||||
if (ctx->has_paddles && (size == 33 || size == 38)) {
|
||||
if (ctx->has_paddles && (size == 33 || size == 38 || size == 50)) {
|
||||
int paddle_index;
|
||||
int button1_bit;
|
||||
int button2_bit;
|
||||
@@ -532,7 +559,7 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
|
||||
/* The mapped controller state is at offset 4, the raw state is at offset 18, compare them to see if the paddles are mapped */
|
||||
paddles_mapped = (SDL_memcmp(&data[4], &data[18], 2) != 0);
|
||||
|
||||
} else /* if (size == 38) */ {
|
||||
} else if (size == 38) {
|
||||
/* XBox One Elite Series 2 */
|
||||
paddle_index = 18;
|
||||
button1_bit = 0x01;
|
||||
@@ -540,6 +567,15 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
|
||||
button3_bit = 0x04;
|
||||
button4_bit = 0x08;
|
||||
paddles_mapped = (data[19] != 0);
|
||||
|
||||
} else /* if (size == 50) */{
|
||||
/* XBox One Elite Series 2 */
|
||||
paddle_index = 22;
|
||||
button1_bit = 0x01;
|
||||
button2_bit = 0x02;
|
||||
button3_bit = 0x04;
|
||||
button4_bit = 0x08;
|
||||
paddles_mapped = (data[23] != 0);
|
||||
}
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
SDL_Log(">>> Paddles: %d,%d,%d,%d mapped = %s\n",
|
||||
@@ -595,6 +631,14 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
|
||||
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXboxOne_HandleStatusPacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
|
||||
{
|
||||
if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) {
|
||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_DriverXboxOne_HandleModePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
|
||||
{
|
||||
@@ -627,8 +671,10 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons16(SDL_Joystick *joystick, SDL_Driver
|
||||
|
||||
/*
|
||||
* Xbox One S with firmware 4.8.1923 uses a 17 byte packet with BACK button in byte 16 and the GUIDE button in a separate packet (on Windows), or in byte 15 (on Linux)
|
||||
* Xbox One S with firmware 5.x uses a 17 byte packet with BACK and GUIDE buttons in byte 15
|
||||
* Xbox One Elite Series 2 with firmware 4.7.1872 uses a 55 byte packet with BACK button in byte 16, paddles starting at byte 33, and the GUIDE button in a separate packet
|
||||
* Xbox One Elite Series 2 with firmware 4.8.1908 uses a 33 byte packet with BACK button in byte 16, paddles starting at byte 17, and the GUIDE button in a separate packet
|
||||
* Xbox One Elite Series 2 with firmware 5.11.3112 uses a 19 byte packet with BACK and GUIDE buttons in byte 15
|
||||
* Xbox Series X with firmware 5.5.2641 uses a 17 byte packet with BACK and GUIDE buttons in byte 15, and SHARE button in byte 17
|
||||
*/
|
||||
static void
|
||||
@@ -644,10 +690,7 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXb
|
||||
}
|
||||
|
||||
if (ctx->last_state[15] != data[15]) {
|
||||
if (ctx->has_share_button) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[15] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
} else if (!ctx->has_guide_packet) {
|
||||
if (!ctx->has_guide_packet) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_GUIDE, (data[15] & 0x10) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_START, (data[15] & 0x08) ? SDL_PRESSED : SDL_RELEASED);
|
||||
@@ -655,12 +698,11 @@ HIDAPI_DriverXboxOneBluetooth_HandleButtons(SDL_Joystick *joystick, SDL_DriverXb
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_RIGHTSTICK, (data[15] & 0x40) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
if (ctx->last_state[16] != data[16]) {
|
||||
if (ctx->has_share_button) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
} else {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
if (ctx->has_share_button) {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, (data[15] & 0x04) ? SDL_PRESSED : SDL_RELEASED);
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_MISC1, (data[16] & 0x01) ? SDL_PRESSED : SDL_RELEASED);
|
||||
} else {
|
||||
SDL_PrivateJoystickButton(joystick, SDL_CONTROLLER_BUTTON_BACK, ((data[15] & 0x04) || (data[16] & 0x01)) ? SDL_PRESSED : SDL_RELEASED);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -727,8 +769,13 @@ HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, SDL_Driv
|
||||
if (size == 16) {
|
||||
/* Original Xbox One S, with separate report for guide button */
|
||||
HIDAPI_DriverXboxOneBluetooth_HandleButtons16(joystick, ctx, data, size);
|
||||
} else {
|
||||
} else if (size > 16) {
|
||||
HIDAPI_DriverXboxOneBluetooth_HandleButtons(joystick, ctx, data, size);
|
||||
} else {
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
SDL_Log("Unknown Bluetooth state packet format\n");
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
|
||||
if (ctx->last_state[13] != data[13]) {
|
||||
@@ -908,7 +955,7 @@ HIDAPI_DriverXboxOne_UpdateJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||
Uint8 data[USB_PACKET_LENGTH];
|
||||
int size;
|
||||
|
||||
while ((size = hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
while ((size = SDL_hid_read_timeout(device->dev, data, sizeof(data), 0)) > 0) {
|
||||
#ifdef DEBUG_XBOX_PROTOCOL
|
||||
HIDAPI_DumpPacket("Xbox One packet: size = %d", data, size);
|
||||
#endif
|
||||
@@ -961,16 +1008,18 @@ HIDAPI_DriverXboxOne_UpdateJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
|
||||
is firmware version 5.5.2641.0, and product version 0x0505 = 1285
|
||||
then 8 bytes of unknown data
|
||||
*/
|
||||
if (data[1] == 0x20) {
|
||||
#ifdef DEBUG_JOYSTICK
|
||||
SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time));
|
||||
SDL_Log("Controller announce after %u ms\n", (SDL_GetTicks() - ctx->start_time));
|
||||
#endif
|
||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING);
|
||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_START_NEGOTIATING);
|
||||
} else {
|
||||
/* Possibly an announce from a device plugged into the controller */
|
||||
}
|
||||
break;
|
||||
case 0x03:
|
||||
/* Controller heartbeat */
|
||||
if (ctx->init_state < XBOX_ONE_INIT_STATE_COMPLETE) {
|
||||
SetInitState(ctx, XBOX_ONE_INIT_STATE_COMPLETE);
|
||||
}
|
||||
/* Controller status update */
|
||||
HIDAPI_DriverXboxOne_HandleStatusPacket(joystick, ctx, data, size);
|
||||
break;
|
||||
case 0x04:
|
||||
/* Unknown chatty controller information, sent by both sides */
|
||||
@@ -1060,7 +1109,7 @@ HIDAPI_DriverXboxOne_CloseJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
|
||||
{
|
||||
SDL_LockMutex(device->dev_lock);
|
||||
{
|
||||
hid_close(device->dev);
|
||||
SDL_hid_close(device->dev);
|
||||
device->dev = NULL;
|
||||
|
||||
SDL_free(device->context);
|
||||
@@ -1078,6 +1127,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
|
||||
{
|
||||
SDL_HINT_JOYSTICK_HIDAPI_XBOX,
|
||||
SDL_TRUE,
|
||||
SDL_TRUE,
|
||||
HIDAPI_DriverXboxOne_IsSupportedDevice,
|
||||
HIDAPI_DriverXboxOne_GetDeviceName,
|
||||
HIDAPI_DriverXboxOne_InitDevice,
|
||||
@@ -1087,7 +1137,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
|
||||
HIDAPI_DriverXboxOne_OpenJoystick,
|
||||
HIDAPI_DriverXboxOne_RumbleJoystick,
|
||||
HIDAPI_DriverXboxOne_RumbleJoystickTriggers,
|
||||
HIDAPI_DriverXboxOne_HasJoystickLED,
|
||||
HIDAPI_DriverXboxOne_GetJoystickCapabilities,
|
||||
HIDAPI_DriverXboxOne_SetJoystickLED,
|
||||
HIDAPI_DriverXboxOne_SendJoystickEffect,
|
||||
HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled,
|
||||
|
@@ -25,52 +25,17 @@
|
||||
#include "SDL_atomic.h"
|
||||
#include "SDL_endian.h"
|
||||
#include "SDL_hints.h"
|
||||
#include "SDL_thread.h"
|
||||
#include "SDL_timer.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "SDL_log.h"
|
||||
#include "../SDL_sysjoystick.h"
|
||||
#include "SDL_hidapijoystick_c.h"
|
||||
#include "SDL_hidapi_rumble.h"
|
||||
#include "../../SDL_hints_c.h"
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#include "../../core/windows/SDL_windows.h"
|
||||
#include "../windows/SDL_rawinputjoystick_c.h"
|
||||
#endif
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include <mach/mach.h>
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/hid/IOHIDDevice.h>
|
||||
#include <IOKit/usb/USBSpec.h>
|
||||
#endif
|
||||
|
||||
#ifdef SDL_USE_LIBUDEV
|
||||
#include "../../core/linux/SDL_udev.h"
|
||||
#include <poll.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
#include <unistd.h> /* just in case we didn't use that SDL_USE_LIBUDEV block... */
|
||||
#include <errno.h> /* errno, strerror */
|
||||
#include <fcntl.h>
|
||||
#include <limits.h> /* For the definition of NAME_MAX */
|
||||
#include <sys/inotify.h>
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
typedef enum
|
||||
{
|
||||
ENUMERATION_UNSET,
|
||||
ENUMERATION_LIBUDEV,
|
||||
ENUMERATION_FALLBACK
|
||||
} LinuxEnumerationMethod;
|
||||
|
||||
static LinuxEnumerationMethod linux_enumeration_method = ENUMERATION_UNSET;
|
||||
#endif
|
||||
|
||||
struct joystick_hwdata
|
||||
{
|
||||
@@ -109,434 +74,12 @@ static SDL_HIDAPI_DeviceDriver *SDL_HIDAPI_drivers[] = {
|
||||
};
|
||||
static int SDL_HIDAPI_numdrivers = 0;
|
||||
static SDL_SpinLock SDL_HIDAPI_spinlock;
|
||||
static Uint32 SDL_HIDAPI_change_count = 0;
|
||||
static SDL_HIDAPI_Device *SDL_HIDAPI_devices;
|
||||
static int SDL_HIDAPI_numjoysticks = 0;
|
||||
static SDL_bool initialized = SDL_FALSE;
|
||||
static SDL_bool shutting_down = SDL_FALSE;
|
||||
|
||||
#if defined(HAVE_INOTIFY)
|
||||
static int inotify_fd = -1;
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
static const SDL_UDEV_Symbols * usyms = NULL;
|
||||
#endif
|
||||
|
||||
static struct
|
||||
{
|
||||
SDL_bool m_bHaveDevicesChanged;
|
||||
SDL_bool m_bCanGetNotifications;
|
||||
Uint32 m_unLastDetect;
|
||||
|
||||
#if defined(__WIN32__)
|
||||
SDL_threadID m_nThreadID;
|
||||
WNDCLASSEXA m_wndClass;
|
||||
HWND m_hwndMsg;
|
||||
HDEVNOTIFY m_hNotify;
|
||||
double m_flLastWin32MessageCheck;
|
||||
#endif
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
IONotificationPortRef m_notificationPort;
|
||||
mach_port_t m_notificationMach;
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
struct udev *m_pUdev;
|
||||
struct udev_monitor *m_pUdevMonitor;
|
||||
int m_nUdevFd;
|
||||
#endif
|
||||
} SDL_HIDAPI_discovery;
|
||||
|
||||
|
||||
#ifdef __WIN32__
|
||||
struct _DEV_BROADCAST_HDR
|
||||
{
|
||||
DWORD dbch_size;
|
||||
DWORD dbch_devicetype;
|
||||
DWORD dbch_reserved;
|
||||
};
|
||||
|
||||
typedef struct _DEV_BROADCAST_DEVICEINTERFACE_A
|
||||
{
|
||||
DWORD dbcc_size;
|
||||
DWORD dbcc_devicetype;
|
||||
DWORD dbcc_reserved;
|
||||
GUID dbcc_classguid;
|
||||
char dbcc_name[ 1 ];
|
||||
} DEV_BROADCAST_DEVICEINTERFACE_A, *PDEV_BROADCAST_DEVICEINTERFACE_A;
|
||||
|
||||
typedef struct _DEV_BROADCAST_HDR DEV_BROADCAST_HDR;
|
||||
#define DBT_DEVICEARRIVAL 0x8000 /* system detected a new device */
|
||||
#define DBT_DEVICEREMOVECOMPLETE 0x8004 /* device was removed from the system */
|
||||
#define DBT_DEVTYP_DEVICEINTERFACE 0x00000005 /* device interface class */
|
||||
#define DBT_DEVNODES_CHANGED 0x0007
|
||||
#define DBT_CONFIGCHANGED 0x0018
|
||||
#define DBT_DEVICETYPESPECIFIC 0x8005 /* type specific event */
|
||||
#define DBT_DEVINSTSTARTED 0x8008 /* device installed and started */
|
||||
|
||||
#include <initguid.h>
|
||||
DEFINE_GUID(GUID_DEVINTERFACE_USB_DEVICE, 0xA5DCBF10L, 0x6530, 0x11D2, 0x90, 0x1F, 0x00, 0xC0, 0x4F, 0xB9, 0x51, 0xED);
|
||||
|
||||
static LRESULT CALLBACK ControllerWndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (message) {
|
||||
case WM_DEVICECHANGE:
|
||||
switch (wParam) {
|
||||
case DBT_DEVICEARRIVAL:
|
||||
case DBT_DEVICEREMOVECOMPLETE:
|
||||
if (((DEV_BROADCAST_HDR*)lParam)->dbch_devicetype == DBT_DEVTYP_DEVICEINTERFACE) {
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return DefWindowProc(hwnd, message, wParam, lParam);
|
||||
}
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
static void CallbackIOServiceFunc(void *context, io_iterator_t portIterator)
|
||||
{
|
||||
/* Must drain the iterator, or we won't receive new notifications */
|
||||
io_object_t entry;
|
||||
while ((entry = IOIteratorNext(portIterator)) != 0) {
|
||||
IOObjectRelease(entry);
|
||||
*(SDL_bool*)context = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
#endif /* __MACOSX__ */
|
||||
|
||||
#ifdef HAVE_INOTIFY
|
||||
#ifdef HAVE_INOTIFY_INIT1
|
||||
static int SDL_inotify_init1(void) {
|
||||
return inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
|
||||
}
|
||||
#else
|
||||
static int SDL_inotify_init1(void) {
|
||||
int fd = inotify_init();
|
||||
if (fd < 0) return -1;
|
||||
fcntl(fd, F_SETFL, O_NONBLOCK);
|
||||
fcntl(fd, F_SETFD, FD_CLOEXEC);
|
||||
return fd;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int
|
||||
StrHasPrefix(const char *string, const char *prefix)
|
||||
{
|
||||
return (SDL_strncmp(string, prefix, SDL_strlen(prefix)) == 0);
|
||||
}
|
||||
|
||||
static int
|
||||
StrIsInteger(const char *string)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
if (*string == '\0') {
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (p = string; *p != '\0'; p++) {
|
||||
if (*p < '0' || *p > '9') {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
static void
|
||||
HIDAPI_InitializeDiscovery()
|
||||
{
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_FALSE;
|
||||
SDL_HIDAPI_discovery.m_unLastDetect = 0;
|
||||
|
||||
#if defined(__WIN32__)
|
||||
SDL_HIDAPI_discovery.m_nThreadID = SDL_ThreadID();
|
||||
|
||||
SDL_zero(SDL_HIDAPI_discovery.m_wndClass);
|
||||
SDL_HIDAPI_discovery.m_wndClass.hInstance = GetModuleHandle(NULL);
|
||||
SDL_HIDAPI_discovery.m_wndClass.lpszClassName = "SDL_HIDAPI_DEVICE_DETECTION";
|
||||
SDL_HIDAPI_discovery.m_wndClass.lpfnWndProc = ControllerWndProc; /* This function is called by windows */
|
||||
SDL_HIDAPI_discovery.m_wndClass.cbSize = sizeof(WNDCLASSEX);
|
||||
|
||||
RegisterClassExA(&SDL_HIDAPI_discovery.m_wndClass);
|
||||
SDL_HIDAPI_discovery.m_hwndMsg = CreateWindowExA(0, "SDL_HIDAPI_DEVICE_DETECTION", NULL, 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL);
|
||||
|
||||
{
|
||||
DEV_BROADCAST_DEVICEINTERFACE_A devBroadcast;
|
||||
|
||||
SDL_zero(devBroadcast);
|
||||
devBroadcast.dbcc_size = sizeof( devBroadcast );
|
||||
devBroadcast.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
|
||||
devBroadcast.dbcc_classguid = GUID_DEVINTERFACE_USB_DEVICE;
|
||||
|
||||
/* DEVICE_NOTIFY_ALL_INTERFACE_CLASSES is important, makes GUID_DEVINTERFACE_USB_DEVICE ignored,
|
||||
* but that seems to be necessary to get a notice after each individual usb input device actually
|
||||
* installs, rather than just as the composite device is seen.
|
||||
*/
|
||||
SDL_HIDAPI_discovery.m_hNotify = RegisterDeviceNotification( SDL_HIDAPI_discovery.m_hwndMsg, &devBroadcast, DEVICE_NOTIFY_WINDOW_HANDLE | DEVICE_NOTIFY_ALL_INTERFACE_CLASSES );
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = ( SDL_HIDAPI_discovery.m_hNotify != 0 );
|
||||
}
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
SDL_HIDAPI_discovery.m_notificationPort = IONotificationPortCreate(kIOMasterPortDefault);
|
||||
if (SDL_HIDAPI_discovery.m_notificationPort) {
|
||||
{
|
||||
io_iterator_t portIterator = 0;
|
||||
io_object_t entry;
|
||||
IOReturn result = IOServiceAddMatchingNotification(
|
||||
SDL_HIDAPI_discovery.m_notificationPort,
|
||||
kIOFirstMatchNotification,
|
||||
IOServiceMatching(kIOHIDDeviceKey),
|
||||
CallbackIOServiceFunc, &SDL_HIDAPI_discovery.m_bHaveDevicesChanged, &portIterator);
|
||||
|
||||
if (result == 0) {
|
||||
/* Must drain the existing iterator, or we won't receive new notifications */
|
||||
while ((entry = IOIteratorNext(portIterator)) != 0) {
|
||||
IOObjectRelease(entry);
|
||||
}
|
||||
} else {
|
||||
IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort);
|
||||
SDL_HIDAPI_discovery.m_notificationPort = nil;
|
||||
}
|
||||
}
|
||||
{
|
||||
io_iterator_t portIterator = 0;
|
||||
io_object_t entry;
|
||||
IOReturn result = IOServiceAddMatchingNotification(
|
||||
SDL_HIDAPI_discovery.m_notificationPort,
|
||||
kIOTerminatedNotification,
|
||||
IOServiceMatching(kIOHIDDeviceKey),
|
||||
CallbackIOServiceFunc, &SDL_HIDAPI_discovery.m_bHaveDevicesChanged, &portIterator);
|
||||
|
||||
if (result == 0) {
|
||||
/* Must drain the existing iterator, or we won't receive new notifications */
|
||||
while ((entry = IOIteratorNext(portIterator)) != 0) {
|
||||
IOObjectRelease(entry);
|
||||
}
|
||||
} else {
|
||||
IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort);
|
||||
SDL_HIDAPI_discovery.m_notificationPort = nil;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SDL_HIDAPI_discovery.m_notificationMach = MACH_PORT_NULL;
|
||||
if (SDL_HIDAPI_discovery.m_notificationPort) {
|
||||
SDL_HIDAPI_discovery.m_notificationMach = IONotificationPortGetMachPort(SDL_HIDAPI_discovery.m_notificationPort);
|
||||
}
|
||||
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = (SDL_HIDAPI_discovery.m_notificationMach != MACH_PORT_NULL);
|
||||
|
||||
#endif // __MACOSX__
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
if (linux_enumeration_method == ENUMERATION_LIBUDEV) {
|
||||
SDL_HIDAPI_discovery.m_pUdev = NULL;
|
||||
SDL_HIDAPI_discovery.m_pUdevMonitor = NULL;
|
||||
SDL_HIDAPI_discovery.m_nUdevFd = -1;
|
||||
|
||||
usyms = SDL_UDEV_GetUdevSyms();
|
||||
if (usyms) {
|
||||
SDL_HIDAPI_discovery.m_pUdev = usyms->udev_new();
|
||||
}
|
||||
if (SDL_HIDAPI_discovery.m_pUdev) {
|
||||
SDL_HIDAPI_discovery.m_pUdevMonitor = usyms->udev_monitor_new_from_netlink(SDL_HIDAPI_discovery.m_pUdev, "udev");
|
||||
if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
|
||||
usyms->udev_monitor_enable_receiving(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
SDL_HIDAPI_discovery.m_nUdevFd = usyms->udev_monitor_get_fd(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
{
|
||||
#if defined(HAVE_INOTIFY)
|
||||
inotify_fd = SDL_inotify_init1();
|
||||
|
||||
if (inotify_fd < 0) {
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
|
||||
"Unable to initialize inotify, falling back to polling: %s",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
/* We need to watch for attribute changes in addition to
|
||||
* creation, because when a device is first created, it has
|
||||
* permissions that we can't read. When udev chmods it to
|
||||
* something that we maybe *can* read, we'll get an
|
||||
* IN_ATTRIB event to tell us. */
|
||||
if (inotify_add_watch(inotify_fd, "/dev",
|
||||
IN_CREATE | IN_DELETE | IN_MOVE | IN_ATTRIB) < 0) {
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
SDL_LogWarn(SDL_LOG_CATEGORY_INPUT,
|
||||
"Unable to add inotify watch, falling back to polling: %s",
|
||||
strerror (errno));
|
||||
return;
|
||||
}
|
||||
|
||||
SDL_HIDAPI_discovery.m_bCanGetNotifications = SDL_TRUE;
|
||||
#endif /* HAVE_INOTIFY */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_UpdateDiscovery()
|
||||
{
|
||||
if (!SDL_HIDAPI_discovery.m_bCanGetNotifications) {
|
||||
const Uint32 SDL_HIDAPI_DETECT_INTERVAL_MS = 3000; /* Update every 3 seconds */
|
||||
Uint32 now = SDL_GetTicks();
|
||||
if (!SDL_HIDAPI_discovery.m_unLastDetect || SDL_TICKS_PASSED(now, SDL_HIDAPI_discovery.m_unLastDetect + SDL_HIDAPI_DETECT_INTERVAL_MS)) {
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
SDL_HIDAPI_discovery.m_unLastDetect = now;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(__WIN32__)
|
||||
#if 0 /* just let the usual SDL_PumpEvents loop dispatch these, fixing bug 4286. --ryan. */
|
||||
/* We'll only get messages on the same thread that created the window */
|
||||
if (SDL_ThreadID() == SDL_HIDAPI_discovery.m_nThreadID) {
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0, PM_NOREMOVE)) {
|
||||
if (GetMessageA(&msg, SDL_HIDAPI_discovery.m_hwndMsg, 0, 0) != 0) {
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif /* __WIN32__ */
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
if (SDL_HIDAPI_discovery.m_notificationPort) {
|
||||
struct { mach_msg_header_t hdr; char payload[ 4096 ]; } msg;
|
||||
while (mach_msg(&msg.hdr, MACH_RCV_MSG | MACH_RCV_TIMEOUT, 0, sizeof(msg), SDL_HIDAPI_discovery.m_notificationMach, 0, MACH_PORT_NULL) == KERN_SUCCESS) {
|
||||
IODispatchCalloutFromMessage(NULL, &msg.hdr, SDL_HIDAPI_discovery.m_notificationPort);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
if (linux_enumeration_method == ENUMERATION_LIBUDEV) {
|
||||
if (SDL_HIDAPI_discovery.m_nUdevFd >= 0) {
|
||||
/* Drain all notification events.
|
||||
* We don't expect a lot of device notifications so just
|
||||
* do a new discovery on any kind or number of notifications.
|
||||
* This could be made more restrictive if necessary.
|
||||
*/
|
||||
for (;;) {
|
||||
struct pollfd PollUdev;
|
||||
struct udev_device *pUdevDevice;
|
||||
|
||||
PollUdev.fd = SDL_HIDAPI_discovery.m_nUdevFd;
|
||||
PollUdev.events = POLLIN;
|
||||
if (poll(&PollUdev, 1, 0) != 1) {
|
||||
break;
|
||||
}
|
||||
|
||||
pUdevDevice = usyms->udev_monitor_receive_device(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
if (pUdevDevice) {
|
||||
const char *action = NULL;
|
||||
action = usyms->udev_device_get_action(pUdevDevice);
|
||||
if (!action || SDL_strcmp(action, "add") == 0 || SDL_strcmp(action, "remove") == 0) {
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
}
|
||||
usyms->udev_device_unref(pUdevDevice);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
#endif /* SDL_USE_LIBUDEV */
|
||||
{
|
||||
#if defined(HAVE_INOTIFY)
|
||||
if (inotify_fd >= 0) {
|
||||
union
|
||||
{
|
||||
struct inotify_event event;
|
||||
char storage[4096];
|
||||
char enough_for_inotify[sizeof (struct inotify_event) + NAME_MAX + 1];
|
||||
} buf;
|
||||
ssize_t bytes;
|
||||
size_t remain = 0;
|
||||
size_t len;
|
||||
|
||||
bytes = read(inotify_fd, &buf, sizeof (buf));
|
||||
|
||||
if (bytes > 0) {
|
||||
remain = (size_t) bytes;
|
||||
}
|
||||
|
||||
while (remain > 0) {
|
||||
if (buf.event.len > 0 &&
|
||||
!SDL_HIDAPI_discovery.m_bHaveDevicesChanged) {
|
||||
if (StrHasPrefix(buf.event.name, "hidraw") &&
|
||||
StrIsInteger(buf.event.name + strlen ("hidraw"))) {
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_TRUE;
|
||||
/* We found an hidraw change. We still continue to
|
||||
* drain the inotify fd to avoid leaving old
|
||||
* notifications in the queue. */
|
||||
}
|
||||
}
|
||||
|
||||
len = sizeof (struct inotify_event) + buf.event.len;
|
||||
remain -= len;
|
||||
|
||||
if (remain != 0) {
|
||||
memmove(&buf.storage[0], &buf.storage[len], remain);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_INOTIFY */
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_ShutdownDiscovery()
|
||||
{
|
||||
#if defined(__WIN32__)
|
||||
if (SDL_HIDAPI_discovery.m_hNotify)
|
||||
UnregisterDeviceNotification(SDL_HIDAPI_discovery.m_hNotify);
|
||||
|
||||
if (SDL_HIDAPI_discovery.m_hwndMsg) {
|
||||
DestroyWindow(SDL_HIDAPI_discovery.m_hwndMsg);
|
||||
}
|
||||
|
||||
UnregisterClassA(SDL_HIDAPI_discovery.m_wndClass.lpszClassName, SDL_HIDAPI_discovery.m_wndClass.hInstance);
|
||||
#endif
|
||||
|
||||
#if defined(__MACOSX__)
|
||||
if (SDL_HIDAPI_discovery.m_notificationPort) {
|
||||
IONotificationPortDestroy(SDL_HIDAPI_discovery.m_notificationPort);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(SDL_USE_LIBUDEV)
|
||||
if (linux_enumeration_method == ENUMERATION_LIBUDEV &&
|
||||
usyms) {
|
||||
if (SDL_HIDAPI_discovery.m_pUdevMonitor) {
|
||||
usyms->udev_monitor_unref(SDL_HIDAPI_discovery.m_pUdevMonitor);
|
||||
}
|
||||
if (SDL_HIDAPI_discovery.m_pUdev) {
|
||||
usyms->udev_unref(SDL_HIDAPI_discovery.m_pUdev);
|
||||
}
|
||||
SDL_UDEV_ReleaseUdevSyms();
|
||||
usyms = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
HIDAPI_DumpPacket(const char *prefix, Uint8 *data, int size)
|
||||
{
|
||||
@@ -658,8 +201,7 @@ static void
|
||||
HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
if (device->driver) {
|
||||
/* Already setup */
|
||||
return;
|
||||
return; /* Already setup */
|
||||
}
|
||||
|
||||
device->driver = HIDAPI_GetDeviceDriver(device);
|
||||
@@ -681,8 +223,7 @@ static void
|
||||
HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
|
||||
{
|
||||
if (!device->driver) {
|
||||
/* Already cleaned up */
|
||||
return;
|
||||
return; /* Already cleaned up */
|
||||
}
|
||||
|
||||
/* Disconnect any joysticks */
|
||||
@@ -767,17 +308,7 @@ HIDAPI_JoystickInit(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(__MACOSX__) || defined(__IPHONEOS__) || defined(__TVOS__)
|
||||
/* The hidapi framwork is weak-linked on Apple platforms */
|
||||
int HID_API_EXPORT HID_API_CALL hid_init(void) __attribute__((weak_import));
|
||||
|
||||
if (hid_init == NULL) {
|
||||
SDL_SetError("Couldn't initialize hidapi, framework not available");
|
||||
return -1;
|
||||
}
|
||||
#endif /* __MACOSX__ || __IPHONEOS__ || __TVOS__ */
|
||||
|
||||
if (hid_init() < 0) {
|
||||
if (SDL_hid_init() < 0) {
|
||||
SDL_SetError("Couldn't initialize hidapi");
|
||||
return -1;
|
||||
}
|
||||
@@ -788,7 +319,6 @@ HIDAPI_JoystickInit(void)
|
||||
}
|
||||
SDL_AddHintCallback(SDL_HINT_JOYSTICK_HIDAPI,
|
||||
SDL_HIDAPIDriverHintChanged, NULL);
|
||||
HIDAPI_InitializeDiscovery();
|
||||
HIDAPI_JoystickDetect();
|
||||
HIDAPI_UpdateDevices();
|
||||
|
||||
@@ -863,10 +393,13 @@ HIDAPI_ConvertString(const wchar_t *wide_string)
|
||||
if (wide_string) {
|
||||
string = SDL_iconv_string("UTF-8", "WCHAR_T", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t));
|
||||
if (!string) {
|
||||
if (sizeof(wchar_t) == sizeof(Uint16)) {
|
||||
switch (sizeof(wchar_t)) {
|
||||
case 2:
|
||||
string = SDL_iconv_string("UTF-8", "UCS-2-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t));
|
||||
} else if (sizeof(wchar_t) == sizeof(Uint32)) {
|
||||
break;
|
||||
case 4:
|
||||
string = SDL_iconv_string("UTF-8", "UCS-4-INTERNAL", (char*)wide_string, (SDL_wcslen(wide_string)+1)*sizeof(wchar_t));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -874,7 +407,7 @@ HIDAPI_ConvertString(const wchar_t *wide_string)
|
||||
}
|
||||
|
||||
static void
|
||||
HIDAPI_AddDevice(struct hid_device_info *info)
|
||||
HIDAPI_AddDevice(struct SDL_hid_device_info *info)
|
||||
{
|
||||
SDL_HIDAPI_Device *device;
|
||||
SDL_HIDAPI_Device *curr, *last = NULL;
|
||||
@@ -1038,7 +571,7 @@ static void
|
||||
HIDAPI_UpdateDeviceList(void)
|
||||
{
|
||||
SDL_HIDAPI_Device *device;
|
||||
struct hid_device_info *devs, *info;
|
||||
struct SDL_hid_device_info *devs, *info;
|
||||
|
||||
SDL_LockJoysticks();
|
||||
|
||||
@@ -1051,7 +584,7 @@ HIDAPI_UpdateDeviceList(void)
|
||||
|
||||
/* Enumerate the devices */
|
||||
if (SDL_HIDAPI_numdrivers > 0) {
|
||||
devs = hid_enumerate(0, 0);
|
||||
devs = SDL_hid_enumerate(0, 0);
|
||||
if (devs) {
|
||||
for (info = devs; info; info = info->next) {
|
||||
device = HIDAPI_GetJoystickByInfo(info->path, info->vendor_id, info->product_id);
|
||||
@@ -1061,7 +594,7 @@ HIDAPI_UpdateDeviceList(void)
|
||||
HIDAPI_AddDevice(info);
|
||||
}
|
||||
}
|
||||
hid_free_enumeration(devs);
|
||||
SDL_hid_free_enumeration(devs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1202,11 +735,10 @@ static void
|
||||
HIDAPI_JoystickDetect(void)
|
||||
{
|
||||
if (SDL_AtomicTryLock(&SDL_HIDAPI_spinlock)) {
|
||||
HIDAPI_UpdateDiscovery();
|
||||
if (SDL_HIDAPI_discovery.m_bHaveDevicesChanged) {
|
||||
/* FIXME: We probably need to schedule an update in a few seconds as well */
|
||||
Uint32 count = SDL_hid_device_change_count();
|
||||
if (SDL_HIDAPI_change_count != count) {
|
||||
HIDAPI_UpdateDeviceList();
|
||||
SDL_HIDAPI_discovery.m_bHaveDevicesChanged = SDL_FALSE;
|
||||
SDL_HIDAPI_change_count = count;
|
||||
}
|
||||
SDL_AtomicUnlock(&SDL_HIDAPI_spinlock);
|
||||
}
|
||||
@@ -1363,15 +895,15 @@ HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16
|
||||
return result;
|
||||
}
|
||||
|
||||
static SDL_bool
|
||||
HIDAPI_JoystickHasLED(SDL_Joystick *joystick)
|
||||
static Uint32
|
||||
HIDAPI_JoystickGetCapabilities(SDL_Joystick *joystick)
|
||||
{
|
||||
SDL_bool result = SDL_FALSE;
|
||||
Uint32 result = 0;
|
||||
|
||||
if (joystick->hwdata) {
|
||||
SDL_HIDAPI_Device *device = joystick->hwdata->device;
|
||||
|
||||
result = device->driver->HasJoystickLED(device, joystick);
|
||||
result = device->driver->GetJoystickCapabilities(device, joystick);
|
||||
}
|
||||
|
||||
return result;
|
||||
@@ -1470,17 +1002,8 @@ HIDAPI_JoystickQuit(void)
|
||||
|
||||
shutting_down = SDL_TRUE;
|
||||
|
||||
HIDAPI_ShutdownDiscovery();
|
||||
|
||||
SDL_HIDAPI_QuitRumble();
|
||||
|
||||
#if defined(HAVE_INOTIFY)
|
||||
if (inotify_fd >= 0) {
|
||||
close(inotify_fd);
|
||||
inotify_fd = -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
while (SDL_HIDAPI_devices) {
|
||||
HIDAPI_DelDevice(SDL_HIDAPI_devices);
|
||||
}
|
||||
@@ -1495,7 +1018,7 @@ HIDAPI_JoystickQuit(void)
|
||||
SDL_DelHintCallback(SDL_HINT_JOYSTICK_HIDAPI,
|
||||
SDL_HIDAPIDriverHintChanged, NULL);
|
||||
|
||||
hid_exit();
|
||||
SDL_hid_exit();
|
||||
|
||||
shutting_down = SDL_FALSE;
|
||||
initialized = SDL_FALSE;
|
||||
@@ -1520,7 +1043,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
|
||||
HIDAPI_JoystickOpen,
|
||||
HIDAPI_JoystickRumble,
|
||||
HIDAPI_JoystickRumbleTriggers,
|
||||
HIDAPI_JoystickHasLED,
|
||||
HIDAPI_JoystickGetCapabilities,
|
||||
HIDAPI_JoystickSetLED,
|
||||
HIDAPI_JoystickSendEffect,
|
||||
HIDAPI_JoystickSetSensorsEnabled,
|
||||
|
@@ -27,7 +27,7 @@
|
||||
#include "SDL_mutex.h"
|
||||
#include "SDL_joystick.h"
|
||||
#include "SDL_gamecontroller.h"
|
||||
#include "../../hidapi/hidapi/hidapi.h"
|
||||
#include "SDL_hidapi.h"
|
||||
#include "../usb_ids.h"
|
||||
|
||||
/* This is the full set of HIDAPI drivers available */
|
||||
@@ -70,7 +70,7 @@ typedef struct _SDL_HIDAPI_Device
|
||||
struct _SDL_HIDAPI_DeviceDriver *driver;
|
||||
void *context;
|
||||
SDL_mutex *dev_lock;
|
||||
hid_device *dev;
|
||||
SDL_hid_device *dev;
|
||||
SDL_atomic_t rumble_pending;
|
||||
int num_joysticks;
|
||||
SDL_JoystickID *joysticks;
|
||||
@@ -88,6 +88,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
|
||||
{
|
||||
const char *hint;
|
||||
SDL_bool enabled;
|
||||
SDL_bool enabled_default;
|
||||
SDL_bool (*IsSupportedDevice)(const char *name, SDL_GameControllerType type, Uint16 vendor_id, Uint16 product_id, Uint16 version, int interface_number, int interface_class, int interface_subclass, int interface_protocol);
|
||||
const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id);
|
||||
SDL_bool (*InitDevice)(SDL_HIDAPI_Device *device);
|
||||
@@ -97,7 +98,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
|
||||
SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
|
||||
int (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
|
||||
int (*RumbleJoystickTriggers)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble);
|
||||
SDL_bool (*HasJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
|
||||
Uint32 (*GetJoystickCapabilities)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
|
||||
int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
|
||||
int (*SendJoystickEffect)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, const void *data, int size);
|
||||
int (*SetJoystickSensorsEnabled)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, SDL_bool enabled);
|
||||
|
@@ -23,6 +23,43 @@
|
||||
|
||||
#pragma pack(1)
|
||||
|
||||
#define HID_FEATURE_REPORT_BYTES 64
|
||||
|
||||
// Header for all host <==> target messages
|
||||
typedef struct
|
||||
{
|
||||
unsigned char type;
|
||||
unsigned char length;
|
||||
} FeatureReportHeader;
|
||||
|
||||
// Generic controller attribute structure
|
||||
typedef struct
|
||||
{
|
||||
unsigned char attributeTag;
|
||||
uint32_t attributeValue;
|
||||
} ControllerAttribute;
|
||||
|
||||
// Generic controller settings structure
|
||||
typedef struct
|
||||
{
|
||||
ControllerAttribute attributes[ ( HID_FEATURE_REPORT_BYTES - sizeof( FeatureReportHeader ) ) / sizeof( ControllerAttribute ) ];
|
||||
} MsgGetAttributes;
|
||||
|
||||
|
||||
// This is the only message struct that application code should use to interact with feature request messages. Any new
|
||||
// messages should be added to the union. The structures defined here should correspond to the ones defined in
|
||||
// ValveDeviceCore.cpp.
|
||||
//
|
||||
typedef struct
|
||||
{
|
||||
FeatureReportHeader header;
|
||||
union
|
||||
{
|
||||
MsgGetAttributes getAttributes;
|
||||
} payload;
|
||||
|
||||
} FeatureReportMsg;
|
||||
|
||||
// Roll this version forward anytime that you are breaking compatibility of existing
|
||||
// message types within ValveInReport_t or the header itself. Hopefully this should
|
||||
// be super rare and instead you shoudl just add new message payloads to the union,
|
||||
|
Reference in New Issue
Block a user