gb/src/joypad.rs

145 lines
3.3 KiB
Rust
Raw Normal View History

2021-03-21 02:11:45 +00:00
use bitfield::bitfield;
#[derive(Debug, Clone, Copy, Default)]
pub struct Joypad {
pub status: JoypadStatus,
2021-05-04 04:11:39 +00:00
pub interrupt: bool,
}
impl Joypad {
pub fn interrupt(&self) -> bool {
self.interrupt
}
pub fn set_interrupt(&mut self, value: bool) {
self.interrupt = value;
}
2021-03-21 02:11:45 +00:00
}
bitfield! {
pub struct JoypadStatus(u8);
impl Debug;
2021-05-04 04:11:39 +00:00
from into RowState, action_row, set_action_row: 5, 5;
from into RowState, direction_row, set_direction_row: 4, 4;
from into ButtonState, down_start, _set_down_start: 3, 3;
from into ButtonState, up_select, _set_up_select: 2, 2;
from into ButtonState, left_b, _set_left_b: 1, 1;
from into ButtonState, right_a, _set_right_a: 0, 0;
}
impl JoypadStatus {
pub(crate) fn update(&mut self, byte: u8) {
// Bytes 3 -> 0 are Read Only
let mask = 0b00001111;
let read_only = self.0 & mask;
self.0 = (byte & !mask) | read_only;
}
}
2021-05-04 04:11:39 +00:00
impl JoypadStatus {
pub fn set_down_start(&mut self, state: ButtonState, int: &mut bool) {
if !(*int) {
*int = self.down_start() == ButtonState::Released && state == ButtonState::Pressed;
}
self._set_down_start(state);
}
pub fn set_up_select(&mut self, state: ButtonState, int: &mut bool) {
if !(*int) {
*int = self.up_select() == ButtonState::Released && state == ButtonState::Pressed;
}
self._set_up_select(state);
}
pub fn set_left_b(&mut self, state: ButtonState, int: &mut bool) {
if !(*int) {
*int = self.left_b() == ButtonState::Released && state == ButtonState::Pressed;
}
self._set_left_b(state);
}
pub fn set_right_a(&mut self, state: ButtonState, int: &mut bool) {
if !(*int) {
*int = self.right_a() == ButtonState::Released && state == ButtonState::Pressed;
}
self._set_right_a(state);
}
}
impl Default for JoypadStatus {
fn default() -> Self {
Self(0xFF)
}
2021-03-21 02:11:45 +00:00
}
impl Copy for JoypadStatus {}
impl Clone for JoypadStatus {
fn clone(&self) -> Self {
*self
}
}
impl From<JoypadStatus> for u8 {
fn from(status: JoypadStatus) -> Self {
status.0
2021-03-21 02:11:45 +00:00
}
}
2021-05-04 04:11:39 +00:00
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ButtonState {
Pressed = 0,
Released = 1,
}
2021-03-21 02:11:45 +00:00
2021-05-04 04:11:39 +00:00
impl From<u8> for ButtonState {
fn from(byte: u8) -> Self {
match byte {
0b00 => Self::Pressed,
0b01 => Self::Released,
_ => unreachable!("{:#04X} is not a valid value for ButtonStatus", byte),
2021-03-21 02:11:45 +00:00
}
}
}
2021-03-21 02:11:45 +00:00
2021-05-04 04:11:39 +00:00
impl From<ButtonState> for u8 {
fn from(status: ButtonState) -> Self {
status as u8
2021-03-21 02:11:45 +00:00
}
}
2021-03-21 02:11:45 +00:00
2021-05-04 04:11:39 +00:00
impl From<bool> for ButtonState {
fn from(value: bool) -> Self {
match value {
true => Self::Pressed,
false => Self::Released,
2021-03-21 02:11:45 +00:00
}
}
}
2021-05-04 04:11:39 +00:00
#[derive(Debug, Clone, Copy, PartialEq)]
enum RowState {
Selected,
Deselected,
2021-03-21 02:11:45 +00:00
}
2021-05-04 04:11:39 +00:00
impl From<u8> for RowState {
2021-03-21 02:11:45 +00:00
fn from(byte: u8) -> Self {
match byte {
0b00 => Self::Selected,
0b01 => Self::Deselected,
_ => unreachable!("{:#04X} is not a valid value for ButtonRowStatus", byte),
2021-03-21 02:11:45 +00:00
}
}
}
2021-05-04 04:11:39 +00:00
impl From<RowState> for u8 {
fn from(status: RowState) -> Self {
status as u8
2021-03-21 02:11:45 +00:00
}
}