agb/src/input.rs

100 lines
2.3 KiB
Rust
Raw Normal View History

2021-03-07 04:58:59 +11:00
use bitflags::bitflags;
use core::convert::From;
pub enum Tri {
Positive = 1,
Zero = 0,
Negative = -1,
}
impl From<(bool, bool)> for Tri {
fn from(a: (bool, bool)) -> Tri {
let b1 = a.0 as i8;
let b2 = a.1 as i8;
unsafe { core::mem::transmute(b2 - b1) }
}
}
bitflags! {
pub struct Button: u32 {
const A = 1 << 0;
const B = 1 << 1;
const SELECT = 1 << 2;
const START = 1 << 3;
const RIGHT = 1 << 4;
const LEFT = 1 << 5;
const UP = 1 << 6;
const DOWN = 1 << 7;
const R = 1 << 8;
const L = 1 << 9;
}
}
const KEY_MASK: u16 = 0b1111111111;
const BUTTON_INPUT: *mut u16 = (0x04000130) as *mut u16;
// const BUTTON_INTURRUPT: *mut u16 = (0x04000132) as *mut u16;
pub struct ButtonController {
previous: u16,
current: u16,
}
impl Default for ButtonController {
fn default() -> Self {
ButtonController::new()
}
}
impl ButtonController {
pub fn new() -> Self {
ButtonController {
previous: 0,
current: 0,
}
}
pub fn update(&mut self) {
self.previous = self.current;
self.current = unsafe { BUTTON_INPUT.read_volatile() } ^ KEY_MASK;
}
pub fn x_tri(&self) -> Tri {
let left = self.is_pressed(Button::LEFT);
let right = self.is_pressed(Button::RIGHT);
(left, right).into()
}
pub fn y_tri(&self) -> Tri {
let up = self.is_pressed(Button::UP);
let down = self.is_pressed(Button::DOWN);
(up, down).into()
}
pub fn is_pressed(&self, keys: Button) -> bool {
let currently_pressed = self.current as u32;
let keys = keys.bits();
(currently_pressed & keys) != 0
}
pub fn is_released(&self, keys: Button) -> bool {
!self.is_pressed(keys)
}
pub fn is_just_pressed(&self, keys: Button) -> bool {
let current = self.current as u32;
let previous = self.previous as u32;
let keys = keys.bits();
((current & keys) != 0) && ((previous & keys) == 0)
}
pub fn is_just_released(&self, keys: Button) -> bool {
let current = self.current as u32;
let previous = self.previous as u32;
let keys = keys.bits();
((current & keys) == 0) && ((previous & keys) != 0)
}
}