From 40a3f4c812b180e7c49bd55051d787369e0e4d4e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Magalh=C3=A3es?= <joamag@gmail.com> Date: Wed, 6 Jul 2022 17:38:45 +0100 Subject: [PATCH] feat: initial support for key pressing --- examples/sdl/src/main.rs | 30 ++++++++++++++++++++++++++++-- src/cpu.rs | 6 ++++++ src/gb.rs | 14 +++++++++++++- src/mmu.rs | 4 ++++ src/pad.rs | 30 ++++++++++++++++++++++++++++++ 5 files changed, 81 insertions(+), 3 deletions(-) diff --git a/examples/sdl/src/main.rs b/examples/sdl/src/main.rs index 437fdbb0..ecc0eeae 100644 --- a/examples/sdl/src/main.rs +++ b/examples/sdl/src/main.rs @@ -1,10 +1,11 @@ use boytacean::{ gb::GameBoy, + pad::PadKey, ppu::{DISPLAY_HEIGHT, DISPLAY_WIDTH}, }; use sdl2::{ - event::Event, image::LoadSurface, pixels::PixelFormatEnum, surface::Surface, video::Window, - AudioSubsystem, EventPump, TimerSubsystem, VideoSubsystem, + event::Event, image::LoadSurface, keyboard::Keycode, pixels::PixelFormatEnum, surface::Surface, + video::Window, AudioSubsystem, EventPump, TimerSubsystem, VideoSubsystem, }; /// The base title to be used in the window. @@ -112,6 +113,17 @@ fn main() { while let Some(event) = graphics.event_pump.poll_event() { match event { Event::Quit { .. } => break 'main, + + Event::KeyDown { + keycode: Some(keycode), + .. + } => game_boy.key_press(key_to_pad(keycode)), + + Event::KeyUp { + keycode: Some(keycode), + .. + } => game_boy.key_lift(key_to_pad(keycode)), + _ => (), } } @@ -146,3 +158,17 @@ fn main() { graphics.timer_subsystem.delay(17); } } + +fn key_to_pad(keycode: Keycode) -> PadKey { + match keycode { + Keycode::Up => PadKey::Up, + Keycode::Down => PadKey::Down, + Keycode::Left => PadKey::Left, + Keycode::Right => PadKey::Right, + Keycode::Space => PadKey::Start, + Keycode::Return => PadKey::Select, + Keycode::A => PadKey::A, + Keycode::S => PadKey::B, + _ => PadKey::A, + } +} diff --git a/src/cpu.rs b/src/cpu.rs index 6afaf341..e56b8e5f 100644 --- a/src/cpu.rs +++ b/src/cpu.rs @@ -3,6 +3,7 @@ use core::panic; use crate::{ inst::{EXTENDED, INSTRUCTIONS}, mmu::Mmu, + pad::Pad, ppu::Ppu, }; @@ -177,6 +178,11 @@ impl Cpu { self.mmu().ppu() } + #[inline(always)] + pub fn pad(&mut self) -> &mut Pad { + self.mmu().pad() + } + #[inline(always)] pub fn halted(&self) -> bool { self.halted diff --git a/src/gb.rs b/src/gb.rs index 715b9600..b58146b6 100644 --- a/src/gb.rs +++ b/src/gb.rs @@ -2,7 +2,7 @@ use crate::{ cpu::Cpu, data::{BootRom, DMG_BOOT, DMG_BOOTIX, MGB_BOOTIX, SGB_BOOT}, mmu::Mmu, - pad::Pad, + pad::{Pad, PadKey}, ppu::{Ppu, Tile, FRAME_BUFFER_SIZE}, util::read_file, }; @@ -35,6 +35,14 @@ impl GameBoy { self.cpu.reset(); } + pub fn key_press(&mut self, key: PadKey) { + self.pad().key_press(key); + } + + pub fn key_lift(&mut self, key: PadKey) { + self.pad().key_lift(key); + } + pub fn pc(&self) -> u16 { self.cpu.pc() } @@ -132,6 +140,10 @@ impl GameBoy { self.cpu.ppu() } + pub fn pad(&mut self) -> &mut Pad { + self.cpu.pad() + } + pub fn frame_buffer(&mut self) -> &Box<[u8; FRAME_BUFFER_SIZE]> { &(self.ppu().frame_buffer) } diff --git a/src/mmu.rs b/src/mmu.rs index 71db7029..34292804 100644 --- a/src/mmu.rs +++ b/src/mmu.rs @@ -45,6 +45,10 @@ impl Mmu { &mut self.ppu } + pub fn pad(&mut self) -> &mut Pad { + &mut self.pad + } + pub fn boot_active(&self) -> bool { self.boot_active } diff --git a/src/pad.rs b/src/pad.rs index f147fb50..5d14fd25 100644 --- a/src/pad.rs +++ b/src/pad.rs @@ -1,3 +1,6 @@ +#[cfg(feature = "wasm")] +use wasm_bindgen::prelude::*; + pub struct Pad { down: bool, up: bool, @@ -16,6 +19,7 @@ pub enum PadSelection { Direction, } +#[cfg_attr(feature = "wasm", wasm_bindgen)] pub enum PadKey { Up, Down, @@ -87,4 +91,30 @@ impl Pad { addr => panic!("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, + } + } + + 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, + } + } } -- GitLab