Begin reimplementation of CHIP-8 Dxyn opcode
This commit is contained in:
parent
f49426c371
commit
2e2497206f
34
src/emu.rs
34
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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]
|
||||
|
|
|
@ -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],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue