Skip to content

Commit

Permalink
Added SDL_JoystickRumbleTriggers() and SDL_GameControllerRumbleTrigge…
Browse files Browse the repository at this point in the history
…rs()
  • Loading branch information
slouken committed Nov 12, 2020
1 parent 067630a commit 1e2caac
Show file tree
Hide file tree
Showing 28 changed files with 326 additions and 10 deletions.
17 changes: 15 additions & 2 deletions include/SDL_gamecontroller.h
Expand Up @@ -398,18 +398,31 @@ extern DECLSPEC Uint8 SDLCALL SDL_GameControllerGetButton(SDL_GameController *ga
SDL_GameControllerButton button);

/**
* Trigger a rumble effect
* Start a rumble effect
* Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
*
* \param gamecontroller The controller to vibrate
* \param low_frequency_rumble The intensity of the low frequency (left) rumble motor, from 0 to 0xFFFF
* \param high_frequency_rumble The intensity of the high frequency (right) rumble motor, from 0 to 0xFFFF
* \param duration_ms The duration of the rumble effect, in milliseconds
*
* \return 0, or -1 if rumble isn't supported on this joystick
* \return 0, or -1 if rumble isn't supported on this controller
*/
extern DECLSPEC int SDLCALL SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble, Uint32 duration_ms);

/**
* Start a rumble effect in the game controller's triggers
* Each call to this function cancels any previous trigger rumble effect, and calling it with 0 intensity stops any rumbling.
*
* \param gamecontroller The controller to vibrate
* \param left_rumble The intensity of the left trigger rumble motor, from 0 to 0xFFFF
* \param right_rumble The intensity of the right trigger rumble motor, from 0 to 0xFFFF
* \param duration_ms The duration of the rumble effect, in milliseconds
*
* \return 0, or -1 if rumble isn't supported on this controller
*/
extern DECLSPEC int SDLCALL SDL_GameControllerRumbleTriggers(SDL_GameController *gamecontroller, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms);

/**
* Return whether a controller has an LED
*
Expand Down
15 changes: 14 additions & 1 deletion include/SDL_joystick.h
Expand Up @@ -420,7 +420,7 @@ extern DECLSPEC Uint8 SDLCALL SDL_JoystickGetButton(SDL_Joystick * joystick,
int button);

/**
* Trigger a rumble effect
* Start a rumble effect
* Each call to this function cancels any previous rumble effect, and calling it with 0 intensity stops any rumbling.
*
* \param joystick The joystick to vibrate
Expand All @@ -432,6 +432,19 @@ 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);

/**
* Start a rumble effect in the joystick's triggers
* Each call to this function cancels any previous trigger rumble effect, and calling it with 0 intensity stops any rumbling.
*
* \param joystick The joystick to vibrate
* \param left_rumble The intensity of the left trigger rumble motor, from 0 to 0xFFFF
* \param right_rumble The intensity of the right trigger rumble motor, from 0 to 0xFFFF
* \param duration_ms The duration of the rumble effect, in milliseconds
*
* \return 0, or -1 if trigger rumble isn't supported on this joystick
*/
extern DECLSPEC int SDLCALL SDL_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms);

/**
* Return whether a joystick has an LED
*
Expand Down
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_overrides.h
Expand Up @@ -772,3 +772,5 @@
#define SDL_GameControllerSetLED SDL_GameControllerSetLED_REAL
#define SDL_JoystickHasLED SDL_JoystickHasLED_REAL
#define SDL_JoystickSetLED SDL_JoystickSetLED_REAL
#define SDL_GameControllerRumbleTriggers SDL_GameControllerRumbleTriggers_REAL
#define SDL_JoystickRumbleTriggers SDL_JoystickRumbleTriggers_REAL
2 changes: 2 additions & 0 deletions src/dynapi/SDL_dynapi_procs.h
Expand Up @@ -833,3 +833,5 @@ SDL_DYNAPI_PROC(SDL_bool,SDL_GameControllerHasLED,(SDL_GameController *a),(a),re
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)
SDL_DYNAPI_PROC(int,SDL_GameControllerRumbleTriggers,(SDL_GameController *a, Uint16 b, Uint16 c, Uint32 d),(a,b,c,d),return)
SDL_DYNAPI_PROC(int,SDL_JoystickRumbleTriggers,(SDL_Joystick *a, Uint16 b, Uint16 c, Uint32 d),(a,b,c,d),return)
6 changes: 6 additions & 0 deletions src/joystick/SDL_gamecontroller.c
Expand Up @@ -2151,6 +2151,12 @@ SDL_GameControllerRumble(SDL_GameController *gamecontroller, Uint16 low_frequenc
return SDL_JoystickRumble(SDL_GameControllerGetJoystick(gamecontroller), low_frequency_rumble, high_frequency_rumble, duration_ms);
}

int
SDL_GameControllerRumbleTriggers(SDL_GameController *gamecontroller, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms)
{
return SDL_JoystickRumbleTriggers(SDL_GameControllerGetJoystick(gamecontroller), left_rumble, right_rumble, duration_ms);
}

SDL_bool
SDL_GameControllerHasLED(SDL_GameController *gamecontroller)
{
Expand Down
47 changes: 47 additions & 0 deletions src/joystick/SDL_joystick.c
Expand Up @@ -901,6 +901,40 @@ SDL_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16
return result;
}

int
SDL_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble, Uint32 duration_ms)
{
int result;

if (!SDL_PrivateJoystickValid(joystick)) {
return -1;
}

SDL_LockJoysticks();
if (left_rumble == joystick->left_trigger_rumble && right_rumble == joystick->right_trigger_rumble) {
/* Just update the expiration */
result = 0;
} else {
result = joystick->driver->RumbleTriggers(joystick, left_rumble, right_rumble);
}

/* Save the rumble value regardless of success, so we don't spam the driver */
joystick->left_trigger_rumble = left_rumble;
joystick->right_trigger_rumble = right_rumble;

if ((left_rumble || right_rumble) && duration_ms) {
joystick->trigger_rumble_expiration = SDL_GetTicks() + SDL_min(duration_ms, SDL_MAX_RUMBLE_DURATION_MS);
if (!joystick->trigger_rumble_expiration) {
joystick->trigger_rumble_expiration = 1;
}
} else {
joystick->trigger_rumble_expiration = 0;
}
SDL_UnlockJoysticks();

return result;
}

SDL_bool
SDL_JoystickHasLED(SDL_Joystick * joystick)
{
Expand Down Expand Up @@ -978,6 +1012,9 @@ SDL_JoystickClose(SDL_Joystick * joystick)
if (joystick->rumble_expiration) {
SDL_JoystickRumble(joystick, 0, 0, 0);
}
if (joystick->trigger_rumble_expiration) {
SDL_JoystickRumbleTriggers(joystick, 0, 0, 0);
}

joystick->driver->Close(joystick);
joystick->hwdata = NULL;
Expand Down Expand Up @@ -1437,6 +1474,16 @@ SDL_JoystickUpdate(void)
}
SDL_UnlockJoysticks();
}

if (joystick->trigger_rumble_expiration) {
SDL_LockJoysticks();
/* Double check now that the lock is held */
if (joystick->trigger_rumble_expiration &&
SDL_TICKS_PASSED(SDL_GetTicks(), joystick->trigger_rumble_expiration)) {
SDL_JoystickRumbleTriggers(joystick, 0, 0, 0);
}
SDL_UnlockJoysticks();
}
}

SDL_LockJoysticks();
Expand Down
5 changes: 5 additions & 0 deletions src/joystick/SDL_sysjoystick.h
Expand Up @@ -64,6 +64,10 @@ struct _SDL_Joystick
Uint16 high_frequency_rumble;
Uint32 rumble_expiration;

Uint16 left_trigger_rumble;
Uint16 right_trigger_rumble;
Uint32 trigger_rumble_expiration;

Uint8 led_red;
Uint8 led_green;
Uint8 led_blue;
Expand Down Expand Up @@ -126,6 +130,7 @@ typedef struct _SDL_JoystickDriver

/* Rumble functionality */
int (*Rumble)(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16 high_frequency_rumble);
int (*RumbleTriggers)(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble);

/* LED functionality */
SDL_bool (*HasLED)(SDL_Joystick * joystick);
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/android/SDL_sysjoystick.c
Expand Up @@ -633,6 +633,12 @@ ANDROID_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uin
return SDL_Unsupported();
}

static int
ANDROID_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
ANDROID_JoystickHasLED(SDL_Joystick * joystick)
{
Expand Down Expand Up @@ -723,6 +729,7 @@ SDL_JoystickDriver SDL_ANDROID_JoystickDriver =
ANDROID_JoystickGetDeviceInstanceID,
ANDROID_JoystickOpen,
ANDROID_JoystickRumble,
ANDROID_JoystickRumbleTriggers,
ANDROID_JoystickHasLED,
ANDROID_JoystickSetLED,
ANDROID_JoystickUpdate,
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/bsd/SDL_sysjoystick.c
Expand Up @@ -762,6 +762,12 @@ BSD_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint16
return SDL_Unsupported();
}

static int
BSD_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
BSD_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
{
Expand Down Expand Up @@ -792,6 +798,7 @@ SDL_JoystickDriver SDL_BSD_JoystickDriver =
BSD_JoystickGetDeviceInstanceID,
BSD_JoystickOpen,
BSD_JoystickRumble,
BSD_JoystickRumbleTriggers,
BSD_JoystickHasLED,
BSD_JoystickSetLED,
BSD_JoystickUpdate,
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/darwin/SDL_sysjoystick.c
Expand Up @@ -922,6 +922,12 @@ DARWIN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint
return 0;
}

static int
DARWIN_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
DARWIN_JoystickHasLED(SDL_Joystick * joystick)
{
Expand Down Expand Up @@ -1081,6 +1087,7 @@ SDL_JoystickDriver SDL_DARWIN_JoystickDriver =
DARWIN_JoystickGetDeviceInstanceID,
DARWIN_JoystickOpen,
DARWIN_JoystickRumble,
DARWIN_JoystickRumbleTriggers,
DARWIN_JoystickHasLED,
DARWIN_JoystickSetLED,
DARWIN_JoystickUpdate,
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/dummy/SDL_sysjoystick.c
Expand Up @@ -89,6 +89,12 @@ DUMMY_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble, Uint1
return SDL_Unsupported();
}

static int
DUMMY_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
DUMMY_JoystickHasLED(SDL_Joystick * joystick)
{
Expand Down Expand Up @@ -134,6 +140,7 @@ SDL_JoystickDriver SDL_DUMMY_JoystickDriver =
DUMMY_JoystickGetDeviceInstanceID,
DUMMY_JoystickOpen,
DUMMY_JoystickRumble,
DUMMY_JoystickRumbleTriggers,
DUMMY_JoystickHasLED,
DUMMY_JoystickSetLED,
DUMMY_JoystickUpdate,
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/emscripten/SDL_sysjoystick.c
Expand Up @@ -403,6 +403,12 @@ EMSCRIPTEN_JoystickRumble(SDL_Joystick * joystick, Uint16 low_frequency_rumble,
return SDL_Unsupported();
}

static int
EMSCRIPTEN_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
EMSCRIPTEN_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
{
Expand Down Expand Up @@ -433,6 +439,7 @@ SDL_JoystickDriver SDL_EMSCRIPTEN_JoystickDriver =
EMSCRIPTEN_JoystickGetDeviceInstanceID,
EMSCRIPTEN_JoystickOpen,
EMSCRIPTEN_JoystickRumble,
EMSCRIPTEN_JoystickRumbleTriggers,
EMSCRIPTEN_JoystickHasLED,
EMSCRIPTEN_JoystickSetLED,
EMSCRIPTEN_JoystickUpdate,
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/haiku/SDL_haikujoystick.cc
Expand Up @@ -259,6 +259,12 @@ extern "C"
return SDL_Unsupported();
}


static int HAIKU_JoystickRumbleTriggers(SDL_Joystick * joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
HAIKU_JoystickGetGamepadMapping(int device_index, SDL_GamepadMapping *out)
{
Expand Down Expand Up @@ -287,6 +293,7 @@ extern "C"
HAIKU_JoystickGetDeviceInstanceID,
HAIKU_JoystickOpen,
HAIKU_JoystickRumble,
HAIKU_JoystickRumbleTriggers,
HAIKU_JoystickHasLED,
HAIKU_JoystickSetLED,
HAIKU_JoystickUpdate,
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/hidapi/SDL_hidapi_gamecube.c
Expand Up @@ -363,6 +363,12 @@ HIDAPI_DriverGameCube_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *jo
return -1;
}

static int
HIDAPI_DriverGameCube_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
HIDAPI_DriverGameCube_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
Expand Down Expand Up @@ -414,6 +420,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverGameCube =
HIDAPI_DriverGameCube_UpdateDevice,
HIDAPI_DriverGameCube_OpenJoystick,
HIDAPI_DriverGameCube_RumbleJoystick,
HIDAPI_DriverGameCube_RumbleJoystickTriggers,
HIDAPI_DriverGameCube_HasJoystickLED,
HIDAPI_DriverGameCube_SetJoystickLED,
HIDAPI_DriverGameCube_CloseJoystick,
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/hidapi/SDL_hidapi_ps4.c
Expand Up @@ -373,6 +373,12 @@ HIDAPI_DriverPS4_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joystic
return 0;
}

static int
HIDAPI_DriverPS4_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
HIDAPI_DriverPS4_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
Expand Down Expand Up @@ -588,6 +594,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverPS4 =
HIDAPI_DriverPS4_UpdateDevice,
HIDAPI_DriverPS4_OpenJoystick,
HIDAPI_DriverPS4_RumbleJoystick,
HIDAPI_DriverPS4_RumbleJoystickTriggers,
HIDAPI_DriverPS4_HasJoystickLED,
HIDAPI_DriverPS4_SetJoystickLED,
HIDAPI_DriverPS4_CloseJoystick,
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/hidapi/SDL_hidapi_switch.c
Expand Up @@ -923,6 +923,12 @@ HIDAPI_DriverSwitch_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joys
return HIDAPI_DriverSwitch_ActuallyRumbleJoystick(ctx, low_frequency_rumble, high_frequency_rumble);
}

static int
HIDAPI_DriverSwitch_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
HIDAPI_DriverSwitch_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
Expand Down Expand Up @@ -1289,6 +1295,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverSwitch =
HIDAPI_DriverSwitch_UpdateDevice,
HIDAPI_DriverSwitch_OpenJoystick,
HIDAPI_DriverSwitch_RumbleJoystick,
HIDAPI_DriverSwitch_RumbleJoystickTriggers,
HIDAPI_DriverSwitch_HasJoystickLED,
HIDAPI_DriverSwitch_SetJoystickLED,
HIDAPI_DriverSwitch_CloseJoystick,
Expand Down
7 changes: 7 additions & 0 deletions src/joystick/hidapi/SDL_hidapi_xbox360.c
Expand Up @@ -796,6 +796,12 @@ HIDAPI_DriverXbox360_RumbleJoystick(SDL_HIDAPI_Device *device, SDL_Joystick *joy
return 0;
}

static int
HIDAPI_DriverXbox360_RumbleJoystickTriggers(SDL_HIDAPI_Device *device, SDL_Joystick *joystick, Uint16 left_rumble, Uint16 right_rumble)
{
return SDL_Unsupported();
}

static SDL_bool
HIDAPI_DriverXbox360_HasJoystickLED(SDL_HIDAPI_Device *device, SDL_Joystick *joystick)
{
Expand Down Expand Up @@ -1317,6 +1323,7 @@ SDL_HIDAPI_DeviceDriver SDL_HIDAPI_DriverXbox360 =
HIDAPI_DriverXbox360_UpdateDevice,
HIDAPI_DriverXbox360_OpenJoystick,
HIDAPI_DriverXbox360_RumbleJoystick,
HIDAPI_DriverXbox360_RumbleJoystickTriggers,
HIDAPI_DriverXbox360_HasJoystickLED,
HIDAPI_DriverXbox360_SetJoystickLED,
HIDAPI_DriverXbox360_CloseJoystick,
Expand Down

0 comments on commit 1e2caac

Please sign in to comment.