diff --git a/src/processor/memory.rs b/src/processor/memory.rs index 25d4380..7acc887 100644 --- a/src/processor/memory.rs +++ b/src/processor/memory.rs @@ -1,10 +1,7 @@ -use self::mmio::{Joypad, JoypadBank}; +use self::mmio::Joypad; pub use self::rom::Rom; -use crate::{ - processor::{get_bit, SplitRegister}, - verbose_println, -}; -use gilrs::{Button, ConnectedGamepadsIterator}; +use crate::{processor::SplitRegister, verbose_println}; +use gilrs::ConnectedGamepadsIterator; use minifb::Key; use std::io::{stdout, Write}; @@ -136,12 +133,7 @@ impl Memory { match address { 0xFF00 => { // joypad - if !get_bit(data, 5) { - self.joypad.bank_sel = JoypadBank::Action - } - if !get_bit(data, 4) { - self.joypad.bank_sel = JoypadBank::Direction - } + self.joypad.mmio_write(data); } 0xFF02 => { if data == 0x81 { @@ -214,37 +206,7 @@ impl Memory { keys: Vec, gamepads: ConnectedGamepadsIterator, ) -> bool { - let old = self.joypad; - self.joypad = Joypad { - bank_sel: self.joypad.bank_sel, - down: false, - up: false, - left: false, - right: false, - start: false, - select: false, - b: false, - a: false, - }; - for (_, pad) in gamepads { - self.joypad.down |= pad.is_pressed(Button::DPadDown); - self.joypad.up |= pad.is_pressed(Button::DPadUp); - self.joypad.left |= pad.is_pressed(Button::DPadLeft); - self.joypad.right |= pad.is_pressed(Button::DPadRight); - self.joypad.start |= pad.is_pressed(Button::Start); - self.joypad.select |= pad.is_pressed(Button::Select); - self.joypad.a |= pad.is_pressed(Button::East); - self.joypad.b |= pad.is_pressed(Button::South); - } - self.joypad.down |= keys.contains(&Key::Down) || keys.contains(&Key::S); - self.joypad.up |= keys.contains(&Key::Up) || keys.contains(&Key::W); - self.joypad.left |= keys.contains(&Key::Left) || keys.contains(&Key::A); - self.joypad.right |= keys.contains(&Key::Right) || keys.contains(&Key::D); - self.joypad.start |= keys.contains(&Key::Equal); - self.joypad.select |= keys.contains(&Key::Minus); - self.joypad.a |= keys.contains(&Key::Apostrophe); - self.joypad.b |= keys.contains(&Key::Semicolon); - self.joypad != old + self.joypad.update_pressed_keys(keys, gamepads) } pub(super) fn cpu_ram_init(&mut self) { diff --git a/src/processor/memory/mmio/joypad.rs b/src/processor/memory/mmio/joypad.rs index 801ed0d..02ed6e7 100644 --- a/src/processor/memory/mmio/joypad.rs +++ b/src/processor/memory/mmio/joypad.rs @@ -1,22 +1,24 @@ -use crate::util::clear_bit; +use crate::util::{clear_bit, get_bit}; +use gilrs::{Button, ConnectedGamepadsIterator}; +use minifb::Key; #[derive(Debug, Clone, Copy, PartialEq)] -pub enum JoypadBank { +enum JoypadBank { Action, Direction, } #[derive(Debug, Clone, Copy, PartialEq)] pub struct Joypad { - pub bank_sel: JoypadBank, - pub down: bool, - pub up: bool, - pub left: bool, - pub right: bool, - pub start: bool, - pub select: bool, - pub b: bool, - pub a: bool, + bank_sel: JoypadBank, + down: bool, + up: bool, + left: bool, + right: bool, + start: bool, + select: bool, + b: bool, + a: bool, } impl Joypad { @@ -56,6 +58,53 @@ impl Joypad { } reg } + + pub fn mmio_write(&mut self, data: u8) { + if !get_bit(data, 5) { + self.bank_sel = JoypadBank::Action; + } + if !get_bit(data, 4) { + self.bank_sel = JoypadBank::Direction; + } + } + + pub fn update_pressed_keys( + &mut self, + keys: Vec, + gamepads: ConnectedGamepadsIterator, + ) -> bool { + let old = *self; + *self = Joypad { + bank_sel: self.bank_sel, + down: false, + up: false, + left: false, + right: false, + start: false, + select: false, + b: false, + a: false, + }; + for (_, pad) in gamepads { + self.down |= pad.is_pressed(Button::DPadDown); + self.up |= pad.is_pressed(Button::DPadUp); + self.left |= pad.is_pressed(Button::DPadLeft); + self.right |= pad.is_pressed(Button::DPadRight); + self.start |= pad.is_pressed(Button::Start); + self.select |= pad.is_pressed(Button::Select); + self.a |= pad.is_pressed(Button::East); + self.b |= pad.is_pressed(Button::South); + } + self.down |= keys.contains(&Key::Down) || keys.contains(&Key::S); + self.up |= keys.contains(&Key::Up) || keys.contains(&Key::W); + self.left |= keys.contains(&Key::Left) || keys.contains(&Key::A); + self.right |= keys.contains(&Key::Right) || keys.contains(&Key::D); + self.start |= keys.contains(&Key::Equal); + self.select |= keys.contains(&Key::Minus); + self.a |= keys.contains(&Key::Apostrophe); + self.b |= keys.contains(&Key::Semicolon); + *self != old + } } impl Default for Joypad { diff --git a/src/processor/memory/mmio/mod.rs b/src/processor/memory/mmio/mod.rs index 1b205fc..b00cd38 100644 --- a/src/processor/memory/mmio/mod.rs +++ b/src/processor/memory/mmio/mod.rs @@ -1,4 +1,4 @@ mod apu; mod joypad; pub use apu::Apu; -pub use joypad::{Joypad, JoypadBank}; +pub use joypad::Joypad;