103 lines
3.9 KiB
Odin
103 lines
3.9 KiB
Odin
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
|
|
}
|