Refactor joypad

This commit is contained in:
Franco Colmenarez 2021-11-15 09:15:31 -05:00
parent d601f2e67e
commit c1dc14680e
2 changed files with 30 additions and 22 deletions

View File

@ -1,3 +1,5 @@
use std::rc::Rc;
use std::cell::RefCell;
use crate::utils::{ use crate::utils::{
get_bit, get_bit,
BitIndex, BitIndex,
@ -52,11 +54,11 @@ pub struct Bus {
game_rom: ROM, game_rom: ROM,
data: [u8; 0x10000], data: [u8; 0x10000],
pub reset_timer: bool, pub reset_timer: bool,
pub joypad: Joypad, joypad: Rc<RefCell<Joypad>>,
} }
impl Bus { impl Bus {
pub fn new() -> Self { pub fn new(joypad: Rc<RefCell<Joypad>>) -> Self {
let args: Vec<String> = std::env::args().collect(); let args: Vec<String> = std::env::args().collect();
if args.len() < 2 { if args.len() < 2 {
println!("Please, specify a ROM file"); println!("Please, specify a ROM file");
@ -97,7 +99,7 @@ impl Bus {
data, data,
game_rom, game_rom,
reset_timer: false, reset_timer: false,
joypad: Joypad::new(), joypad,
} }
} }
@ -107,7 +109,7 @@ impl Bus {
} else if address == INTERRUPT_ENABLE_ADDRESS || address == INTERRUPT_FLAG_ADDRESS { } else if address == INTERRUPT_ENABLE_ADDRESS || address == INTERRUPT_FLAG_ADDRESS {
return 0b11100000 | self.data[address as usize]; return 0b11100000 | self.data[address as usize];
} else if address == JOYPAD_ADDRESS { } else if address == JOYPAD_ADDRESS {
return self.joypad.read(self.data[address as usize]); return self.joypad.borrow().read(self.data[address as usize]);
} }
self.data[address as usize] self.data[address as usize]
} }

View File

@ -1,4 +1,6 @@
// use std::{thread, time}; // use std::{thread, time};
use std::rc::Rc;
use std::cell::RefCell;
use winit_input_helper::WinitInputHelper; use winit_input_helper::WinitInputHelper;
use winit::event::{VirtualKeyCode}; use winit::event::{VirtualKeyCode};
@ -6,91 +8,95 @@ use crate::cpu::{CPU, Cycles, Interrupt};
use crate::ppu::PPU; use crate::ppu::PPU;
use crate::bus::Bus; use crate::bus::Bus;
use crate::timer::Timer; use crate::timer::Timer;
use crate::joypad::{Button}; use crate::joypad::{Joypad, Button};
pub struct Emulator { pub struct Emulator {
cpu: CPU, cpu: CPU,
ppu: PPU, ppu: PPU,
bus: Bus, bus: Bus,
timer: Timer, timer: Timer,
joypad: Rc<RefCell<Joypad>>,
} }
impl Emulator { impl Emulator {
pub fn new() -> Self { pub fn new() -> Self {
let joypad = Rc::new(RefCell::new(Joypad::new()));
Self { Self {
cpu: CPU::new(), cpu: CPU::new(),
ppu: PPU::new(), ppu: PPU::new(),
bus: Bus::new(), bus: Bus::new(Rc::clone(&joypad)),
timer: Timer::new(), timer: Timer::new(),
joypad: joypad,
} }
} }
pub fn handle_input(&mut self, input: &WinitInputHelper) { pub fn handle_input(&mut self, input: &WinitInputHelper) {
let mut change = false; let mut change = false;
let mut joypad = self.joypad.borrow_mut();
if input.key_pressed(VirtualKeyCode::K) { if input.key_pressed(VirtualKeyCode::K) {
change = true; change = true;
self.bus.joypad.press(Button::A); joypad.press(Button::A);
} }
if input.key_pressed(VirtualKeyCode::J) { if input.key_pressed(VirtualKeyCode::J) {
change = true; change = true;
self.bus.joypad.press(Button::B); joypad.press(Button::B);
} }
if input.key_pressed(VirtualKeyCode::W) { if input.key_pressed(VirtualKeyCode::W) {
change = true; change = true;
self.bus.joypad.press(Button::Up); joypad.press(Button::Up);
} }
if input.key_pressed(VirtualKeyCode::S) { if input.key_pressed(VirtualKeyCode::S) {
change = true; change = true;
self.bus.joypad.press(Button::Down); joypad.press(Button::Down);
} }
if input.key_pressed(VirtualKeyCode::A) { if input.key_pressed(VirtualKeyCode::A) {
change = true; change = true;
self.bus.joypad.press(Button::Left); joypad.press(Button::Left);
} }
if input.key_pressed(VirtualKeyCode::D) { if input.key_pressed(VirtualKeyCode::D) {
change = true; change = true;
self.bus.joypad.press(Button::Right); joypad.press(Button::Right);
} }
if input.key_pressed(VirtualKeyCode::N) { if input.key_pressed(VirtualKeyCode::N) {
change = true; change = true;
self.bus.joypad.press(Button::Start); joypad.press(Button::Start);
} }
if input.key_pressed(VirtualKeyCode::B) { if input.key_pressed(VirtualKeyCode::B) {
change = true; change = true;
self.bus.joypad.press(Button::Select); joypad.press(Button::Select);
} }
if input.key_released(VirtualKeyCode::K) { if input.key_released(VirtualKeyCode::K) {
change = true; change = true;
self.bus.joypad.release(Button::A); joypad.release(Button::A);
} }
if input.key_released(VirtualKeyCode::J) { if input.key_released(VirtualKeyCode::J) {
change = true; change = true;
self.bus.joypad.release(Button::B); joypad.release(Button::B);
} }
if input.key_released(VirtualKeyCode::W) { if input.key_released(VirtualKeyCode::W) {
change = true; change = true;
self.bus.joypad.release(Button::Up); joypad.release(Button::Up);
} }
if input.key_released(VirtualKeyCode::S) { if input.key_released(VirtualKeyCode::S) {
change = true; change = true;
self.bus.joypad.release(Button::Down); joypad.release(Button::Down);
} }
if input.key_released(VirtualKeyCode::A) { if input.key_released(VirtualKeyCode::A) {
change = true; change = true;
self.bus.joypad.release(Button::Left); joypad.release(Button::Left);
} }
if input.key_released(VirtualKeyCode::D) { if input.key_released(VirtualKeyCode::D) {
change = true; change = true;
self.bus.joypad.release(Button::Right); joypad.release(Button::Right);
} }
if input.key_released(VirtualKeyCode::N) { if input.key_released(VirtualKeyCode::N) {
change = true; change = true;
self.bus.joypad.release(Button::Start); joypad.release(Button::Start);
} }
if input.key_released(VirtualKeyCode::B) { if input.key_released(VirtualKeyCode::B) {
change = true; change = true;
self.bus.joypad.release(Button::Select); joypad.release(Button::Select);
} }
if change { if change {
self.bus.set_interrupt_flag(Interrupt::Joypad, true); self.bus.set_interrupt_flag(Interrupt::Joypad, true);