Choose save data location
This commit is contained in:
+72
-44
@@ -18,6 +18,7 @@ use tracing::{error, warn};
|
||||
|
||||
use crate::{
|
||||
audio::Audio,
|
||||
config::SaveDataLocation,
|
||||
graphics::TextureSink,
|
||||
memory::{MemoryRange, MemoryRegion},
|
||||
};
|
||||
@@ -74,12 +75,13 @@ pub struct EmulatorBuilder {
|
||||
state: Arc<Atomic<EmulatorState>>,
|
||||
audio_on: Arc<[AtomicBool; 2]>,
|
||||
linked: Arc<AtomicBool>,
|
||||
save_data_location: Arc<Atomic<SaveDataLocation>>,
|
||||
start_paused: bool,
|
||||
watch_rom: Arc<[AtomicBool; 2]>,
|
||||
}
|
||||
|
||||
impl EmulatorBuilder {
|
||||
pub fn new() -> (Self, EmulatorClient) {
|
||||
pub fn new(save_data_location: SaveDataLocation) -> (Self, EmulatorClient) {
|
||||
let (queue, commands) = mpsc::channel();
|
||||
let builder = Self {
|
||||
rom: None,
|
||||
@@ -91,6 +93,7 @@ impl EmulatorBuilder {
|
||||
state: Arc::new(Atomic::new(EmulatorState::Paused)),
|
||||
audio_on: Arc::new([AtomicBool::new(true), AtomicBool::new(true)]),
|
||||
linked: Arc::new(AtomicBool::new(false)),
|
||||
save_data_location: Arc::new(Atomic::new(save_data_location)),
|
||||
start_paused: false,
|
||||
watch_rom: Arc::new([AtomicBool::new(false), AtomicBool::new(false)]),
|
||||
};
|
||||
@@ -98,8 +101,9 @@ impl EmulatorBuilder {
|
||||
queue,
|
||||
sim_state: builder.sim_state.clone(),
|
||||
state: builder.state.clone(),
|
||||
watch_rom: builder.watch_rom.clone(),
|
||||
linked: builder.linked.clone(),
|
||||
save_data_location: builder.save_data_location.clone(),
|
||||
watch_rom: builder.watch_rom.clone(),
|
||||
};
|
||||
(builder, client)
|
||||
}
|
||||
@@ -131,18 +135,42 @@ impl EmulatorBuilder {
|
||||
}
|
||||
|
||||
pub fn build(self) -> Result<Emulator> {
|
||||
let mut emulator = Emulator::new(
|
||||
self.commands,
|
||||
self.sim_state,
|
||||
self.state,
|
||||
self.audio_on,
|
||||
self.watch_rom,
|
||||
self.linked,
|
||||
);
|
||||
if let Some(path) = self.rom {
|
||||
let Self {
|
||||
rom,
|
||||
commands,
|
||||
sim_state,
|
||||
state,
|
||||
audio_on,
|
||||
watch_rom,
|
||||
linked,
|
||||
save_data_location,
|
||||
start_paused,
|
||||
} = self;
|
||||
let mut emulator = Emulator {
|
||||
sims: vec![],
|
||||
carts: [None, None],
|
||||
audio: Audio::init(),
|
||||
commands,
|
||||
sim_state,
|
||||
state,
|
||||
audio_on,
|
||||
watch_rom,
|
||||
linked,
|
||||
save_data_location,
|
||||
profilers: [None, None],
|
||||
renderers: HashMap::new(),
|
||||
messages: HashMap::new(),
|
||||
debuggers: HashMap::new(),
|
||||
stdouts: HashMap::new(),
|
||||
watched_regions: HashMap::new(),
|
||||
eye_contents: [vec![0u8; 384 * 224 * 2], vec![0u8; 384 * 224 * 2]],
|
||||
audio_samples: Vec::with_capacity(EXPECTED_FRAME_SIZE),
|
||||
buffer: vec![],
|
||||
};
|
||||
if let Some(path) = rom {
|
||||
emulator.load_cart(SimId::Player1, &path)?;
|
||||
}
|
||||
if self.start_paused {
|
||||
if start_paused {
|
||||
emulator.pause_sims()?;
|
||||
}
|
||||
Ok(emulator)
|
||||
@@ -159,6 +187,7 @@ pub struct Emulator {
|
||||
audio_on: Arc<[AtomicBool; 2]>,
|
||||
watch_rom: Arc<[AtomicBool; 2]>,
|
||||
linked: Arc<AtomicBool>,
|
||||
save_data_location: Arc<Atomic<SaveDataLocation>>,
|
||||
profilers: [Option<ProfileSender>; 2],
|
||||
renderers: HashMap<SimId, TextureSink>,
|
||||
messages: HashMap<SimId, mpsc::Sender<Toast>>,
|
||||
@@ -171,36 +200,6 @@ pub struct Emulator {
|
||||
}
|
||||
|
||||
impl Emulator {
|
||||
fn new(
|
||||
commands: mpsc::Receiver<EmulatorCommand>,
|
||||
sim_state: Arc<[Atomic<SimState>; 2]>,
|
||||
state: Arc<Atomic<EmulatorState>>,
|
||||
audio_on: Arc<[AtomicBool; 2]>,
|
||||
watch_rom: Arc<[AtomicBool; 2]>,
|
||||
linked: Arc<AtomicBool>,
|
||||
) -> Self {
|
||||
Self {
|
||||
sims: vec![],
|
||||
carts: [None, None],
|
||||
audio: Audio::init(),
|
||||
commands,
|
||||
sim_state,
|
||||
state,
|
||||
audio_on,
|
||||
watch_rom,
|
||||
linked,
|
||||
profilers: [None, None],
|
||||
renderers: HashMap::new(),
|
||||
messages: HashMap::new(),
|
||||
debuggers: HashMap::new(),
|
||||
stdouts: HashMap::new(),
|
||||
watched_regions: HashMap::new(),
|
||||
eye_contents: [vec![0u8; 384 * 224 * 2], vec![0u8; 384 * 224 * 2]],
|
||||
audio_samples: Vec::with_capacity(EXPECTED_FRAME_SIZE),
|
||||
buffer: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reload_cart(&mut self, sim_id: SimId) -> Result<()> {
|
||||
let Some(cart) = &self.carts[sim_id.to_index()] else {
|
||||
return Ok(());
|
||||
@@ -211,7 +210,12 @@ impl Emulator {
|
||||
|
||||
pub fn load_cart(&mut self, sim_id: SimId, path: &Path) -> Result<()> {
|
||||
let watch = self.watch_rom[sim_id.to_index()].load(Ordering::Acquire);
|
||||
let cart = Cart::load(path, sim_id, watch)?;
|
||||
let cart = Cart::load(
|
||||
path,
|
||||
sim_id,
|
||||
self.save_data_location.load(Ordering::Acquire),
|
||||
watch,
|
||||
)?;
|
||||
self.try_reset_sim(sim_id, Some(cart))?;
|
||||
Ok(())
|
||||
}
|
||||
@@ -224,7 +228,12 @@ impl Emulator {
|
||||
};
|
||||
let watch = self.watch_rom[SimId::Player2.to_index()].load(Ordering::Acquire);
|
||||
let cart = match file_path {
|
||||
Some(rom_path) => Some(Cart::load(&rom_path, SimId::Player2, watch)?),
|
||||
Some(rom_path) => Some(Cart::load(
|
||||
&rom_path,
|
||||
SimId::Player2,
|
||||
self.save_data_location.load(Ordering::Acquire),
|
||||
watch,
|
||||
)?),
|
||||
None => None,
|
||||
};
|
||||
self.try_reset_sim(SimId::Player2, cart)?;
|
||||
@@ -687,6 +696,20 @@ impl Emulator {
|
||||
cart.stop_watching();
|
||||
}
|
||||
}
|
||||
EmulatorCommand::SetSaveDataLocation(save_data_location) => {
|
||||
self.save_data_location
|
||||
.store(save_data_location, Ordering::Release);
|
||||
for sim_id in SimId::values() {
|
||||
if let Some(cart) = self.carts[sim_id.to_index()].as_mut()
|
||||
&& let Err(error) = cart.change_save_data_location(save_data_location)
|
||||
{
|
||||
self.report_error(
|
||||
sim_id,
|
||||
format!("Error changing save data location: {error}"),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
EmulatorCommand::StartSecondSim(path) => {
|
||||
if let Err(error) = self.start_second_sim(path) {
|
||||
self.report_error(
|
||||
@@ -854,6 +877,7 @@ pub enum EmulatorCommand {
|
||||
LoadGame(SimId, PathBuf),
|
||||
ReloadRom(SimId),
|
||||
WatchRom(SimId, bool),
|
||||
SetSaveDataLocation(SaveDataLocation),
|
||||
StartSecondSim(Option<PathBuf>),
|
||||
StopSecondSim,
|
||||
Pause,
|
||||
@@ -943,6 +967,7 @@ pub struct EmulatorClient {
|
||||
sim_state: Arc<[Atomic<SimState>; 2]>,
|
||||
state: Arc<Atomic<EmulatorState>>,
|
||||
linked: Arc<AtomicBool>,
|
||||
save_data_location: Arc<Atomic<SaveDataLocation>>,
|
||||
watch_rom: Arc<[AtomicBool; 2]>,
|
||||
}
|
||||
|
||||
@@ -959,6 +984,9 @@ impl EmulatorClient {
|
||||
pub fn are_sims_linked(&self) -> bool {
|
||||
self.linked.load(Ordering::Acquire)
|
||||
}
|
||||
pub fn save_data_location(&self) -> SaveDataLocation {
|
||||
self.save_data_location.load(Ordering::Acquire)
|
||||
}
|
||||
pub fn is_rom_watched(&self, sim_id: SimId) -> bool {
|
||||
self.watch_rom[sim_id.to_index()].load(Ordering::Acquire)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user