input handling

This commit is contained in:
Alex Janka 2023-02-07 09:09:52 +11:00
parent 3725382752
commit b363de3608
2 changed files with 96 additions and 3 deletions

View file

@ -248,12 +248,12 @@ impl CPU {
} }
fn enter_vblank(&mut self, lcdc: &LCDC) { fn enter_vblank(&mut self, lcdc: &LCDC) {
self.memory.update_pressed_keys(self.window.get_keys());
self.gpu.mode = DrawMode::VBlank; self.gpu.mode = DrawMode::VBlank;
if lcdc.enable { if lcdc.enable {
self.render_window(); self.render_window();
self.memory.set(0xFF0F, set_bit(self.memory.get(0xFF0F), 0)); self.memory.set(0xFF0F, set_bit(self.memory.get(0xFF0F), 0));
} }
// println!("lcdc: {:#?}", lcdc);
} }
fn exit_vblank(&mut self) { fn exit_vblank(&mut self) {

View file

@ -1,10 +1,84 @@
use std::io::{stdout, Write}; use std::io::{stdout, Write};
use minifb::Key;
use crate::verbose_println; use crate::verbose_println;
use super::{clear_bit, get_bit};
pub(crate) type Address = u16; pub(crate) type Address = u16;
pub(crate) type ROM = Vec<u8>; pub(crate) type ROM = Vec<u8>;
enum JoypadBank {
Action,
Direction,
}
struct Joypad {
bank_sel: JoypadBank,
down: bool,
up: bool,
left: bool,
right: bool,
start: bool,
select: bool,
b: bool,
a: bool,
}
impl Joypad {
fn as_register(&self) -> u8 {
let mut reg = 0xFF;
match self.bank_sel {
JoypadBank::Action => {
if self.start {
reg = clear_bit(reg, 3);
}
if self.select {
reg = clear_bit(reg, 2);
}
if self.b {
reg = clear_bit(reg, 1);
}
if self.a {
reg = clear_bit(reg, 0);
}
}
JoypadBank::Direction => {
if self.down {
reg = clear_bit(reg, 3);
}
if self.up {
reg = clear_bit(reg, 2);
}
if self.left {
reg = clear_bit(reg, 1);
}
if self.right {
reg = clear_bit(reg, 0);
}
}
}
reg
}
}
impl Default for Joypad {
fn default() -> Self {
Self {
bank_sel: JoypadBank::Action,
down: false,
up: false,
left: false,
right: false,
start: false,
select: false,
b: false,
a: false,
}
}
}
#[allow(dead_code)] #[allow(dead_code)]
pub struct Memory { pub struct Memory {
pub(super) bootrom: ROM, pub(super) bootrom: ROM,
@ -20,6 +94,7 @@ pub struct Memory {
pub(super) ime_scheduled: u8, pub(super) ime_scheduled: u8,
pub(super) io: [u8; 76], pub(super) io: [u8; 76],
pub(super) user_mode: bool, pub(super) user_mode: bool,
joypad: Joypad,
} }
impl Memory { impl Memory {
@ -38,6 +113,7 @@ impl Memory {
ime_scheduled: 0x0, ime_scheduled: 0x0,
io: [0xFF; 76], io: [0xFF; 76],
user_mode: false, user_mode: false,
joypad: Joypad::default(),
} }
} }
@ -66,7 +142,7 @@ impl Memory {
return self.oam[(address - 0xFE00) as usize]; return self.oam[(address - 0xFE00) as usize];
} }
0xFEA0..0xFF00 => { 0xFEA0..0xFF00 => {
return 0x0; return 0xFF;
} }
0xFF00..0xFF4C => self.get_io(address), 0xFF00..0xFF4C => self.get_io(address),
0xFF4C..0xFF80 => { 0xFF4C..0xFF80 => {
@ -133,7 +209,7 @@ impl Memory {
fn get_io(&self, address: Address) -> u8 { fn get_io(&self, address: Address) -> u8 {
if address == 0xFF00 { if address == 0xFF00 {
return 0xFF; return self.joypad.as_register();
} }
return self.io[(address - 0xFF00) as usize]; return self.io[(address - 0xFF00) as usize];
} }
@ -153,6 +229,12 @@ impl Memory {
0xFF04 => self.io[addr_l] = 0, 0xFF04 => self.io[addr_l] = 0,
0xFF00 => { 0xFF00 => {
// joypad // joypad
if !get_bit(data, 5) {
self.joypad.bank_sel = JoypadBank::Action
}
if !get_bit(data, 4) {
self.joypad.bank_sel = JoypadBank::Direction
}
} }
0xFF11 | 0xFF14 | 0xFF16 | 0xFF19 | 0xFF1E | 0xFF23 | 0xFF26 => { 0xFF11 | 0xFF14 | 0xFF16 | 0xFF19 | 0xFF1E | 0xFF23 | 0xFF26 => {
// sound // sound
@ -176,4 +258,15 @@ impl Memory {
} }
} }
} }
pub fn update_pressed_keys(&mut self, keys: Vec<Key>) {
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);
}
} }