funny mouse cursor
This commit is contained in:
parent
873037f9f1
commit
52f7414dfe
91
src/main.rs
91
src/main.rs
|
@ -27,6 +27,9 @@ use ferretro_components::provided::{
|
||||||
sdl2::{Sdl2SurfaceComponent, SimpleSdl2AudioComponent},
|
sdl2::{Sdl2SurfaceComponent, SimpleSdl2AudioComponent},
|
||||||
stdlib::{SleepFramerateLimitComponent, PathBufComponent},
|
stdlib::{SleepFramerateLimitComponent, PathBufComponent},
|
||||||
};
|
};
|
||||||
|
use sdl2::mouse::{Cursor, MouseUtil};
|
||||||
|
use sdl2::rect::Rect;
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||||
|
|
||||||
|
@ -60,7 +63,11 @@ impl GuiState {
|
||||||
struct Zretro {
|
struct Zretro {
|
||||||
emu: Pin<Box<RetroComponentBase>>,
|
emu: Pin<Box<RetroComponentBase>>,
|
||||||
canvas: WindowCanvas,
|
canvas: WindowCanvas,
|
||||||
font: Surface<'static>,
|
font_surf: Surface<'static>,
|
||||||
|
mouse_util: MouseUtil,
|
||||||
|
mouse_cursor: Cursor,
|
||||||
|
mouse_shadow_surf: Surface<'static>,
|
||||||
|
mouse_shadow_pos: Rect,
|
||||||
rng: Xoshiro128Plus,
|
rng: Xoshiro128Plus,
|
||||||
ui_bg: Option<Surface<'static>>,
|
ui_bg: Option<Surface<'static>>,
|
||||||
snowflakes: Vec<Point>,
|
snowflakes: Vec<Point>,
|
||||||
|
@ -68,7 +75,21 @@ struct Zretro {
|
||||||
event_pump: EventPump,
|
event_pump: EventPump,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const BG_COLOR: Color = Color { r: 65, g: 44, b: 130, a: 255 };
|
||||||
const FONT_PNG: &'static [u8] = include_bytes!("lifont.png");
|
const FONT_PNG: &'static [u8] = include_bytes!("lifont.png");
|
||||||
|
const MOUSE_PNG: &'static [u8] = include_bytes!("zmouse.png");
|
||||||
|
const MOUSE_SHADOW_PNG: &'static [u8] = include_bytes!("zmouse-shadow.png");
|
||||||
|
|
||||||
|
fn surface_asset(asset: &'static [u8]) -> Result<Surface<'static>> {
|
||||||
|
let rwops = sdl2::rwops::RWops::from_bytes(asset)?;
|
||||||
|
let surf_shortlived = rwops.load_png()?;
|
||||||
|
// there's a nonsemantic inheritance of lifetime from ImageRWops::load_png. TODO: pr
|
||||||
|
unsafe {
|
||||||
|
let ptr = surf_shortlived.raw();
|
||||||
|
std::mem::forget(surf_shortlived);
|
||||||
|
Ok(Surface::from_ll(ptr))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Zretro {
|
impl Zretro {
|
||||||
fn new(opt: Opt) -> Result<Self> {
|
fn new(opt: Opt) -> Result<Self> {
|
||||||
|
@ -111,14 +132,14 @@ impl Zretro {
|
||||||
emu.init().unwrap();
|
emu.init().unwrap();
|
||||||
emu.load_game(&opt.rom).unwrap(); // TODO: optional via CLI positional arg, menu-browsable
|
emu.load_game(&opt.rom).unwrap(); // TODO: optional via CLI positional arg, menu-browsable
|
||||||
|
|
||||||
let rwops = sdl2::rwops::RWops::from_bytes(FONT_PNG)?;
|
let font_surf = surface_asset(FONT_PNG)?;
|
||||||
let font_shortlived = rwops.load_png()?;
|
let mouse_surf = surface_asset(MOUSE_PNG)?;
|
||||||
// there's a nonsemantic inheritance of lifetime from ImageRWops::load_png. TODO: pr
|
let mouse_shadow_surf = surface_asset(MOUSE_SHADOW_PNG)?;
|
||||||
let font = unsafe {
|
|
||||||
let ptr = font_shortlived.raw();
|
let mouse_util = sdl_context.mouse();
|
||||||
std::mem::forget(font_shortlived);
|
let mouse_cursor = Cursor::from_surface(&mouse_surf, 0, 0)?;
|
||||||
Surface::from_ll(ptr)
|
mouse_cursor.set();
|
||||||
};
|
let mouse_shadow_pos = mouse_shadow_surf.rect();
|
||||||
|
|
||||||
let mut rng = rand_xoshiro::Xoshiro128Plus::from_entropy();
|
let mut rng = rand_xoshiro::Xoshiro128Plus::from_entropy();
|
||||||
let mut ui_bg = Surface::new(geometry.base_width, geometry.base_height, PixelFormatEnum::ABGR8888)?;
|
let mut ui_bg = Surface::new(geometry.base_width, geometry.base_height, PixelFormatEnum::ABGR8888)?;
|
||||||
|
@ -133,7 +154,11 @@ impl Zretro {
|
||||||
Ok(Zretro {
|
Ok(Zretro {
|
||||||
emu,
|
emu,
|
||||||
canvas,
|
canvas,
|
||||||
font,
|
font_surf,
|
||||||
|
mouse_util,
|
||||||
|
mouse_cursor,
|
||||||
|
mouse_shadow_surf,
|
||||||
|
mouse_shadow_pos,
|
||||||
rng,
|
rng,
|
||||||
ui_bg: Some(ui_bg),
|
ui_bg: Some(ui_bg),
|
||||||
snowflakes,
|
snowflakes,
|
||||||
|
@ -144,7 +169,9 @@ impl Zretro {
|
||||||
|
|
||||||
fn update_snow(&mut self) -> Result<()> {
|
fn update_snow(&mut self) -> Result<()> {
|
||||||
let mut ui_bg = self.ui_bg.take().ok_or("no ui_bg?")?;
|
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 mut bg_color = BG_COLOR;
|
||||||
|
bg_color.a = 128;
|
||||||
|
ui_bg.fill_rect(None, bg_color)?;
|
||||||
let w = ui_bg.width() as i32;
|
let w = ui_bg.width() as i32;
|
||||||
let h = ui_bg.height() as i32;
|
let h = ui_bg.height() as i32;
|
||||||
let halflen = self.snowflakes.len() / 2;
|
let halflen = self.snowflakes.len() / 2;
|
||||||
|
@ -167,25 +194,35 @@ impl Zretro {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn toggle_mode(&mut self) -> Result<()> {
|
||||||
|
self.mode.toggle();
|
||||||
|
let audio: &SimpleSdl2AudioComponent = self.emu.component_ref()?;
|
||||||
|
match self.mode {
|
||||||
|
GuiState::Menus => {
|
||||||
|
audio.silence_buffer();
|
||||||
|
self.mouse_cursor.set();
|
||||||
|
self.mouse_util.show_cursor(true);
|
||||||
|
}
|
||||||
|
GuiState::Game => {
|
||||||
|
self.mouse_util.show_cursor(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
fn run(&mut self) -> Result<()> {
|
fn run(&mut self) -> Result<()> {
|
||||||
let tc = self.canvas.texture_creator();
|
let tc = self.canvas.texture_creator();
|
||||||
let font_tx = tc.create_texture_from_surface(&self.font)?;
|
let font_tx = tc.create_texture_from_surface(&self.font_surf)?;
|
||||||
let mut font_rect = self.font.rect();
|
let mut font_rect = self.font_surf.rect();
|
||||||
font_rect.set_height(64);
|
font_rect.set_height(64);
|
||||||
'outer: loop {
|
'outer: loop {
|
||||||
for event in self.event_pump.poll_iter() {
|
let events = self.event_pump.poll_iter().collect_vec();
|
||||||
|
for event in events {
|
||||||
match event {
|
match event {
|
||||||
Event::Quit { .. } => break 'outer,
|
Event::Quit { .. } => break 'outer,
|
||||||
Event::KeyDown { keycode: Some(keycode), .. } => {
|
Event::KeyDown { keycode: Some(keycode), .. } => {
|
||||||
match keycode {
|
match keycode {
|
||||||
Keycode::Escape => {
|
Keycode::Escape => self.toggle_mode()?,
|
||||||
self.mode.toggle();
|
|
||||||
let audio: &SimpleSdl2AudioComponent = self.emu.component_ref()?;
|
|
||||||
match self.mode {
|
|
||||||
GuiState::Menus => audio.silence_buffer(),
|
|
||||||
GuiState::Game => {} //audio.resume(),
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,6 +231,10 @@ impl Zretro {
|
||||||
self.emu.libretro_core().unload_game();
|
self.emu.libretro_core().unload_game();
|
||||||
self.emu.load_game(filename)?;
|
self.emu.load_game(filename)?;
|
||||||
}
|
}
|
||||||
|
Event::MouseMotion { x, y, .. } => {
|
||||||
|
self.mouse_shadow_pos.set_x(x + 5);
|
||||||
|
self.mouse_shadow_pos.set_y(y + 7);
|
||||||
|
},
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -215,8 +256,10 @@ impl Zretro {
|
||||||
|
|
||||||
if let GuiState::Menus = self.mode {
|
if let GuiState::Menus = self.mode {
|
||||||
self.update_snow()?;
|
self.update_snow()?;
|
||||||
let ui_bg_surf_ref = self.ui_bg.as_ref().ok_or("no bg?")?;
|
let ui_bg_mut = self.ui_bg.as_mut().ok_or("no bg?")?;
|
||||||
let mut ui_tx = tc.create_texture_from_surface(ui_bg_surf_ref)?;
|
|
||||||
|
let _ = self.mouse_shadow_surf.blit(None, ui_bg_mut, self.mouse_shadow_pos);
|
||||||
|
let mut ui_tx = tc.create_texture_from_surface(ui_bg_mut)?;
|
||||||
ui_tx.set_blend_mode(BlendMode::Blend);
|
ui_tx.set_blend_mode(BlendMode::Blend);
|
||||||
self.canvas.copy(&ui_tx, None, None)?;
|
self.canvas.copy(&ui_tx, None, None)?;
|
||||||
self.canvas.copy(&font_tx, font_rect, font_rect)?;
|
self.canvas.copy(&font_tx, font_rect, font_rect)?;
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 564 B |
Binary file not shown.
After Width: | Height: | Size: 650 B |
Loading…
Reference in New Issue