[gpu] Implement scaling

This commit is contained in:
2024-02-19 12:59:29 +05:30
parent 384359812a
commit b7615368c3
3 changed files with 60 additions and 35 deletions

View File

@@ -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))
}
}

View File

@@ -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<u8>, 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)
}

View File

@@ -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<TryFromSliceError> for EmulatorError{
}
}
impl From<std::io::Error> for EmulatorError{
fn from(value: Error) -> Self {
EmulatorIOError(value)
}
}