SDL3 gamepad input

This commit is contained in:
Zack Buhman 2026-03-25 15:26:32 -05:00
parent f4844fd7fc
commit df0b7f5598
3 changed files with 92 additions and 14 deletions

View File

@ -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,

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <string.h>
#include <SDL3/SDL.h>
@ -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);

View File

@ -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::font>(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,