diff --git a/src/main.rs b/src/main.rs index b3233b0..e8089b3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ use sdl2::render::{BlendMode, TextureAccess, WindowCanvas}; use simple_logger::SimpleLogger; use device::timer::Timer; use crate::device::Device; +use crate::util::EmulatorResult; use crate::kb_map::get_key_index; use crate::sdl_graphics_adapter::SdlGraphicsAdapter; @@ -21,8 +22,9 @@ mod args; mod device; mod kb_map; mod sdl_graphics_adapter; +mod util; -fn main() { +fn main() -> EmulatorResult<()> { SimpleLogger::new().with_level(LevelFilter::Info).env().init().unwrap(); log::info!("Started emulator"); @@ -36,9 +38,9 @@ fn main() { let compute_handle = thread::Builder::new().name("Compute".to_string()).spawn(move || { do_device_loop(timer, frame_buffer_for_device, termination_signal_sender_receiver); - }).expect("Failed to launch thread"); + })?; - let (mut canvas, mut event_pump) = initiate_sdl(8f32); + let (mut canvas, mut event_pump) = try_initiate_sdl(8f32)?; let mut sdl_graphics_adapter = SdlGraphicsAdapter::new(); @@ -70,8 +72,8 @@ fn main() { // The rest of the game loop goes here... { - let lock = frame_buffer_for_display.lock().expect("Failed to get Display"); - sdl_graphics_adapter.draw_screen(lock, &mut canvas); + let lock = frame_buffer_for_display.lock()?; + sdl_graphics_adapter.draw_screen(lock, &mut canvas)?; } canvas.present(); @@ -81,6 +83,7 @@ fn main() { compute_handle.join().unwrap(); + Ok(()) } fn do_device_loop(mut timer: Timer, frame_buffer: Arc>>, receiver: Receiver<()>) { @@ -118,7 +121,7 @@ fn load_rom() -> [u8; ROM_SIZE] { rom_slice } -fn initiate_sdl(draw_scale: f32) -> (WindowCanvas, EventPump) { +fn try_initiate_sdl(draw_scale: f32) -> EmulatorResult<(WindowCanvas, EventPump)> { let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); // let audio_subsystem = sdl_context.audio().unwrap(); @@ -134,19 +137,18 @@ fn initiate_sdl(draw_scale: f32) -> (WindowCanvas, EventPump) { let window = video_subsystem.window("porcel8", window_width, window_height) .position_centered() - .build() - .unwrap(); - let mut canvas = window.into_canvas().build().unwrap(); + .build()?; + let mut canvas = window.into_canvas().build()?; - canvas.set_scale(draw_scale, draw_scale).expect("Setting scale"); + canvas.set_scale(draw_scale, draw_scale)?; canvas.set_blend_mode(BlendMode::None); canvas.clear(); canvas.present(); - let event_pump = sdl_context.event_pump().unwrap(); - (canvas, event_pump + let event_pump = sdl_context.event_pump()?; + Ok((canvas, event_pump // , audio_queue - ) + )) } diff --git a/src/sdl_graphics_adapter.rs b/src/sdl_graphics_adapter.rs index c62c897..874ba5c 100644 --- a/src/sdl_graphics_adapter.rs +++ b/src/sdl_graphics_adapter.rs @@ -2,6 +2,7 @@ use std::sync::MutexGuard; use sdl2::pixels::PixelFormatEnum; use sdl2::render::{TextureAccess, WindowCanvas}; use crate::device::Device; +use crate::util::EmulatorResult; #[derive(Debug)] pub struct SdlGraphicsAdapter { @@ -17,20 +18,22 @@ impl SdlGraphicsAdapter { rgb_frame_buffer } } - pub fn draw_screen(&mut self, frame_buffer: MutexGuard>, window_canvas: &mut WindowCanvas) { + pub fn draw_screen(&mut self, frame_buffer: MutexGuard>, window_canvas: &mut WindowCanvas) ->EmulatorResult<()> { for (i, pixel) in frame_buffer.iter().enumerate() { let col_component = if *pixel { 0xff } else { 0 }; self.rgb_frame_buffer[3 * i] = col_component; self.rgb_frame_buffer[3 * i + 1] = col_component; self.rgb_frame_buffer[3 * i + 2] = col_component; } + // drop the mutex as it is not required anymore drop(frame_buffer); let tex_creator = window_canvas.texture_creator(); let mut tex = tex_creator.create_texture(PixelFormatEnum::RGB24, TextureAccess::Streaming, Device::FRAME_BUFFER_WIDTH as u32, Device::FRAME_BUFFER_HEIGHT as u32).expect("Failed to create tex"); tex.with_lock(None, |u, i| { u.copy_from_slice(self.rgb_frame_buffer.as_slice()); - }).expect("Unwrap tex"); - window_canvas.copy(&tex, None, None).expect("Failed to set texture"); + })?; + window_canvas.copy(&tex, None, None)?; + Ok(()) } } \ No newline at end of file diff --git a/src/util.rs b/src/util.rs new file mode 100644 index 0000000..6b5ca33 --- /dev/null +++ b/src/util.rs @@ -0,0 +1,44 @@ +use std::sync::PoisonError; +use sdl2::IntegerOrSdlError; +use sdl2::video::WindowBuildError; + +pub type EmulatorResult = Result; + +#[derive(Clone, Debug)] +pub enum EmulatorError { + SdlError(String), + AllocationError, + IOError(String), + MutexInvalidState(String) +} + +impl From for EmulatorError { + fn from(value: String) -> Self { + Self::SdlError(value) + } +} + +impl From for EmulatorError { + fn from(value: WindowBuildError) -> Self { + Self::SdlError(value.to_string()) + } +} + +impl From for EmulatorError { + fn from(value: IntegerOrSdlError) -> Self { + match value { + IntegerOrSdlError::IntegerOverflows(x, y) => { Self::SdlError(format!("{} - {}", x, y)) } + IntegerOrSdlError::SdlError(str) => { Self::SdlError(str) } + } + } +} +impl From for EmulatorError{ + fn from(value: std::io::Error) -> Self { + Self::IOError(value.to_string()) + } +} +impl From> for EmulatorError{ + fn from(value: PoisonError) -> Self { + Self::MutexInvalidState(value.to_string()) + } +} \ No newline at end of file