From 2e2497206f20266de66db55e2c0c8d37b525f4f7 Mon Sep 17 00:00:00 2001 From: Rekai Musuka Date: Mon, 13 Jul 2020 15:28:41 -0500 Subject: [PATCH] Begin reimplementation of CHIP-8 Dxyn opcode --- src/emu.rs | 34 ++++++---------------------------- src/main.rs | 2 +- src/periph.rs | 29 +++++++++++++++++++++++++++-- 3 files changed, 34 insertions(+), 31 deletions(-) diff --git a/src/emu.rs b/src/emu.rs index 5f879b4..771cec0 100644 --- a/src/emu.rs +++ b/src/emu.rs @@ -335,35 +335,13 @@ impl Chip8 { } fn draw(&mut self, x: u8, y: u8, n: u8) { - // read n bytes from memory starting from self.i - // then display them starting at (vx, vy) - let disp_x = self.v[x as usize]; - let disp_y = self.v[y as usize]; + let i = self.i as usize; + let draw_pos = (self.v[x as usize], self.v[y as usize]); + let sprite_data = &self.v[i..(i + n as usize)]; - let mut display_buf = self.display.buf; + let collision = self.display.draw_sprite(draw_pos, sprite_data); - let mut pixel: u8; - self.v[0xF] = 0; - - // TODO: Rewrite Your Solution to better fit - // the rest of your code base. - // http://www.multigesture.net/articles/how-to-write-an-emulator-chip-8-interpreter/ - for i in 0..(n as usize) { - // height of sprite (y-axis) - pixel = self.memory[self.i as usize + i]; - for j in 0..8 { - // Loop over the 8 bits (x-axis) - if (pixel & (0x80 >> j)) != 0 { - let index = (disp_x as usize) + j + (((disp_y as usize) + i) * 64); - - if display_buf[index] == 1 { - self.v[0xF] = 1; - } - - display_buf[index] ^= 1; - } - } - } + self.v[0xF] = if collision { 1 } else { 0 }; } fn skip_on_press(&mut self, x: u8) { @@ -524,7 +502,7 @@ mod test { chip8.cls(); // now check that everything in the display buffer is zeroed out for byte in chip8.display.buf.iter() { - assert_eq!(*byte, 0); + assert_eq!(*byte, 0x0); } } diff --git a/src/main.rs b/src/main.rs index 3c5fbb9..dece6ba 100644 --- a/src/main.rs +++ b/src/main.rs @@ -78,7 +78,7 @@ fn init_window(event_loop: &EventLoop<()>) -> Window { fn draw(chip8_gfx: &[u8], frame: &mut [u8]) { for (i, pixel) in frame.chunks_exact_mut(4).enumerate() { - let rgba = if chip8_gfx[i] != 0 { + let rgba = if chip8_gfx[i] == 1 { [0xFF, 0xFF, 0xFF, 0xFF] } else { [0x00, 0x00, 0x00, 0xFF] diff --git a/src/periph.rs b/src/periph.rs index f1875f5..ef41917 100644 --- a/src/periph.rs +++ b/src/periph.rs @@ -7,14 +7,39 @@ impl Display { const SCREEN_SIZE: usize = 64 * 32; pub fn clear(&mut self) { - self.buf = [0; Self::SCREEN_SIZE] + self.buf = [0x0; Self::SCREEN_SIZE] + } + + pub fn draw_sprite(&mut self, coords: (u8, u8), data: &[u8]) -> bool { + let x = coords.0; + let y = coords.1; + let mut set_vf = false; + // Each Byte is a row, and there are n bytes in data + // When writing, x should not change but y should be incremented + // after each iteration in the loop. + for (i, byte) in data.iter().enumerate() { + // Access every bit of the byte + for j in 0..8 { + let bit = (byte >> j) & 0x01; + let display_index = j as usize + 8 * i as usize; + + let old_value = self.buf[display_index]; + self.buf[display_index] ^= bit; + + if old_value == 0x01 && self.buf[display_index] == 0x00 { + set_vf = true; + } + } + } + + set_vf } } impl Default for Display { fn default() -> Self { Display { - buf: [0; Self::SCREEN_SIZE], + buf: [0x0; Self::SCREEN_SIZE], } } }