[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;
#[derive(Debug,Parser)]
#[command(version, about, long_about = "Byte Pusher Emulator")]
pub struct BytePusherArgs{
#[arg(short,long)]
pub file_name:Option<String>
#[derive(Debug, Parser)]
#[command(version, about, author)]
pub struct BytePusherArgs {
#[arg(short, long, help = "ROM file to load")]
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;
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> {
ram: &'a RamMemory,
@@ -31,6 +34,7 @@ impl<'a> AudioProcessor<'a> {
}
}
impl<'a> AudioProcessor<'a> {
pub fn queue(&mut self) -> EmulatorResult<()> {
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.
// We will then wait for audio to drain to adjust frame timing
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))
}
self.ram.try_copy_block(audio_base_reg, fb)?;
//convert to u8 audio format (Bytepusher stores it as "i8")
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) })
}
fn get_audio_base_reg(&self) -> u16 {
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())
}
}

View File

@@ -5,7 +5,8 @@ use crate::misc::error::DeviceType::GRAPHICS;
use crate::misc::error::EmulatorError;
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)]
pub struct GraphicsProcessor<'a> {

View File

@@ -13,7 +13,7 @@ use simple_logger::SimpleLogger;
use crate::args::BytePusherArgs;
use crate::emu::audio::AudioProcessor;
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::memory::{MEM_LENGTH, RamMemory};
use crate::graphics::graphics_adapter::SDLGraphicsAdapter;
@@ -26,14 +26,13 @@ mod misc;
mod graphics;
fn main() -> EmulatorResult<()> {
let BytePusherArgs { file_name } = BytePusherArgs::parse();
SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap();
let BytePusherArgs { file_name ,draw_scale} = BytePusherArgs::parse();
SimpleLogger::new().with_level(LevelFilter::Info).env().init()?;
let (file_bytes, x) = try_load_rom(&file_name)?;
assert!(x < MEM_LENGTH);
let (file_bytes, ..) = try_load_rom(&file_name)?;
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())?;
@@ -44,9 +43,9 @@ fn main() -> EmulatorResult<()> {
let mut sdl2_graphics_adapter = SDLGraphicsAdapter::new(&graphics_processor);
'running: loop {
canvas.set_draw_color(Color::BLACK);
canvas.clear();
'running: loop {
for event in event_pump.poll_iter() {
match event {
Event::Quit { .. } |
@@ -71,13 +70,12 @@ fn main() -> EmulatorResult<()> {
// The rest of the game loop goes here...
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();
// 60fps - small offset to consider for cpu cycle time
::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))
}
fn initiate_sdl() -> (WindowCanvas, EventPump, AudioQueue<u8>) {
const BASE_RESOLUTION: u32 = 256;
const DRAW_FACTOR: u32 = 4;
const WINDOW_RESOLUTION: u32 = BASE_RESOLUTION * DRAW_FACTOR;
fn initiate_sdl(draw_scale:f32) -> (WindowCanvas, EventPump, AudioQueue<u8>) {
let window_resolution: u32 = (DEVICE_RESOLUTION as f32 * draw_scale) as u32;
let sdl_context = sdl2::init().unwrap();
let video_subsystem = sdl_context.video().unwrap();
let audio_subsystem = sdl_context.audio().unwrap();
@@ -137,18 +133,16 @@ fn initiate_sdl() -> (WindowCanvas, EventPump, AudioQueue<u8>) {
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()
.build()
.unwrap();
let mut canvas = window.into_canvas().build().unwrap();
canvas.set_draw_color(Color::RGB(0x10, 0x10, 0x10));
canvas.set_integer_scale(true).expect("Setting int scale");
canvas.set_scale(draw_scale, draw_scale).expect("Setting scale");
canvas.set_scale(DRAW_FACTOR as f32, DRAW_FACTOR as f32).expect("Setting scale");
canvas.clear();
canvas.set_blend_mode(BlendMode::None);
canvas.clear();
canvas.present();
let event_pump = sdl_context.event_pump().unwrap();
(canvas, event_pump, audio_queue)

View File

@@ -1,6 +1,7 @@
use std::array::TryFromSliceError;
use std::fmt::Debug;
use std::io::Error;
use log::SetLoggerError;
use crate::misc::error::EmulatorError::EmulatorIOError;
#[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 {
EmulatorIOError(value)
}
}
impl From<SetLoggerError> for EmulatorError{
fn from(value: SetLoggerError) -> Self {
EmulatorError::OtherError(None,format!("Logger allocation failed! Error: {}",value))
}
}