From df0b7f55985d157733aa65a9c6c89bc4e8c46649 Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Wed, 25 Mar 2026 15:26:32 -0500 Subject: [PATCH] SDL3 gamepad input --- include/test.h | 3 +- src/main.cpp | 91 ++++++++++++++++++++++++++++++++++++++++++++++++-- src/test.cpp | 12 ++----- 3 files changed, 92 insertions(+), 14 deletions(-) diff --git a/include/test.h b/include/test.h index 94e80e7..81909bc 100644 --- a/include/test.h +++ b/include/test.h @@ -14,8 +14,7 @@ extern "C" { int i, int k, int j, int l, int q, int e); void update_mouse(int x, int y); - void update_joystick(int joystick_index, - float lx, float ly, float rx, float ry, float tl, float tr, + void update_joystick(float lx, float ly, float rx, float ry, float tl, float tr, int up, int down, int left, int right, int a, int b, int x, int y, int leftshoulder, int rightshoulder, diff --git a/src/main.cpp b/src/main.cpp index 4f37ba2..46828fc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,5 @@ #include +#include #include @@ -8,12 +9,92 @@ #include "window.h" #include "view.h" +static int const max_gamepads = 16; +static SDL_Gamepad * gamepads[max_gamepads]; +static int gamepad_count = 0; + +void add_gamepad(SDL_JoystickID instance_id) +{ + SDL_Gamepad * gamepad = SDL_OpenGamepad(instance_id); + char const * name = SDL_GetGamepadName(gamepad); + if (gamepad_count >= max_gamepads) { + printf("too many gamepads; ignoring gamepad %d %s\n", instance_id, name); + SDL_CloseGamepad(gamepad); + } else { + printf("add gamepad %d %s\n", instance_id, name); + gamepads[gamepad_count] = gamepad; + gamepad_count += 1; + } +} + +void remove_gamepad(SDL_JoystickID instance_id) +{ + for (int i = 0; i < gamepad_count; i++) { + if (SDL_GetGamepadID(gamepads[i]) == instance_id) { + int tail = (gamepad_count - i) - 1; + memcpy(&gamepads[i], &gamepads[i+1], tail * (sizeof (gamepads[0]))); + return; + } + } + assert(!"remove_gamepad"); +} + +void update() +{ + for (int i = 0; i < gamepad_count; i++) { + SDL_Gamepad * gamepad = gamepads[i]; + int16_t leftx = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTX); + int16_t lefty = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFTY); + int16_t rightx = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTX); + int16_t righty = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHTY); + int16_t left_trigger = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_LEFT_TRIGGER); + int16_t right_trigger = SDL_GetGamepadAxis(gamepad, SDL_GAMEPAD_AXIS_RIGHT_TRIGGER); + + + bool dpad_up = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_UP); + bool dpad_down = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_DOWN); + bool dpad_left = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_LEFT); + bool dpad_right = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_DPAD_RIGHT); + + bool a = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_SOUTH); + bool b = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_EAST); + bool x = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_WEST); + bool y = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_NORTH); + + bool left_shoulder = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_LEFT_SHOULDER); + bool right_shoulder = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER); + + bool start = SDL_GetGamepadButton(gamepad, SDL_GAMEPAD_BUTTON_RIGHT_SHOULDER); + + float scale = 1.0f / 32767.0f; + update_joystick((float)leftx * scale, + (float)lefty * scale, + (float)rightx * scale, + (float)righty * scale, + (float)left_trigger * scale, + (float)right_trigger * scale, + dpad_up, dpad_down, dpad_left, dpad_right, + a, b, x, y, + left_shoulder, right_shoulder, + start); + } + + view::update_transforms(); +} + int main() { SDL_SetAppMetadata("Bibliotheca", "1.0", "st.idk.bibliotheca"); bool ret; - ret = SDL_Init(SDL_INIT_VIDEO); + SDL_InitFlags sdl_flags + = SDL_INIT_EVENTS + | SDL_INIT_VIDEO + | SDL_INIT_JOYSTICK + | SDL_INIT_GAMEPAD + | SDL_INIT_AUDIO + ; + ret = SDL_Init(sdl_flags); if (!ret) { fprintf(stderr, "SDL_Init(SDL_INIT_VIDEO): %s\n", SDL_GetError()); return 1; @@ -60,12 +141,16 @@ int main() case SDL_EVENT_WINDOW_RESIZED: printf("%d %d\n", event.window.data1, event.window.data2); break; - default: + case SDL_EVENT_GAMEPAD_ADDED: + add_gamepad(event.gdevice.which); + break; + case SDL_EVENT_GAMEPAD_REMOVED: + remove_gamepad(event.gdevice.which); break; } } - view::update_transforms(); + update(); draw(); SDL_GL_SwapWindow(window); diff --git a/src/test.cpp b/src/test.cpp index 1c882c1..440a042 100644 --- a/src/test.cpp +++ b/src/test.cpp @@ -27,7 +27,6 @@ #include "collada/scene.h" #include "collada/types.h" #include "collada/instance_types.h" -#include "pixel_line_art.h" #include "flame.h" #include "new.h" #include "popcount.h" @@ -153,12 +152,6 @@ void load(const char * source_path) uncial_antiqua_fonts = New(font::outline::uncial_antiqua_length); font::outline::load_fonts(uncial_antiqua_fonts, font::outline::uncial_antiqua, font::outline::uncial_antiqua_length); - ////////////////////////////////////////////////////////////////////// - // pixel_line_art - ////////////////////////////////////////////////////////////////////// - - pixel_line_art::load(); - ////////////////////////////////////////////////////////////////////// // quad ////////////////////////////////////////////////////////////////////// @@ -362,8 +355,9 @@ void update_keyboard(int up, int down, int left, int right, static int last_a = 0; -void update_joystick(int joystick_index, - float lx, float ly, float rx, float ry, float tl, float tr, +void update_joystick(float lx, float ly, + float rx, float ry, + float tl, float tr, int up, int down, int left, int right, int a, int b, int x, int y, int leftshoulder, int rightshoulder,