switch between gui/menu modes with esc, support drag-and-drop rom changing
This commit is contained in:
parent
5c0dd5558e
commit
873037f9f1
1 changed files with 78 additions and 19 deletions
89
src/main.rs
89
src/main.rs
|
@ -5,11 +5,16 @@ use std::ffi::CStr;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
|
||||||
use sdl2::render::{WindowCanvas, BlendMode};
|
use sdl2::{
|
||||||
use sdl2::image::ImageRWops;
|
EventPump,
|
||||||
use sdl2::surface::Surface;
|
event::Event,
|
||||||
use sdl2::pixels::{Color, PixelFormatEnum};
|
image::ImageRWops,
|
||||||
use sdl2::rect::Point;
|
keyboard::Keycode,
|
||||||
|
pixels::{Color, PixelFormatEnum},
|
||||||
|
rect::Point,
|
||||||
|
render::{WindowCanvas, BlendMode},
|
||||||
|
surface::Surface,
|
||||||
|
};
|
||||||
|
|
||||||
use rand::{SeedableRng, Rng};
|
use rand::{SeedableRng, Rng};
|
||||||
use rand_xoshiro::Xoshiro128Plus;
|
use rand_xoshiro::Xoshiro128Plus;
|
||||||
|
@ -38,6 +43,20 @@ struct Opt {
|
||||||
system: Option<PathBuf>,
|
system: Option<PathBuf>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum GuiState {
|
||||||
|
Menus,
|
||||||
|
Game
|
||||||
|
}
|
||||||
|
|
||||||
|
impl GuiState {
|
||||||
|
fn toggle(&mut self) {
|
||||||
|
match self {
|
||||||
|
GuiState::Menus => *self = GuiState::Game,
|
||||||
|
GuiState::Game => *self = GuiState::Menus,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct Zretro {
|
struct Zretro {
|
||||||
emu: Pin<Box<RetroComponentBase>>,
|
emu: Pin<Box<RetroComponentBase>>,
|
||||||
canvas: WindowCanvas,
|
canvas: WindowCanvas,
|
||||||
|
@ -45,6 +64,8 @@ struct Zretro {
|
||||||
rng: Xoshiro128Plus,
|
rng: Xoshiro128Plus,
|
||||||
ui_bg: Option<Surface<'static>>,
|
ui_bg: Option<Surface<'static>>,
|
||||||
snowflakes: Vec<Point>,
|
snowflakes: Vec<Point>,
|
||||||
|
mode: GuiState,
|
||||||
|
event_pump: EventPump,
|
||||||
}
|
}
|
||||||
|
|
||||||
const FONT_PNG: &'static [u8] = include_bytes!("lifont.png");
|
const FONT_PNG: &'static [u8] = include_bytes!("lifont.png");
|
||||||
|
@ -53,7 +74,7 @@ impl Zretro {
|
||||||
fn new(opt: Opt) -> Result<Self> {
|
fn new(opt: Opt) -> Result<Self> {
|
||||||
let mut emu = RetroComponentBase::new(&opt.core);
|
let mut emu = RetroComponentBase::new(&opt.core);
|
||||||
|
|
||||||
let geometry = emu.libretro_core().get_system_av_info().geometry;
|
let SystemAvInfo { geometry, .. } = emu.libretro_core().get_system_av_info();
|
||||||
let sys_info = emu.libretro_core().get_system_info();
|
let sys_info = emu.libretro_core().get_system_info();
|
||||||
let title = format!(
|
let title = format!(
|
||||||
"zretro - {}",
|
"zretro - {}",
|
||||||
|
@ -69,6 +90,8 @@ impl Zretro {
|
||||||
.build()?;
|
.build()?;
|
||||||
let canvas = window.into_canvas().build()?;
|
let canvas = window.into_canvas().build()?;
|
||||||
|
|
||||||
|
let event_pump = sdl_context.event_pump()?;
|
||||||
|
|
||||||
let sdl2surf_comp = Sdl2SurfaceComponent::new(emu.libretro_core())?;
|
let sdl2surf_comp = Sdl2SurfaceComponent::new(emu.libretro_core())?;
|
||||||
emu.register_component(sdl2surf_comp)?;
|
emu.register_component(sdl2surf_comp)?;
|
||||||
|
|
||||||
|
@ -86,7 +109,7 @@ impl Zretro {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
emu.init().unwrap();
|
emu.init().unwrap();
|
||||||
emu.load_game(&opt.rom).unwrap();
|
emu.load_game(&opt.rom).unwrap(); // TODO: optional via CLI positional arg, menu-browsable
|
||||||
|
|
||||||
let rwops = sdl2::rwops::RWops::from_bytes(FONT_PNG)?;
|
let rwops = sdl2::rwops::RWops::from_bytes(FONT_PNG)?;
|
||||||
let font_shortlived = rwops.load_png()?;
|
let font_shortlived = rwops.load_png()?;
|
||||||
|
@ -114,6 +137,8 @@ impl Zretro {
|
||||||
rng,
|
rng,
|
||||||
ui_bg: Some(ui_bg),
|
ui_bg: Some(ui_bg),
|
||||||
snowflakes,
|
snowflakes,
|
||||||
|
mode: GuiState::Menus,
|
||||||
|
event_pump,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,21 +172,55 @@ impl Zretro {
|
||||||
let font_tx = tc.create_texture_from_surface(&self.font)?;
|
let font_tx = tc.create_texture_from_surface(&self.font)?;
|
||||||
let mut font_rect = self.font.rect();
|
let mut font_rect = self.font.rect();
|
||||||
font_rect.set_height(64);
|
font_rect.set_height(64);
|
||||||
while let ControlFlow::Continue = self.emu.run() {
|
'outer: loop {
|
||||||
self.update_snow()?;
|
for event in self.event_pump.poll_iter() {
|
||||||
|
match event {
|
||||||
|
Event::Quit { .. } => break 'outer,
|
||||||
|
Event::KeyDown { keycode: Some(keycode), .. } => {
|
||||||
|
match keycode {
|
||||||
|
Keycode::Escape => {
|
||||||
|
self.mode.toggle();
|
||||||
|
let audio: &SimpleSdl2AudioComponent = self.emu.component_ref()?;
|
||||||
|
match self.mode {
|
||||||
|
GuiState::Menus => audio.silence_buffer(),
|
||||||
|
GuiState::Game => {} //audio.resume(),
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Event::KeyUp { .. } => {}
|
||||||
|
Event::DropFile { filename, .. } => {
|
||||||
|
self.emu.libretro_core().unload_game();
|
||||||
|
self.emu.load_game(filename)?;
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let GuiState::Game = self.mode {
|
||||||
|
if let ControlFlow::Break = self.emu.run() {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
let delay: &mut SleepFramerateLimitComponent = self.emu.component_mut()?;
|
||||||
|
delay.do_sleep();
|
||||||
|
}
|
||||||
|
|
||||||
let surfcomp: &Sdl2SurfaceComponent = self.emu.component_ref()?;
|
let surfcomp: &Sdl2SurfaceComponent = self.emu.component_ref()?;
|
||||||
let surface = surfcomp.surface();
|
let emu_surf_ref = surfcomp.surface();
|
||||||
|
let emu_tx = tc.create_texture_from_surface(emu_surf_ref)?;
|
||||||
let emu_tx = tc.create_texture_from_surface(surface)?;
|
self.canvas.clear();
|
||||||
|
self.canvas.copy(&emu_tx, None, None)?;
|
||||||
|
|
||||||
|
if let GuiState::Menus = self.mode {
|
||||||
|
self.update_snow()?;
|
||||||
let ui_bg_surf_ref = self.ui_bg.as_ref().ok_or("no bg?")?;
|
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)?;
|
let mut ui_tx = tc.create_texture_from_surface(ui_bg_surf_ref)?;
|
||||||
ui_tx.set_blend_mode(BlendMode::Blend);
|
ui_tx.set_blend_mode(BlendMode::Blend);
|
||||||
|
|
||||||
self.canvas.clear();
|
|
||||||
self.canvas.copy(&emu_tx, None, None)?;
|
|
||||||
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)?;
|
||||||
|
}
|
||||||
self.canvas.present();
|
self.canvas.present();
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
Loading…
Add table
Reference in a new issue