[ref] Cleanup

This commit is contained in:
2024-02-21 18:52:26 +05:30
parent 7f568f63e1
commit 20c90af201
5 changed files with 41 additions and 33 deletions

View File

@@ -1,8 +1,10 @@
use clap::Parser; use clap::Parser;
#[derive(Debug,Parser)] #[derive(Debug, Parser)]
#[command(version, about, long_about = "Byte Pusher Emulator")] #[command(version, about, author)]
pub struct BytePusherArgs{ pub struct BytePusherArgs {
#[arg(short,long)] #[arg(short, long, help = "ROM file to load")]
pub file_name:Option<String> pub file_name: Option<String>,
#[arg(short, long, help = "Scale at which to draw", default_value_t = 2.0)]
pub draw_scale: f32,
} }

View File

@@ -8,7 +8,10 @@ use crate::misc::error::EmulatorError;
use crate::misc::result::EmulatorResult; use crate::misc::result::EmulatorResult;
pub const AUDIO_BUFFER_SIZE: usize = 256; pub const AUDIO_BUFFER_SIZE: usize = 256;
const I8_SIGN_BYTE: u8 = 0x80;
const AUDIO_REG_START: usize = 6;
const AUDIO_REG_LEN: usize = 2;
const AUDIO_REG_END: usize = AUDIO_REG_START + AUDIO_REG_LEN -1;
pub struct AudioProcessor<'a> { pub struct AudioProcessor<'a> {
ram: &'a RamMemory, ram: &'a RamMemory,
@@ -31,6 +34,7 @@ impl<'a> AudioProcessor<'a> {
} }
} }
impl<'a> AudioProcessor<'a> { impl<'a> AudioProcessor<'a> {
pub fn queue(&mut self) -> EmulatorResult<()> { pub fn queue(&mut self) -> EmulatorResult<()> {
let audio_base_reg = (self.get_audio_base_reg() as u32) << 8; let audio_base_reg = (self.get_audio_base_reg() as u32) << 8;
@@ -39,22 +43,22 @@ impl<'a> AudioProcessor<'a> {
// The CPU frame timing is just a little less than 60 fps to prevent audio stutter. // The CPU frame timing is just a little less than 60 fps to prevent audio stutter.
// We will then wait for audio to drain to adjust frame timing // We will then wait for audio to drain to adjust frame timing
if self.audio_queue.size() == 0 { if self.audio_queue.size() == 0 {
log::trace!("Detected Queue empty!"); log::info!("Detected Queue empty! Audio stutter may occur");
} }
while self.audio_queue.size() > 32 { while self.audio_queue.size() > (AUDIO_BUFFER_SIZE / 2) as u32 {
::std::thread::sleep(Duration::from_micros(1)) ::std::thread::sleep(Duration::from_micros(1))
} }
self.ram.try_copy_block(audio_base_reg, fb)?; self.ram.try_copy_block(audio_base_reg, fb)?;
//convert to u8 audio format (Bytepusher stores it as "i8") //convert to u8 audio format (Bytepusher stores it as "i8")
fb.iter_mut().for_each(|item|{ fb.iter_mut().for_each(|item|{
*item^= 0x80; *item ^= I8_SIGN_BYTE;
}); });
self.audio_queue.queue_audio(fb).map_err(|s| { EmulatorError::OtherError(Some(AUDIO), s) }) self.audio_queue.queue_audio(fb).map_err(|s| { EmulatorError::OtherError(Some(AUDIO), s) })
} }
fn get_audio_base_reg(&self) -> u16 { fn get_audio_base_reg(&self) -> u16 {
let data = self.ram.get_data_ref(); let data = self.ram.get_data_ref();
let audio_base_reg = data.get(6..8).unwrap(); let audio_base_reg = data.get(AUDIO_REG_START..=AUDIO_REG_END).unwrap();
read_big_endian_u16(audio_base_reg.try_into().unwrap()) read_big_endian_u16(audio_base_reg.try_into().unwrap())
} }
} }

View File

@@ -5,7 +5,8 @@ use crate::misc::error::DeviceType::GRAPHICS;
use crate::misc::error::EmulatorError; use crate::misc::error::EmulatorError;
use crate::misc::result::EmulatorResult; use crate::misc::result::EmulatorResult;
pub const DEVICE_FRAMEBUFFER_SIZE: usize = 256 * 256; pub const DEVICE_RESOLUTION: usize = 256;
pub const DEVICE_FRAMEBUFFER_SIZE: usize = DEVICE_RESOLUTION * DEVICE_RESOLUTION;
#[derive(Debug)] #[derive(Debug)]
pub struct GraphicsProcessor<'a> { pub struct GraphicsProcessor<'a> {

View File

@@ -13,7 +13,7 @@ use simple_logger::SimpleLogger;
use crate::args::BytePusherArgs; use crate::args::BytePusherArgs;
use crate::emu::audio::AudioProcessor; use crate::emu::audio::AudioProcessor;
use crate::emu::cpu::Cpu; use crate::emu::cpu::Cpu;
use crate::emu::graphics::GraphicsProcessor; use crate::emu::graphics::{DEVICE_RESOLUTION, GraphicsProcessor};
use crate::emu::keyboard::Keyboard; use crate::emu::keyboard::Keyboard;
use crate::emu::memory::{MEM_LENGTH, RamMemory}; use crate::emu::memory::{MEM_LENGTH, RamMemory};
use crate::graphics::graphics_adapter::SDLGraphicsAdapter; use crate::graphics::graphics_adapter::SDLGraphicsAdapter;
@@ -26,14 +26,13 @@ mod misc;
mod graphics; mod graphics;
fn main() -> EmulatorResult<()> { fn main() -> EmulatorResult<()> {
let BytePusherArgs { file_name } = BytePusherArgs::parse(); let BytePusherArgs { file_name ,draw_scale} = BytePusherArgs::parse();
SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap(); SimpleLogger::new().with_level(LevelFilter::Info).env().init()?;
let (file_bytes, x) = try_load_rom(&file_name)?; let (file_bytes, ..) = try_load_rom(&file_name)?;
assert!(x < MEM_LENGTH);
let (mut canvas, mut event_pump, audio_queue) = initiate_sdl(); let (mut canvas, mut event_pump, audio_queue) = initiate_sdl(draw_scale);
let ram = RamMemory::try_from(file_bytes.as_slice())?; let ram = RamMemory::try_from(file_bytes.as_slice())?;
@@ -44,9 +43,9 @@ fn main() -> EmulatorResult<()> {
let mut sdl2_graphics_adapter = SDLGraphicsAdapter::new(&graphics_processor); let mut sdl2_graphics_adapter = SDLGraphicsAdapter::new(&graphics_processor);
'running: loop {
canvas.set_draw_color(Color::BLACK); canvas.set_draw_color(Color::BLACK);
canvas.clear(); canvas.clear();
'running: loop {
for event in event_pump.poll_iter() { for event in event_pump.poll_iter() {
match event { match event {
Event::Quit { .. } | Event::Quit { .. } |
@@ -71,13 +70,12 @@ fn main() -> EmulatorResult<()> {
// The rest of the game loop goes here... // The rest of the game loop goes here...
cpu.cycle()?; cpu.cycle()?;
// draw graphics
sdl2_graphics_adapter.draw(&mut canvas)?;
// TODO render audio
audio_processor.queue()?;
sdl2_graphics_adapter.draw(&mut canvas)?;
audio_processor.queue()?;
canvas.present(); canvas.present();
// 60fps - small offset to consider for cpu cycle time // 60fps - small offset to consider for cpu cycle time
::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60 - 2000_000)); ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60 - 2000_000));
} }
@@ -121,10 +119,8 @@ fn try_load_rom(file_name_option: &Option<String>) -> EmulatorResult<(Vec<u8>, u
Ok((file_bytes, bytes_read)) Ok((file_bytes, bytes_read))
} }
fn initiate_sdl() -> (WindowCanvas, EventPump, AudioQueue<u8>) { fn initiate_sdl(draw_scale:f32) -> (WindowCanvas, EventPump, AudioQueue<u8>) {
const BASE_RESOLUTION: u32 = 256; let window_resolution: u32 = (DEVICE_RESOLUTION as f32 * draw_scale) as u32;
const DRAW_FACTOR: u32 = 4;
const WINDOW_RESOLUTION: u32 = BASE_RESOLUTION * DRAW_FACTOR;
let sdl_context = sdl2::init().unwrap(); let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap(); let video_subsystem = sdl_context.video().unwrap();
let audio_subsystem = sdl_context.audio().unwrap(); let audio_subsystem = sdl_context.audio().unwrap();
@@ -137,18 +133,16 @@ fn initiate_sdl() -> (WindowCanvas, EventPump, AudioQueue<u8>) {
audio_queue.resume(); audio_queue.resume();
let window = video_subsystem.window("byte-pusher-emu", WINDOW_RESOLUTION, WINDOW_RESOLUTION) let window = video_subsystem.window("byte-pusher-emu", window_resolution, window_resolution)
.position_centered() .position_centered()
.build() .build()
.unwrap(); .unwrap();
let mut canvas = window.into_canvas().build().unwrap(); let mut canvas = window.into_canvas().build().unwrap();
canvas.set_draw_color(Color::RGB(0x10, 0x10, 0x10)); canvas.set_scale(draw_scale, draw_scale).expect("Setting scale");
canvas.set_integer_scale(true).expect("Setting int scale");
canvas.set_scale(DRAW_FACTOR as f32, DRAW_FACTOR as f32).expect("Setting scale");
canvas.clear();
canvas.set_blend_mode(BlendMode::None); canvas.set_blend_mode(BlendMode::None);
canvas.clear();
canvas.present(); canvas.present();
let event_pump = sdl_context.event_pump().unwrap(); let event_pump = sdl_context.event_pump().unwrap();
(canvas, event_pump, audio_queue) (canvas, event_pump, audio_queue)

View File

@@ -1,6 +1,7 @@
use std::array::TryFromSliceError; use std::array::TryFromSliceError;
use std::fmt::Debug; use std::fmt::Debug;
use std::io::Error; use std::io::Error;
use log::SetLoggerError;
use crate::misc::error::EmulatorError::EmulatorIOError; use crate::misc::error::EmulatorError::EmulatorIOError;
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@@ -24,12 +25,18 @@ impl From<TryFromSliceError> for EmulatorError {
} }
} }
impl From<std::io::Error> for EmulatorError { impl From<Error> for EmulatorError {
fn from(value: Error) -> Self { fn from(value: Error) -> Self {
EmulatorIOError(value) EmulatorIOError(value)
} }
} }
impl From<SetLoggerError> for EmulatorError{
fn from(value: SetLoggerError) -> Self {
EmulatorError::OtherError(None,format!("Logger allocation failed! Error: {}",value))
}
}