Added SDL_JoystickHasLED

Currently, this is only supported by the PS4 HIDAPI driver.
This commit is contained in:
Sam Lantinga 2020-11-05 11:07:54 -08:00
parent 83cddd2ebc
commit e555d45331
27 changed files with 278 additions and 75 deletions

View File

@ -404,6 +404,15 @@ extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *ga
*/ */
extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
/**
* Return whether a controller has an LED
*
* \param gamecontroller The controller to query
*
* \return SDL_TRUE, or SDL_FALSE if this controller does not have a modifiable LED
*/
extern DECLSPEC SDL_bool SDLCALL SDL_GameControllerHasLED(SDL_GameController *gamecontroller);
/** /**
* Update a controller's LED color. * Update a controller's LED color.
* *

View File

@ -432,6 +432,15 @@ extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick,
*/ */
extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms); extern DECLSPEC int SDLCALL SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);
/**
* Return whether a joystick has an LED
*
* \param joystick The joystick to query
*
* \return SDL_TRUE, or SDL_FALSE if this joystick does not have a modifiable LED
*/
extern DECLSPEC SDL_bool SDLCALL SDL_JoystickHasLED(SDL_Joystick * joystick);
/** /**
* Update a joystick's LED color. * Update a joystick's LED color.
* *

View File

@ -768,3 +768,7 @@
#define SDL_AndroidRequestPermission SDL_AndroidRequestPermission_REAL #define SDL_AndroidRequestPermission SDL_AndroidRequestPermission_REAL
#define SDL_OpenURL SDL_OpenURL_REAL #define SDL_OpenURL SDL_OpenURL_REAL
#define SDL_HasSurfaceRLE SDL_HasSurfaceRLE_REAL #define SDL_HasSurfaceRLE SDL_HasSurfaceRLE_REAL
#define SDL_GameControllerHasLED SDL_GameControllerHasLED_REAL
#define SDL_GameControllerSetLED SDL_GameControllerSetLED_REAL
#define SDL_JoystickHasLED SDL_JoystickHasLED_REAL
#define SDL_JoystickSetLED SDL_JoystickSetLED_REAL

View File

@ -829,3 +829,7 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_AndroidRequestPermission,(const char *a),(a),return
#endif #endif
SDL_DYNAPI_PROC(int,SDL_OpenURL,(const char *a),(a),return) SDL_DYNAPI_PROC(int,SDL_OpenURL,(const char *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_HasSurfaceRLE,(SDL_Surface *a),(a),return) SDL_DYNAPI_PROC(SDL_bool,SDL_HasSurfaceRLE,(SDL_Surface *a),(a),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasLED,(SDL_GameController *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_GameControllerSetLED,(SDL_GameController *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(SDL_bool,SDL_JoystickHasLED,(SDL_Joystick *a),(a),return)
SDL_DYNAPI_PROC(int,SDL_JoystickSetLED,(SDL_Joystick *a, Uint8 b, Uint8 c, Uint8 d),(a,b,c,d),return)

View File

@ -2107,6 +2107,12 @@ SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequenc
return SDL_JoystickRumble(SDL_GameControllerGetJoystick(gamecontroller), low_frequency_rumble, high_frequency_rumble, duration_ms); return SDL_JoystickRumble(SDL_GameControllerGetJoystick(gamecontroller), low_frequency_rumble, high_frequency_rumble, duration_ms);
} }
SDL_bool
SDL_GameControllerHasLED(SDL_GameController *gamecontroller)
{
return SDL_JoystickHasLED(SDL_GameControllerGetJoystick(gamecontroller));
}
int int
SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue) SDL_GameControllerSetLED(SDL_GameController *gamecontroller, Uint8 red, Uint8 green, Uint8 blue)
{ {

View File

@ -901,6 +901,24 @@ SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16
return result; return result;
} }
SDL_bool
SDL_JoystickHasLED(SDL_Joystick * joystick)
{
SDL_bool result;
if (!SDL_PrivateJoystickValid(joystick)) {
return SDL_FALSE;
}
SDL_LockJoysticks();
result = joystick->driver->HasLED(joystick);
SDL_UnlockJoysticks();
return result;
}
int int
SDL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) SDL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {

View File

@ -128,6 +128,7 @@ typedef struct _SDL_JoystickDriver
int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble); int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
/* LED functionality */ /* LED functionality */
SDL_bool (*HasLED)(SDL_Joystick * joystick);
int (*SetLED)(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue); int (*SetLED)(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue);
/* Function to update the state of a joystick - called as a device poll. /* Function to update the state of a joystick - called as a device poll.

View File

@ -633,6 +633,12 @@ ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin
return SDL_Unsupported(); return SDL_Unsupported();
} }
static SDL_bool
ANDROID_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int static int
ANDROID_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) ANDROID_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -717,6 +723,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickGetDeviceInstanceID, ANDROID_JoystickGetDeviceInstanceID,
ANDROID_JoystickOpen, ANDROID_JoystickOpen,
ANDROID_JoystickRumble, ANDROID_JoystickRumble,
ANDROID_JoystickHasLED,
ANDROID_JoystickSetLED, ANDROID_JoystickSetLED,
ANDROID_JoystickUpdate, ANDROID_JoystickUpdate,
ANDROID_JoystickClose, ANDROID_JoystickClose,

View File

@ -768,6 +768,12 @@ BSD_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
return SDL_FALSE; return SDL_FALSE;
} }
static SDL_bool
BSD_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int static int
BSD_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) BSD_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -786,6 +792,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
BSD_JoystickGetDeviceInstanceID, BSD_JoystickGetDeviceInstanceID,
BSD_JoystickOpen, BSD_JoystickOpen,
BSD_JoystickRumble, BSD_JoystickRumble,
BSD_JoystickHasLED,
BSD_JoystickSetLED, BSD_JoystickSetLED,
BSD_JoystickUpdate, BSD_JoystickUpdate,
BSD_JoystickClose, BSD_JoystickClose,

View File

@ -922,6 +922,12 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
return 0; return 0;
} }
static SDL_bool
DARWIN_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int static int
DARWIN_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) DARWIN_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -1075,6 +1081,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
DARWIN_JoystickGetDeviceInstanceID, DARWIN_JoystickGetDeviceInstanceID,
DARWIN_JoystickOpen, DARWIN_JoystickOpen,
DARWIN_JoystickRumble, DARWIN_JoystickRumble,
DARWIN_JoystickHasLED,
DARWIN_JoystickSetLED, DARWIN_JoystickSetLED,
DARWIN_JoystickUpdate, DARWIN_JoystickUpdate,
DARWIN_JoystickClose, DARWIN_JoystickClose,

View File

@ -89,6 +89,12 @@ DUMMY_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint1
return SDL_Unsupported(); return SDL_Unsupported();
} }
static SDL_bool
DUMMY_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int static int
DUMMY_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) DUMMY_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -128,6 +134,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
DUMMY_JoystickGetDeviceInstanceID, DUMMY_JoystickGetDeviceInstanceID,
DUMMY_JoystickOpen, DUMMY_JoystickOpen,
DUMMY_JoystickRumble, DUMMY_JoystickRumble,
DUMMY_JoystickHasLED,
DUMMY_JoystickSetLED, DUMMY_JoystickSetLED,
DUMMY_JoystickUpdate, DUMMY_JoystickUpdate,
DUMMY_JoystickClose, DUMMY_JoystickClose,

View File

@ -409,6 +409,12 @@ EMSCRIPTEN_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
return SDL_FALSE; return SDL_FALSE;
} }
static SDL_bool
EMSCRIPTEN_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int static int
EMSCRIPTEN_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) EMSCRIPTEN_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -427,6 +433,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
EMSCRIPTEN_JoystickGetDeviceInstanceID, EMSCRIPTEN_JoystickGetDeviceInstanceID,
EMSCRIPTEN_JoystickOpen, EMSCRIPTEN_JoystickOpen,
EMSCRIPTEN_JoystickRumble, EMSCRIPTEN_JoystickRumble,
EMSCRIPTEN_JoystickHasLED,
EMSCRIPTEN_JoystickSetLED, EMSCRIPTEN_JoystickSetLED,
EMSCRIPTEN_JoystickUpdate, EMSCRIPTEN_JoystickUpdate,
EMSCRIPTEN_JoystickClose, EMSCRIPTEN_JoystickClose,

View File

@ -265,6 +265,11 @@ extern "C"
return SDL_FALSE; return SDL_FALSE;
} }
static SDL_bool HAIKU_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int HAIKU_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) static int HAIKU_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
return SDL_Unsupported(); return SDL_Unsupported();
@ -282,6 +287,7 @@ extern "C"
HAIKU_JoystickGetDeviceInstanceID, HAIKU_JoystickGetDeviceInstanceID,
HAIKU_JoystickOpen, HAIKU_JoystickOpen,
HAIKU_JoystickRumble, HAIKU_JoystickRumble,
HAIKU_JoystickHasLED,
HAIKU_JoystickSetLED, HAIKU_JoystickSetLED,
HAIKU_JoystickUpdate, HAIKU_JoystickUpdate,
HAIKU_JoystickClose, HAIKU_JoystickClose,

View File

@ -363,6 +363,12 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
return -1; return -1;
} }
static SDL_bool
HIDAPI_DriverGameCube_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
return SDL_FALSE;
}
static int static int
HIDAPI_DriverGameCube_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) HIDAPI_DriverGameCube_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -408,6 +414,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
HIDAPI_DriverGameCube_UpdateDevice, HIDAPI_DriverGameCube_UpdateDevice,
HIDAPI_DriverGameCube_OpenJoystick, HIDAPI_DriverGameCube_OpenJoystick,
HIDAPI_DriverGameCube_RumbleJoystick, HIDAPI_DriverGameCube_RumbleJoystick,
HIDAPI_DriverGameCube_HasJoystickLED,
HIDAPI_DriverGameCube_SetJoystickLED, HIDAPI_DriverGameCube_SetJoystickLED,
HIDAPI_DriverGameCube_CloseJoystick, HIDAPI_DriverGameCube_CloseJoystick,
HIDAPI_DriverGameCube_FreeDevice, HIDAPI_DriverGameCube_FreeDevice,

View File

@ -102,7 +102,7 @@ typedef struct {
int player_index; int player_index;
Uint16 rumble_left; Uint16 rumble_left;
Uint16 rumble_right; Uint16 rumble_right;
Uint8 color_set; SDL_bool color_set;
Uint8 led_red; Uint8 led_red;
Uint8 led_green; Uint8 led_green;
Uint8 led_blue; Uint8 led_blue;
@ -365,12 +365,18 @@ HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
return 0; return 0;
} }
static SDL_bool
HIDAPI_DriverPS4_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
return SDL_TRUE;
}
static int static int
HIDAPI_DriverPS4_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) HIDAPI_DriverPS4_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context; SDL_DriverPS4_Context *ctx = (SDL_DriverPS4_Context *)device->context;
ctx->color_set = 1; ctx->color_set = SDL_TRUE;
ctx->led_red = red; ctx->led_red = red;
ctx->led_green = green; ctx->led_green = green;
ctx->led_blue = blue; ctx->led_blue = blue;
@ -564,6 +570,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
HIDAPI_DriverPS4_UpdateDevice, HIDAPI_DriverPS4_UpdateDevice,
HIDAPI_DriverPS4_OpenJoystick, HIDAPI_DriverPS4_OpenJoystick,
HIDAPI_DriverPS4_RumbleJoystick, HIDAPI_DriverPS4_RumbleJoystick,
HIDAPI_DriverPS4_HasJoystickLED,
HIDAPI_DriverPS4_SetJoystickLED, HIDAPI_DriverPS4_SetJoystickLED,
HIDAPI_DriverPS4_CloseJoystick, HIDAPI_DriverPS4_CloseJoystick,
HIDAPI_DriverPS4_FreeDevice, HIDAPI_DriverPS4_FreeDevice,

View File

@ -1034,6 +1034,13 @@ HIDAPI_DriverSteam_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joyst
return SDL_Unsupported(); return SDL_Unsupported();
} }
static SDL_bool
HIDAPI_DriverSteam_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
/* You should use the full Steam Input API for LED support */
return SDL_FALSE;
}
static int static int
HIDAPI_DriverSteam_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) HIDAPI_DriverSteam_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -1171,6 +1178,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSteam =
HIDAPI_DriverSteam_UpdateDevice, HIDAPI_DriverSteam_UpdateDevice,
HIDAPI_DriverSteam_OpenJoystick, HIDAPI_DriverSteam_OpenJoystick,
HIDAPI_DriverSteam_RumbleJoystick, HIDAPI_DriverSteam_RumbleJoystick,
HIDAPI_DriverSteam_HasJoystickLED,
HIDAPI_DriverSteam_SetJoystickLED, HIDAPI_DriverSteam_SetJoystickLED,
HIDAPI_DriverSteam_CloseJoystick, HIDAPI_DriverSteam_CloseJoystick,
HIDAPI_DriverSteam_FreeDevice, HIDAPI_DriverSteam_FreeDevice,

View File

@ -920,6 +920,13 @@ HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
return HIDAPI_DriverSwitch_ActuallyRumbleJoystick(ctx, low_frequency_rumble, high_frequency_rumble); return HIDAPI_DriverSwitch_ActuallyRumbleJoystick(ctx, low_frequency_rumble, high_frequency_rumble);
} }
static SDL_bool
HIDAPI_DriverSwitch_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
/* Doesn't have an RGB LED, so don't return true here */
return SDL_FALSE;
}
static int static int
HIDAPI_DriverSwitch_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) HIDAPI_DriverSwitch_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -1273,6 +1280,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
HIDAPI_DriverSwitch_UpdateDevice, HIDAPI_DriverSwitch_UpdateDevice,
HIDAPI_DriverSwitch_OpenJoystick, HIDAPI_DriverSwitch_OpenJoystick,
HIDAPI_DriverSwitch_RumbleJoystick, HIDAPI_DriverSwitch_RumbleJoystick,
HIDAPI_DriverSwitch_HasJoystickLED,
HIDAPI_DriverSwitch_SetJoystickLED, HIDAPI_DriverSwitch_SetJoystickLED,
HIDAPI_DriverSwitch_CloseJoystick, HIDAPI_DriverSwitch_CloseJoystick,
HIDAPI_DriverSwitch_FreeDevice, HIDAPI_DriverSwitch_FreeDevice,

View File

@ -796,6 +796,13 @@ HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
return 0; return 0;
} }
static SDL_bool
HIDAPI_DriverXbox360_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
/* Doesn't have an RGB LED, so don't return true here */
return SDL_FALSE;
}
static int static int
HIDAPI_DriverXbox360_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) HIDAPI_DriverXbox360_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -1308,6 +1315,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
HIDAPI_DriverXbox360_UpdateDevice, HIDAPI_DriverXbox360_UpdateDevice,
HIDAPI_DriverXbox360_OpenJoystick, HIDAPI_DriverXbox360_OpenJoystick,
HIDAPI_DriverXbox360_RumbleJoystick, HIDAPI_DriverXbox360_RumbleJoystick,
HIDAPI_DriverXbox360_HasJoystickLED,
HIDAPI_DriverXbox360_SetJoystickLED, HIDAPI_DriverXbox360_SetJoystickLED,
HIDAPI_DriverXbox360_CloseJoystick, HIDAPI_DriverXbox360_CloseJoystick,
HIDAPI_DriverXbox360_FreeDevice, HIDAPI_DriverXbox360_FreeDevice,

View File

@ -157,6 +157,13 @@ HIDAPI_DriverXbox360W_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
return 0; return 0;
} }
static SDL_bool
HIDAPI_DriverXbox360W_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
/* Doesn't have an RGB LED, so don't return true here */
return SDL_FALSE;
}
static int static int
HIDAPI_DriverXbox360W_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) HIDAPI_DriverXbox360W_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -300,6 +307,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360W =
HIDAPI_DriverXbox360W_UpdateDevice, HIDAPI_DriverXbox360W_UpdateDevice,
HIDAPI_DriverXbox360W_OpenJoystick, HIDAPI_DriverXbox360W_OpenJoystick,
HIDAPI_DriverXbox360W_RumbleJoystick, HIDAPI_DriverXbox360W_RumbleJoystick,
HIDAPI_DriverXbox360W_HasJoystickLED,
HIDAPI_DriverXbox360W_SetJoystickLED, HIDAPI_DriverXbox360W_SetJoystickLED,
HIDAPI_DriverXbox360W_CloseJoystick, HIDAPI_DriverXbox360W_CloseJoystick,
HIDAPI_DriverXbox360W_FreeDevice, HIDAPI_DriverXbox360W_FreeDevice,

View File

@ -364,6 +364,13 @@ HIDAPI_DriverXboxOne_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
return 0; return 0;
} }
static SDL_bool
HIDAPI_DriverXboxOne_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
/* Doesn't have an RGB LED, so don't return true here */
return SDL_FALSE;
}
static int static int
HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue) HIDAPI_DriverXboxOne_SetJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -836,6 +843,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXboxOne =
HIDAPI_DriverXboxOne_UpdateDevice, HIDAPI_DriverXboxOne_UpdateDevice,
HIDAPI_DriverXboxOne_OpenJoystick, HIDAPI_DriverXboxOne_OpenJoystick,
HIDAPI_DriverXboxOne_RumbleJoystick, HIDAPI_DriverXboxOne_RumbleJoystick,
HIDAPI_DriverXboxOne_HasJoystickLED,
HIDAPI_DriverXboxOne_SetJoystickLED, HIDAPI_DriverXboxOne_SetJoystickLED,
HIDAPI_DriverXboxOne_CloseJoystick, HIDAPI_DriverXboxOne_CloseJoystick,
HIDAPI_DriverXboxOne_FreeDevice, HIDAPI_DriverXboxOne_FreeDevice,

View File

@ -1048,6 +1048,20 @@ HIDAPI_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
return result; return result;
} }
static SDL_bool
HIDAPI_JoystickHasLED(SDL_Joystick * joystick)
{
SDL_bool result = SDL_FALSE;
if (joystick->hwdata) {
SDL_HIDAPI_Device *device = joystick->hwdata->device;
result = device->driver->HasJoystickLED(device, joystick);
}
return result;
}
static int static int
HIDAPI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) HIDAPI_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -1138,6 +1152,7 @@ SDL_JoystickDriver SDL_HIDAPI_JoystickDriver =
HIDAPI_JoystickGetDeviceInstanceID, HIDAPI_JoystickGetDeviceInstanceID,
HIDAPI_JoystickOpen, HIDAPI_JoystickOpen,
HIDAPI_JoystickRumble, HIDAPI_JoystickRumble,
HIDAPI_JoystickHasLED,
HIDAPI_JoystickSetLED, HIDAPI_JoystickSetLED,
HIDAPI_JoystickUpdate, HIDAPI_JoystickUpdate,
HIDAPI_JoystickClose, HIDAPI_JoystickClose,

View File

@ -94,6 +94,7 @@ typedef struct _SDL_HIDAPI_DeviceDriver
SDL_bool (*UpdateDevice)(SDL_HIDAPI_Device *device); SDL_bool (*UpdateDevice)(SDL_HIDAPI_Device *device);
SDL_bool (*OpenJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); 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 (*RumbleJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
SDL_bool (*HasJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue); int (*SetJoystickLED)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint8 red, Uint8 green, Uint8 blue);
void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick); void (*CloseJoystick)(SDL_HIDAPI_Device *device, SDL_Joystick *joystick);
void (*FreeDevice)(SDL_HIDAPI_Device *device); void (*FreeDevice)(SDL_HIDAPI_Device *device);

View File

@ -827,7 +827,7 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
@implementation SDL_RumbleMotor { @implementation SDL_RumbleMotor {
CHHapticEngine *engine API_AVAILABLE(ios(13.0), tvos(14.0)); CHHapticEngine *engine API_AVAILABLE(ios(13.0), tvos(14.0));
id<CHHapticPatternPlayer> player API_AVAILABLE(ios(13.0), tvos(14.0)); id<CHHapticPatternPlayer> player API_AVAILABLE(ios(13.0), tvos(14.0));
bool active; bool active;
} }
-(void)cleanup -(void)cleanup
@ -845,91 +845,91 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
-(int)setIntensity:(float)intensity -(int)setIntensity:(float)intensity
{ {
@autoreleasepool { @autoreleasepool {
if (@available(iOS 14.0, tvOS 14.0, *)) { if (@available(iOS 14.0, tvOS 14.0, *)) {
NSError *error; NSError *error;
if (self->engine == nil) { if (self->engine == nil) {
return SDL_SetError("Haptics engine was stopped"); return SDL_SetError("Haptics engine was stopped");
} }
if (intensity == 0.0f) { if (intensity == 0.0f) {
if (self->player && self->active) { if (self->player && self->active) {
[self->player stopAtTime:0 error:&error]; [self->player stopAtTime:0 error:&error];
} }
self->active = false; self->active = false;
return 0; return 0;
} }
if (self->player == nil) { if (self->player == nil) {
CHHapticEventParameter *param = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:1.0f]; CHHapticEventParameter *param = [[CHHapticEventParameter alloc] initWithParameterID:CHHapticEventParameterIDHapticIntensity value:1.0f];
CHHapticEvent *event = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObjects:param, nil] relativeTime:0 duration:GCHapticDurationInfinite]; CHHapticEvent *event = [[CHHapticEvent alloc] initWithEventType:CHHapticEventTypeHapticContinuous parameters:[NSArray arrayWithObjects:param, nil] relativeTime:0 duration:GCHapticDurationInfinite];
CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:event] parameters:[[NSArray alloc] init] error:&error]; CHHapticPattern *pattern = [[CHHapticPattern alloc] initWithEvents:[NSArray arrayWithObject:event] parameters:[[NSArray alloc] init] error:&error];
if (error != nil) { if (error != nil) {
return SDL_SetError("Couldn't create haptic pattern: %s", [error.localizedDescription UTF8String]); return SDL_SetError("Couldn't create haptic pattern: %s", [error.localizedDescription UTF8String]);
} }
self->player = [self->engine createPlayerWithPattern:pattern error:&error]; self->player = [self->engine createPlayerWithPattern:pattern error:&error];
if (error != nil) { if (error != nil) {
return SDL_SetError("Couldn't create haptic player: %s", [error.localizedDescription UTF8String]); return SDL_SetError("Couldn't create haptic player: %s", [error.localizedDescription UTF8String]);
} }
self->active = false; self->active = false;
} }
CHHapticDynamicParameter *param = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:intensity relativeTime:0]; CHHapticDynamicParameter *param = [[CHHapticDynamicParameter alloc] initWithParameterID:CHHapticDynamicParameterIDHapticIntensityControl value:intensity relativeTime:0];
[self->player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error]; [self->player sendParameters:[NSArray arrayWithObject:param] atTime:0 error:&error];
if (error != nil) { if (error != nil) {
return SDL_SetError("Couldn't update haptic player: %s", [error.localizedDescription UTF8String]); return SDL_SetError("Couldn't update haptic player: %s", [error.localizedDescription UTF8String]);
} }
if (!self->active) { if (!self->active) {
[self->player startAtTime:0 error:&error]; [self->player startAtTime:0 error:&error];
self->active = true; self->active = true;
} }
} }
return 0; return 0;
} }
} }
-(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(ios(14.0), tvos(14.0)) -(id) initWithController:(GCController*)controller locality:(GCHapticsLocality)locality API_AVAILABLE(ios(14.0), tvos(14.0))
{ {
@autoreleasepool { @autoreleasepool {
NSError *error; NSError *error;
self->engine = [controller.haptics createEngineWithLocality:locality]; self->engine = [controller.haptics createEngineWithLocality:locality];
if (self->engine == nil) { if (self->engine == nil) {
SDL_SetError("Couldn't create haptics engine"); SDL_SetError("Couldn't create haptics engine");
return nil; return nil;
} }
[self->engine startAndReturnError:&error]; [self->engine startAndReturnError:&error];
if (error != nil) { if (error != nil) {
SDL_SetError("Couldn't start haptics engine"); SDL_SetError("Couldn't start haptics engine");
return nil; return nil;
} }
__weak typeof(self) weakSelf = self; __weak typeof(self) weakSelf = self;
self->engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) { self->engine.stoppedHandler = ^(CHHapticEngineStoppedReason stoppedReason) {
SDL_RumbleMotor *_this = weakSelf; SDL_RumbleMotor *_this = weakSelf;
if (_this == nil) { if (_this == nil) {
return; return;
} }
_this->player = nil; _this->player = nil;
_this->engine = nil; _this->engine = nil;
}; };
self->engine.resetHandler = ^{ self->engine.resetHandler = ^{
SDL_RumbleMotor *_this = weakSelf; SDL_RumbleMotor *_this = weakSelf;
if (_this == nil) { if (_this == nil) {
return; return;
} }
_this->player = nil; _this->player = nil;
[_this->engine startAndReturnError:nil]; [_this->engine startAndReturnError:nil];
}; };
return self; return self;
} }
} }
@end @end
@ -960,8 +960,8 @@ IOS_MFIJoystickUpdate(SDL_Joystick * joystick)
-(void)cleanup -(void)cleanup
{ {
[self->low_frequency_motor cleanup]; [self->low_frequency_motor cleanup];
[self->high_frequency_motor cleanup]; [self->high_frequency_motor cleanup];
} }
@end @end
@ -1008,6 +1008,12 @@ IOS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16
#endif #endif
} }
static SDL_bool
IOS_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int static int
IOS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) IOS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -1044,9 +1050,9 @@ IOS_JoystickClose(SDL_Joystick * joystick)
@autoreleasepool { @autoreleasepool {
#ifdef ENABLE_MFI_RUMBLE #ifdef ENABLE_MFI_RUMBLE
if (device->rumble) { if (device->rumble) {
SDL_RumbleContext *rumble = (__bridge SDL_RumbleContext *)device->rumble; SDL_RumbleContext *rumble = (__bridge SDL_RumbleContext *)device->rumble;
[rumble cleanup]; [rumble cleanup];
CFRelease(device->rumble); CFRelease(device->rumble);
device->rumble = NULL; device->rumble = NULL;
} }
@ -1122,6 +1128,7 @@ SDL_JoystickDriver SDL_IOS_JoystickDriver =
IOS_JoystickGetDeviceInstanceID, IOS_JoystickGetDeviceInstanceID,
IOS_JoystickOpen, IOS_JoystickOpen,
IOS_JoystickRumble, IOS_JoystickRumble,
IOS_JoystickHasLED,
IOS_JoystickSetLED, IOS_JoystickSetLED,
IOS_JoystickUpdate, IOS_JoystickUpdate,
IOS_JoystickClose, IOS_JoystickClose,

View File

@ -891,6 +891,12 @@ LINUX_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint1
return 0; return 0;
} }
static SDL_bool
LINUX_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int static int
LINUX_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) LINUX_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -1372,6 +1378,7 @@ SDL_JoystickDriver SDL_LINUX_JoystickDriver =
LINUX_JoystickGetDeviceInstanceID, LINUX_JoystickGetDeviceInstanceID,
LINUX_JoystickOpen, LINUX_JoystickOpen,
LINUX_JoystickRumble, LINUX_JoystickRumble,
LINUX_JoystickHasLED,
LINUX_JoystickSetLED, LINUX_JoystickSetLED,
LINUX_JoystickUpdate, LINUX_JoystickUpdate,
LINUX_JoystickClose, LINUX_JoystickClose,

View File

@ -339,6 +339,13 @@ VIRTUAL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin
} }
static SDL_bool
VIRTUAL_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int static int
VIRTUAL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) VIRTUAL_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -416,6 +423,7 @@ SDL_JoystickDriver SDL_VIRTUAL_JoystickDriver =
VIRTUAL_JoystickGetDeviceInstanceID, VIRTUAL_JoystickGetDeviceInstanceID,
VIRTUAL_JoystickOpen, VIRTUAL_JoystickOpen,
VIRTUAL_JoystickRumble, VIRTUAL_JoystickRumble,
VIRTUAL_JoystickHasLED,
VIRTUAL_JoystickSetLED, VIRTUAL_JoystickSetLED,
VIRTUAL_JoystickUpdate, VIRTUAL_JoystickUpdate,
VIRTUAL_JoystickClose, VIRTUAL_JoystickClose,

View File

@ -500,6 +500,12 @@ WINDOWS_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin
} }
} }
static SDL_bool
WINDOWS_JoystickHasLED(SDL_Joystick * joystick)
{
return SDL_FALSE;
}
static int static int
WINDOWS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue) WINDOWS_JoystickSetLED(SDL_Joystick * joystick, Uint8 red, Uint8 green, Uint8 blue)
{ {
@ -589,6 +595,7 @@ SDL_JoystickDriver SDL_WINDOWS_JoystickDriver =
WINDOWS_JoystickGetDeviceInstanceID, WINDOWS_JoystickGetDeviceInstanceID,
WINDOWS_JoystickOpen, WINDOWS_JoystickOpen,
WINDOWS_JoystickRumble, WINDOWS_JoystickRumble,
WINDOWS_JoystickHasLED,
WINDOWS_JoystickSetLED, WINDOWS_JoystickSetLED,
WINDOWS_JoystickUpdate, WINDOWS_JoystickUpdate,
WINDOWS_JoystickClose, WINDOWS_JoystickClose,

View File

@ -193,6 +193,18 @@ loop(void *arg)
} }
} }
/* Update LED based on left thumbstick position */
{
Uint8 r, g, b;
Sint16 x = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_LEFTX);
Sint16 y = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_LEFTY);
r = (Uint8)((float)(((int)x + 32767) * 255) / 65535);
b = (Uint8)((float)(((int)y + 32767) * 255) / 65535);
g = (Uint8)((int)(r + b) / 2);
SDL_GameControllerSetLED(gamecontroller, r, g, b);
}
/* Update rumble based on trigger state */ /* Update rumble based on trigger state */
{ {
Uint16 low_frequency_rumble = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) * 2; Uint16 low_frequency_rumble = SDL_GameControllerGetAxis(gamecontroller, SDL_CONTROLLER_AXIS_TRIGGERLEFT) * 2;