diff --git a/Cargo.lock b/Cargo.lock index 87493da..553f583 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -414,6 +414,7 @@ dependencies = [ "futures", "gilrs", "minifb", + "once_cell", "rand", "ringbuf", "samplerate", @@ -863,9 +864,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.17.0" +version = "1.17.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f61fba1741ea2b3d6a1e3178721804bb716a68a6aeba1149b5d52e3d464ea66" +checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3" [[package]] name = "orbclient" diff --git a/Cargo.toml b/Cargo.toml index 8f5958c..432fdf9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -16,3 +16,4 @@ cpal = "0.15.0" ringbuf = "0.3.2" async-ringbuf = "0.1.2" futures = "0.3.26" +once_cell = "1.17.1" diff --git a/src/main.rs b/src/main.rs index 6e975a3..da06d81 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,6 +6,7 @@ mod util; use clap::{ArgGroup, Parser}; use gilrs::Gilrs; use minifb::{Window, WindowOptions}; +use once_cell::sync::OnceCell; use processor::{ memory::{Memory, Rom}, Cpu, @@ -13,9 +14,10 @@ use processor::{ use std::{ fs, io::{self, stdout, Write}, - sync::RwLock, }; +use crate::processor::gpu; + #[macro_export] macro_rules! verbose_println { ($($tts:tt)*) => { @@ -66,23 +68,34 @@ struct Args { /// Step emulation by... #[arg(long)] step_by: Option, + + /// Step emulation by... + #[arg(short, long)] + scale_factor: Option, } static mut PAUSE_ENABLED: bool = false; static mut PAUSE_QUEUED: bool = false; -static VERBOSE: RwLock = RwLock::new(false); +static VERBOSE: OnceCell = OnceCell::new(); const WIDTH: usize = 160; const HEIGHT: usize = 144; -const FACTOR: usize = 3; +static FACTOR: OnceCell = OnceCell::new(); fn main() { let args = Args::parse(); - { - let mut v = VERBOSE.write().unwrap(); - *v = args.verbose; - } + + VERBOSE.set(args.verbose).unwrap(); + + FACTOR + .set(if let Some(factor) = args.scale_factor { + factor + } else { + 3 + }) + .unwrap(); + gpu::init_statics(); let rom: Rom = match fs::read(args.rom) { Ok(data) => Rom::load(data), @@ -101,8 +114,8 @@ fn main() { let mut window = Window::new( format!("{} on {}", rom.get_title(), rom.mbc_type()).as_str(), - WIDTH * FACTOR, - HEIGHT * FACTOR, + WIDTH * FACTOR.get().unwrap(), + HEIGHT * FACTOR.get().unwrap(), WindowOptions::default(), ) .unwrap_or_else(|e| { @@ -196,8 +209,8 @@ fn print_cycles(cycles: &i32) { } fn is_verbose() -> bool { - match VERBOSE.read() { - Ok(v) => *v, - Err(_) => false, + match VERBOSE.get() { + Some(v) => *v, + None => false, } } diff --git a/src/processor/gpu.rs b/src/processor/gpu.rs index 237bfb1..7a66423 100644 --- a/src/processor/gpu.rs +++ b/src/processor/gpu.rs @@ -10,14 +10,24 @@ use crate::{ FACTOR, HEIGHT, WIDTH, }; use minifb::{Window, WindowOptions}; +use once_cell::sync::OnceCell; mod tile_window; mod types; const TILE_WINDOW_WIDTH: usize = 16 * 8; const TILE_WINDOW_HEIGHT: usize = 24 * 8; -const TILE_WINDOW_WIDTH_SCALED: usize = TILE_WINDOW_WIDTH * FACTOR; -const TILE_WINDOW_HEIGHT_SCALED: usize = TILE_WINDOW_HEIGHT * FACTOR; +static TILE_WINDOW_WIDTH_SCALED: OnceCell = OnceCell::new(); +static TILE_WINDOW_HEIGHT_SCALED: OnceCell = OnceCell::new(); + +pub fn init_statics() { + TILE_WINDOW_WIDTH_SCALED + .set(TILE_WINDOW_WIDTH * FACTOR.get().unwrap()) + .unwrap(); + TILE_WINDOW_HEIGHT_SCALED + .set(TILE_WINDOW_HEIGHT * FACTOR.get().unwrap()) + .unwrap(); +} pub struct Gpu { pub buffer: Vec, @@ -35,15 +45,15 @@ impl Gpu { let tile_window = if enable_tile_window { let mut window = Window::new( "Tiles", - TILE_WINDOW_WIDTH_SCALED, - TILE_WINDOW_HEIGHT_SCALED, + *TILE_WINDOW_WIDTH_SCALED.get().unwrap(), + *TILE_WINDOW_HEIGHT_SCALED.get().unwrap(), WindowOptions::default(), ) .unwrap_or_else(|e| { panic!("{e}"); }); - window.set_position((550 + (WIDTH * FACTOR)) as isize, 50); + window.set_position((550 + (WIDTH * FACTOR.get().unwrap())) as isize, 50); window.topmost(true); Some(TileWindow::new(window)) } else { @@ -406,9 +416,14 @@ impl Cpu { } fn render_window(&mut self) { - self.gpu.scaled_buffer = scale_buffer(&self.gpu.buffer, WIDTH, HEIGHT, FACTOR); + self.gpu.scaled_buffer = + scale_buffer(&self.gpu.buffer, WIDTH, HEIGHT, *FACTOR.get().unwrap()); self.window - .update_with_buffer(&self.gpu.scaled_buffer, WIDTH * FACTOR, HEIGHT * FACTOR) + .update_with_buffer( + &self.gpu.scaled_buffer, + WIDTH * FACTOR.get().unwrap(), + HEIGHT * FACTOR.get().unwrap(), + ) .unwrap(); } } diff --git a/src/processor/gpu/tile_window.rs b/src/processor/gpu/tile_window.rs index f370728..f60a2b1 100644 --- a/src/processor/gpu/tile_window.rs +++ b/src/processor/gpu/tile_window.rs @@ -22,7 +22,11 @@ impl TileWindow { pub(super) fn new(window: Window) -> Self { Self { sprite_buffer: vec![0; TILE_WINDOW_WIDTH * TILE_WINDOW_HEIGHT], - sprite_buffer_scaled: vec![0; TILE_WINDOW_WIDTH_SCALED * TILE_WINDOW_HEIGHT_SCALED], + sprite_buffer_scaled: vec![ + 0; + TILE_WINDOW_WIDTH_SCALED.get().unwrap() + * TILE_WINDOW_HEIGHT_SCALED.get().unwrap() + ], sprite_window: window, } } @@ -53,13 +57,13 @@ impl TileWindow { &self.sprite_buffer, TILE_WINDOW_WIDTH, TILE_WINDOW_HEIGHT, - FACTOR, + *FACTOR.get().unwrap(), ); self.sprite_window .update_with_buffer( &self.sprite_buffer_scaled, - TILE_WINDOW_WIDTH_SCALED, - TILE_WINDOW_HEIGHT_SCALED, + *TILE_WINDOW_WIDTH_SCALED.get().unwrap(), + *TILE_WINDOW_HEIGHT_SCALED.get().unwrap(), ) .unwrap(); }