Begin reimplementation of CHIP-8 Dxyn opcode

This commit is contained in:
Rekai Musuka 2020-07-13 15:28:41 -05:00
parent f49426c371
commit 2e2497206f
3 changed files with 34 additions and 31 deletions

View File

@ -335,35 +335,13 @@ impl Chip8 {
} }
fn draw(&mut self, x: u8, y: u8, n: u8) { fn draw(&mut self, x: u8, y: u8, n: u8) {
// read n bytes from memory starting from self.i let i = self.i as usize;
// then display them starting at (vx, vy) let draw_pos = (self.v[x as usize], self.v[y as usize]);
let disp_x = self.v[x as usize]; let sprite_data = &self.v[i..(i + n as usize)];
let disp_y = self.v[y 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] = if collision { 1 } else { 0 };
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;
}
}
}
} }
fn skip_on_press(&mut self, x: u8) { fn skip_on_press(&mut self, x: u8) {
@ -524,7 +502,7 @@ mod test {
chip8.cls(); chip8.cls();
// now check that everything in the display buffer is zeroed out // now check that everything in the display buffer is zeroed out
for byte in chip8.display.buf.iter() { for byte in chip8.display.buf.iter() {
assert_eq!(*byte, 0); assert_eq!(*byte, 0x0);
} }
} }

View File

@ -78,7 +78,7 @@ fn init_window(event_loop: &EventLoop<()>) -> Window {
fn draw(chip8_gfx: &[u8], frame: &mut [u8]) { fn draw(chip8_gfx: &[u8], frame: &mut [u8]) {
for (i, pixel) in frame.chunks_exact_mut(4).enumerate() { 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] [0xFF, 0xFF, 0xFF, 0xFF]
} else { } else {
[0x00, 0x00, 0x00, 0xFF] [0x00, 0x00, 0x00, 0xFF]

View File

@ -7,14 +7,39 @@ impl Display {
const SCREEN_SIZE: usize = 64 * 32; const SCREEN_SIZE: usize = 64 * 32;
pub fn clear(&mut self) { 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 { impl Default for Display {
fn default() -> Self { fn default() -> Self {
Display { Display {
buf: [0; Self::SCREEN_SIZE], buf: [0x0; Self::SCREEN_SIZE],
} }
} }
} }