commit 00098d83918691e91c4ecd0f18bd9e542c5ce9a1 from: Witcher01 date: Sat Jul 24 21:41:04 2021 UTC changed arrays to vecs, video driver only holds vec commit - e4b3bdecac0878c575ac410513582983b59f82eb commit + 00098d83918691e91c4ecd0f18bd9e542c5ce9a1 blob - 4b055bbd7b017259a2000c802efb1f80797b9570 blob + 11a1422a4ad5b4db09bfa55ee568cb7b7a36c4d9 --- src/chip8.rs +++ src/chip8.rs @@ -1,40 +1,76 @@ +use crate::drivers::VideoDriver; + #[derive(Debug)] /// Represents a Chip8 machine pub struct Chip8 { /// Memory of 4096 8 bit wide locations /// 0x000 - 0x1FF is usually reserved for the interpreter /// 0x200 is where most Chip8 programs start - mem: [u8; 4096], - /// 16 registers, commonly named V0-VF - regs: [u8; 16], - /// 12 bit wide address register + mem: Vec, + /// 16 registers, commonly named V0-VF. + regs: Vec, + /// 12 bit wide address register. i_reg: u16, - /// 16-bit Program Counter + /// 16-bit Program Counter. pc: u16, - /// Call stack with a maximum size of 16 - stack: [u16; 16], - /// Stack pointer, pointing to the topmost level of the stack + /// Call stack with a maximum size of 16. + stack: Vec, + /// Stack pointer, pointing to the topmost level of the stack. stack_pointer: u8, /// Delay timer - /// The value of timer is being decremented at a rate of 60Hz + /// The value of timer is being decremented at a rate of 60Hz. delay_timer: u8, /// Sound timer - /// The value of this timer is being decremented at a rate of 60Hz + /// The value of this timer is being decremented at a rate of 60Hz. sound_timer: u8, + /// Video Driver + video_driver: VideoDriver, } -// should be implemented ourselves since Default is not implemented for array with sizes > 32 -impl Default for Chip8 { - fn default() -> Self { +/// Instructions of the Chip8. +pub enum Instruction { + /// Clears the screen. + CLS, +} + +impl Chip8 { + pub fn new() -> Self { Self { - mem: [0; 4096], - regs: [0; 16], + mem: vec![0; 4096], + regs: vec![0; 16], i_reg: 0, pc: 0, - stack: [0; 16], + stack: vec![0; 16], stack_pointer: 0, delay_timer: 0, sound_timer: 0, + video_driver: VideoDriver::new(), } } + + /// Execute a given instruction. + pub fn execute(&mut self, instruction: Instruction) -> Result<(), String> { + match instruction { + // CLS + Instruction::CLS => { + self.video_driver.clear(); + }, + }; + + Ok(()) + } } + +// this makes the code easier to read +/// Convert a raw u16 instruction to an Instruction enum. +pub fn raw_to_instruction(instruction: u16) -> Result { + match instruction { + // CLS + 0x00E0 => { + return Ok(Instruction::CLS) + }, + _ => { + return Err(format!("{:x}: not an instruction", instruction)); + } + } +} blob - 80942aa10242e5df4a275e3fbee886492b0beb37 blob + 4a0bc3f1f549d1db39b1c9566156cd08f79de702 --- src/drivers/video_driver.rs +++ src/drivers/video_driver.rs @@ -1,39 +1,22 @@ -use minifb::{Window, WindowOptions}; - // TODO: cli arg const STRETCH_FACTOR: usize = 2; const WINDOW_WIDTH: usize = 64 * STRETCH_FACTOR; const WINDOW_HEIGHT: usize = 32 * STRETCH_FACTOR; -/// Contains the window to draw to. +#[derive(Debug)] +/// Contains the buffer that will be used to draw to the window. pub struct VideoDriver { - window: Window, + buffer: Vec, } impl VideoDriver { - /// Create a new window. + /// Create a new buffer. pub fn new() -> Self { - let mut w = Window::new("yac8e", 64, 32, WindowOptions::default()) - .expect("Unable to open a window"); - - Self { window: w } + Self { buffer: vec![0; WINDOW_WIDTH * WINDOW_HEIGHT] } } - /// Draw the given array to the window. - pub fn draw(&mut self, pixels: &[u32; WINDOW_WIDTH * WINDOW_HEIGHT]) { - self.window - .update_with_buffer(pixels, WINDOW_WIDTH, WINDOW_HEIGHT) - .expect("Wrong buffer size"); - } - - /// Clears the window. + /// Clears the buffer. pub fn clear(&mut self) { - todo!(); + self.buffer.clear(); } } - -pub fn from_u8_rgb(r: u8, g: u8, b: u8) -> u32 { - let (r, g, b) = (r as u32, g as u32, b as u32); - - (r << 16) | (g << 8) | b -} blob - 66927a6fa454baaa4883edc86a7461e617fb3f8c blob + b2d6b056b7cfc8cc73a88825087bab39f390f2a8 --- src/main.rs +++ src/main.rs @@ -1,11 +1,16 @@ mod chip8; mod drivers; -use drivers::VideoDriver; +use chip8::Chip8; +use minifb::{Window, WindowOptions}; + fn main() -> Result<(), String> { - let v = VideoDriver::new(); + let mut w = Window::new("yac8e", 64, 32, WindowOptions::default()) + .expect("Unable to open a window"); + let chip8 = Chip8::new(); + std::thread::sleep(std::time::Duration::from_secs(1)); Ok(())