diff --git a/Cargo.lock b/Cargo.lock index 89d6383..ccb954a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -152,6 +152,7 @@ checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" name = "chip8" version = "0.1.0" dependencies = [ + "lazy_static", "pixels", "rand", "rodio", diff --git a/Cargo.toml b/Cargo.toml index 96206e8..7c3ce74 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,3 +12,4 @@ rand = "0.7.3" winit = "0.22.2" winit_input_helper = "0.7.0" rodio = "0.11.0" +lazy_static = "1.4.0" diff --git a/src/emu.rs b/src/emu.rs index a809850..f47311e 100644 --- a/src/emu.rs +++ b/src/emu.rs @@ -62,7 +62,6 @@ impl Chip8 { pub fn execute_cycle(&mut self) { // Reset Request Redraw self.request_redraw = false; - let opcode = self.get_opcode(); self.pc += 2; // Immediately increment the Program Counter diff --git a/src/main.rs b/src/main.rs index d38fdf5..982cafe 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,7 +1,4 @@ -// I used: http://devernay.free.fr/hacks/chip8/C8TECH10.HTM#00E0 -// and https://en.wikipedia.org/wiki/CHIP-8#Opcode_table -// for information about how to implement a CHIP-8 Emulator -use chip8::emu::Chip8; +use chip8::{emu::Chip8, periph::TimerManager}; use pixels::{wgpu::Surface, Pixels, SurfaceTexture}; use std::path::Path; use std::time::{Duration, Instant}; @@ -25,6 +22,8 @@ fn main() { let rom_path = Path::new("./games/c8games/INVADERS"); chip8.load_rom(rom_path).expect("Unable to load ROM"); + TimerManager::start(); + let mut start = Instant::now(); let frametime = Duration::from_nanos(1e+9 as u64 / OPCODES_PER_SECOND); diff --git a/src/periph.rs b/src/periph.rs index ed93f57..3966abb 100644 --- a/src/periph.rs +++ b/src/periph.rs @@ -1,6 +1,14 @@ +use lazy_static::lazy_static; use rodio::{source::SineWave, Sink}; +use std::sync::Mutex; +use std::thread; use std::time::{Duration, Instant}; +lazy_static! { + static ref SOUND_TIMER: Mutex = Mutex::new(Timer::default().with_beep()); + static ref DELAY_TIMER: Mutex = Mutex::new(Timer::default()); +} + #[derive(Copy, Clone)] pub struct Display { pub buf: [u8; Self::WIDTH as usize * Self::HEIGHT as usize], @@ -57,6 +65,25 @@ impl Default for Display { } } +pub struct TimerManager; + +impl TimerManager { + pub fn start() { + thread::spawn(|| { + let duration = Duration::from_nanos(1e+9 as u64 / 60); + let mut start = Instant::now(); + + loop { + if Instant::now().duration_since(start) > duration { + SOUND_TIMER.lock().unwrap().tick(); + DELAY_TIMER.lock().unwrap().tick(); + start = Instant::now(); + } + } + }); + } +} + #[derive(Debug, Copy, Clone)] pub struct Timer { remaining: u8,