early-access version 2847

This commit is contained in:
pineappleEA
2022-07-19 05:48:31 +02:00
parent ba74a2373c
commit 05e3c38e7f
498 changed files with 16027 additions and 27028 deletions

View File

@@ -53,7 +53,6 @@ typedef struct {
/* Without this variable, hid_write starts to lag a TON */
SDL_bool rumbleUpdate;
SDL_bool m_bUseButtonLabels;
SDL_bool useRumbleBrake;
} SDL_DriverGameCube_Context;
static SDL_bool
@@ -71,7 +70,7 @@ HIDAPI_DriverGameCube_IsSupportedDevice(const char *name, SDL_GameControllerType
}
static const char *
HIDAPI_DriverGameCube_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverGameCube_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Nintendo GameCube Controller";
}
@@ -93,14 +92,6 @@ static void SDLCALL SDL_GameControllerButtonReportingHintChanged(void *userdata,
ctx->m_bUseButtonLabels = SDL_GetStringBoolean(hint, SDL_TRUE);
}
static void SDLCALL SDL_JoystickGameCubeRumbleBrakeHintChanged(void *userdata, const char *name, const char *oldValue, const char *hint)
{
if (hint) {
SDL_DriverGameCube_Context *ctx = (SDL_DriverGameCube_Context *)userdata;
ctx->useRumbleBrake = SDL_GetStringBoolean(hint, SDL_FALSE);
}
}
static Uint8 RemapButton(SDL_DriverGameCube_Context *ctx, Uint8 button)
{
if (!ctx->m_bUseButtonLabels) {
@@ -151,7 +142,6 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
ctx->joysticks[2] = -1;
ctx->joysticks[3] = -1;
ctx->rumble[0] = rumbleMagic;
ctx->useRumbleBrake = SDL_FALSE;
if (device->vendor_id != USB_VENDOR_NINTENDO) {
ctx->pc_mode = SDL_TRUE;
@@ -205,8 +195,6 @@ HIDAPI_DriverGameCube_InitDevice(SDL_HIDAPI_Device *device)
}
}
SDL_AddHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE,
SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx);
SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
@@ -451,22 +439,12 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
for (i = 0; i < MAX_CONTROLLERS; i += 1) {
if (joystick->instance_id == ctx->joysticks[i]) {
if (ctx->wireless[i]) {
return SDL_SetError("Nintendo GameCube WaveBird controllers do not support rumble");
return SDL_SetError("Ninteno GameCube WaveBird controllers do not support rumble");
}
if (!ctx->rumbleAllowed[i]) {
return SDL_SetError("Second USB cable for WUP-028 not connected");
}
if (ctx->useRumbleBrake) {
if (low_frequency_rumble == 0 && high_frequency_rumble > 0) {
val = 0; /* if only low is 0 we want to do a regular stop*/
} else if (low_frequency_rumble == 0 && high_frequency_rumble == 0) {
val = 2; /* if both frequencies are 0 we want to do a hard stop */
} else {
val = 1; /* normal rumble */
}
} else {
val = (low_frequency_rumble > 0 || high_frequency_rumble > 0);
}
val = (low_frequency_rumble > 0 || high_frequency_rumble > 0);
if (val != ctx->rumble[i + 1]) {
ctx->rumble[i + 1] = val;
ctx->rumbleUpdate = SDL_TRUE;
@@ -476,7 +454,8 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
}
/* Should never get here! */
return SDL_SetError("Couldn't find joystick");
SDL_SetError("Couldn't find joystick");
return -1;
}
static int
@@ -544,8 +523,6 @@ HIDAPI_DriverGameCube_FreeDevice(SDL_HIDAPI_Device *device)
SDL_DelHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
SDL_DelHintCallback(SDL_HINT_JOYSTICK_GAMECUBE_RUMBLE_BRAKE,
SDL_JoystickGameCubeRumbleBrakeHintChanged, ctx);
SDL_LockMutex(device->dev_lock);
{

View File

@@ -54,7 +54,7 @@ HIDAPI_DriverLuna_IsSupportedDevice(const char *name, SDL_GameControllerType typ
}
static const char *
HIDAPI_DriverLuna_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverLuna_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Amazon Luna Controller";
}
@@ -267,16 +267,16 @@ HIDAPI_DriverLuna_HandleBluetoothStatePacket(SDL_Joystick *joystick, SDL_DriverL
/* Battery level report */
int level = data[1] * 100 / 0xFF;
if (level == 0) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
}
else if (level <= 20) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
}
else if (level <= 70) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
}
else {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
}
return;

View File

@@ -155,7 +155,7 @@ HIDAPI_DriverPS4_IsSupportedDevice(const char *name, SDL_GameControllerType type
}
static const char *
HIDAPI_DriverPS4_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverPS4_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
if (vendor_id == USB_VENDOR_SONY) {
return "PS4 Controller";
@@ -177,12 +177,6 @@ static SDL_bool HIDAPI_DriverPS4_CanRumble(Uint16 vendor_id, Uint16 product_id)
(product_id == USB_PRODUCT_RAZER_PANTHERA || product_id == USB_PRODUCT_RAZER_PANTHERA_EVO)) {
return SDL_FALSE;
}
/* The Victrix Pro FS v2 will hang on reboot if we send output reports */
if (vendor_id == USB_VENDOR_PDP && product_id == USB_PRODUCT_VICTRIX_FS_PRO_V2) {
return SDL_FALSE;
}
return SDL_TRUE;
}
@@ -801,18 +795,18 @@ HIDAPI_DriverPS4_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev,
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
if (packet->ucBatteryLevel & 0x10) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
} else {
/* Battery level ranges from 0 to 10 */
int level = (packet->ucBatteryLevel & 0xF);
if (level == 0) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
} else if (level <= 2) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
} else if (level <= 7) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
} else {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
}
}

View File

@@ -59,7 +59,6 @@ typedef enum
{
k_EPS5FeatureReportIdCalibration = 0x05,
k_EPS5FeatureReportIdSerialNumber = 0x09,
k_EPS5FeatureReportIdFirmwareInfo = 0x20,
} EPS5FeatureReportId;
typedef struct
@@ -185,7 +184,7 @@ HIDAPI_DriverPS5_IsSupportedDevice(const char *name, SDL_GameControllerType type
}
static const char *
HIDAPI_DriverPS5_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverPS5_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
if (vendor_id == USB_VENDOR_SONY) {
return "PS5 Controller";
@@ -602,13 +601,6 @@ HIDAPI_DriverPS5_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
data[6], data[5], data[4], data[3], data[2], data[1]);
joystick->serial = SDL_strdup(serial);
}
/* Read the firmware version
This will also enable enhanced reports over Bluetooth
*/
if (ReadFeatureReport(device->dev, k_EPS5FeatureReportIdFirmwareInfo, data, USB_PACKET_LENGTH) >= 46) {
joystick->firmware_version = (Uint16)data[44] | ((Uint16)data[45] << 8);
}
}
if (!joystick->serial && device->serial && SDL_strlen(device->serial) == 12) {
@@ -755,11 +747,7 @@ HIDAPI_DriverPS5_SendJoystickEffect(SDL_HIDAPI_Device *device, SDL_Joystick *joy
}
}
if (SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size) != report_size) {
return -1;
}
return 0;
return SDL_HIDAPI_SendRumbleAndUnlock(device, data, report_size);
}
static int
@@ -969,10 +957,7 @@ HIDAPI_DriverPS5_HandleStatePacket(SDL_Joystick *joystick, SDL_hid_device *dev,
axis = ((int)packet->ucRightJoystickY * 257) - 32768;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
/* A check of packet->ucBatteryLevel & 0x10 should work as a check for BT vs USB but doesn't
* seem to always work. Possibly related to being 100% charged?
*/
if (!ctx->is_bluetooth) {
if (packet->ucBatteryLevel & 0x10) {
/* 0x20 set means fully charged */
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
} else {

View File

@@ -53,7 +53,7 @@ typedef struct SDL_HIDAPI_RumbleContext
static SDL_HIDAPI_RumbleContext rumble_context;
static int SDLCALL SDL_HIDAPI_RumbleThread(void *data)
static int SDL_HIDAPI_RumbleThread(void *data)
{
SDL_HIDAPI_RumbleContext *ctx = (SDL_HIDAPI_RumbleContext *)data;

View File

@@ -55,7 +55,7 @@ HIDAPI_DriverStadia_IsSupportedDevice(const char *name, SDL_GameControllerType t
}
static const char *
HIDAPI_DriverStadia_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverStadia_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Google Stadia Controller";
}

View File

@@ -1004,7 +1004,7 @@ HIDAPI_DriverSteam_IsSupportedDevice(const char *name, SDL_GameControllerType ty
}
static const char *
HIDAPI_DriverSteam_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverSteam_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Steam Controller";
}

View File

@@ -63,11 +63,6 @@
#define SWITCH_GYRO_SCALE 14.2842f
#define SWITCH_ACCEL_SCALE 4096.f
#define SWITCH_GYRO_SCALE_OFFSET 13371.0f
#define SWITCH_GYRO_SCALE_MULT 936.0f
#define SWITCH_ACCEL_SCALE_OFFSET 16384.0f
#define SWITCH_ACCEL_SCALE_MULT 4.0f
typedef enum {
k_eSwitchInputReportIDs_SubcommandReply = 0x21,
k_eSwitchInputReportIDs_FullControllerState = 0x30,
@@ -119,14 +114,6 @@ typedef enum {
#define k_unSPIStickCalibrationEndOffset 0x604E
#define k_unSPIStickCalibrationLength (k_unSPIStickCalibrationEndOffset - k_unSPIStickCalibrationStartOffset + 1)
#define k_unSPIIMUScaleStartOffset 0x6020
#define k_unSPIIMUScaleEndOffset 0x6037
#define k_unSPIIMUScaleLength (k_unSPIIMUScaleEndOffset - k_unSPIIMUScaleStartOffset + 1)
#define k_unSPIIMUUserScaleStartOffset 0x8026
#define k_unSPIIMUUserScaleEndOffset 0x8039
#define k_unSPIIMUUserScaleLength (k_unSPIIMUUserScaleEndOffset - k_unSPIIMUUserScaleStartOffset + 1)
#pragma pack(1)
typedef struct
{
@@ -279,16 +266,6 @@ typedef struct {
Sint16 sMax;
} axis[2];
} m_StickExtents[2];
struct IMUScaleData {
float fAccelScaleX;
float fAccelScaleY;
float fAccelScaleZ;
float fGyroScaleX;
float fGyroScaleY;
float fGyroScaleZ;
} m_IMUScaleData;
} SDL_DriverSwitch_Context;
@@ -305,29 +282,9 @@ HasHomeLED(int vendor_id, int product_id)
return SDL_FALSE;
}
/* The Nintendo Online classic controllers don't have a Home LED */
if (vendor_id == USB_VENDOR_NINTENDO &&
(product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER ||
product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER ||
product_id == USB_PRODUCT_NINTENDO_SNES_CONTROLLER)) {
return SDL_FALSE;
}
return SDL_TRUE;
}
static SDL_bool
AlwaysUsesLabels(int vendor_id, int product_id)
{
/* These controllers don't have a diamond button configuration, so always use labels */
if (vendor_id == USB_VENDOR_NINTENDO &&
(product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER ||
product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER)) {
return SDL_TRUE;
}
return SDL_FALSE;
}
static SDL_bool
IsGameCubeFormFactor(int vendor_id, int product_id)
{
@@ -362,7 +319,7 @@ HIDAPI_DriverSwitch_IsSupportedDevice(const char *name, SDL_GameControllerType t
}
static const char *
HIDAPI_DriverSwitch_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverSwitch_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
/* Give a user friendly name for this controller */
if (vendor_id == USB_VENDOR_NINTENDO) {
@@ -375,24 +332,8 @@ HIDAPI_DriverSwitch_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 pro
}
if (product_id == USB_PRODUCT_NINTENDO_SWITCH_JOY_CON_RIGHT) {
/* Use the given name for the Nintendo Online NES Controllers */
if (SDL_strncmp(name, "NES Controller", 14) == 0) {
return name;
}
return "Nintendo Switch Joy-Con Right";
}
if (product_id == USB_PRODUCT_NINTENDO_N64_CONTROLLER) {
return "Nintendo N64 Controller";
}
if (product_id == USB_PRODUCT_NINTENDO_SEGA_GENESIS_CONTROLLER) {
return "Nintendo SEGA Genesis Controller";
}
if (product_id == USB_PRODUCT_NINTENDO_SNES_CONTROLLER) {
return "Nintendo SNES Controller";
}
}
return "Nintendo Switch Pro Controller";
@@ -828,72 +769,6 @@ static SDL_bool LoadStickCalibration(SDL_DriverSwitch_Context *ctx, Uint8 input_
return SDL_TRUE;
}
static SDL_bool LoadIMUCalibration(SDL_DriverSwitch_Context* ctx)
{
Uint8* pIMUScale;
SwitchSubcommandInputPacket_t* reply = NULL;
Sint16 sAccelRawX, sAccelRawY, sAccelRawZ, sGyroRawX, sGyroRawY, sGyroRawZ;
/* Read Calibration Info */
SwitchSPIOpData_t readParams;
readParams.unAddress = k_unSPIIMUScaleStartOffset;
readParams.ucLength = k_unSPIIMUScaleLength;
if (!WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t*)&readParams, sizeof(readParams), &reply)) {
const float accelScale = SDL_STANDARD_GRAVITY / SWITCH_ACCEL_SCALE;
const float gyroScale = (float)M_PI / 180.0f / SWITCH_GYRO_SCALE;
ctx->m_IMUScaleData.fAccelScaleX = accelScale;
ctx->m_IMUScaleData.fAccelScaleY = accelScale;
ctx->m_IMUScaleData.fAccelScaleZ = accelScale;
ctx->m_IMUScaleData.fGyroScaleX = gyroScale;
ctx->m_IMUScaleData.fGyroScaleY = gyroScale;
ctx->m_IMUScaleData.fGyroScaleZ = gyroScale;
return SDL_FALSE;
}
/* IMU scale gives us multipliers for converting raw values to real world values */
pIMUScale = reply->spiReadData.rgucReadData;
sAccelRawX = ((pIMUScale[1] << 8) & 0xF00) | pIMUScale[0];
sAccelRawY = ((pIMUScale[3] << 8) & 0xF00) | pIMUScale[2];
sAccelRawZ = ((pIMUScale[5] << 8) & 0xF00) | pIMUScale[4];
sGyroRawX = ((pIMUScale[13] << 8) & 0xF00) | pIMUScale[12];
sGyroRawY = ((pIMUScale[15] << 8) & 0xF00) | pIMUScale[14];
sGyroRawZ = ((pIMUScale[17] << 8) & 0xF00) | pIMUScale[16];
/* Check for user calibration data. If it's present and set, it'll override the factory settings */
readParams.unAddress = k_unSPIIMUUserScaleStartOffset;
readParams.ucLength = k_unSPIIMUUserScaleLength;
if (WriteSubcommand(ctx, k_eSwitchSubcommandIDs_SPIFlashRead, (uint8_t*)&readParams, sizeof(readParams), &reply) && (pIMUScale[0] | pIMUScale[1] << 8) == 0xA1B2) {
pIMUScale = reply->spiReadData.rgucReadData;
sAccelRawX = ((pIMUScale[3] << 8) & 0xF00) | pIMUScale[2];
sAccelRawY = ((pIMUScale[5] << 8) & 0xF00) | pIMUScale[4];
sAccelRawZ = ((pIMUScale[7] << 8) & 0xF00) | pIMUScale[6];
sGyroRawX = ((pIMUScale[15] << 8) & 0xF00) | pIMUScale[14];
sGyroRawY = ((pIMUScale[17] << 8) & 0xF00) | pIMUScale[16];
sGyroRawZ = ((pIMUScale[19] << 8) & 0xF00) | pIMUScale[18];
}
/* Accelerometer scale */
ctx->m_IMUScaleData.fAccelScaleX = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawX) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleY = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawY) * SDL_STANDARD_GRAVITY;
ctx->m_IMUScaleData.fAccelScaleZ = SWITCH_ACCEL_SCALE_MULT / (float)(SWITCH_ACCEL_SCALE_OFFSET - (float)sAccelRawZ) * SDL_STANDARD_GRAVITY;
/* Gyro scale */
ctx->m_IMUScaleData.fGyroScaleX = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawX) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleY = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawY) * (float)M_PI / 180.0f;
ctx->m_IMUScaleData.fGyroScaleZ = SWITCH_GYRO_SCALE_MULT / (float)(SWITCH_GYRO_SCALE_OFFSET - (float)sGyroRawZ) * (float)M_PI / 180.0f;
return SDL_TRUE;
}
static Sint16 ApplyStickCalibrationCentered(SDL_DriverSwitch_Context *ctx, int nStick, int nAxis, Sint16 sRawValue, Sint16 sCenter)
{
sRawValue -= sCenter;
@@ -1039,11 +914,6 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
goto error;
}
if (!LoadIMUCalibration(ctx)) {
SDL_SetError("Couldn't load sensor calibration");
goto error;
}
if (!SetVibrationEnabled(ctx, 1)) {
SDL_SetError("Couldn't enable vibration");
goto error;
@@ -1097,12 +967,8 @@ HIDAPI_DriverSwitch_OpenJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joysti
ctx->m_bIsGameCube = SDL_TRUE;
}
if (AlwaysUsesLabels(device->vendor_id, device->product_id)) {
ctx->m_bUseButtonLabels = SDL_TRUE;
} else {
SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
}
SDL_AddHintCallback(SDL_HINT_GAMECONTROLLER_USE_BUTTON_LABELS,
SDL_GameControllerButtonReportingHintChanged, ctx);
/* Initialize the joystick capabilities */
if (ctx->m_eControllerType == k_eSwitchDeviceInfoControllerType_JoyConLeft ||
@@ -1157,7 +1023,8 @@ HIDAPI_DriverSwitch_ActuallyRumbleJoystick(SDL_DriverSwitch_Context *ctx, Uint16
ctx->m_bRumbleActive = (low_frequency_rumble || high_frequency_rumble) ? SDL_TRUE : SDL_FALSE;
if (!WriteRumble(ctx)) {
return SDL_SetError("Couldn't send rumble packet");
SDL_SetError("Couldn't send rumble packet");
return -1;
}
return 0;
}
@@ -1280,6 +1147,20 @@ HIDAPI_DriverSwitch_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Joy
return 0;
}
static float
HIDAPI_DriverSwitch_ScaleGyro(Sint16 value)
{
float result = (value / SWITCH_GYRO_SCALE) * (float)M_PI / 180.0f;
return result;
}
static float
HIDAPI_DriverSwitch_ScaleAccel(Sint16 value)
{
float result = (value / SWITCH_ACCEL_SCALE) * SDL_STANDARD_GRAVITY;
return result;
}
static void HandleInputOnlyControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_Context *ctx, SwitchInputOnlyControllerStatePacket_t *packet)
{
Sint16 axis;
@@ -1477,13 +1358,13 @@ static void SendSensorUpdate(SDL_Joystick *joystick, SDL_DriverSwitch_Context *c
* users will want consistent axis mappings across devices.
*/
if (type == SDL_SENSOR_GYRO) {
data[0] = -(ctx->m_IMUScaleData.fGyroScaleY * (float)values[1]);
data[1] = ctx->m_IMUScaleData.fGyroScaleZ * (float)values[2];
data[2] = -(ctx->m_IMUScaleData.fGyroScaleX * (float)values[0]);
data[0] = -HIDAPI_DriverSwitch_ScaleGyro(values[1]);
data[1] = HIDAPI_DriverSwitch_ScaleGyro(values[2]);
data[2] = -HIDAPI_DriverSwitch_ScaleGyro(values[0]);
} else {
data[0] = -(ctx->m_IMUScaleData.fAccelScaleY * (float)values[1]);
data[1] = ctx->m_IMUScaleData.fAccelScaleZ * (float)values[2];
data[2] = -(ctx->m_IMUScaleData.fAccelScaleX * (float)values[0]);
data[0] = -HIDAPI_DriverSwitch_ScaleAccel(values[1]);
data[1] = HIDAPI_DriverSwitch_ScaleAccel(values[2]);
data[2] = -HIDAPI_DriverSwitch_ScaleAccel(values[0]);
}
/* Right Joy-Con flips some axes, so let's flip them back for consistency */
@@ -1560,20 +1441,20 @@ static void HandleFullControllerState(SDL_Joystick *joystick, SDL_DriverSwitch_C
* LSB of connection nibble is USB/Switch connection status
*/
if (packet->controllerState.ucBatteryAndConnection & 0x1) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_WIRED);
joystick->epowerlevel = SDL_JOYSTICK_POWER_WIRED;
} else {
/* LSB of the battery nibble is used to report charging.
* The battery level is reported from 0(empty)-8(full)
*/
int level = (packet->controllerState.ucBatteryAndConnection & 0xE0) >> 4;
if (level == 0) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
} else if (level <= 2) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
} else if (level <= 6) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
} else {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
}
}

View File

@@ -83,7 +83,7 @@ HIDAPI_DriverXbox360_IsSupportedDevice(const char *name, SDL_GameControllerType
}
static const char *
HIDAPI_DriverXbox360_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverXbox360_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return NULL;
}

View File

@@ -57,7 +57,7 @@ HIDAPI_DriverXbox360W_IsSupportedDevice(const char *name, SDL_GameControllerType
}
static const char *
HIDAPI_DriverXbox360W_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverXbox360W_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return "Xbox 360 Wireless Controller";
}
@@ -81,13 +81,13 @@ UpdatePowerLevel(SDL_Joystick *joystick, Uint8 level)
float normalized_level = (float)level / 255.0f;
if (normalized_level <= 0.05f) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_EMPTY);
joystick->epowerlevel = SDL_JOYSTICK_POWER_EMPTY;
} else if (normalized_level <= 0.20f) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_LOW);
joystick->epowerlevel = SDL_JOYSTICK_POWER_LOW;
} else if (normalized_level <= 0.70f) {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_MEDIUM);
joystick->epowerlevel = SDL_JOYSTICK_POWER_MEDIUM;
} else {
SDL_PrivateJoystickBatteryLevel(joystick, SDL_JOYSTICK_POWER_FULL);
joystick->epowerlevel = SDL_JOYSTICK_POWER_FULL;
}
}

View File

@@ -285,7 +285,7 @@ HIDAPI_DriverXboxOne_IsSupportedDevice(const char *name, SDL_GameControllerType
}
static const char *
HIDAPI_DriverXboxOne_GetDeviceName(const char *name, Uint16 vendor_id, Uint16 product_id)
HIDAPI_DriverXboxOne_GetDeviceName(Uint16 vendor_id, Uint16 product_id)
{
return NULL;
}
@@ -478,6 +478,30 @@ HIDAPI_DriverXboxOne_SetJoystickSensorsEnabled(SDL_HIDAPI_Device *device, SDL_Jo
return SDL_Unsupported();
}
static Sint16 FilterLeftThumb(Sint16 axis)
{
if (axis <= XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE && axis >= -XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE) {
return 0;
}
return axis;
}
static Sint16 FilterRightThumb(Sint16 axis)
{
if (axis <= XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE && axis >= -XINPUT_GAMEPAD_RIGHT_THUMB_DEADZONE) {
return 0;
}
return axis;
}
static Sint16 FilterTrigger(Sint16 axis)
{
if (axis <= XINPUT_GAMEPAD_TRIGGER_THRESHOLD) {
return 0;
}
return axis;
}
static void
HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne_Context *ctx, Uint8 *data, int size)
{
@@ -612,7 +636,7 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
if (axis == -32768 && size == 30 && (data[22] & 0x80) != 0) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, FilterTrigger(axis));
axis = ((int)*(Sint16*)(&data[8]) * 64) - 32768;
if (axis == -32768 && size == 30 && (data[22] & 0x40) != 0) {
@@ -621,16 +645,16 @@ HIDAPI_DriverXboxOne_HandleStatePacket(SDL_Joystick *joystick, SDL_DriverXboxOne
if (axis == 32704) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, FilterTrigger(axis));
axis = *(Sint16*)(&data[10]);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, FilterLeftThumb(axis));
axis = *(Sint16*)(&data[12]);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, ~axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, FilterLeftThumb(~axis));
axis = *(Sint16*)(&data[14]);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, FilterRightThumb(axis));
axis = *(Sint16*)(&data[16]);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, ~axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, FilterRightThumb(~axis));
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
}
@@ -830,22 +854,22 @@ HIDAPI_DriverXboxOneBluetooth_HandleStatePacket(SDL_Joystick *joystick, SDL_Driv
if (axis == 32704) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERLEFT, FilterTrigger(axis));
axis = ((int)*(Sint16*)(&data[11]) * 64) - 32768;
if (axis == 32704) {
axis = 32767;
}
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_TRIGGERRIGHT, FilterTrigger(axis));
axis = (int)*(Uint16*)(&data[1]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTX, FilterLeftThumb(axis));
axis = (int)*(Uint16*)(&data[3]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_LEFTY, FilterLeftThumb(axis));
axis = (int)*(Uint16*)(&data[5]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTX, FilterRightThumb(axis));
axis = (int)*(Uint16*)(&data[7]) - 0x8000;
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, axis);
SDL_PrivateJoystickAxis(joystick, SDL_CONTROLLER_AXIS_RIGHTY, FilterRightThumb(axis));
SDL_memcpy(ctx->last_state, data, SDL_min(size, sizeof(ctx->last_state)));
}

View File

@@ -110,96 +110,11 @@ HIDAPI_RemapVal(float val, float val_min, float val_max, float output_min, float
static void HIDAPI_JoystickDetect(void);
static void HIDAPI_JoystickClose(SDL_Joystick *joystick);
static SDL_GameControllerType
SDL_GetJoystickGameControllerProtocol(const char *name, Uint16 vendor, Uint16 product, int interface_number, int interface_class, int interface_subclass, int interface_protocol)
{
static const int LIBUSB_CLASS_VENDOR_SPEC = 0xFF;
static const int XB360_IFACE_SUBCLASS = 93;
static const int XB360_IFACE_PROTOCOL = 1; /* Wired */
static const int XB360W_IFACE_PROTOCOL = 129; /* Wireless */
static const int XBONE_IFACE_SUBCLASS = 71;
static const int XBONE_IFACE_PROTOCOL = 208;
SDL_GameControllerType type = SDL_CONTROLLER_TYPE_UNKNOWN;
/* This code should match the checks in libusb/hid.c and HIDDeviceManager.java */
if (interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
interface_subclass == XB360_IFACE_SUBCLASS &&
(interface_protocol == XB360_IFACE_PROTOCOL ||
interface_protocol == XB360W_IFACE_PROTOCOL)) {
static const int SUPPORTED_VENDORS[] = {
0x0079, /* GPD Win 2 */
0x044f, /* Thrustmaster */
0x045e, /* Microsoft */
0x046d, /* Logitech */
0x056e, /* Elecom */
0x06a3, /* Saitek */
0x0738, /* Mad Catz */
0x07ff, /* Mad Catz */
0x0e6f, /* PDP */
0x0f0d, /* Hori */
0x1038, /* SteelSeries */
0x11c9, /* Nacon */
0x12ab, /* Unknown */
0x1430, /* RedOctane */
0x146b, /* BigBen */
0x1532, /* Razer */
0x15e4, /* Numark */
0x162e, /* Joytech */
0x1689, /* Razer Onza */
0x1949, /* Lab126, Inc. */
0x1bad, /* Harmonix */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
0x2c22, /* Qanba */
};
int i;
for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
if (vendor == SUPPORTED_VENDORS[i]) {
type = SDL_CONTROLLER_TYPE_XBOX360;
break;
}
}
}
if (interface_number == 0 &&
interface_class == LIBUSB_CLASS_VENDOR_SPEC &&
interface_subclass == XBONE_IFACE_SUBCLASS &&
interface_protocol == XBONE_IFACE_PROTOCOL) {
static const int SUPPORTED_VENDORS[] = {
0x045e, /* Microsoft */
0x0738, /* Mad Catz */
0x0e6f, /* PDP */
0x0f0d, /* Hori */
0x1532, /* Razer */
0x20d6, /* PowerA */
0x24c6, /* PowerA */
0x2e24, /* Hyperkin */
};
int i;
for (i = 0; i < SDL_arraysize(SUPPORTED_VENDORS); ++i) {
if (vendor == SUPPORTED_VENDORS[i]) {
type = SDL_CONTROLLER_TYPE_XBOXONE;
break;
}
}
}
if (type == SDL_CONTROLLER_TYPE_UNKNOWN) {
type = SDL_GetJoystickGameControllerTypeFromVIDPID(vendor, product, name, SDL_FALSE);
}
return type;
}
static SDL_bool
HIDAPI_IsDeviceSupported(Uint16 vendor_id, Uint16 product_id, Uint16 version, const char *name)
{
int i;
SDL_GameControllerType type = SDL_GetJoystickGameControllerProtocol(name, vendor_id, product_id, -1, 0, 0, 0);
SDL_GameControllerType type = SDL_GetJoystickGameControllerType(name, vendor_id, product_id, -1, 0, 0, 0);
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
@@ -219,8 +134,14 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device)
const Uint16 USAGE_MULTIAXISCONTROLLER = 0x0008;
int i;
SDL_GameControllerType type;
SDL_JoystickGUID check_guid;
if (SDL_ShouldIgnoreJoystick(device->name, device->guid)) {
/* Make sure we have a generic GUID here, otherwise if we pass a HIDAPI
guid, this call will create a game controller mapping for the device.
*/
check_guid = device->guid;
check_guid.data[14] = 0;
if (SDL_ShouldIgnoreJoystick(device->name, check_guid)) {
return NULL;
}
@@ -233,7 +154,7 @@ HIDAPI_GetDeviceDriver(SDL_HIDAPI_Device *device)
}
}
type = SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
type = SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
SDL_HIDAPI_DeviceDriver *driver = SDL_HIDAPI_drivers[i];
if (driver->enabled && driver->IsSupportedDevice(device->name, type, device->vendor_id, device->product_id, device->version, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol)) {
@@ -285,8 +206,8 @@ HIDAPI_SetupDeviceDriver(SDL_HIDAPI_Device *device)
device->driver = HIDAPI_GetDeviceDriver(device);
if (device->driver) {
const char *name = device->driver->GetDeviceName(device->name, device->vendor_id, device->product_id);
if (name && name != device->name) {
const char *name = device->driver->GetDeviceName(device->vendor_id, device->product_id);
if (name) {
SDL_free(device->name);
device->name = SDL_strdup(name);
}
@@ -306,7 +227,7 @@ HIDAPI_CleanupDeviceDriver(SDL_HIDAPI_Device *device)
}
/* Disconnect any joysticks */
while (device->num_joysticks && device->joysticks) {
while (device->num_joysticks) {
HIDAPI_JoystickDisconnected(device, device->joysticks[0]);
}
@@ -388,7 +309,8 @@ HIDAPI_JoystickInit(void)
#endif
if (SDL_hid_init() < 0) {
return SDL_SetError("Couldn't initialize hidapi");
SDL_SetError("Couldn't initialize hidapi");
return -1;
}
for (i = 0; i < SDL_arraysize(SDL_HIDAPI_drivers); ++i) {
@@ -542,6 +464,38 @@ HIDAPI_AddDevice(struct SDL_hid_device_info *info)
char *serial_number = HIDAPI_ConvertString(info->serial_number);
device->name = SDL_CreateJoystickName(device->vendor_id, device->product_id, manufacturer_string, product_string);
if (SDL_strncmp(device->name, "0x", 2) == 0) {
/* Couldn't find a controller name, try to give it one based on device type */
const char *name = NULL;
switch (SDL_GetJoystickGameControllerType(NULL, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol)) {
case SDL_CONTROLLER_TYPE_XBOX360:
name = "Xbox 360 Controller";
break;
case SDL_CONTROLLER_TYPE_XBOXONE:
name = "Xbox One Controller";
break;
case SDL_CONTROLLER_TYPE_PS3:
name = "PS3 Controller";
break;
case SDL_CONTROLLER_TYPE_PS4:
name = "PS4 Controller";
break;
case SDL_CONTROLLER_TYPE_PS5:
name = "PS5 Controller";
break;
case SDL_CONTROLLER_TYPE_NINTENDO_SWITCH_PRO:
name = "Nintendo Switch Pro Controller";
break;
default:
break;
}
if (name) {
SDL_free(device->name);
device->name = SDL_strdup(name);
}
}
if (manufacturer_string) {
SDL_free(manufacturer_string);
@@ -674,13 +628,13 @@ HIDAPI_IsEquivalentToDevice(Uint16 vendor_id, Uint16 product_id, SDL_HIDAPI_Devi
/* If we're looking for the raw input Xbox One controller, match it against any other Xbox One controller */
if (product_id == USB_PRODUCT_XBOX_ONE_XBOXGIP_CONTROLLER &&
SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == SDL_CONTROLLER_TYPE_XBOXONE) {
SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == SDL_CONTROLLER_TYPE_XBOXONE) {
return SDL_TRUE;
}
/* If we're looking for an XInput controller, match it against any other Xbox controller */
if (product_id == USB_PRODUCT_XBOX_ONE_XINPUT_CONTROLLER) {
SDL_GameControllerType type = SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
SDL_GameControllerType type = SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol);
if (type == SDL_CONTROLLER_TYPE_XBOX360 || type == SDL_CONTROLLER_TYPE_XBOXONE) {
return SDL_TRUE;
}
@@ -709,7 +663,7 @@ HIDAPI_IsDeviceTypePresent(SDL_GameControllerType type)
device = SDL_HIDAPI_devices;
while (device) {
if (device->driver &&
SDL_GetJoystickGameControllerProtocol(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == type) {
SDL_GetJoystickGameControllerType(device->name, device->vendor_id, device->product_id, device->interface_number, device->interface_class, device->interface_subclass, device->interface_protocol) == type) {
result = SDL_TRUE;
break;
}
@@ -830,21 +784,6 @@ HIDAPI_JoystickGetDeviceName(int device_index)
return name;
}
static const char *
HIDAPI_JoystickGetDevicePath(int device_index)
{
SDL_HIDAPI_Device *device;
const char *path = NULL;
device = HIDAPI_GetDeviceByIndex(device_index, NULL);
if (device) {
/* FIXME: The device could be freed after this path is returned... */
path = device->path;
}
return path;
}
static int
HIDAPI_JoystickGetDevicePlayerIndex(int device_index)
{
@@ -932,7 +871,8 @@ HIDAPI_JoystickRumble(SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint1
result = device->driver->RumbleJoystick(device, joystick, low_frequency_rumble, high_frequency_rumble);
} else {
result = SDL_SetError("Rumble failed, device disconnected");
SDL_SetError("Rumble failed, device disconnected");
result = -1;
}
return result;
@@ -948,7 +888,8 @@ HIDAPI_JoystickRumbleTriggers(SDL_Joystick *joystick, Uint16 left_rumble, Uint16
result = device->driver->RumbleJoystickTriggers(device, joystick, left_rumble, right_rumble);
} else {
result = SDL_SetError("Rumble failed, device disconnected");
SDL_SetError("Rumble failed, device disconnected");
result = -1;
}
return result;
@@ -978,7 +919,8 @@ HIDAPI_JoystickSetLED(SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue
result = device->driver->SetJoystickLED(device, joystick, red, green, blue);
} else {
result = SDL_SetError("SetLED failed, device disconnected");
SDL_SetError("SetLED failed, device disconnected");
result = -1;
}
return result;
@@ -994,7 +936,8 @@ HIDAPI_JoystickSendEffect(SDL_Joystick *joystick, const void *data, int size)
result = device->driver->SendJoystickEffect(device, joystick, data, size);
} else {
result = SDL_SetError("SendEffect failed, device disconnected");
SDL_SetError("SendEffect failed, device disconnected");
result = -1;
}
return result;
@@ -1010,7 +953,8 @@ HIDAPI_JoystickSetSensorsEnabled(SDL_Joystick *joystick, SDL_bool enabled)
result = device->driver->SetJoystickSensorsEnabled(device, joystick, enabled);
} else {
result = SDL_SetError("SetSensorsEnabled failed, device disconnected");
SDL_SetError("SetSensorsEnabled failed, device disconnected");
result = -1;
}
return result;
@@ -1092,7 +1036,6 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
HIDAPI_JoystickGetCount,
HIDAPI_JoystickDetect,
HIDAPI_JoystickGetDeviceName,
HIDAPI_JoystickGetDevicePath,
HIDAPI_JoystickGetDevicePlayerIndex,
HIDAPI_JoystickSetDevicePlayerIndex,
HIDAPI_JoystickGetDeviceGUID,

View File

@@ -90,7 +90,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
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)(const char *name, Uint16 vendor_id, Uint16 product_id);
const char *(*GetDeviceName)(Uint16 vendor_id, Uint16 product_id);
SDL_bool (*InitDevice)(SDL_HIDAPI_Device *device);
int (*GetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id);
void (*SetDevicePlayerIndex)(SDL_HIDAPI_Device *device, SDL_JoystickID instance_id, int player_index);