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,
|
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) {
|
||||||
|
|
99
src/main.rs
99
src/main.rs
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue