Compare commits

...
3 Commits
7 changed files with 83 additions and 18 deletions
Generated
+21
View File
@@ -1892,6 +1892,12 @@ dependencies = [
"windows-sys 0.52.0",
]
[[package]]
name = "rustversion"
version = "1.0.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e819f2bc632f285be6d7cd36e25940d45b2391dd6d9b939e79de557f7014248"
[[package]]
name = "same-file"
version = "1.0.6"
@@ -1972,6 +1978,7 @@ dependencies = [
"pollster",
"rtrb",
"rubato",
"thread-priority",
"wgpu",
"winit",
]
@@ -2118,6 +2125,20 @@ dependencies = [
"syn 2.0.87",
]
[[package]]
name = "thread-priority"
version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cfe075d7053dae61ac5413a34ea7d4913b6e6207844fd726bdd858b37ff72bf5"
dependencies = [
"bitflags 2.6.0",
"cfg-if",
"libc",
"log",
"rustversion",
"winapi",
]
[[package]]
name = "tiny-skia"
version = "0.11.4"
+1
View File
@@ -19,6 +19,7 @@ num-traits = "0.2"
pollster = "0.4"
rtrb = "0.3"
rubato = "0.16"
thread-priority = "1"
wgpu = "22.1"
winit = "0.30"
+10 -3
View File
@@ -58,6 +58,7 @@ pub struct WindowState {
pub surface_desc: wgpu::SurfaceConfiguration,
pub surface: wgpu::Surface<'static>,
pub hidpi_factor: f64,
pub minimized: bool,
}
impl WindowState {
@@ -105,6 +106,7 @@ impl WindowState {
surface_desc,
surface,
hidpi_factor,
minimized: false,
}
}
@@ -114,9 +116,14 @@ impl WindowState {
}
pub fn handle_resize(&mut self, size: &PhysicalSize<u32>) {
self.surface_desc.width = size.width;
self.surface_desc.height = size.height;
self.surface.configure(&self.device, &self.surface_desc);
if size.width > 0 && size.height > 0 {
self.minimized = false;
self.surface_desc.width = size.width;
self.surface_desc.height = size.height;
self.surface.configure(&self.device, &self.surface_desc);
} else {
self.minimized = true;
}
}
}
+17 -2
View File
@@ -30,6 +30,7 @@ pub struct GameWindow {
client: EmulatorClient,
input_mapper: Arc<RwLock<InputMapper>>,
proxy: EventLoopProxy<UserEvent>,
paused_due_to_minimize: bool,
}
impl GameWindow {
@@ -165,6 +166,7 @@ impl GameWindow {
client,
input_mapper,
proxy,
paused_due_to_minimize: false,
}
}
@@ -181,7 +183,9 @@ impl GameWindow {
let frame = match window.surface.get_current_texture() {
Ok(frame) => frame,
Err(e) => {
eprintln!("dropped frame: {e:?}");
if !self.window.minimized {
eprintln!("dropped frame: {e:?}");
}
return;
}
};
@@ -325,7 +329,18 @@ impl AppWindow for GameWindow {
fn handle_event(&mut self, event_loop: &ActiveEventLoop, event: &Event<UserEvent>) {
match event {
Event::WindowEvent { event, .. } => match event {
WindowEvent::Resized(size) => self.window.handle_resize(size),
WindowEvent::Resized(size) => {
self.window.handle_resize(size);
if self.window.minimized {
if self.client.is_running() {
self.client.send_command(EmulatorCommand::Pause);
self.paused_due_to_minimize = true;
}
} else if self.paused_due_to_minimize {
self.client.send_command(EmulatorCommand::Resume);
self.paused_due_to_minimize = false;
}
}
WindowEvent::CloseRequested => event_loop.exit(),
WindowEvent::RedrawRequested => self.draw(event_loop),
_ => (),
+3 -1
View File
@@ -73,7 +73,9 @@ impl InputWindow {
let frame = match window.surface.get_current_texture() {
Ok(frame) => frame,
Err(e) => {
eprintln!("dropped frame: {e:?}");
if !self.window.minimized {
eprintln!("dropped frame: {e:?}");
}
return;
}
};
+15 -1
View File
@@ -3,7 +3,7 @@ use std::{
path::{Path, PathBuf},
sync::{
atomic::{AtomicBool, Ordering},
mpsc::{self, TryRecvError},
mpsc::{self, RecvError, TryRecvError},
Arc,
},
};
@@ -94,19 +94,33 @@ impl Emulator {
let mut eye_contents = vec![0u8; 384 * 224 * 2];
let mut audio_samples = vec![];
loop {
let mut idle = true;
if self.running.load(Ordering::Acquire) {
idle = false;
self.sim.emulate_frame();
}
if let Some(renderer) = &mut self.renderer {
if self.sim.read_pixels(&mut eye_contents) {
idle = false;
renderer.render(&eye_contents);
}
}
self.sim.read_samples(&mut audio_samples);
if !audio_samples.is_empty() {
idle = false;
self.audio.update(&audio_samples);
audio_samples.clear();
}
if idle {
// The game is paused, and we have output all the video/audio we have.
// Block the thread until a new command comes in.
match self.commands.recv() {
Ok(command) => self.handle_command(command),
Err(RecvError) => {
return;
}
}
}
loop {
match self.commands.try_recv() {
Ok(command) => self.handle_command(command),
+16 -11
View File
@@ -1,9 +1,10 @@
use std::{path::PathBuf, process, thread};
use std::{path::PathBuf, process};
use anyhow::Result;
use app::App;
use clap::Parser;
use emulator::EmulatorBuilder;
use thread_priority::{ThreadBuilder, ThreadPriority};
use winit::event_loop::{ControlFlow, EventLoop};
mod app;
@@ -26,16 +27,20 @@ fn main() -> Result<()> {
if let Some(path) = args.rom {
builder = builder.with_rom(&path);
}
thread::spawn(move || {
let mut emulator = match builder.build() {
Ok(e) => e,
Err(err) => {
eprintln!("Error initializing emulator: {err}");
process::exit(1);
}
};
emulator.run();
});
ThreadBuilder::default()
.name("Emulator".to_owned())
.priority(ThreadPriority::Max)
.spawn_careless(move || {
let mut emulator = match builder.build() {
Ok(e) => e,
Err(err) => {
eprintln!("Error initializing emulator: {err}");
process::exit(1);
}
};
emulator.run();
})?;
let event_loop = EventLoop::with_user_event().build().unwrap();
event_loop.set_control_flow(ControlFlow::Poll);