Compare commits

...

2 Commits

Author SHA1 Message Date
Michael Kohl 408480a4ef Update dependencies 2021-04-05 17:12:46 +07:00
Michael Kohl 026aec826e Add sound timer handling 2021-04-05 17:12:05 +07:00
5 changed files with 95 additions and 14 deletions

12
Cargo.lock generated
View File

@ -113,9 +113,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
[[package]]
name = "libc"
version = "0.2.91"
version = "0.2.92"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8916b1f6ca17130ec6568feccee27c156ad12037880833a3b842a823236502e7"
checksum = "56d855069fafbb9b344c0f962150cd2c1187975cb1c22c1522c240d8c4986714"
[[package]]
name = "memchr"
@ -161,9 +161,9 @@ checksum = "24d5f089152e60f62d28b835fbff2cd2e8dc0baf1ac13343bef92ab7eed84548"
[[package]]
name = "sdl2"
version = "0.34.3"
version = "0.34.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fcbb85f4211627a7291c83434d6bbfa723e28dcaa53c7606087e3c61929e4b9c"
checksum = "505d7a6ef5f96289a6ec50fc8b65ec75f5571f0aa94fa6ea230f6b228fa05d57"
dependencies = [
"bitflags",
"lazy_static",
@ -173,9 +173,9 @@ dependencies = [
[[package]]
name = "sdl2-sys"
version = "0.34.3"
version = "0.34.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "28d81feded049b9c14eceb4a4f6d596a98cebbd59abdba949c5552a015466d33"
checksum = "4cb164f53dbcad111de976bbf1f3083d3fcdeda88da9cfa281c70822720ee3da"
dependencies = [
"cfg-if 0.1.10",
"cmake",

55
src/chip8/audio.rs Normal file
View File

@ -0,0 +1,55 @@
use sdl2::audio::{AudioCallback, AudioDevice, AudioSpecDesired};
use sdl2::AudioSubsystem;
pub struct SquareWave {
phase_inc: f32,
phase: f32,
volume: f32,
}
impl AudioCallback for SquareWave {
type Channel = f32;
fn callback(&mut self, out: &mut [f32]) {
for x in out.iter_mut() {
*x = if self.phase <= 0.5 {
self.volume
} else {
-self.volume
};
self.phase = (self.phase + self.phase_inc) % 1.0;
}
}
}
pub struct Speaker {
pub device: AudioDevice<SquareWave>,
}
impl Speaker {
pub fn new(audio_subsystem: &AudioSubsystem) -> Self {
let spec = AudioSpecDesired {
freq: Some(5000),
channels: Some(1),
samples: None,
};
let device = audio_subsystem
.open_playback(None, &spec, |spec| SquareWave {
phase_inc: 440.0 / spec.freq as f32,
phase: 0.0,
volume: 0.25,
})
.expect("Could not initialize audio device");
Speaker { device }
}
pub fn beep(&mut self, status: bool) {
if status {
self.device.resume();
} else {
self.device.pause();
}
}
}

View File

@ -1,33 +1,55 @@
use crate::chip8::audio::Speaker;
use crate::chip8::display::Screen;
use crate::chip8::keyboard::Keyboard;
use crate::chip8::memory::Memory;
use crate::chip8::registers::{Register, Registers};
use crate::chip8::stack::Stack;
use sdl2::AudioSubsystem;
use std::{thread, time::Duration};
pub struct Chip8 {
pub memory: Memory,
pub registers: Registers,
pub stack: Stack,
pub keyboard: Keyboard,
pub screen: Screen,
pub speaker: Speaker,
}
impl Chip8 {
pub fn new() -> Chip8 {
pub fn new(audio_subsystem: &AudioSubsystem) -> Chip8 {
Chip8 {
memory: Memory::new(),
registers: Registers::new(),
stack: Stack::new(),
keyboard: Keyboard::new(),
screen: Screen::new(),
speaker: Speaker::new(audio_subsystem),
}
}
pub fn delay_if_necessary(&mut self) -> () {
pub fn handle_timers(&mut self) -> () {
self.handle_delay_timer();
self.handle_sound_timer();
}
pub fn handle_delay_timer(&mut self) -> () {
let delay_timer = self.registers.get(Register::DT);
if delay_timer > 0 {
::std::thread::sleep(::std::time::Duration::new(0, 1_000_000_000u32 / 60));
thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
self.registers.set(Register::DT, delay_timer - 1);
}
}
pub fn handle_sound_timer(&mut self) {
let sound_timer = self.registers.get(Register::ST);
let status = sound_timer > 0;
self.speaker.beep(status);
if status {
thread::sleep(Duration::new(0, 1_000_000_000u32 / 60));
self.registers.set(Register::ST, sound_timer - 1);
}
}
}

View File

@ -1,3 +1,4 @@
pub mod audio;
pub mod display;
pub mod emulator;
pub mod keyboard;

View File

@ -11,13 +11,15 @@ use sdl2::rect::Rect;
const EMULATOR_WINDOW_TITLE: &str = "Rust CHIP-8";
fn main() -> Result<(), String> {
let mut chip8 = Chip8::new();
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
let audio_subsystem = sdl_context.audio()?;
let mut chip8 = Chip8::new(&audio_subsystem);
chip8.screen.draw_sprite(24, 13, chip8.memory.read(20, 5));
chip8.screen.draw_sprite(29, 13, chip8.memory.read(10, 5));
chip8.screen.draw_sprite(34, 13, chip8.memory.read(40, 5));
let sdl_context = sdl2::init()?;
let video_subsystem = sdl_context.video()?;
chip8.registers.set(chip8::registers::Register::ST, 5);
let window = video_subsystem
.window(
@ -85,7 +87,8 @@ fn main() -> Result<(), String> {
}
canvas.present();
chip8.delay_if_necessary();
chip8.handle_delay_timer();
chip8.handle_sound_timer();
}
Ok(())