From 371d25c8c99f6db487c938f8b7f391d45e26d3a4 Mon Sep 17 00:00:00 2001 From: GideonSerf Date: Sat, 24 Feb 2024 17:47:27 +0200 Subject: [PATCH] Gamepad rumble support with SDL2 (#3819) * Added gamepad rumble to rcore_desktop.c and rcore_desktop_sdl.c Still need to add to the rest of the platforms. * Add SetGamepadVibration warnings to unimplemented platforms. * Added MAX_GAMEPAD_VIBRATION_TIME The rumble in SDL2 will continue for MAX_GAMEPAD_VIBRATION_TIME unless the user cancels it with a call to SetGamepadVibration(0.0f,0.0f,0.0f) * Cast float duration value to Uint 32 * Changed defines from int to float and fixed typo --------- Co-authored-by: Gideon Serfontein --- src/config.h | 1 + src/platforms/rcore_android.c | 6 ++++++ src/platforms/rcore_desktop.c | 6 ++++++ src/platforms/rcore_desktop_sdl.c | 15 +++++++++++++++ src/platforms/rcore_drm.c | 6 ++++++ src/platforms/rcore_web.c | 6 ++++++ src/raylib.h | 21 +++++++++++---------- src/rcore.c | 3 +++ 8 files changed, 54 insertions(+), 10 deletions(-) diff --git a/src/config.h b/src/config.h index 34d2e9648..10aca978a 100644 --- a/src/config.h +++ b/src/config.h @@ -81,6 +81,7 @@ #define MAX_GAMEPADS 4 // Maximum number of gamepads supported #define MAX_GAMEPAD_AXIS 8 // Maximum number of axis supported (per gamepad) #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) +#define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #define MAX_KEY_PRESSED_QUEUE 16 // Maximum number of keys in the key input queue #define MAX_CHAR_PRESSED_QUEUE 16 // Maximum number of characters in the char input queue diff --git a/src/platforms/rcore_android.c b/src/platforms/rcore_android.c index cc124d952..23b8f4369 100644 --- a/src/platforms/rcore_android.c +++ b/src/platforms/rcore_android.c @@ -613,6 +613,12 @@ int SetGamepadMappings(const char *mappings) return 0; } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +{ + TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); +} + // Set mouse position XY void SetMousePosition(int x, int y) { diff --git a/src/platforms/rcore_desktop.c b/src/platforms/rcore_desktop.c index 4c98fcdf6..dbfc29e01 100644 --- a/src/platforms/rcore_desktop.c +++ b/src/platforms/rcore_desktop.c @@ -1050,6 +1050,12 @@ int SetGamepadMappings(const char *mappings) return glfwUpdateGamepadMappings(mappings); } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +{ + TRACELOG(LOG_WARNING, "GamepadSetVibration() not available on target platform"); +} + // Set mouse position XY void SetMousePosition(int x, int y) { diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c index 2e2d190cb..f567119ed 100644 --- a/src/platforms/rcore_desktop_sdl.c +++ b/src/platforms/rcore_desktop_sdl.c @@ -938,6 +938,21 @@ int SetGamepadMappings(const char *mappings) return SDL_GameControllerAddMapping(mappings); } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +{ + //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)) + { + SDL_JoystickRumble(platform.gamepad[gamepad], (Uint16)(leftMotor*65535.0f), (Uint16)(rightMotor*65535.0f), (Uint32)(MAX_GAMEPAD_VIBRATION_TIME*1000.0f)); + } +} + // Set mouse position XY void SetMousePosition(int x, int y) { diff --git a/src/platforms/rcore_drm.c b/src/platforms/rcore_drm.c index 12e749a02..d303ab1da 100644 --- a/src/platforms/rcore_drm.c +++ b/src/platforms/rcore_drm.c @@ -519,6 +519,12 @@ int SetGamepadMappings(const char *mappings) return 0; } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +{ + TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); +} + // Set mouse position XY void SetMousePosition(int x, int y) { diff --git a/src/platforms/rcore_web.c b/src/platforms/rcore_web.c index a13f69908..9328b8c9b 100644 --- a/src/platforms/rcore_web.c +++ b/src/platforms/rcore_web.c @@ -850,6 +850,12 @@ int SetGamepadMappings(const char *mappings) return 0; } +// Set gamepad vibration +void SetGamepadVibration(int gamepad, float leftMotor, float rightMotor) +{ + TRACELOG(LOG_WARNING, "GamepadSetVibration() not implemented on target platform"); +} + // Set mouse position XY void SetMousePosition(int x, int y) { diff --git a/src/raylib.h b/src/raylib.h index 7cf4e6536..d857f1c74 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1162,16 +1162,17 @@ RLAPI int GetCharPressed(void); // Get char presse RLAPI void SetExitKey(int key); // Set a custom key to exit program (default is ESC) // Input-related functions: gamepads -RLAPI bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available -RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id -RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once -RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed -RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once -RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed -RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed -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 bool IsGamepadAvailable(int gamepad); // Check if a gamepad is available +RLAPI const char *GetGamepadName(int gamepad); // Get gamepad internal name id +RLAPI bool IsGamepadButtonPressed(int gamepad, int button); // Check if a gamepad button has been pressed once +RLAPI bool IsGamepadButtonDown(int gamepad, int button); // Check if a gamepad button is being pressed +RLAPI bool IsGamepadButtonReleased(int gamepad, int button); // Check if a gamepad button has been released once +RLAPI bool IsGamepadButtonUp(int gamepad, int button); // Check if a gamepad button is NOT being pressed +RLAPI int GetGamepadButtonPressed(void); // Get the last gamepad button pressed +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 // Input-related functions: mouse RLAPI bool IsMouseButtonPressed(int button); // Check if a mouse button has been pressed once diff --git a/src/rcore.c b/src/rcore.c index f4abe117a..024f0d121 100644 --- a/src/rcore.c +++ b/src/rcore.c @@ -224,6 +224,9 @@ __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigne #ifndef MAX_GAMEPAD_BUTTONS #define MAX_GAMEPAD_BUTTONS 32 // Maximum number of buttons supported (per gamepad) #endif +#ifndef MAX_GAMEPAD_VIBRATION_TIME + #define MAX_GAMEPAD_VIBRATION_TIME 2.0f // Maximum vibration time in seconds +#endif #ifndef MAX_TOUCH_POINTS #define MAX_TOUCH_POINTS 8 // Maximum number of touch points supported #endif