From c5f08f76845c4c68f39eb1b2054f6b1977d4aaee Mon Sep 17 00:00:00 2001 From: jan Date: Sat, 4 Jan 2025 23:34:44 +0100 Subject: [PATCH] reimplemented the gamepad support with gilrs --- src/main.rs | 19 ++++++++++--- src/utils.rs | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 91 insertions(+), 6 deletions(-) diff --git a/src/main.rs b/src/main.rs index 6196661..71c17be 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,8 +2,8 @@ mod cli; mod engine; mod ui; mod utils; - -use anyhow::Result; +#[allow(unused)] +use anyhow::{anyhow, Context, Result}; use clap::Parser; use cli::Cli; use engine::Engine; @@ -31,7 +31,6 @@ fn window_conf() -> Conf { #[macroquad::main(window_conf)] async fn main() -> Result<()> { let cli = Cli::parse(); - // show_mouse(cli.cursor); let mut buffer = [Color::from_rgba(255, 255, 255, 255); 256 * 256]; let texture = Texture2D::from_image(&Image::gen_image_color(256, 256, BLACK)); @@ -42,6 +41,11 @@ async fn main() -> Result<()> { let initial_state = read_u16s_from_file(&cli.program)?; let mut engine = Engine::new(initial_state.clone()); let mut paused = false; + #[cfg(feature = "gamepad")] + let mut gilrs = match Gilrs::new() { + Ok(g) => g, + _ => return Err(anyhow!("Gamepad could not be loaded")), + }; loop { let start_time = Instant::now(); @@ -62,9 +66,16 @@ async fn main() -> Result<()> { engine.step()?; ipf += 1; } + #[cfg(feature = "gamepad")] + while let Some(event) = gilrs.next_event() { + gilrs.update(&event); + } let _engine_elapsed = engine_start.elapsed(); - let (mpos, keycode) = get_input_code(); + #[cfg(not(feature = "gamepad"))] + let (mpos, keycode) = get_input_code_no_gamepad(); + #[cfg(feature = "gamepad")] + let (mpos, keycode) = get_input_code_gamepad(&gilrs); engine.perform_sync(mpos, keycode, &mut raw_buffer); update_image_buffer(&mut buffer, &raw_buffer); image.update(&buffer); diff --git a/src/utils.rs b/src/utils.rs index 3545169..b2ef3e2 100644 --- a/src/utils.rs +++ b/src/utils.rs @@ -1,3 +1,5 @@ +#[allow(unused)] +use crate::ui::Layout; use anyhow::Result; use flate2::read::GzDecoder; use macroquad::color::Color; @@ -5,6 +7,8 @@ use macroquad::prelude::*; use std::fs::File; use std::io::Read; const RES: usize = 256; +#[cfg(feature = "gamepad")] +use gilrs::{Axis, Button, Gilrs}; pub fn read_u16s_from_file(file_path: &str) -> Result> { let mut file = File::open(file_path)?; @@ -46,8 +50,77 @@ pub fn update_image_buffer(imbuff: &mut [Color; RES * RES], screen: &[u16; RES * } } } -#[cfg(not(feature = "gamepad"))] -pub fn get_input_code() -> (u16, u16) { + +#[cfg(feature = "gamepad")] +pub fn get_input_code_gamepad(gilrs: &Gilrs) -> (u16, u16) { + #[cfg(not(feature = "gamepad"))] + return get_input_code_no_gamepad(); + let mut key_code = 0_u16; + let mp = Layout::generate().clamp_mouse(); + let pos_code = (mp.1 as u16 * 256) + mp.0 as u16; + let Some(gamepad) = gilrs.gamepads().next().map(|t| t.1) else { + return get_input_code_no_gamepad(); + }; + let tol = 0.5; + let axis_horizontal = gamepad + .axis_data(Axis::LeftStickX) + .map(|a| a.value()) + .unwrap_or(0.); + let axis_vertical = gamepad + .axis_data(Axis::LeftStickY) + .map(|a| a.value()) + .unwrap_or(0.); + if is_key_down(KeyCode::Space) + || is_mouse_button_down(MouseButton::Left) + || gamepad.is_pressed(Button::East) + { + key_code += 1; + } + if is_key_down(KeyCode::B) + || is_mouse_button_down(MouseButton::Right) + || gamepad.is_pressed(Button::South) + { + key_code += 2; + } + if is_key_down(KeyCode::W) + || is_key_down(KeyCode::Up) + || gamepad.is_pressed(Button::DPadUp) + || axis_vertical > tol + { + key_code += 4 + } + if is_key_down(KeyCode::S) + || is_key_down(KeyCode::Down) + || gamepad.is_pressed(Button::DPadDown) + || axis_vertical < -tol + { + key_code += 8 + } + if is_key_down(KeyCode::A) + || is_key_down(KeyCode::Left) + || gamepad.is_pressed(Button::DPadLeft) + || axis_horizontal < -tol + { + key_code += 16 + } + if is_key_down(KeyCode::D) + || is_key_down(KeyCode::Right) + || gamepad.is_pressed(Button::DPadRight) + || axis_horizontal > tol + { + key_code += 32 + } + if is_key_down(KeyCode::N) || gamepad.is_pressed(Button::Select) { + key_code += 64 + } + if is_key_down(KeyCode::M) || gamepad.is_pressed(Button::Start) { + key_code += 128 + } + + (pos_code, key_code) +} + +pub fn get_input_code_no_gamepad() -> (u16, u16) { use crate::ui::Layout; let mp = Layout::generate().clamp_mouse(); @@ -78,5 +151,6 @@ pub fn get_input_code() -> (u16, u16) { if is_key_down(KeyCode::M) { key_code += 128 } + (pos_code, key_code) }