From f8f6aa09075dc1719a8f6063062a3bdba74a7c3e Mon Sep 17 00:00:00 2001 From: Asdqwe Date: Mon, 21 Oct 2024 19:06:37 -0300 Subject: [PATCH] [rcore] Adds implementation to `SetGamepadVibration()` on `PLATFORM_WEB` and updates it on `PLATFORM_DESKTOP_SDL` to handle duration (#4410) * Updates SetGamepadVibration() * Handle MAX_GAMEPAD_VIBRATION_TIME * Revert low/high parameters back to left/rightMotor * Fix missin semicolon * Convert duration to seconds * Add SetGamepadVibration() implementation to PLATFORM_WEB --- src/platforms/rcore_android.c | 2 +- src/platforms/rcore_desktop_glfw.c | 2 +- src/platforms/rcore_desktop_sdl.c | 18 +++++++++--------- src/platforms/rcore_drm.c | 4 ++-- src/platforms/rcore_web.c | 29 +++++++++++++++++++++++++++-- src/raylib.h | 2 +- 6 files changed, 41 insertions(+), 16 deletions(-) diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 88438c9b0095..85ce82a3a153 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -615,7 +615,7 @@ int SetGamepadMappings(const char *mappings) } // Set gamepad vibration -void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) { TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); } diff --git a/src/platforms/rcore_desktop_glfw.c b/src/platforms/rcore_desktop_glfw.c index 0bc52ac9e32f..41f7fac39a1b 100644 --- a/src/platforms/rcore_desktop_glfw.c +++ b/src/platforms/rcore_desktop_glfw.c @@ -1060,7 +1060,7 @@ int SetGamepadMappings(const char *mappings) } // Set gamepad vibration -void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) { TRACELOG(LOG_WARNING, "GamepadSetVibration() not available on target platform"); } diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index b4ceb78ebf25..7cbe0354efc7 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -953,17 +953,17 @@ int SetGamepadMappings(const char *mappings) } // Set gamepad vibration -void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) { - // Limit input values to between 0.0f and 1.0f - leftMotor = (0.0f > leftMotor)? 0.0f : leftMotor; - rightMotor = (0.0f > rightMotor)? 0.0f : rightMotor; - leftMotor = (1.0f < leftMotor)? 1.0f : leftMotor; - rightMotor = (1.0f < rightMotor)? 1.0f : rightMotor; - - if (IsGamepadAvailable(gamepad)) + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (duration > 0.0f)) { - SDL_GameControllerRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f)); + if (leftMotor < 0.0f) leftMotor = 0.0f; + if (leftMotor > 1.0f) leftMotor = 1.0f; + if (rightMotor < 0.0f) rightMotor = 0.0f; + if (rightMotor > 1.0f) rightMotor = 1.0f; + if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME; + + SDL_GameControllerRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(duration*1000.0f)); } } diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index e77457b1baa5..eb8ef0103062 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -610,7 +610,7 @@ int SetGamepadMappings(const char *mappings) } // Set gamepad vibration -void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) { TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); } @@ -763,7 +763,7 @@ int InitPlatform(void) drmModeConnector *con = drmModeGetConnector(platform.fd, res->connectors[i]); TRACELOG(LOG_TRACE, "DISPLAY: Connector modes detected: %i", con->count_modes); - + // In certain cases the status of the conneciton is reported as UKNOWN, but it is still connected. // This might be a hardware or software limitation like on Raspberry Pi Zero with composite output. if (((con->connection == DRM_MODE_CONNECTED) || (con->connection == DRM_MODE_UNKNOWNCONNECTION)) && (con->encoder_id)) diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index 36af66a4787e..5fddbb371ab0 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -892,9 +892,34 @@ int SetGamepadMappings(const char *mappings) } // Set gamepad vibration -void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration) { - TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); + if ((gamepad < MAX_GAMEPADS) && CORE.Input.Gamepad.ready[gamepad] && (duration > 0.0f)) + { + if (leftMotor < 0.0f) leftMotor = 0.0f; + if (leftMotor > 1.0f) leftMotor = 1.0f; + if (rightMotor < 0.0f) rightMotor = 0.0f; + if (rightMotor > 1.0f) rightMotor = 1.0f; + if (duration > MAX_GAMEPAD_VIBRATION_TIME) duration = MAX_GAMEPAD_VIBRATION_TIME; + duration *= 1000.0f; // Convert duration to ms + + // Note: At the moment (2024.10.21) Chrome, Edge, Opera, Safari, Android Chrome, Android Webview only support the vibrationActuator API, + // and Firefox only supports the hapticActuators API + EM_ASM({ + try + { + navigator.getGamepads()[$0].vibrationActuator.playEffect('dual-rumble', { startDelay: 0, duration: $3, weakMagnitude: $1, strongMagnitude: $2 }); + } + catch (e) + { + try + { + navigator.getGamepads()[$0].hapticActuators[0].pulse($2, $3); + } + catch (e) { } + } + }, gamepad, leftMotor, rightMotor, duration); + } } // Set mouse position XY diff --git a/src/raylib.h b/src/raylib.h index 25ee6943f7e2..fc505f78762f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1184,7 +1184,7 @@ RLAPI int GetGamepadButtonPressed(void); RLAPI int GetGamepadAxisCount(int gamepad); // Get gamepad axis count for a gamepad RLAPI float GetGamepadAxisMovement(int gamepad, int axis); // Get axis movement value for a gamepad axis RLAPI int SetGamepadMappings(const char *mappings); // Set internal gamepad mappings (SDL_GameControllerDB) -RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor); // Set gamepad vibration for both motors +RLAPI void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor, float duration); // Set gamepad vibration for both motors (duration in seconds) // Input-related functions: mouse RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once