From abc39e74ef85f9de7519ac7dbb998a30a3cbb36c Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Tue, 15 Jul 2025 20:05:46 +0200 Subject: [PATCH] Remember ROM dir (#508) * Remember ROM dir * more * more * more * more * more --- src/ui/cheats.rs | 16 ++++++++++---- src/ui/config.rs | 2 ++ src/ui/gui.rs | 34 +++++++++++++++++++++++----- src/ui/gui/appwindow.slint | 7 +++--- src/ui/gui/cheat_page.slint | 7 +++--- src/ui/gui/netplay_create.slint | 7 +++--- src/ui/gui/netplay_join.slint | 7 +++--- src/ui/gui/netplay_page.slint | 1 + src/ui/gui/settings_page.slint | 1 + src/ui/netplay.rs | 39 +++++++++++++++++++++++++-------- 10 files changed, 91 insertions(+), 30 deletions(-) diff --git a/src/ui/cheats.rs b/src/ui/cheats.rs index 26a970f..b55c491 100644 --- a/src/ui/cheats.rs +++ b/src/ui/cheats.rs @@ -15,10 +15,18 @@ pub type Cheats = std::collections::BTreeMap 0, }; app.set_resolution(combobox_value); + + if let Some(rom_dir_str) = config.rom_dir.to_str() { + app.set_rom_dir(rom_dir_str.into()); + } } fn update_input_profiles(weak: &slint::Weak, config: &ui::config::Config) { @@ -351,6 +357,7 @@ pub fn run_rom( .unwrap(); let mut device = device::Device::new(); + device.ui.config.rom_dir = file_path.parent().unwrap().to_path_buf(); for i in 0..4 { if gb_paths.rom[i].is_some() && gb_paths.ram[i].is_some() { @@ -390,16 +397,31 @@ pub fn run_rom( vru_window_notifier.try_send(None).unwrap(); } - weak.upgrade_in_event_loop(move |handle| handle.set_game_running(false)) - .unwrap(); + let rom_dir = device.ui.config.rom_dir.clone(); + weak.upgrade_in_event_loop(move |handle| { + if let Some(rom_dir_str) = rom_dir.to_str() { + handle.set_rom_dir(rom_dir_str.into()); + } + handle.set_game_running(false); + }) + .unwrap(); }) .unwrap(); } fn open_rom(app: &AppWindow) { - let select_rom = rfd::AsyncFileDialog::new() - .set_title("Select ROM") - .pick_file(); + let rom_dir = app.get_rom_dir(); + let select_rom = if !rom_dir.is_empty() + && let Ok(exists) = std::fs::exists(&rom_dir) + && exists + { + rfd::AsyncFileDialog::new().set_directory(rom_dir) + } else { + rfd::AsyncFileDialog::new() + } + .set_title("Select ROM") + .add_filter("ROM files", &N64_EXTENSIONS) + .pick_file(); let mut select_gb_rom = [None, None, None, None]; let mut select_gb_ram = [None, None, None, None]; @@ -408,11 +430,13 @@ fn open_rom(app: &AppWindow) { select_gb_rom[i] = Some( rfd::AsyncFileDialog::new() .set_title(format!("GB ROM P{}", i + 1)) + .add_filter("GB ROM files", &["gb", "gbc"]) .pick_file(), ); select_gb_ram[i] = Some( rfd::AsyncFileDialog::new() .set_title(format!("GB RAM P{}", i + 1)) + .add_filter("GB RAM files", &["sav", "ram"]) .pick_file(), ); } diff --git a/src/ui/gui/appwindow.slint b/src/ui/gui/appwindow.slint index 3d40a21..7c24360 100644 --- a/src/ui/gui/appwindow.slint +++ b/src/ui/gui/appwindow.slint @@ -29,7 +29,7 @@ export component AppWindow inherits Window { callback join_session_button_clicked; callback netplay_discord_button_clicked; callback netplay_feedback_button_clicked; - callback cheats_select_rom_clicked; + callback cheats_select_rom_clicked(string); callback cheats_clear_clicked; callback cheat_toggled(string, string, string, bool); in property version <=> AboutData.version; @@ -41,6 +41,7 @@ export component AppWindow inherits Window { in-out property overclock_n64_cpu <=> SettingsData.overclock_n64_cpu; in-out property disable_expansion_pak <=> SettingsData.disable_expansion_pak; in-out property resolution <=> SettingsData.resolution; + in-out property rom_dir <=> SettingsData.rom_dir; in-out property emulate_vru <=> ControllerData.emulate_vru; in-out property controller_enabled <=> ControllerData.controller_enabled; in-out property transferpak <=> ControllerData.transferpak; @@ -102,8 +103,8 @@ export component AppWindow inherits Window { } } if(side-bar.current-item == 3): Cheats { - cheats_select_rom_clicked => { - cheats_select_rom_clicked(); + cheats_select_rom_clicked(rom_dir) => { + cheats_select_rom_clicked(rom_dir); } cheats_clear_clicked => { cheats_clear_clicked(); diff --git a/src/ui/gui/cheat_page.slint b/src/ui/gui/cheat_page.slint index f3cf02e..6918af5 100644 --- a/src/ui/gui/cheat_page.slint +++ b/src/ui/gui/cheat_page.slint @@ -3,6 +3,7 @@ import { ListView, HorizontalBox, VerticalBox, Button, GroupBox, CheckBox } from "std-widgets.slint"; import { Page } from "page.slint"; +import { SettingsData } from "settings_page.slint"; export global CheatsData { in-out property cheat_game_name; @@ -12,7 +13,7 @@ export global CheatsData { export component Cheats inherits Page { title: @tr("Cheats"); - callback cheats_select_rom_clicked; + callback cheats_select_rom_clicked(string); callback cheats_clear_clicked; callback cheat_toggled(string, string, string, bool); @@ -23,13 +24,13 @@ export component Cheats inherits Page { if CheatsData.cheat_game_name == "": Button { text: @tr("Select ROM"); clicked => { - cheats_select_rom_clicked(); + cheats_select_rom_clicked(SettingsData.rom_dir); } } if CheatsData.cheat_game_name != "": Button { text: CheatsData.cheat_game_name; clicked => { - cheats_select_rom_clicked(); + cheats_select_rom_clicked(SettingsData.rom_dir); } } Rectangle { diff --git a/src/ui/gui/netplay_create.slint b/src/ui/gui/netplay_create.slint index ebee874..7bea0a2 100644 --- a/src/ui/gui/netplay_create.slint +++ b/src/ui/gui/netplay_create.slint @@ -12,8 +12,9 @@ export component NetplayCreate inherits Window { in-out property pending_session <=> NetplayData.pending_session; in-out property rom_path <=> NetplayData.rom_path; in-out property peer_addr <=> NetplayData.peer_addr; + in-out property rom_dir <=> NetplayData.rom_dir; callback get_ping(string); - callback select_rom; + callback select_rom(string); callback create_session(string, string, string, string, string, string, string); VerticalBox { @@ -83,13 +84,13 @@ export component NetplayCreate inherits Window { if NetplayData.game_name == "": Button { text: @tr("Select ROM"); clicked => { - select_rom(); + select_rom(NetplayData.rom_dir); } } if NetplayData.game_name != "": Button { text: NetplayData.game_name; clicked => { - select_rom(); + select_rom(NetplayData.rom_dir); } } diff --git a/src/ui/gui/netplay_join.slint b/src/ui/gui/netplay_join.slint index 507f1c1..c372416 100644 --- a/src/ui/gui/netplay_join.slint +++ b/src/ui/gui/netplay_join.slint @@ -15,9 +15,10 @@ export component NetplayJoin inherits Window { in-out property peer_addr <=> NetplayData.peer_addr; in-out property pending_session <=> NetplayData.pending_session; in-out property rom_path <=> NetplayData.rom_path; + in-out property rom_dir <=> NetplayData.rom_dir; callback get_ping(string); callback refresh_session(string); - callback select_rom; + callback select_rom(string); callback join_session(string, string, string, int); VerticalBox { @@ -104,13 +105,13 @@ export component NetplayJoin inherits Window { if NetplayData.game_name == "": Button { text: @tr("Select ROM"); clicked => { - select_rom(); + select_rom(NetplayData.rom_dir); } } if NetplayData.game_name != "": Button { text: NetplayData.game_name; clicked => { - select_rom(); + select_rom(NetplayData.rom_dir); } } diff --git a/src/ui/gui/netplay_page.slint b/src/ui/gui/netplay_page.slint index 6467977..32ae732 100644 --- a/src/ui/gui/netplay_page.slint +++ b/src/ui/gui/netplay_page.slint @@ -20,6 +20,7 @@ export global NetplayData { in-out property <[[StandardListViewItem]]> sessions; in-out property <[int]> ports; in-out property current_session: -1; + in-out property rom_dir; } export component Netplay inherits Page { diff --git a/src/ui/gui/settings_page.slint b/src/ui/gui/settings_page.slint index 49b091b..c798244 100644 --- a/src/ui/gui/settings_page.slint +++ b/src/ui/gui/settings_page.slint @@ -12,6 +12,7 @@ export global SettingsData { in-out property overclock_n64_cpu; in-out property disable_expansion_pak; in-out property resolution; + in-out property rom_dir; } export component Settings inherits Page { diff --git a/src/ui/netplay.rs b/src/ui/netplay.rs index c9fe34d..0b67bc7 100644 --- a/src/ui/netplay.rs +++ b/src/ui/netplay.rs @@ -173,10 +173,21 @@ fn populate_server_names(weak: slin }); } -fn select_rom(weak: slint::Weak) { - let select_rom = rfd::AsyncFileDialog::new() - .set_title("Select ROM") - .pick_file(); +fn select_rom( + weak: slint::Weak, + rom_dir: slint::SharedString, +) { + let select_rom = if !rom_dir.is_empty() + && let Ok(exists) = std::fs::exists(&rom_dir) + && exists + { + rfd::AsyncFileDialog::new().set_directory(rom_dir) + } else { + rfd::AsyncFileDialog::new() + } + .set_title("Select ROM") + .add_filter("ROM files", &ui::gui::N64_EXTENSIONS) + .pick_file(); tokio::spawn(async move { if let Some(file) = select_rom.await { if let Some(rom_contents) = device::get_rom_contents(file.path()) { @@ -252,6 +263,7 @@ fn update_ping( pub fn setup_create_window( create_window: &NetplayCreate, game_settings: GameSettings, + rom_dir: slint::SharedString, weak_app: slint::Weak, ) { let (netplay_read_sender, netplay_read_receiver): ( @@ -264,14 +276,15 @@ pub fn setup_create_window( tokio::sync::broadcast::Receiver>, ) = tokio::sync::broadcast::channel(5); + create_window.set_rom_dir(rom_dir); populate_server_names(create_window.as_weak()); let weak = create_window.as_weak(); create_window.on_get_ping(move |server_url| { update_ping(weak.clone(), server_url.to_string()); }); let weak = create_window.as_weak(); - create_window.on_select_rom(move || { - select_rom(weak.clone()); + create_window.on_select_rom(move |rom_dir| { + select_rom(weak.clone(), rom_dir); }); let weak = create_window.as_weak(); @@ -937,6 +950,7 @@ fn setup_wait_window( pub fn setup_join_window( join_window: &NetplayJoin, fullscreen: bool, + rom_dir: slint::SharedString, weak_app: slint::Weak, ) { let (netplay_read_sender, netplay_read_receiver): ( @@ -949,6 +963,7 @@ pub fn setup_join_window( tokio::sync::broadcast::Receiver>, ) = tokio::sync::broadcast::channel(5); + join_window.set_rom_dir(rom_dir); populate_server_names(join_window.as_weak()); let weak = join_window.as_weak(); join_window.on_get_ping(move |server_url| { @@ -959,8 +974,8 @@ pub fn setup_join_window( .unwrap(); }); let weak = join_window.as_weak(); - join_window.on_select_rom(move || { - select_rom(weak.clone()); + join_window.on_select_rom(move |rom_dir| { + select_rom(weak.clone(), rom_dir); }); let sender = netplay_write_sender.clone(); @@ -1019,6 +1034,7 @@ pub fn netplay_window(app: &AppWindow, controller_paths: &[Option]) { disable_expansion_pak: handle.get_disable_expansion_pak(), cheats: std::collections::HashMap::new(), // not used here }, + handle.get_rom_dir(), weak_app, ); }) @@ -1035,7 +1051,12 @@ pub fn netplay_window(app: &AppWindow, controller_paths: &[Option]) { .upgrade_in_event_loop(move |handle| { let join_window = NetplayJoin::new().unwrap(); save_settings(&handle, &controller_paths); - setup_join_window(&join_window, handle.get_fullscreen(), weak_app); + setup_join_window( + &join_window, + handle.get_fullscreen(), + handle.get_rom_dir(), + weak_app, + ); }) .unwrap(); });