chip8_emulator_rs/video/
sdl_video.rs

1use sdl2::{pixels::Color, rect::Rect, render::Canvas, video::Window, Sdl};
2
3use crate::{SCREEN_HEIGHT, SCREEN_WIDTH};
4
5use super::Video;
6
7pub struct SDLVideo {
8    canvas: Canvas<Window>,
9    scale: u32,
10}
11
12impl SDLVideo {
13    pub fn new(sdl_context: &Sdl, scale: u32) -> Result<Self, Box<dyn std::error::Error>> {
14        let video_subsystem = sdl_context.video()?;
15
16        let window_width = SCREEN_WIDTH as u32 * scale;
17        let window_height = SCREEN_HEIGHT as u32 * scale;
18
19        let window = video_subsystem
20            .window("TODO: BETTER NAME", window_width, window_height)
21            .position_centered()
22            .build()?;
23
24        let canvas = window.into_canvas().build()?;
25
26        Ok(Self { canvas, scale })
27    }
28}
29
30impl Video for SDLVideo {
31    fn draw_to_window(&mut self, pixels: &[[bool; SCREEN_WIDTH]; SCREEN_HEIGHT]) {
32        self.canvas.set_draw_color(Color::BLACK);
33        self.canvas.clear();
34
35        let scale = self.scale;
36
37        let rects = pixels
38            .iter()
39            .enumerate()
40            .flat_map(|(y, row)| {
41                row.iter().enumerate().filter_map(move |(x, pixel)| {
42                    let rect = Rect::new(
43                        x as i32 * scale as i32,
44                        y as i32 * scale as i32,
45                        scale,
46                        scale,
47                    );
48                    match *pixel {
49                        true => Some(rect),
50                        false => None,
51                    }
52                })
53            })
54            .collect::<Vec<Rect>>();
55
56        // Draw pixels
57        self.canvas.set_draw_color(Color::WHITE);
58        self.canvas.fill_rects(rects.as_slice()).unwrap();
59
60        // Update screen
61        self.canvas.present();
62    }
63}