aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAstatin <[email protected]>2025-07-22 23:14:05 +0200
committerAstatin <[email protected]>2025-07-22 23:14:05 +0200
commita5b89a18526a5b56b74f3ced3d0ebe6ad35a4551 (patch)
tree50751e0e5be68f15c666e08cde2496f72dca0a91
parent87092ea395b910c2c40c5e1244ebec51032c064a (diff)
Add headless option
-rw-r--r--src/desktop/window.rs8
-rw-r--r--src/io.rs6
-rw-r--r--src/main.rs22
3 files changed, 33 insertions, 3 deletions
diff --git a/src/desktop/window.rs b/src/desktop/window.rs
index 0d5bd8c..5265fd2 100644
--- a/src/desktop/window.rs
+++ b/src/desktop/window.rs
@@ -20,6 +20,14 @@ const HEIGHT: u32 = 144;
pub type Keys = Arc<Mutex<HashSet<KeyCode>>>;
+pub struct Headless;
+
+impl Window for Headless {
+ fn update(&mut self, _fb: Box<[u32; 160 * 144]>) -> Option<WindowSignal> {
+ None
+ }
+}
+
pub struct DesktopWindow {
fb_send: Sender<Box<[u32; 160 * 144]>>,
signal_recv: Receiver<WindowSignal>,
diff --git a/src/io.rs b/src/io.rs
index 730fc55..8ed35e8 100644
--- a/src/io.rs
+++ b/src/io.rs
@@ -36,6 +36,12 @@ pub trait Window {
fn update(&mut self, fb: Box<[u32; 160 * 144]>) -> Option<WindowSignal>;
}
+impl<T: Window + ?Sized> Window for Box<T> {
+ fn update(&mut self, fb: Box<[u32; 160 * 144]>) -> Option<WindowSignal> {
+ (**self).update(fb)
+ }
+}
+
pub trait Serial {
fn read_data(&self) -> u8;
fn read_control(&self) -> u8;
diff --git a/src/main.rs b/src/main.rs
index 8303fc3..ee815f8 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,9 +9,12 @@ pub mod mmio;
pub mod opcodes;
pub mod state;
+use std::collections::HashSet;
+use std::sync::{Arc, Mutex};
+
use crate::desktop::input::{Gamepad, GamepadRecorder, GamepadReplay, Keyboard};
use crate::desktop::load_save::FSLoadSave;
-use crate::io::{Input, Serial};
+use crate::io::{Input, Serial, Window};
use crate::logs::{log, LogLevel};
use clap::Parser;
@@ -61,6 +64,10 @@ struct Cli {
#[arg(long, default_value_t = false)]
stop_dump_state: bool,
+ /// Do not create a window
+ #[arg(long, default_value_t = false)]
+ headless: bool,
+
/// Window title
#[arg(long, default_value = "Gameboy Emulator")]
title: String,
@@ -89,7 +96,16 @@ fn main() {
log(LogLevel::Infos, format!("Starting {:?}...", &cli.rom));
- let window = desktop::window::DesktopWindow::new(cli.title).unwrap();
+ let (window, keys): (Box<dyn Window>, desktop::window::Keys) = if cli.headless {
+ (
+ Box::new(desktop::window::Headless),
+ Arc::new(Mutex::new(HashSet::new())),
+ )
+ } else {
+ let window = desktop::window::DesktopWindow::new(cli.title).unwrap();
+ let keys = window.keys.clone();
+ (Box::new(window), keys)
+ };
let serial: Box<dyn Serial> =
match (cli.fifo_input, cli.fifo_output, cli.listen, cli.connect) {
@@ -109,7 +125,7 @@ fn main() {
let mut gamepad: Box<dyn Input> = if let Some(record_file) = cli.replay_input {
Box::new(GamepadReplay::new(record_file))
} else if cli.keyboard {
- Box::new(Keyboard::new(window.keys.clone()))
+ Box::new(Keyboard::new(keys))
} else {
Box::new(Gamepad::new())
};