From f05e01b7de72c5cb91ed0e277a9ddb894c9e99ad Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Tue, 14 Jul 2020 22:44:26 -0500 Subject: [PATCH] Implement User Input, add req_redraw flag, fix Fx15 bug --- src/emu.rs | 17 ++++++--- src/main.rs | 99 +++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 105 insertions(+), 11 deletions(-) diff --git a/src/emu.rs b/src/emu.rs index 7ae98de..6ddc7d3 100644 --- a/src/emu.rs +++ b/src/emu.rs @@ -8,13 +8,14 @@ pub struct Chip8 { i: u16, pc: u16, sp: u8, - key: Keypad, v: [u8; 16], stack: [u16; 16], memory: [u8; 4096], delay: Timer, sound: Timer, + pub key: Keypad, pub display: Display, + pub request_redraw: bool, } impl Default for Chip8 { @@ -23,13 +24,14 @@ impl Default for Chip8 { i: 0, pc: 0x200, // Progrm counter starts at 0x200 sp: 0, - key: Default::default(), v: [0; 16], stack: [0; 16], memory: [0; 4096], delay: Default::default(), sound: Default::default(), - display: Display::default(), + key: Default::default(), + display: Default::default(), + request_redraw: false, }; chip8.load_font_set(); @@ -58,6 +60,9 @@ impl Chip8 { ]; pub fn execute_cycle(&mut self) { + // Reset Request Redraw + self.request_redraw = false; + let opcode = self.get_opcode(); self.pc += 2; // Immediately increment the Program Counter @@ -163,7 +168,7 @@ impl Chip8 { // Fx0A (0xF, _, 0x0, 0xA) => self.loop_until_key_vx(x), // Fx15 - (0xF, _, 0x1, 0x15) => self.set_delay_to_vx(x), + (0xF, _, 0x1, 0x5) => self.set_delay_to_vx(x), // Fx18 (0xF, _, 0x1, 0x8) => self.set_sound_to_vx(x), // Fx1E @@ -177,13 +182,14 @@ impl Chip8 { // Fx65 (0xF, _, 0x6, 0x5) => self.load_into_vx_from_i(x), // Otherwise... - _ => panic!("UNIMPLEMENTED OPCODE: {:#x}", opcode), + _ => eprintln!("UNIMPLEMENTED OPCODE: {:#x}", opcode), } } fn cls(&mut self) { // Clear the display self.display.clear(); + self.request_redraw = true; } fn ret(&mut self) { @@ -338,6 +344,7 @@ impl Chip8 { let collision = self.display.draw_sprite(draw_pos, sprite_data); self.v[0xF] = if collision { 1 } else { 0 }; + self.request_redraw = true; } fn skip_on_press(&mut self, x: u8) { diff --git a/src/main.rs b/src/main.rs index a80ae49..5e7bc5c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,7 @@ fn main() { let window = init_window(&event_loop); let mut pixels = init_pixels(&window); - let rom_path = Path::new("./games/test_opcode.ch8"); + let rom_path = Path::new("./games/c8games/INVADERS"); chip8.load_rom(rom_path).expect("Unable to load ROM"); event_loop.run(move |event, _, control_flow| { @@ -38,21 +38,108 @@ fn main() { } if input.update(&event) { - if input.key_pressed(VirtualKeyCode::Escape) || input.quit() { - *control_flow = ControlFlow::Exit; - return; - } + handle_input(&mut chip8, &mut input, control_flow); if let Some(size) = input.window_resized() { pixels.resize(size.width, size.height); } chip8.execute_cycle(); - window.request_redraw(); + if chip8.request_redraw { + window.request_redraw(); + } } }); } +fn handle_input(chip8: &mut Chip8, input: &mut WinitInputHelper, control_flow: &mut ControlFlow) { + if input.key_pressed(VirtualKeyCode::Escape) || input.quit() { + *control_flow = ControlFlow::Exit; + return; + } + + if input.key_pressed(VirtualKeyCode::Key1) { + chip8.key.set_key(0x1); + } else { + chip8.key.unset_key(0x1); + } + if input.key_pressed(VirtualKeyCode::Key2) { + chip8.key.set_key(0x2); + } else { + chip8.key.set_key(0x2); + } + if input.key_pressed(VirtualKeyCode::Key3) { + chip8.key.set_key(0x3); + } else { + chip8.key.set_key(0x3); + } + if input.key_pressed(VirtualKeyCode::Key4) { + chip8.key.set_key(0xC); + } else { + chip8.key.set_key(0xC); + } + if input.key_pressed(VirtualKeyCode::Q) { + chip8.key.set_key(0x4); + } else { + chip8.key.set_key(0x4); + } + if input.key_pressed(VirtualKeyCode::W) { + chip8.key.set_key(0x5); + } else { + chip8.key.set_key(0x5); + } + if input.key_pressed(VirtualKeyCode::E) { + chip8.key.set_key(0x6); + } else { + chip8.key.set_key(0x6); + } + if input.key_pressed(VirtualKeyCode::R) { + chip8.key.set_key(0xD); + } else { + chip8.key.set_key(0xD); + } + if input.key_pressed(VirtualKeyCode::A) { + chip8.key.set_key(0x7); + } else { + chip8.key.set_key(0x7); + } + if input.key_pressed(VirtualKeyCode::S) { + chip8.key.set_key(0x8); + } else { + chip8.key.set_key(0x8); + } + if input.key_pressed(VirtualKeyCode::D) { + chip8.key.set_key(0x9); + } else { + chip8.key.set_key(0x9); + } + if input.key_pressed(VirtualKeyCode::F) { + chip8.key.set_key(0x5); + } else { + chip8.key.set_key(0x5); + } + if input.key_pressed(VirtualKeyCode::Z) { + chip8.key.set_key(0xA); + } else { + chip8.key.set_key(0xA); + } + if input.key_pressed(VirtualKeyCode::X) { + chip8.key.set_key(0x0); + } else { + chip8.key.set_key(0x0); + } + if input.key_pressed(VirtualKeyCode::C) { + chip8.key.set_key(0xB); + } else { + chip8.key.set_key(0xB); + } + if input.key_pressed(VirtualKeyCode::V) { + chip8.key.set_key(0xF); + } else { + chip8.key.set_key(0xF); + } +} + fn init_pixels(window: &Window) -> Pixels { let surface = Surface::create(window); let texture = SurfaceTexture::new(WIDTH, HEIGHT, surface);