From b7615368c39f0860a077a911fcb61154c78c62a2 Mon Sep 17 00:00:00 2001 From: Atreya Bain Date: Mon, 19 Feb 2024 12:59:29 +0530 Subject: [PATCH] [gpu] Implement scaling --- src/graphics/graphics_adapter.rs | 34 +++++++++++++--------- src/main.rs | 50 +++++++++++++++++++------------- src/misc/emulator_error.rs | 11 ++++++- 3 files changed, 60 insertions(+), 35 deletions(-) diff --git a/src/graphics/graphics_adapter.rs b/src/graphics/graphics_adapter.rs index d447de1..8e7df24 100644 --- a/src/graphics/graphics_adapter.rs +++ b/src/graphics/graphics_adapter.rs @@ -1,4 +1,5 @@ use std::fmt::{Debug, Formatter}; +use sdl2::rect::Rect; use sdl2::render::WindowCanvas; use crate::emu::graphics::GraphicsProcessor; use crate::graphics::color::Color; @@ -8,39 +9,44 @@ use crate::misc::result::EmulatorResult; #[derive(Clone)] pub struct SDLGraphicsAdapter<'a> { - pub graphics_processor: &'a GraphicsProcessor<'a> + pub graphics_processor: &'a GraphicsProcessor<'a>, } -impl <'a> Debug for SDLGraphicsAdapter<'a> { +impl<'a> Debug for SDLGraphicsAdapter<'a> { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { f.write_str("SDL2 adapter") } } -impl <'a> SDLGraphicsAdapter<'a> { - pub fn new(graphics_processor: &'a GraphicsProcessor)->SDLGraphicsAdapter<'a>{ - SDLGraphicsAdapter{ +impl<'a> SDLGraphicsAdapter<'a> { + pub fn new(graphics_processor: &'a GraphicsProcessor) -> SDLGraphicsAdapter<'a> { + SDLGraphicsAdapter { graphics_processor } } - pub fn draw(&self, canvas:&mut WindowCanvas) -> EmulatorResult<()> { + pub fn draw(&self, canvas: &mut WindowCanvas, draw_factor: u32) -> EmulatorResult<()> { let fb = self.graphics_processor.get_framebuffer(); - let xyc = fb.iter().enumerate().map(|(i,e)| { + let xyc = fb.iter().enumerate().map(|(i, e)| { let i = i as u32; - let y_coord = (i&0xff00 )>> 8; - let x_coord = i&0x00ff; + let y_coord = (i & 0xff00) >> 8; + let x_coord = i & 0x00ff; let color = Color::new(*e); - (x_coord,y_coord,color) + (x_coord, y_coord, color) }); - for (x,y,c) in xyc{ + for (x, y, c) in xyc { canvas.set_draw_color(c.get_rgb()); - let coordinates = (x as i32,y as i32); - let draw_result = canvas.draw_point(coordinates).map_err(|str|EmulatorError::OtherError(str)); - + let coordinates = (x as i32, y as i32); + let draw_result = Self::draw_scaled_point(canvas, coordinates, draw_factor); draw_result?; } Ok(()) } + + fn draw_scaled_point(canvas: &mut WindowCanvas, coordinates: (i32, i32), draw_factor: u32) -> Result<(), EmulatorError> { + canvas + .fill_rect(Rect::new(coordinates.0*draw_factor as i32, coordinates.1*draw_factor as i32, draw_factor, draw_factor)) + .map_err(|str| EmulatorError::OtherError(str)) + } } diff --git a/src/main.rs b/src/main.rs index 90b2508..d92fd39 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,6 @@ use simple_logger::SimpleLogger; use crate::emu::cpu::Cpu; use crate::emu::graphics::GraphicsProcessor; use crate::emu::ram::{MEM_LENGTH, RamMemory}; -use crate::emu::mmu::{Memory}; use crate::graphics::graphics_adapter::SDLGraphicsAdapter; use crate::misc::result::EmulatorResult; @@ -21,52 +20,63 @@ mod misc; mod graphics; fn main() -> EmulatorResult<()> { - let mut fileLoc = File::open("rom.BytePusher").unwrap(); - let mut filebytes = vec![0u8; MEM_LENGTH]; - let x = fileLoc.read(&mut filebytes).unwrap(); + let (file_bytes, x) = try_load_rom()?; assert!(x < MEM_LENGTH); SimpleLogger::new().env().init().unwrap(); - let ram = RamMemory::try_from(filebytes.as_slice())?; + let ram = RamMemory::try_from(file_bytes.as_slice())?; - let (mut canvas,mut event_pump) = initiate_sdl(); + let (mut canvas, mut event_pump, draw_factor) = initiate_sdl(); let graphics_processor = GraphicsProcessor::try_new(&ram)?; let sdl2_graphics_adapter = SDLGraphicsAdapter::new(&graphics_processor); - let cpu = Cpu::new(&ram,&graphics_processor); + let cpu = Cpu::new(&ram, &graphics_processor); - let mut i = 0; 'running: loop { - i = (i + 1) % 255; - canvas.set_draw_color(Color::RGB(0,0,0)); + canvas.set_draw_color(Color::BLACK); canvas.clear(); for event in event_pump.poll_iter() { match event { - Event::Quit {..} | + Event::Quit { .. } | Event::KeyDown { keycode: Some(Keycode::Escape), .. } => { - break 'running - }, + break 'running; + } event => { - log::info!("Received window event {:?}",event); + log::trace!("Received window event {:?}",event); } } - } - cpu.cycle()?; // The rest of the game loop goes here... - sdl2_graphics_adapter.draw(&mut canvas)?; + cpu.cycle()?; + // draw graphics + sdl2_graphics_adapter.draw(&mut canvas, draw_factor)?; + // TODO render audio + canvas.present(); + ::std::thread::sleep(Duration::new(0, 1_000_000_000u32 / 60)); } Ok(()) } -fn initiate_sdl() -> (WindowCanvas, EventPump) { +fn try_load_rom() -> EmulatorResult<(Vec, usize)> { + let mut file_bytes = vec![0u8; MEM_LENGTH]; + + let mut file_handle = File::open("rom.BytePusher")?; + let x = file_handle.read(&mut file_bytes)?; + + Ok((file_bytes, x)) +} + +fn initiate_sdl() -> (WindowCanvas, EventPump, u32) { + const BASE_RESOLUTION: u32 = 256; + const DRAW_FACTOR: u32 = 4; + const WINDOW_RESOLUTION: u32 = BASE_RESOLUTION * DRAW_FACTOR; let sdl_context = sdl2::init().unwrap(); let video_subsystem = sdl_context.video().unwrap(); - let window = video_subsystem.window("rust-sdl2 demo", 512, 512) + let window = video_subsystem.window("byte-pusher-emu", WINDOW_RESOLUTION, WINDOW_RESOLUTION) .position_centered() .build() .unwrap(); @@ -76,5 +86,5 @@ fn initiate_sdl() -> (WindowCanvas, EventPump) { canvas.clear(); canvas.present(); let mut event_pump = sdl_context.event_pump().unwrap(); - (canvas, event_pump) + (canvas, event_pump, DRAW_FACTOR) } diff --git a/src/misc/emulator_error.rs b/src/misc/emulator_error.rs index fc444a8..d1270d9 100644 --- a/src/misc/emulator_error.rs +++ b/src/misc/emulator_error.rs @@ -1,5 +1,7 @@ use std::array::TryFromSliceError; use std::fmt::Debug; +use std::io::Error; +use crate::misc::emulator_error::EmulatorError::EmulatorIOError; #[derive(Debug, Copy, Clone)] pub enum DeviceType { @@ -13,11 +15,12 @@ pub enum DeviceType { GRAPHICS, } -#[derive(Debug, Clone)] +#[derive(Debug)] pub enum EmulatorError { AllocationFailure(DeviceType, &'static str), UnreachableMemory(DeviceType, u32), InvalidColor(u8), + EmulatorIOError(Error), OtherError(String) } @@ -27,6 +30,12 @@ impl From for EmulatorError{ } } +impl From for EmulatorError{ + fn from(value: Error) -> Self { + EmulatorIOError(value) + } +} +