diff --git a/Cargo.lock b/Cargo.lock index 6e9bcab..a6291b9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1006,6 +1006,7 @@ dependencies = [ "ahash", "egui", "enum-map", + "image", "log", "mime_guess2", ] diff --git a/Cargo.toml b/Cargo.toml index b4e617f..05495c4 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,7 +11,7 @@ clap = { version = "4", features = ["derive"] } cpal = { git = "https://github.com/sidit77/cpal.git", rev = "66ed6be" } directories = "5" egui = { version = "0.29", features = ["serde"] } -egui_extras = "0.29" +egui_extras = { version = "0.29", features = ["image"] } egui-toast = "0.15" egui-winit = "0.29" egui-wgpu = { version = "0.29", features = ["winit"] } diff --git a/src/app.rs b/src/app.rs index 6151db5..30589f3 100644 --- a/src/app.rs +++ b/src/app.rs @@ -18,7 +18,7 @@ use crate::{ emulator::{EmulatorClient, EmulatorCommand, SimId}, input::MappingProvider, persistence::Persistence, - window::{AppWindow, GameWindow, InputWindow}, + window::{AboutWindow, AppWindow, GameWindow, InputWindow}, }; fn load_icon() -> anyhow::Result { @@ -179,6 +179,10 @@ impl ApplicationHandler for Application { }; viewport.app.handle_gamepad_event(&event); } + UserEvent::OpenAbout => { + let about = AboutWindow; + self.open(event_loop, Box::new(about)); + } UserEvent::OpenInput => { let input = InputWindow::new(self.mappings.clone()); self.open(event_loop, Box::new(input)); @@ -254,6 +258,7 @@ impl Viewport { s.wrap_mode = Some(TextWrapMode::Extend); s.visuals.menu_rounding = Default::default(); }); + egui_extras::install_image_loaders(&ctx); let mut info = ViewportInfo::default(); let mut builder = app.initial_viewport(); @@ -365,6 +370,7 @@ impl Drop for Viewport { #[derive(Debug)] pub enum UserEvent { GamepadEvent(gilrs::Event), + OpenAbout, OpenInput, OpenPlayer2, } diff --git a/src/window.rs b/src/window.rs index fdc95d3..fd53acc 100644 --- a/src/window.rs +++ b/src/window.rs @@ -1,8 +1,10 @@ +pub use about::AboutWindow; use egui::{Context, ViewportBuilder, ViewportId}; pub use game::GameWindow; pub use input::InputWindow; use winit::event::KeyEvent; +mod about; mod game; mod game_screen; mod input; diff --git a/src/window/about.rs b/src/window/about.rs new file mode 100644 index 0000000..43bd18b --- /dev/null +++ b/src/window/about.rs @@ -0,0 +1,30 @@ +use egui::{CentralPanel, Context, Image, ViewportBuilder, ViewportId}; + +use super::AppWindow; + +pub struct AboutWindow; + +impl AppWindow for AboutWindow { + fn viewport_id(&self) -> ViewportId { + ViewportId::from_hash_of("About") + } + + fn initial_viewport(&self) -> ViewportBuilder { + ViewportBuilder::default() + .with_title("About Lemur") + .with_inner_size((300.0, 200.0)) + } + + fn show(&mut self, ctx: &Context) { + CentralPanel::default().show(ctx, |ui| { + ui.vertical_centered(|ui| { + ui.label("Lemur Virtual Boy Emulator"); + ui.hyperlink("https://git.virtual-boy.com/PVB/lemur"); + let logo = Image::new(egui::include_image!("../../assets/lemur-256x256.png")) + .max_width(256.0) + .maintain_aspect_ratio(true); + ui.add(logo); + }); + }); + } +} diff --git a/src/window/game.rs b/src/window/game.rs index c028579..2570d07 100644 --- a/src/window/game.rs +++ b/src/window/game.rs @@ -98,6 +98,36 @@ impl GameWindow { ui.close_menu(); } }); + ui.menu_button("Options", |ui| self.show_options_menu(ctx, ui)); + ui.menu_button("Multiplayer", |ui| { + if self.sim_id == SimId::Player1 + && !self.client.has_player_2() + && ui.button("Open Player 2").clicked() + { + self.client + .send_command(EmulatorCommand::StartSecondSim(None)); + self.proxy.send_event(UserEvent::OpenPlayer2).unwrap(); + ui.close_menu(); + } + if self.client.has_player_2() { + let linked = self.client.are_sims_linked(); + if linked && ui.button("Unlink").clicked() { + self.client.send_command(EmulatorCommand::Unlink); + ui.close_menu(); + } + if !linked && ui.button("Link").clicked() { + self.client.send_command(EmulatorCommand::Link); + ui.close_menu(); + } + } + }); + ui.menu_button("About", |ui| { + self.proxy.send_event(UserEvent::OpenAbout).unwrap(); + ui.close_menu(); + }); + } + + fn show_options_menu(&mut self, ctx: &Context, ui: &mut Ui) { ui.menu_button("Video", |ui| { ui.menu_button("Screen Size", |ui| { let current_dims = ctx.input(|i| i.viewport().inner_rect.unwrap()); @@ -207,28 +237,6 @@ impl GameWindow { ui.close_menu(); } }); - ui.menu_button("Multiplayer", |ui| { - if self.sim_id == SimId::Player1 - && !self.client.has_player_2() - && ui.button("Open Player 2").clicked() - { - self.client - .send_command(EmulatorCommand::StartSecondSim(None)); - self.proxy.send_event(UserEvent::OpenPlayer2).unwrap(); - ui.close_menu(); - } - if self.client.has_player_2() { - let linked = self.client.are_sims_linked(); - if linked && ui.button("Unlink").clicked() { - self.client.send_command(EmulatorCommand::Unlink); - ui.close_menu(); - } - if !linked && ui.button("Link").clicked() { - self.client.send_command(EmulatorCommand::Link); - ui.close_menu(); - } - } - }); } fn show_color_picker(&mut self, ui: &mut Ui) {