summaryrefslogtreecommitdiffhomepage
path: root/src
diff options
context:
space:
mode:
authorA <[email protected]>2024-02-04 11:24:05 +0100
committerGitHub <[email protected]>2024-02-04 11:24:05 +0100
commita96b224b384c7be1f97dcd0dbdcf858d97660ffd (patch)
tree726aa1425ea1cb76c8b4499d5fe6009da0a3fccc /src
parent868d515fbc6805d506bf97cf134379d6c293d75c (diff)
downloadraylib-a96b224b384c7be1f97dcd0dbdcf858d97660ffd.tar.gz
raylib-a96b224b384c7be1f97dcd0dbdcf858d97660ffd.zip
Add gamepad support to PLATFORM_DESKTOP_SDL (#3776)
Co-authored-by: Arthur <[email protected]>
Diffstat (limited to 'src')
-rw-r--r--src/platforms/rcore_desktop_sdl.c166
1 files changed, 150 insertions, 16 deletions
diff --git a/src/platforms/rcore_desktop_sdl.c b/src/platforms/rcore_desktop_sdl.c
index 7b386b2c..2e2d190c 100644
--- a/src/platforms/rcore_desktop_sdl.c
+++ b/src/platforms/rcore_desktop_sdl.c
@@ -64,7 +64,7 @@ typedef struct {
SDL_Window *window;
SDL_GLContext glContext;
- SDL_Joystick *gamepad;
+ SDL_Joystick *gamepad[MAX_GAMEPADS];
SDL_Cursor *cursor;
bool cursorRelative;
} PlatformData;
@@ -978,8 +978,18 @@ void PollInputEvents(void)
else CORE.Input.Mouse.previousPosition = CORE.Input.Mouse.currentPosition;
// Reset last gamepad button/axis registered state
- CORE.Input.Gamepad.lastButtonPressed = GAMEPAD_BUTTON_UNKNOWN;
- for (int i = 0; i < MAX_GAMEPADS; i++) CORE.Input.Gamepad.axisCount[i] = 0;
+ for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++)
+ {
+ // Check if gamepad is available
+ if (CORE.Input.Gamepad.ready[i])
+ {
+ // Register previous gamepad button states
+ for (int k = 0; k < MAX_GAMEPAD_BUTTONS; k++)
+ {
+ CORE.Input.Gamepad.previousButtonState[i][k] = CORE.Input.Gamepad.currentButtonState[i][k];
+ }
+ }
+ }
// Register previous touch states
for (int i = 0; i < MAX_TOUCH_POINTS; i++) CORE.Input.Touch.previousTouchState[i] = CORE.Input.Touch.currentTouchState[i];
@@ -1215,20 +1225,134 @@ void PollInputEvents(void)
} break;
// Check gamepad events
- case SDL_JOYAXISMOTION:
+ case SDL_JOYDEVICEADDED:
{
- // Motion on gamepad 0
- if (event.jaxis.which == 0)
- {
- // X axis motion
- if (event.jaxis.axis == 0)
+ int jid = event.jdevice.which;
+ if (!CORE.Input.Gamepad.ready[jid] && (jid < MAX_GAMEPADS)) {
+ platform.gamepad[jid] = SDL_JoystickOpen(jid);
+
+ if (platform.gamepad[jid])
{
- //...
+ CORE.Input.Gamepad.ready[jid] = true;
+ CORE.Input.Gamepad.axisCount[jid] = SDL_JoystickNumAxes(platform.gamepad[jid]);
+ CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
+ CORE.Input.Gamepad.axisState[jid][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
+ strncpy(CORE.Input.Gamepad.name[jid], SDL_JoystickName(platform.gamepad[jid]), 63);
+ CORE.Input.Gamepad.name[jid][63] = '\0';
}
- // Y axis motion
- else if (event.jaxis.axis == 1)
+ else
{
- //...
+ TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
+ }
+ }
+ } break;
+ case SDL_JOYDEVICEREMOVED:
+ {
+ int jid = event.jdevice.which;
+ if (jid == SDL_JoystickInstanceID(platform.gamepad[jid])) {
+ SDL_JoystickClose(platform.gamepad[jid]);
+ platform.gamepad[jid] = SDL_JoystickOpen(0);
+ CORE.Input.Gamepad.ready[jid] = false;
+ memset(CORE.Input.Gamepad.name[jid], 0, 64);
+ }
+ } break;
+ case SDL_JOYBUTTONDOWN:
+ {
+ int button = -1;
+
+ switch (event.jbutton.button)
+ {
+ case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break;
+ case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
+ case SDL_CONTROLLER_BUTTON_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break;
+ case SDL_CONTROLLER_BUTTON_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break;
+
+ case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break;
+ case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break;
+
+ case SDL_CONTROLLER_BUTTON_BACK: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break;
+ case SDL_CONTROLLER_BUTTON_GUIDE: button = GAMEPAD_BUTTON_MIDDLE; break;
+ case SDL_CONTROLLER_BUTTON_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break;
+
+ case SDL_CONTROLLER_BUTTON_DPAD_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break;
+ case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break;
+ case SDL_CONTROLLER_BUTTON_DPAD_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break;
+ case SDL_CONTROLLER_BUTTON_DPAD_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break;
+
+ case SDL_CONTROLLER_BUTTON_LEFTSTICK: button = GAMEPAD_BUTTON_LEFT_THUMB; break;
+ case SDL_CONTROLLER_BUTTON_RIGHTSTICK: button = GAMEPAD_BUTTON_RIGHT_THUMB; break;
+ default: break;
+ }
+
+ if (button >= 0)
+ {
+ CORE.Input.Gamepad.currentButtonState[event.jbutton.which][button] = 1;
+ CORE.Input.Gamepad.lastButtonPressed = button;
+ }
+ } break;
+ case SDL_JOYBUTTONUP:
+ {
+ int button = -1;
+
+ switch (event.jbutton.button)
+ {
+ case SDL_CONTROLLER_BUTTON_Y: button = GAMEPAD_BUTTON_RIGHT_FACE_UP; break;
+ case SDL_CONTROLLER_BUTTON_B: button = GAMEPAD_BUTTON_RIGHT_FACE_RIGHT; break;
+ case SDL_CONTROLLER_BUTTON_A: button = GAMEPAD_BUTTON_RIGHT_FACE_DOWN; break;
+ case SDL_CONTROLLER_BUTTON_X: button = GAMEPAD_BUTTON_RIGHT_FACE_LEFT; break;
+
+ case SDL_CONTROLLER_BUTTON_LEFTSHOULDER: button = GAMEPAD_BUTTON_LEFT_TRIGGER_1; break;
+ case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER: button = GAMEPAD_BUTTON_RIGHT_TRIGGER_1; break;
+
+ case SDL_CONTROLLER_BUTTON_BACK: button = GAMEPAD_BUTTON_MIDDLE_LEFT; break;
+ case SDL_CONTROLLER_BUTTON_GUIDE: button = GAMEPAD_BUTTON_MIDDLE; break;
+ case SDL_CONTROLLER_BUTTON_START: button = GAMEPAD_BUTTON_MIDDLE_RIGHT; break;
+
+ case SDL_CONTROLLER_BUTTON_DPAD_UP: button = GAMEPAD_BUTTON_LEFT_FACE_UP; break;
+ case SDL_CONTROLLER_BUTTON_DPAD_RIGHT: button = GAMEPAD_BUTTON_LEFT_FACE_RIGHT; break;
+ case SDL_CONTROLLER_BUTTON_DPAD_DOWN: button = GAMEPAD_BUTTON_LEFT_FACE_DOWN; break;
+ case SDL_CONTROLLER_BUTTON_DPAD_LEFT: button = GAMEPAD_BUTTON_LEFT_FACE_LEFT; break;
+
+ case SDL_CONTROLLER_BUTTON_LEFTSTICK: button = GAMEPAD_BUTTON_LEFT_THUMB; break;
+ case SDL_CONTROLLER_BUTTON_RIGHTSTICK: button = GAMEPAD_BUTTON_RIGHT_THUMB; break;
+ default: break;
+ }
+
+ if (button >= 0)
+ {
+ CORE.Input.Gamepad.currentButtonState[event.jbutton.which][button] = 0;
+ if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
+ }
+ } break;
+ case SDL_JOYAXISMOTION:
+ {
+ int axis = -1;
+
+ switch (event.jaxis.axis)
+ {
+ case SDL_CONTROLLER_AXIS_LEFTX: axis = GAMEPAD_AXIS_LEFT_X; break;
+ case SDL_CONTROLLER_AXIS_LEFTY: axis = GAMEPAD_AXIS_LEFT_Y; break;
+ case SDL_CONTROLLER_AXIS_RIGHTX: axis = GAMEPAD_AXIS_RIGHT_X; break;
+ case SDL_CONTROLLER_AXIS_RIGHTY: axis = GAMEPAD_AXIS_RIGHT_Y; break;
+ case SDL_CONTROLLER_AXIS_TRIGGERLEFT: axis = GAMEPAD_AXIS_LEFT_TRIGGER; break;
+ case SDL_CONTROLLER_AXIS_TRIGGERRIGHT: axis = GAMEPAD_AXIS_RIGHT_TRIGGER; break;
+ default: break;
+ }
+
+ if (axis >= 0)
+ {
+ // SDL axis value range is -32768 to 32767, we normalize it to RayLib's -1.0 to 1.0f range
+ float value = event.jaxis.value / (float) 32767;
+ CORE.Input.Gamepad.axisState[event.jaxis.which][axis] = value;
+
+ // Register button state for triggers in addition to their axes
+ if ((axis == GAMEPAD_AXIS_LEFT_TRIGGER) || (axis == GAMEPAD_AXIS_RIGHT_TRIGGER))
+ {
+ int button = (axis == GAMEPAD_AXIS_LEFT_TRIGGER) ? GAMEPAD_BUTTON_LEFT_TRIGGER_2 : GAMEPAD_BUTTON_RIGHT_TRIGGER_2;
+ int pressed = (value > 0.1f);
+ CORE.Input.Gamepad.currentButtonState[event.jaxis.which][button] = pressed;
+ if (pressed) CORE.Input.Gamepad.lastButtonPressed = button;
+ else if (CORE.Input.Gamepad.lastButtonPressed == button) CORE.Input.Gamepad.lastButtonPressed = 0;
}
}
} break;
@@ -1405,10 +1529,20 @@ int InitPlatform(void)
// Initialize input events system
//----------------------------------------------------------------------------
- if (SDL_NumJoysticks() >= 1)
+ // Initialize gamepads
+ for (int i = 0; (i < SDL_NumJoysticks()) && (i < MAX_GAMEPADS); i++)
{
- platform.gamepad = SDL_JoystickOpen(0);
- //if (platform.gamepadgamepad == NULL) TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
+ platform.gamepad[i] = SDL_JoystickOpen(i);
+ if (platform.gamepad[i])
+ {
+ CORE.Input.Gamepad.ready[i] = true;
+ CORE.Input.Gamepad.axisCount[i] = SDL_JoystickNumAxes(platform.gamepad[i]);
+ CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_LEFT_TRIGGER] = -1.0f;
+ CORE.Input.Gamepad.axisState[i][GAMEPAD_AXIS_RIGHT_TRIGGER] = -1.0f;
+ strncpy(CORE.Input.Gamepad.name[i], SDL_JoystickName(platform.gamepad[i]), 63);
+ CORE.Input.Gamepad.name[i][63] = '\0';
+ }
+ else TRACELOG(LOG_WARNING, "PLATFORM: Unable to open game controller [ERROR: %s]", SDL_GetError());
}
// Disable mouse events being interpreted as touch events