diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index 88438c9b0..85ce82a3a 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 0bc52ac9e..41f7fac39 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 b4ceb78eb..7cbe0354e 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 e77457b1b..eb8ef0103 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 36af66a47..5fddbb371 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 25ee6943f..fc505f787 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