Compare commits
No commits in common. "main" and "v0.9.1" have entirely different histories.
|
@ -2165,7 +2165,7 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "lemur"
|
name = "lemur"
|
||||||
version = "0.9.2"
|
version = "0.9.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"atoi",
|
"atoi",
|
||||||
|
|
|
@ -4,7 +4,7 @@ description = "An emulator for the Virtual Boy."
|
||||||
repository = "https://git.virtual-boy.com/PVB/lemur"
|
repository = "https://git.virtual-boy.com/PVB/lemur"
|
||||||
publish = false
|
publish = false
|
||||||
license = "MIT"
|
license = "MIT"
|
||||||
version = "0.9.2"
|
version = "0.9.1"
|
||||||
edition = "2024"
|
edition = "2024"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4ed3b7299507b8ea0079a0965f33b0c8a6886572
|
Subproject commit 8598eab087cced12b92a411f6c7f2eb9de51310f
|
12
src/app.rs
12
src/app.rs
|
@ -24,8 +24,8 @@ use crate::{
|
||||||
persistence::Persistence,
|
persistence::Persistence,
|
||||||
window::{
|
window::{
|
||||||
AboutWindow, AppWindow, BgMapWindow, CharacterDataWindow, FrameBufferWindow, GameWindow,
|
AboutWindow, AppWindow, BgMapWindow, CharacterDataWindow, FrameBufferWindow, GameWindow,
|
||||||
GdbServerWindow, HotkeysWindow, InitArgs, InputWindow, ObjectWindow, ProfileWindow,
|
GdbServerWindow, HotkeysWindow, InputWindow, ObjectWindow, ProfileWindow, RegisterWindow,
|
||||||
RegisterWindow, TerminalWindow, WorldWindow,
|
TerminalWindow, WorldWindow,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -423,13 +423,7 @@ impl Viewport {
|
||||||
let (window, state) = create_window_and_state(&ctx, event_loop, &builder, &mut painter);
|
let (window, state) = create_window_and_state(&ctx, event_loop, &builder, &mut painter);
|
||||||
egui_winit::update_viewport_info(&mut info, &ctx, &window, true);
|
egui_winit::update_viewport_info(&mut info, &ctx, &window, true);
|
||||||
|
|
||||||
let render_state = painter.render_state();
|
app.on_init(&ctx, painter.render_state().as_ref().unwrap());
|
||||||
let args = InitArgs {
|
|
||||||
ctx: &ctx,
|
|
||||||
window: &window,
|
|
||||||
render_state: render_state.as_ref().unwrap(),
|
|
||||||
};
|
|
||||||
app.on_init(args);
|
|
||||||
Self {
|
Self {
|
||||||
painter,
|
painter,
|
||||||
ctx,
|
ctx,
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use std::sync::Arc;
|
|
||||||
|
|
||||||
pub use about::AboutWindow;
|
pub use about::AboutWindow;
|
||||||
use egui::{Context, ViewportBuilder, ViewportId};
|
use egui::{Context, ViewportBuilder, ViewportId};
|
||||||
pub use game::GameWindow;
|
pub use game::GameWindow;
|
||||||
|
@ -11,7 +9,7 @@ pub use terminal::TerminalWindow;
|
||||||
pub use vip::{
|
pub use vip::{
|
||||||
BgMapWindow, CharacterDataWindow, FrameBufferWindow, ObjectWindow, RegisterWindow, WorldWindow,
|
BgMapWindow, CharacterDataWindow, FrameBufferWindow, ObjectWindow, RegisterWindow, WorldWindow,
|
||||||
};
|
};
|
||||||
use winit::{event::KeyEvent, window::Window};
|
use winit::event::KeyEvent;
|
||||||
|
|
||||||
use crate::emulator::SimId;
|
use crate::emulator::SimId;
|
||||||
|
|
||||||
|
@ -33,8 +31,9 @@ pub trait AppWindow {
|
||||||
}
|
}
|
||||||
fn initial_viewport(&self) -> ViewportBuilder;
|
fn initial_viewport(&self) -> ViewportBuilder;
|
||||||
fn show(&mut self, ctx: &Context);
|
fn show(&mut self, ctx: &Context);
|
||||||
fn on_init(&mut self, args: InitArgs) {
|
fn on_init(&mut self, ctx: &Context, render_state: &egui_wgpu::RenderState) {
|
||||||
let _ = args;
|
let _ = ctx;
|
||||||
|
let _ = render_state;
|
||||||
}
|
}
|
||||||
fn on_destroy(&mut self) {}
|
fn on_destroy(&mut self) {}
|
||||||
fn handle_key_event(&mut self, event: &KeyEvent) -> bool {
|
fn handle_key_event(&mut self, event: &KeyEvent) -> bool {
|
||||||
|
@ -46,9 +45,3 @@ pub trait AppWindow {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct InitArgs<'a> {
|
|
||||||
pub ctx: &'a Context,
|
|
||||||
pub window: &'a Arc<Window>,
|
|
||||||
pub render_state: &'a egui_wgpu::RenderState,
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,14 +1,10 @@
|
||||||
use std::{
|
use std::{sync::mpsc, time::Duration};
|
||||||
sync::{Arc, mpsc},
|
|
||||||
time::Duration,
|
|
||||||
};
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
app::UserEvent,
|
app::UserEvent,
|
||||||
emulator::{EmulatorClient, EmulatorCommand, EmulatorState, SimId, SimState},
|
emulator::{EmulatorClient, EmulatorCommand, EmulatorState, SimId, SimState},
|
||||||
input::{Command, ShortcutProvider},
|
input::{Command, ShortcutProvider},
|
||||||
persistence::Persistence,
|
persistence::Persistence,
|
||||||
window::InitArgs,
|
|
||||||
};
|
};
|
||||||
use anyhow::Context as _;
|
use anyhow::Context as _;
|
||||||
use egui::{
|
use egui::{
|
||||||
|
@ -51,7 +47,6 @@ pub struct GameWindow {
|
||||||
screen: Option<GameScreen>,
|
screen: Option<GameScreen>,
|
||||||
messages: Option<mpsc::Receiver<Toast>>,
|
messages: Option<mpsc::Receiver<Toast>>,
|
||||||
color_picker: Option<ColorPickerState>,
|
color_picker: Option<ColorPickerState>,
|
||||||
window: Option<Arc<winit::window::Window>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GameWindow {
|
impl GameWindow {
|
||||||
|
@ -78,7 +73,6 @@ impl GameWindow {
|
||||||
screen: None,
|
screen: None,
|
||||||
messages: None,
|
messages: None,
|
||||||
color_picker: None,
|
color_picker: None,
|
||||||
window: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +87,8 @@ impl GameWindow {
|
||||||
match command {
|
match command {
|
||||||
Command::OpenRom => {
|
Command::OpenRom => {
|
||||||
let rom = rfd::FileDialog::new()
|
let rom = rfd::FileDialog::new()
|
||||||
.add_filter("Virtual Boy ROMs", &["vb", "vbrom", "elf", "isx"])
|
.add_filter("Virtual Boy ROMs", &["vb", "vbrom"])
|
||||||
|
.add_filter("Executable files", &["", "elf", "isx"])
|
||||||
.pick_file();
|
.pick_file();
|
||||||
if let Some(path) = rom {
|
if let Some(path) = rom {
|
||||||
self.client
|
self.client
|
||||||
|
@ -145,7 +140,8 @@ impl GameWindow {
|
||||||
.clicked()
|
.clicked()
|
||||||
{
|
{
|
||||||
let rom = rfd::FileDialog::new()
|
let rom = rfd::FileDialog::new()
|
||||||
.add_filter("Virtual Boy ROMs", &["vb", "vbrom", "elf", "isx"])
|
.add_filter("Virtual Boy ROMs", &["vb", "vbrom"])
|
||||||
|
.add_filter("Executable files", &["", "elf", "isx"])
|
||||||
.pick_file();
|
.pick_file();
|
||||||
if let Some(path) = rom {
|
if let Some(path) = rom {
|
||||||
self.client
|
self.client
|
||||||
|
@ -304,13 +300,10 @@ impl GameWindow {
|
||||||
self.client
|
self.client
|
||||||
.send_command(EmulatorCommand::Screenshot(self.sim_id, tx));
|
.send_command(EmulatorCommand::Screenshot(self.sim_id, tx));
|
||||||
let bytes = rx.await.context("Could not take screenshot")?;
|
let bytes = rx.await.context("Could not take screenshot")?;
|
||||||
let mut file_dialog = rfd::FileDialog::new()
|
let file = rfd::FileDialog::new()
|
||||||
.add_filter("PNG images", &["png"])
|
.add_filter("PNG images", &["png"])
|
||||||
.set_file_name("screenshot.png");
|
.set_file_name("screenshot.png")
|
||||||
if let Some(window) = self.window.as_ref() {
|
.save_file();
|
||||||
file_dialog = file_dialog.set_parent(window);
|
|
||||||
}
|
|
||||||
let file = file_dialog.save_file();
|
|
||||||
let Some(path) = file else {
|
let Some(path) = file else {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
};
|
};
|
||||||
|
@ -554,8 +547,8 @@ impl AppWindow for GameWindow {
|
||||||
self.toasts.show(ctx);
|
self.toasts.show(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_init(&mut self, args: InitArgs) {
|
fn on_init(&mut self, _ctx: &Context, render_state: &egui_wgpu::RenderState) {
|
||||||
let (screen, sink) = GameScreen::init(args.render_state);
|
let (screen, sink) = GameScreen::init(render_state);
|
||||||
let (message_sink, message_source) = mpsc::channel();
|
let (message_sink, message_source) = mpsc::channel();
|
||||||
self.client.send_command(EmulatorCommand::ConnectToSim(
|
self.client.send_command(EmulatorCommand::ConnectToSim(
|
||||||
self.sim_id,
|
self.sim_id,
|
||||||
|
@ -564,7 +557,6 @@ impl AppWindow for GameWindow {
|
||||||
));
|
));
|
||||||
self.screen = Some(screen);
|
self.screen = Some(screen);
|
||||||
self.messages = Some(message_source);
|
self.messages = Some(message_source);
|
||||||
self.window = Some(args.window.clone());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_destroy(&mut self) {
|
fn on_destroy(&mut self) {
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
use std::{fs, sync::Arc, time::Duration};
|
use std::{fs, time::Duration};
|
||||||
|
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use egui::{Button, CentralPanel, Checkbox, Label, ViewportBuilder, ViewportId};
|
use egui::{Button, CentralPanel, Checkbox, Label, ViewportBuilder, ViewportId};
|
||||||
use egui_notify::{Anchor, Toast, Toasts};
|
use egui_notify::{Anchor, Toast, Toasts};
|
||||||
use winit::window::Window;
|
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
emulator::{EmulatorClient, EmulatorCommand, EmulatorState, SimId},
|
emulator::{EmulatorClient, EmulatorCommand, EmulatorState, SimId},
|
||||||
profiler::{Profiler, ProfilerStatus},
|
profiler::{Profiler, ProfilerStatus},
|
||||||
window::{AppWindow, InitArgs},
|
window::AppWindow,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct ProfileWindow {
|
pub struct ProfileWindow {
|
||||||
|
@ -16,7 +15,6 @@ pub struct ProfileWindow {
|
||||||
client: EmulatorClient,
|
client: EmulatorClient,
|
||||||
profiler: Profiler,
|
profiler: Profiler,
|
||||||
toasts: Toasts,
|
toasts: Toasts,
|
||||||
window: Option<Arc<Window>>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ProfileWindow {
|
impl ProfileWindow {
|
||||||
|
@ -29,7 +27,6 @@ impl ProfileWindow {
|
||||||
.with_anchor(Anchor::BottomLeft)
|
.with_anchor(Anchor::BottomLeft)
|
||||||
.with_margin((10.0, 10.0).into())
|
.with_margin((10.0, 10.0).into())
|
||||||
.reverse(true),
|
.reverse(true),
|
||||||
window: None,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,13 +59,10 @@ impl ProfileWindow {
|
||||||
|
|
||||||
fn try_finish_recording(&mut self) -> Result<Option<String>> {
|
fn try_finish_recording(&mut self) -> Result<Option<String>> {
|
||||||
let bytes_receiver = self.profiler.finish_recording();
|
let bytes_receiver = self.profiler.finish_recording();
|
||||||
let mut file_dialog = rfd::FileDialog::new()
|
let file = rfd::FileDialog::new()
|
||||||
.add_filter("Profiler files", &["json"])
|
.add_filter("Profiler files", &["json"])
|
||||||
.set_file_name("profile.json");
|
.set_file_name("profile.json")
|
||||||
if let Some(window) = self.window.as_ref() {
|
.save_file();
|
||||||
file_dialog = file_dialog.set_parent(window);
|
|
||||||
}
|
|
||||||
let file = file_dialog.save_file();
|
|
||||||
if let Some(path) = file {
|
if let Some(path) = file {
|
||||||
let bytes = pollster::block_on(bytes_receiver)?;
|
let bytes = pollster::block_on(bytes_receiver)?;
|
||||||
let _ = fs::remove_file(&path);
|
let _ = fs::remove_file(&path);
|
||||||
|
@ -166,8 +160,4 @@ impl AppWindow for ProfileWindow {
|
||||||
});
|
});
|
||||||
self.toasts.show(ctx);
|
self.toasts.show(ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_init(&mut self, args: InitArgs) {
|
|
||||||
self.window = Some(args.window.clone());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
||||||
memory::{MemoryClient, MemoryView},
|
memory::{MemoryClient, MemoryView},
|
||||||
window::{
|
window::{
|
||||||
AppWindow, InitArgs,
|
AppWindow,
|
||||||
utils::{NumberEdit, UiExt},
|
utils::{NumberEdit, UiExt},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -187,8 +187,8 @@ impl AppWindow for BgMapWindow {
|
||||||
.with_inner_size((640.0, 480.0))
|
.with_inner_size((640.0, 480.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_init(&mut self, args: InitArgs) {
|
fn on_init(&mut self, ctx: &Context, _render_state: &egui_wgpu::RenderState) {
|
||||||
args.ctx.add_texture_loader(self.loader.clone());
|
ctx.add_texture_loader(self.loader.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self, ctx: &Context) {
|
fn show(&mut self, ctx: &Context) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use crate::{
|
||||||
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
||||||
memory::{MemoryClient, MemoryView},
|
memory::{MemoryClient, MemoryView},
|
||||||
window::{
|
window::{
|
||||||
AppWindow, InitArgs,
|
AppWindow,
|
||||||
utils::{NumberEdit, UiExt as _},
|
utils::{NumberEdit, UiExt as _},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -251,8 +251,8 @@ impl AppWindow for CharacterDataWindow {
|
||||||
.with_inner_size((640.0, 480.0))
|
.with_inner_size((640.0, 480.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_init(&mut self, args: InitArgs) {
|
fn on_init(&mut self, ctx: &Context, _render_state: &egui_wgpu::RenderState) {
|
||||||
args.ctx.add_texture_loader(self.loader.clone());
|
ctx.add_texture_loader(self.loader.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self, ctx: &Context) {
|
fn show(&mut self, ctx: &Context) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
||||||
memory::{MemoryClient, MemoryView},
|
memory::{MemoryClient, MemoryView},
|
||||||
window::{
|
window::{
|
||||||
AppWindow, InitArgs,
|
AppWindow,
|
||||||
utils::{NumberEdit, UiExt as _},
|
utils::{NumberEdit, UiExt as _},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -153,8 +153,8 @@ impl AppWindow for FrameBufferWindow {
|
||||||
.with_inner_size((640.0, 480.0))
|
.with_inner_size((640.0, 480.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_init(&mut self, args: InitArgs) {
|
fn on_init(&mut self, ctx: &Context, _render_state: &egui_wgpu::RenderState) {
|
||||||
args.ctx.add_texture_loader(self.loader.clone());
|
ctx.add_texture_loader(self.loader.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self, ctx: &Context) {
|
fn show(&mut self, ctx: &Context) {
|
||||||
|
|
|
@ -11,7 +11,7 @@ use crate::{
|
||||||
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
||||||
memory::{MemoryClient, MemoryView},
|
memory::{MemoryClient, MemoryView},
|
||||||
window::{
|
window::{
|
||||||
AppWindow, InitArgs,
|
AppWindow,
|
||||||
utils::{NumberEdit, UiExt as _},
|
utils::{NumberEdit, UiExt as _},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -208,8 +208,8 @@ impl AppWindow for ObjectWindow {
|
||||||
.with_inner_size((640.0, 500.0))
|
.with_inner_size((640.0, 500.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_init(&mut self, args: InitArgs) {
|
fn on_init(&mut self, ctx: &Context, _render_state: &egui_wgpu::RenderState) {
|
||||||
args.ctx.add_texture_loader(self.loader.clone());
|
ctx.add_texture_loader(self.loader.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self, ctx: &Context) {
|
fn show(&mut self, ctx: &Context) {
|
||||||
|
|
|
@ -17,7 +17,7 @@ use crate::{
|
||||||
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
images::{ImageBuffer, ImageParams, ImageProcessor, ImageRenderer, ImageTextureLoader},
|
||||||
memory::{MemoryClient, MemoryRef, MemoryView},
|
memory::{MemoryClient, MemoryRef, MemoryView},
|
||||||
window::{
|
window::{
|
||||||
AppWindow, InitArgs,
|
AppWindow,
|
||||||
utils::{NumberEdit, UiExt as _},
|
utils::{NumberEdit, UiExt as _},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -523,8 +523,8 @@ impl AppWindow for WorldWindow {
|
||||||
.with_inner_size((640.0, 520.0))
|
.with_inner_size((640.0, 520.0))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn on_init(&mut self, args: InitArgs) {
|
fn on_init(&mut self, ctx: &Context, _render_state: &egui_wgpu::RenderState) {
|
||||||
args.ctx.add_texture_loader(self.loader.clone());
|
ctx.add_texture_loader(self.loader.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn show(&mut self, ctx: &Context) {
|
fn show(&mut self, ctx: &Context) {
|
||||||
|
|
Loading…
Reference in New Issue