Make menu items functional

This commit is contained in:
2024-11-04 22:18:57 -05:00
parent 756835f90e
commit 593475960d
6 changed files with 255 additions and 21 deletions
+14 -4
View File
@@ -350,18 +350,28 @@ impl ApplicationHandler for App {
height = ui.window_size()[1];
ui.menu("ROM", || {
if ui.menu_item("Open ROM") {
println!("clicked");
let rom = native_dialog::FileDialog::new()
.add_filter("Virtual Boy ROMs", &["vb", "vbrom"])
.show_open_single_file()
.unwrap();
if let Some(path) = rom {
self.client.send_command(EmulatorCommand::LoadGame(path));
}
}
if ui.menu_item("Quit") {
event_loop.exit();
}
});
ui.menu("Emulation", || {
if ui.menu_item("Pause") {
println!("clicked");
if self.client.is_running() {
if ui.menu_item("Pause") {
self.client.send_command(EmulatorCommand::Pause);
}
} else if ui.menu_item("Resume") {
self.client.send_command(EmulatorCommand::Resume);
}
if ui.menu_item("Reset") {
println!("clicked");
self.client.send_command(EmulatorCommand::Reset);
}
});
});
+48 -5
View File
@@ -1,7 +1,11 @@
use std::{
fs,
path::{Path, PathBuf},
sync::mpsc::{self, TryRecvError},
sync::{
atomic::{AtomicBool, Ordering},
mpsc::{self, TryRecvError},
Arc,
},
};
use anyhow::Result;
@@ -11,6 +15,7 @@ use crate::{audio::Audio, renderer::GameRenderer, shrooms_vb_core::CoreVB};
pub struct EmulatorBuilder {
rom: Option<PathBuf>,
commands: mpsc::Receiver<EmulatorCommand>,
running: Arc<AtomicBool>,
}
impl EmulatorBuilder {
@@ -19,8 +24,12 @@ impl EmulatorBuilder {
let builder = Self {
rom: None,
commands,
running: Arc::new(AtomicBool::new(false)),
};
let client = EmulatorClient {
queue,
running: builder.running.clone(),
};
let client = EmulatorClient { queue };
(builder, client)
}
@@ -32,7 +41,7 @@ impl EmulatorBuilder {
}
pub fn build(self) -> Result<Emulator> {
let mut emulator = Emulator::new(self.commands)?;
let mut emulator = Emulator::new(self.commands, self.running)?;
if let Some(path) = self.rom {
emulator.load_rom(&path)?;
}
@@ -45,21 +54,28 @@ pub struct Emulator {
audio: Audio,
commands: mpsc::Receiver<EmulatorCommand>,
renderer: Option<GameRenderer>,
running: Arc<AtomicBool>,
has_game: bool,
}
impl Emulator {
fn new(commands: mpsc::Receiver<EmulatorCommand>) -> Result<Self> {
fn new(commands: mpsc::Receiver<EmulatorCommand>, running: Arc<AtomicBool>) -> Result<Self> {
Ok(Self {
sim: CoreVB::new(),
audio: Audio::init()?,
commands,
renderer: None,
running,
has_game: false,
})
}
pub fn load_rom(&mut self, path: &Path) -> Result<()> {
let bytes = fs::read(path)?;
self.sim.reset();
self.sim.load_rom(bytes)?;
self.has_game = true;
self.running.store(true, Ordering::Release);
Ok(())
}
@@ -67,7 +83,9 @@ impl Emulator {
let mut eye_contents = vec![0u8; 384 * 224 * 2];
let mut audio_samples = vec![];
loop {
self.sim.emulate_frame();
if self.running.load(Ordering::Acquire) {
self.sim.emulate_frame();
}
if let Some(renderer) = &mut self.renderer {
if self.sim.read_pixels(&mut eye_contents) {
renderer.render(&eye_contents);
@@ -97,6 +115,23 @@ impl Emulator {
EmulatorCommand::SetRenderer(renderer) => {
self.renderer = Some(renderer);
}
EmulatorCommand::LoadGame(path) => {
if let Err(error) = self.load_rom(&path) {
eprintln!("error loading rom: {}", error);
}
}
EmulatorCommand::Pause => {
self.running.store(false, Ordering::Release);
}
EmulatorCommand::Resume => {
if self.has_game {
self.running.store(true, Ordering::Relaxed);
}
}
EmulatorCommand::Reset => {
self.sim.reset();
self.running.store(true, Ordering::Release);
}
EmulatorCommand::PressStart => {
self.sim.set_keys(0x1003);
}
@@ -110,15 +145,23 @@ impl Emulator {
#[derive(Debug)]
pub enum EmulatorCommand {
SetRenderer(GameRenderer),
LoadGame(PathBuf),
Pause,
Resume,
Reset,
PressStart,
ReleaseStart,
}
pub struct EmulatorClient {
queue: mpsc::Sender<EmulatorCommand>,
running: Arc<AtomicBool>,
}
impl EmulatorClient {
pub fn is_running(&self) -> bool {
self.running.load(Ordering::Acquire)
}
pub fn send_command(&self, command: EmulatorCommand) {
if let Err(err) = self.queue.send(command) {
eprintln!(
+13 -5
View File
@@ -1,4 +1,4 @@
use std::{path::PathBuf, thread};
use std::{path::PathBuf, process, thread};
use anyhow::Result;
use app::App;
@@ -14,16 +14,24 @@ mod shrooms_vb_core;
#[derive(Parser)]
struct Args {
rom: PathBuf,
rom: Option<PathBuf>,
}
fn main() -> Result<()> {
let args = Args::parse();
let (builder, client) = EmulatorBuilder::new();
let builder = builder.with_rom(&args.rom);
let (mut builder, client) = EmulatorBuilder::new();
if let Some(path) = args.rom {
builder = builder.with_rom(&path);
}
thread::spawn(move || {
let mut emulator = builder.build().unwrap();
let mut emulator = match builder.build() {
Ok(e) => e,
Err(err) => {
eprintln!("Error initializing emulator: {err}");
process::exit(1);
}
};
emulator.run();
});
+4
View File
@@ -119,6 +119,10 @@ impl CoreVB {
CoreVB { sim }
}
pub fn reset(&mut self) {
unsafe { vb_reset(self.sim) };
}
pub fn load_rom(&mut self, rom: Vec<u8>) -> Result<()> {
self.unload_rom();