Implement User Input, add req_redraw flag, fix Fx15 bug
This commit is contained in:
parent
9b88965cab
commit
f05e01b7de
17
src/emu.rs
17
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) {
|
||||
|
|
97
src/main.rs
97
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();
|
||||
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);
|
||||
|
|
Loading…
Reference in New Issue