Added controller support.

Added SDL3 controller mappings and loaded with raylib.
Updated input manager to get active controller, check for disconnect etc
and then use that within the poll input proc.
This commit is contained in:
2026-09-23 07:52:42 +02:00
parent d40395fae4
commit c50f9cb2b7
3 changed files with 2330 additions and 17 deletions
+10 -3
View File
@@ -1,5 +1,6 @@
package game
import "core:strings"
import rl "vendor:raylib"
VIEWPORT_W :: 1280
@@ -32,19 +33,25 @@ Game :: struct {
res_index: int
}
// AO: lets me load this at compile time!
gamepad_compat := #load("../gamecontrollerdb.txt", string)
// ------------------------------------------------------------------------------
// Game Lifecycle
// ------------------------------------------------------------------------------
game_init :: proc(game: ^Game) {
//rl.SetConfigFlags({.WINDOW_RESIZABLE, .MSAA_4X_HINT})
rl.SetConfigFlags({.MSAA_4X_HINT})
rl.SetConfigFlags({.WINDOW_ALWAYS_RUN, .MSAA_4X_HINT})
game.res_index = 2
game.window_w = RESOLUTIONS[game.res_index].width
game.window_h = RESOLUTIONS[game.res_index].height
rl.InitWindow(game.window_w, game.window_h, WINDOW_TITLE)
rl.SetTargetFPS(60)
rl.SetExitKey(.KEY_NULL)
gamepad_cstr := strings.clone_to_cstring(gamepad_compat)
defer delete(gamepad_cstr)
rl.SetGamepadMappings(gamepad_cstr)
// init any global managers
audio_init(&game.audio)
+61 -14
View File
@@ -20,30 +20,77 @@ Input_Event :: struct {
pause_pressed: bool,
}
// Currently active controller
active_gamepad_id: i32 = -1
update_active_gamepad :: proc() {
// is there currently a controller, if so check if its still connected.
if active_gamepad_id != -1 {
if rl.IsGamepadAvailable(active_gamepad_id) {
// do nothing still connected
return
}
// else we lost connection
active_gamepad_id = -1
rl.TraceLog(.WARNING, "Controller disconnected!!")
}
for i: i32 = 0; i < 4; i += 1 {
if rl.IsGamepadAvailable(i) {
active_gamepad_id = i
return
}
}
}
poll_input :: proc() -> Input_Event {
input_event := Input_Event{}
input_dir := rl.Vector2{0, 0}
// --------------------------------------------------------------------------
// Continuous Input ie movement code
// --------------------------------------------------------------------------
if rl.IsKeyDown(.W) || rl.IsKeyDown(.UP) { input_dir.y -= 1 }
if rl.IsKeyDown(.S) || rl.IsKeyDown(.DOWN) { input_dir.y += 1 }
update_active_gamepad()
gamepad_active := active_gamepad_id != -1
gid := active_gamepad_id
if input_dir.x != 0 || input_dir.y != 0 {
input_dir = rl.Vector2Normalize(input_dir)
// --------------------------------------------------------------------------
// Continuous Input (keyboard + gamepad d-pad)
// --------------------------------------------------------------------------
if rl.IsKeyDown(.W) || rl.IsKeyDown(.UP) || (gamepad_active && rl.IsGamepadButtonDown(gid, .LEFT_FACE_UP)) { input_dir.y -= 1 }
if rl.IsKeyDown(.S) || rl.IsKeyDown(.DOWN) || (gamepad_active && rl.IsGamepadButtonDown(gid, .LEFT_FACE_DOWN)) { input_dir.y += 1 }
// --------------------------------------------------------------------------
// Analog stick input gamepads
// --------------------------------------------------------------------------
if gamepad_active {
DEADZONE :: 0.25
axis_y := rl.GetGamepadAxisMovement(gid, .LEFT_Y)
// apply deadzone and combine with input if moved
if abs(axis_y) > DEADZONE { input_dir.y = axis_y }
}
input_event.move_dir = input_dir
// Normalize so diagonal movement isn't faster than cardinal directions
if input_dir.x != 0 || input_dir.y != 0 do input_event.move_dir = rl.Vector2Normalize(input_dir)
// --------------------------------------------------------------------------
// actions single press ie menu navigation etc
// --------------------------------------------------------------------------
input_event.up_pressed = rl.IsKeyPressed(.W) || rl.IsKeyPressed(.UP)
input_event.down_pressed = rl.IsKeyPressed(.S) || rl.IsKeyPressed(.DOWN)
input_event.left_pressed = rl.IsKeyPressed(.A) || rl.IsKeyPressed(.LEFT)
input_event.right_pressed = rl.IsKeyPressed(.D) || rl.IsKeyPressed(.RIGHT)
input_event.confirm_pressed = rl.IsKeyPressed(.ENTER) || rl.IsKeyPressed(.SPACE)
input_event.pause_pressed = rl.IsKeyPressed(.P)
input_event.up_pressed = rl.IsKeyPressed(.W) || rl.IsKeyPressed(.UP) ||
(gamepad_active && rl.IsGamepadButtonPressed(gid, .LEFT_FACE_UP))
input_event.down_pressed = rl.IsKeyPressed(.S) || rl.IsKeyPressed(.DOWN) ||
(gamepad_active && rl.IsGamepadButtonPressed(gid, .LEFT_FACE_DOWN))
input_event.left_pressed = rl.IsKeyPressed(.A) || rl.IsKeyPressed(.LEFT) ||
(gamepad_active && rl.IsGamepadButtonPressed(gid, .LEFT_FACE_LEFT))
input_event.right_pressed = rl.IsKeyPressed(.D) || rl.IsKeyPressed(.RIGHT) ||
(gamepad_active && rl.IsGamepadButtonPressed(gid, .LEFT_FACE_RIGHT))
input_event.confirm_pressed = rl.IsKeyPressed(.ENTER) || rl.IsKeyPressed(.SPACE) ||
(gamepad_active && rl.IsGamepadButtonPressed(gid, .RIGHT_FACE_DOWN))
input_event.pause_pressed = rl.IsKeyPressed(.SPACE) ||
(gamepad_active && rl.IsGamepadButtonPressed(gid, .MIDDLE_RIGHT))
return input_event
}