diff --git a/src/main.rs b/src/main.rs index d131151..25a3d4d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -7,10 +7,14 @@ use std::path::PathBuf; use std::pin::Pin; use std::rc::Rc; -use sdl2::render::{WindowCanvas, Texture, TextureCreator}; +use sdl2::render::{WindowCanvas, BlendMode}; use sdl2::image::ImageRWops; use sdl2::surface::Surface; -use sdl2::video::WindowContext; +use sdl2::pixels::{Color, PixelFormatEnum}; +use sdl2::rect::Rect; + +use rand::{SeedableRng, Rng}; +use rand_xoshiro::Xoshiro128Plus; use structopt::StructOpt; @@ -40,6 +44,9 @@ struct Zretro { emu: Pin>, canvas: WindowCanvas, font: Surface<'static>, + rng: Xoshiro128Plus, + ui_bg: Option>, + snowflakes: Vec, sdl2surf_comp: Rc>, } @@ -63,7 +70,7 @@ impl Zretro { .window(title.as_str(), geometry.base_width, geometry.base_height) .borderless() .build()?; - let mut canvas = window.into_canvas().build()?; + let canvas = window.into_canvas().build()?; let sdl2surf_comp = Rc::new(RefCell::new( Sdl2SurfaceComponent::new(emu.libretro_core())? @@ -95,27 +102,64 @@ impl Zretro { Surface::from_ll(ptr) }; + let mut rng = rand_xoshiro::Xoshiro128Plus::from_entropy(); + let mut ui_bg = Surface::new(geometry.base_width, geometry.base_height, PixelFormatEnum::ABGR8888)?; + ui_bg.fill_rect(None, Color::RGBA(0, 0, 128, 128))?; + let snowflakes = (0..100).into_iter() + .map(|_| Rect::new( + rng.gen_range(0..ui_bg.width() as i32), + rng.gen_range(0..ui_bg.height() as i32), + 2, 2)) + .collect(); + Ok(Zretro { emu, canvas, font, + rng, + ui_bg: Some(ui_bg), + snowflakes, sdl2surf_comp, }) } + fn update_snow(&mut self) -> Result<()> { + let mut ui_bg = self.ui_bg.take().ok_or("no ui_bg?")?; + ui_bg.fill_rect(None, Color::RGBA(0, 0, 128, 128))?; + let w = ui_bg.width() as i32; + let h = ui_bg.height() as i32; + for flake in &mut self.snowflakes { + let x = flake.x() + self.rng.gen_range(-1..=1); + let y = flake.y() + 1; + flake.set_x(x % w); + flake.set_y(y % h); + } + let mut ui_canvas = ui_bg.into_canvas()?; + ui_canvas.set_draw_color(Color::RGBA(255, 255, 255, 160)); + ui_canvas.draw_rects(&self.snowflakes[..])?; + self.ui_bg = Some(ui_canvas.into_surface()); + Ok(()) + } + fn run(&mut self) -> Result<()> { let tc = self.canvas.texture_creator(); let font_tx = tc.create_texture_from_surface(&self.font)?; let mut font_rect = self.font.rect(); font_rect.set_height(64); while let ControlFlow::Continue = self.emu.run() { + self.update_snow()?; let ref_mut = RefCell::try_borrow_mut(&self.sdl2surf_comp)?; - let mut surface = ref_mut.surface(); + let surface = ref_mut.surface(); - let texture = tc.create_texture_from_surface(surface)?; + let emu_tx = tc.create_texture_from_surface(surface)?; + + let ui_bg_surf_ref = self.ui_bg.as_ref().ok_or("no bg?")?; + let mut ui_tx = tc.create_texture_from_surface(ui_bg_surf_ref)?; + ui_tx.set_blend_mode(BlendMode::Blend); self.canvas.clear(); - self.canvas.copy(&texture, None, None)?; + self.canvas.copy(&emu_tx, None, None)?; + self.canvas.copy(&ui_tx, None, None)?; self.canvas.copy(&font_tx, font_rect, font_rect)?; self.canvas.present(); }