#[derive(Copy, Clone)] pub struct Display { pub buf: [u8; Self::WIDTH as usize * Self::HEIGHT as usize], } impl Display { const WIDTH: u8 = 64; const HEIGHT: u8 = 32; pub fn clear(&mut self) { self.buf = [0x0; Self::WIDTH as usize * Self::HEIGHT as usize] } pub fn draw_sprite(&mut self, coords: (u8, u8), data: &[u8]) -> bool { let x = coords.0 % Self::WIDTH; let y = coords.1 % Self::HEIGHT; let mut set_vf = false; // Each byte in data is a row, with the column being data.len() tall // This means when writing this sprite, x will change for each bit in a byte and y // should be incremented by 1 for every new byte we draw to the graphics buffer for (y_offset, byte) in data.iter().enumerate() { // Access every bit of the byte for x_bit_offset in 0..8 { // The Coordinates of this bit in the gfx buffer let gfx_x = x + (7 - x_bit_offset); let gfx_y = y + y_offset as u8; let bit = (byte >> x_bit_offset) & 0x01; // Translate the gfx_x and gfx_y to an index in the 1D buffer let gfx_i = (Self::WIDTH as usize * gfx_y as usize) + gfx_x as usize; if gfx_i >= self.buf.len() { break; // Stop Drawing this spite and move on to the next } if bit == 0x1 && self.buf[gfx_i] == 0x01 { set_vf = true; } self.buf[gfx_i] ^= bit; } } set_vf } } impl Default for Display { fn default() -> Self { Display { buf: [0x0; Self::WIDTH as usize * Self::HEIGHT as usize], } } } #[derive(Debug, Copy, Clone)] pub struct Timer { remaining: u8, enabled: bool, } impl Default for Timer { fn default() -> Self { Timer { remaining: 0, enabled: false, } } } impl Timer { pub fn set(&mut self, secs: u8) { self.remaining = secs; self.enabled = true; } pub fn get(&self) -> u8 { self.remaining } pub fn tick(&mut self) { if self.enabled { self.remaining -= 1; if self.remaining == 0 { self.enabled = false; } } } } #[derive(Debug, Copy, Clone)] pub struct Keypad { keys: [bool; 16], } impl Default for Keypad { fn default() -> Self { Self { keys: [false; 16] } } } impl Keypad { pub fn get_any_pressed(&self) -> Option { for (i, key) in self.keys.iter().enumerate() { if *key { return Some(i as u8); } } None } pub fn reset(&mut self) { self.keys = [false; 16]; } pub fn get_overview(&self) -> [bool; 16] { self.keys } pub fn is_pressed(&self, key: u8) -> bool { self.keys[key as usize] } pub fn set_all(&mut self, keys: [bool; 16]) { self.keys = keys; } pub fn set_key(&mut self, index: usize) { self.keys[index] = true; } pub fn unset_key(&mut self, index: usize) { self.keys[index] = false; } }