Implement User Input, add req_redraw flag, fix Fx15 bug

This commit is contained in:
Rekai Musuka 2020-07-14 22:44:26 -05:00
parent 9b88965cab
commit f05e01b7de
2 changed files with 105 additions and 11 deletions

View File

@ -8,13 +8,14 @@ pub struct Chip8 {
i: u16, i: u16,
pc: u16, pc: u16,
sp: u8, sp: u8,
key: Keypad,
v: [u8; 16], v: [u8; 16],
stack: [u16; 16], stack: [u16; 16],
memory: [u8; 4096], memory: [u8; 4096],
delay: Timer, delay: Timer,
sound: Timer, sound: Timer,
pub key: Keypad,
pub display: Display, pub display: Display,
pub request_redraw: bool,
} }
impl Default for Chip8 { impl Default for Chip8 {
@ -23,13 +24,14 @@ impl Default for Chip8 {
i: 0, i: 0,
pc: 0x200, // Progrm counter starts at 0x200 pc: 0x200, // Progrm counter starts at 0x200
sp: 0, sp: 0,
key: Default::default(),
v: [0; 16], v: [0; 16],
stack: [0; 16], stack: [0; 16],
memory: [0; 4096], memory: [0; 4096],
delay: Default::default(), delay: Default::default(),
sound: Default::default(), sound: Default::default(),
display: Display::default(), key: Default::default(),
display: Default::default(),
request_redraw: false,
}; };
chip8.load_font_set(); chip8.load_font_set();
@ -58,6 +60,9 @@ impl Chip8 {
]; ];
pub fn execute_cycle(&mut self) { pub fn execute_cycle(&mut self) {
// Reset Request Redraw
self.request_redraw = false;
let opcode = self.get_opcode(); let opcode = self.get_opcode();
self.pc += 2; // Immediately increment the Program Counter self.pc += 2; // Immediately increment the Program Counter
@ -163,7 +168,7 @@ impl Chip8 {
// Fx0A // Fx0A
(0xF, _, 0x0, 0xA) => self.loop_until_key_vx(x), (0xF, _, 0x0, 0xA) => self.loop_until_key_vx(x),
// Fx15 // Fx15
(0xF, _, 0x1, 0x15) => self.set_delay_to_vx(x), (0xF, _, 0x1, 0x5) => self.set_delay_to_vx(x),
// Fx18 // Fx18
(0xF, _, 0x1, 0x8) => self.set_sound_to_vx(x), (0xF, _, 0x1, 0x8) => self.set_sound_to_vx(x),
// Fx1E // Fx1E
@ -177,13 +182,14 @@ impl Chip8 {
// Fx65 // Fx65
(0xF, _, 0x6, 0x5) => self.load_into_vx_from_i(x), (0xF, _, 0x6, 0x5) => self.load_into_vx_from_i(x),
// Otherwise... // Otherwise...
_ => panic!("UNIMPLEMENTED OPCODE: {:#x}", opcode), _ => eprintln!("UNIMPLEMENTED OPCODE: {:#x}", opcode),
} }
} }
fn cls(&mut self) { fn cls(&mut self) {
// Clear the display // Clear the display
self.display.clear(); self.display.clear();
self.request_redraw = true;
} }
fn ret(&mut self) { fn ret(&mut self) {
@ -338,6 +344,7 @@ impl Chip8 {
let collision = self.display.draw_sprite(draw_pos, sprite_data); let collision = self.display.draw_sprite(draw_pos, sprite_data);
self.v[0xF] = if collision { 1 } else { 0 }; self.v[0xF] = if collision { 1 } else { 0 };
self.request_redraw = true;
} }
fn skip_on_press(&mut self, x: u8) { fn skip_on_press(&mut self, x: u8) {

View File

@ -21,7 +21,7 @@ fn main() {
let window = init_window(&event_loop); let window = init_window(&event_loop);
let mut pixels = init_pixels(&window); 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"); chip8.load_rom(rom_path).expect("Unable to load ROM");
event_loop.run(move |event, _, control_flow| { event_loop.run(move |event, _, control_flow| {
@ -38,21 +38,108 @@ fn main() {
} }
if input.update(&event) { if input.update(&event) {
if input.key_pressed(VirtualKeyCode::Escape) || input.quit() { handle_input(&mut chip8, &mut input, control_flow);
*control_flow = ControlFlow::Exit;
return;
}
if let Some(size) = input.window_resized() { if let Some(size) = input.window_resized() {
pixels.resize(size.width, size.height); pixels.resize(size.width, size.height);
} }
chip8.execute_cycle(); 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 { fn init_pixels(window: &Window) -> Pixels {
let surface = Surface::create(window); let surface = Surface::create(window);
let texture = SurfaceTexture::new(WIDTH, HEIGHT, surface); let texture = SurfaceTexture::new(WIDTH, HEIGHT, surface);