Newer
Older
//! Gamepad related functions and structures.
#[cfg(feature = "wasm")]
use wasm_bindgen::prelude::*;
#[cfg_attr(feature = "wasm", wasm_bindgen)]
pub enum PadKey {
Up,
Down,
Left,
Right,
Start,
Select,
A,
B,
}
pub struct Pad {
down: bool,
up: bool,
left: bool,
right: bool,
start: bool,
select: bool,
b: bool,
a: bool,
selection: PadSelection,
impl Pad {
pub fn new() -> Self {
Self {
down: false,
up: false,
left: false,
right: false,
start: false,
select: false,
b: false,
a: false,
}
}
pub fn read(&mut self, addr: u16) -> u8 {
match addr {
// 0xFF00 — P1/JOYP: Joypad
0xff00 => {
PadSelection::Action =>
{
#[allow(clippy::bool_to_int_with_if)]
| if self.b { 0x00 } else { 0x02 }
| if self.select { 0x00 } else { 0x04 }
PadSelection::Direction =>
{
#[allow(clippy::bool_to_int_with_if)]
| if self.left { 0x00 } else { 0x02 }
| if self.up { 0x00 } else { 0x04 }
value |= match self.selection {
PadSelection::Action => 0x10,
PadSelection::Direction => 0x20,
PadSelection::None => 0x30,
_ => {
warnln!("Reading from unknown Pad location 0x{:04x}", addr);
0xff
}
}
}
pub fn write(&mut self, addr: u16, value: u8) {
match addr {
// 0xFF00 — P1/JOYP: Joypad
0xff00 => {
self.selection = match value & 0x30 {
0x10 => PadSelection::Action,
0x20 => PadSelection::Direction,
0x30 => PadSelection::None,
_ => PadSelection::None,
};
_ => warnln!("Writing to unknown Pad location 0x{:04x}", addr),
pub fn key_press(&mut self, key: PadKey) {
match key {
PadKey::Up => self.up = true,
PadKey::Down => self.down = true,
PadKey::Left => self.left = true,
PadKey::Right => self.right = true,
PadKey::Start => self.start = true,
PadKey::Select => self.select = true,
PadKey::A => self.a = true,
PadKey::B => self.b = true,
}
// signals that a JoyPad interrupt is pending to be
// handled as a key press has been performed
}
pub fn key_lift(&mut self, key: PadKey) {
match key {
PadKey::Up => self.up = false,
PadKey::Down => self.down = false,
PadKey::Left => self.left = false,
PadKey::Right => self.right = false,
PadKey::Start => self.start = false,
PadKey::Select => self.select = false,
PadKey::A => self.a = false,
PadKey::B => self.b = false,
}
}
pub fn int_pad(&self) -> bool {
self.int_pad
}
pub fn set_int_pad(&mut self, value: bool) {
self.int_pad = value;
}
pub fn ack_pad(&mut self) {
self.set_int_pad(false);
}
impl Default for Pad {
fn default() -> Self {
Self::new()
}
}