separate prepare and run emulator
This commit is contained in:
parent
f7e3f2b6e9
commit
6ae2697a39
4 changed files with 92 additions and 31 deletions
|
@ -5,9 +5,9 @@ use camera::Webcam;
|
||||||
use clap::{ArgGroup, Parser, Subcommand, ValueEnum};
|
use clap::{ArgGroup, Parser, Subcommand, ValueEnum};
|
||||||
use gb_emu_lib::{
|
use gb_emu_lib::{
|
||||||
config::ConfigManager,
|
config::ConfigManager,
|
||||||
connect::{SerialTarget, SramType, StdoutType},
|
connect::{EmulatorMessage, SerialTarget, SramType, StdoutType},
|
||||||
};
|
};
|
||||||
use std::path::PathBuf;
|
use std::{path::PathBuf, sync::mpsc::channel};
|
||||||
|
|
||||||
#[cfg(all(feature = "vulkan", feature = "pixels"))]
|
#[cfg(all(feature = "vulkan", feature = "pixels"))]
|
||||||
compile_error!("select only one rendering backend!");
|
compile_error!("select only one rendering backend!");
|
||||||
|
@ -159,6 +159,15 @@ fn main() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
gb_emu::run(args.into());
|
let (sender, receiver) = channel::<EmulatorMessage>();
|
||||||
|
|
||||||
|
{
|
||||||
|
let sender = sender.clone();
|
||||||
|
ctrlc::set_handler(move || {
|
||||||
|
sender.send(EmulatorMessage::Exit).unwrap();
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
gb_emu::run(gb_emu::prepare(args.into(), sender, receiver));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use std::sync::mpsc::channel;
|
||||||
use std::sync::RwLock;
|
use std::sync::RwLock;
|
||||||
|
|
||||||
use cacao::appkit::menu::{Menu, MenuItem};
|
use cacao::appkit::menu::{Menu, MenuItem};
|
||||||
|
@ -6,6 +7,7 @@ use cacao::appkit::window::{Window, WindowConfig, WindowStyle, WindowToolbarStyl
|
||||||
use cacao::appkit::{App, AppDelegate};
|
use cacao::appkit::{App, AppDelegate};
|
||||||
use cacao::filesystem::FileSelectPanel;
|
use cacao::filesystem::FileSelectPanel;
|
||||||
use cacao::notification_center::Dispatcher;
|
use cacao::notification_center::Dispatcher;
|
||||||
|
use gb_emu_lib::connect::EmulatorMessage;
|
||||||
|
|
||||||
use self::preferences::{PreferencesMessage, PreferencesUi};
|
use self::preferences::{PreferencesMessage, PreferencesUi};
|
||||||
|
|
||||||
|
@ -40,8 +42,12 @@ impl TwincUiApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_file(path: PathBuf) {
|
fn open_file(path: PathBuf) {
|
||||||
println!("open {path:?}");
|
let (sender, receiver) = channel::<EmulatorMessage>();
|
||||||
// gb_emu::run(gb_emu::RunOptions::new(path));
|
gb_emu::run(gb_emu::prepare(
|
||||||
|
gb_emu::RunOptions::new(path),
|
||||||
|
sender,
|
||||||
|
receiver,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for TwincUiApp {
|
impl Default for TwincUiApp {
|
||||||
|
|
|
@ -6,15 +6,18 @@ use debug::Debugger;
|
||||||
use gb_emu_lib::{
|
use gb_emu_lib::{
|
||||||
config::{ConfigManager, NamedConfig},
|
config::{ConfigManager, NamedConfig},
|
||||||
connect::{
|
connect::{
|
||||||
CgbRomType, EmulatorCoreTrait, EmulatorMessage, EmulatorOptions, NoCamera, RomFile,
|
AudioOutput, CameraWrapper, CgbRomType, EmulatorCoreTrait, EmulatorMessage,
|
||||||
SerialTarget, SramType,
|
EmulatorOptions, NoCamera, Rom, RomFile, SerialTarget, SramType,
|
||||||
},
|
},
|
||||||
EmulatorCore,
|
EmulatorCore,
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use std::{
|
use std::{
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
sync::{mpsc::channel, OnceLock},
|
sync::{
|
||||||
|
mpsc::{Receiver, Sender},
|
||||||
|
Arc, Mutex, OnceLock,
|
||||||
|
},
|
||||||
time::{Duration, Instant},
|
time::{Duration, Instant},
|
||||||
};
|
};
|
||||||
use window::WindowManager;
|
use window::WindowManager;
|
||||||
|
@ -96,17 +99,31 @@ impl RunOptions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run(options: RunOptions) -> ! {
|
pub struct PreparedEmulator<C>
|
||||||
let (sender, receiver) = channel::<EmulatorMessage>();
|
where
|
||||||
|
C: gb_emu_lib::connect::PocketCamera,
|
||||||
{
|
{
|
||||||
let sender = sender.clone();
|
sender: Sender<EmulatorMessage>,
|
||||||
ctrlc::set_handler(move || {
|
stream: cpal::Stream,
|
||||||
sender.send(EmulatorMessage::Exit).unwrap();
|
scale_override: usize,
|
||||||
})
|
shader_path: Option<PathBuf>,
|
||||||
.unwrap();
|
resizable: bool,
|
||||||
}
|
rom: Rom<C>,
|
||||||
|
output: AudioOutput,
|
||||||
|
receiver: Receiver<EmulatorMessage>,
|
||||||
|
camera: Arc<Mutex<CameraWrapper<C>>>,
|
||||||
|
serial: SerialTarget,
|
||||||
|
tile_window: bool,
|
||||||
|
layer_window: bool,
|
||||||
|
debug: bool,
|
||||||
|
record: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn prepare(
|
||||||
|
options: RunOptions,
|
||||||
|
sender: Sender<EmulatorMessage>,
|
||||||
|
receiver: Receiver<EmulatorMessage>,
|
||||||
|
) -> PreparedEmulator<NoCamera> {
|
||||||
let config_manager = ConfigManager::get().expect("Could not open config folder");
|
let config_manager = ConfigManager::get().expect("Could not open config folder");
|
||||||
let config = config_manager.load_or_create_base_config();
|
let config = config_manager.load_or_create_base_config();
|
||||||
let standalone_config: StandaloneConfig = config_manager.load_or_create_config();
|
let standalone_config: StandaloneConfig = config_manager.load_or_create_config();
|
||||||
|
@ -152,27 +169,56 @@ pub fn run(options: RunOptions) -> ! {
|
||||||
}
|
}
|
||||||
.unwrap_or(configs.standalone_config.scale_factor);
|
.unwrap_or(configs.standalone_config.scale_factor);
|
||||||
|
|
||||||
let mut window_manager = WindowManager::new(sender, stream, options.record);
|
PreparedEmulator {
|
||||||
|
sender,
|
||||||
|
stream,
|
||||||
|
scale_override,
|
||||||
|
shader_path,
|
||||||
|
resizable,
|
||||||
|
rom,
|
||||||
|
output,
|
||||||
|
receiver,
|
||||||
|
camera,
|
||||||
|
serial: options.serial,
|
||||||
|
tile_window: options.tile_window,
|
||||||
|
layer_window: options.layer_window,
|
||||||
|
debug: options.debug,
|
||||||
|
record: options.record,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let window = window_manager.add_main(scale_override, shader_path, resizable);
|
pub fn run(prepared: PreparedEmulator<NoCamera>) -> ! {
|
||||||
|
let configs = access_config();
|
||||||
|
let mut window_manager = WindowManager::new(prepared.sender, prepared.stream, prepared.record);
|
||||||
|
|
||||||
let tile_window = if options.tile_window {
|
let window = window_manager.add_main(
|
||||||
|
prepared.scale_override,
|
||||||
|
prepared.shader_path,
|
||||||
|
prepared.resizable,
|
||||||
|
);
|
||||||
|
|
||||||
|
let tile_window = if prepared.tile_window {
|
||||||
Some(window_manager.add(configs.standalone_config.scale_factor, None, false))
|
Some(window_manager.add(configs.standalone_config.scale_factor, None, false))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let layer_window = if options.layer_window {
|
let layer_window = if prepared.layer_window {
|
||||||
Some(window_manager.add(configs.standalone_config.scale_factor.min(2), None, false))
|
Some(window_manager.add(configs.standalone_config.scale_factor.min(2), None, false))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let emulator_options =
|
let emulator_options = EmulatorOptions::new_with_config(
|
||||||
EmulatorOptions::new_with_config(config, config_manager.dir(), window, rom, output)
|
configs.emu_config.clone(),
|
||||||
.with_serial_target(options.serial)
|
configs.config_dir.clone(),
|
||||||
.with_tile_window(tile_window)
|
window,
|
||||||
.with_layer_window(layer_window);
|
prepared.rom,
|
||||||
|
prepared.output,
|
||||||
|
)
|
||||||
|
.with_serial_target(prepared.serial)
|
||||||
|
.with_tile_window(tile_window)
|
||||||
|
.with_layer_window(layer_window);
|
||||||
|
|
||||||
// let core: Box<dyn EmulatorCoreTrait> = if args.camera {
|
// let core: Box<dyn EmulatorCoreTrait> = if args.camera {
|
||||||
// Box::new(EmulatorCore::init(receiver, options, Webcam::new()))
|
// Box::new(EmulatorCore::init(receiver, options, Webcam::new()))
|
||||||
|
@ -192,9 +238,9 @@ pub fn run(options: RunOptions) -> ! {
|
||||||
// EmulatorTypes::Normal(core)
|
// EmulatorTypes::Normal(core)
|
||||||
// };
|
// };
|
||||||
|
|
||||||
let mut core = EmulatorCore::init(true, receiver, emulator_options, camera);
|
let mut core = EmulatorCore::init(true, prepared.receiver, emulator_options, prepared.camera);
|
||||||
|
|
||||||
if options.debug {
|
if prepared.debug {
|
||||||
let mut debugger = Debugger::new(Box::new(core));
|
let mut debugger = Debugger::new(Box::new(core));
|
||||||
let mut since = Instant::now();
|
let mut since = Instant::now();
|
||||||
loop {
|
loop {
|
||||||
|
|
|
@ -9,7 +9,7 @@ pub use crate::processor::memory::mmio::joypad::{JoypadButtons, JoypadState};
|
||||||
pub use crate::processor::memory::mmio::serial::{SerialTarget, StdoutType};
|
pub use crate::processor::memory::mmio::serial::{SerialTarget, StdoutType};
|
||||||
use crate::processor::memory::rom::sram_save::SaveDataLocation;
|
use crate::processor::memory::rom::sram_save::SaveDataLocation;
|
||||||
pub use crate::processor::memory::rom::CgbRomType;
|
pub use crate::processor::memory::rom::CgbRomType;
|
||||||
use crate::processor::memory::Rom;
|
pub use crate::processor::memory::Rom;
|
||||||
pub use crate::{HEIGHT, WIDTH};
|
pub use crate::{HEIGHT, WIDTH};
|
||||||
use async_ringbuf::{AsyncHeapConsumer, AsyncHeapProducer, AsyncHeapRb};
|
use async_ringbuf::{AsyncHeapConsumer, AsyncHeapProducer, AsyncHeapRb};
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ where
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum SramType {
|
pub enum SramType {
|
||||||
File(PathBuf),
|
File(PathBuf),
|
||||||
RawBuffer(Arc<RwLock<Vec<u8>>>),
|
RawBuffer(Arc<RwLock<Vec<u8>>>),
|
||||||
|
|
Loading…
Add table
Reference in a new issue