package game import "core:strings" import rl "vendor:raylib" // ------------------------------------------------------------------------------ // Input Manager, captures input events and stores them into a struct. // Passing the struct down allows for components to use inputs independently // ------------------------------------------------------------------------------ Input_Event :: struct { // Continuous movement normalized move_dir: rl.Vector2, // single frame actions UI and triggers up_pressed: bool, down_pressed: bool, left_pressed: bool, right_pressed: bool, confirm_pressed: bool, pause_pressed: bool, } // Currently active controller is_real_pad :: proc(i: i32) -> bool { return rl.IsGamepadAvailable(i) && !strings.contains(string(rl.GetGamepadName(i)), "Mouse") && !strings.contains(string(rl.GetGamepadName(i)), "Keyboard") } update_active_gamepad :: proc(game: ^Game) { // is there currently a controller, if so check if its still connected. if game.controller_gid != -1 { if rl.IsGamepadAvailable(game.controller_gid) { // do nothing still connected return } // else we lost connection game.controller_gid = -1 game.controller_connected = false } for i: i32 = 0; i < 4; i += 1 { if rl.IsGamepadAvailable(i) && is_real_pad(i) { game.controller_connected = true game.controller_gid = i return } } } poll_input :: proc(game: ^Game) -> Input_Event { input_event := Input_Event{} input_dir := rl.Vector2{0, 0} update_active_gamepad(game) gamepad_active := game.controller_connected gid := game.controller_gid // -------------------------------------------------------------------------- // 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 } } // 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) || (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) || (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 }