From 48956dc01647cea8a6d93495c7795df3687ef6a6 Mon Sep 17 00:00:00 2001 From: Logan McNaughton <848146+loganmc10@users.noreply.github.com> Date: Wed, 20 May 2026 11:41:12 +0200 Subject: [PATCH] move some android guards around (#926) * move some android guards around * more --- src/device.rs | 2 +- src/lib.rs | 4 +- src/ui/android.rs | 18 +++- src/ui/cheats.rs | 148 ++++++++++++++---------------- src/ui/gui.rs | 179 +++++++++++++++++++++---------------- src/ui/gui/appwindow.slint | 2 +- src/ui/netplay.rs | 56 +++--------- 7 files changed, 204 insertions(+), 205 deletions(-) diff --git a/src/device.rs b/src/device.rs index 1abf32ae..53f5b7ea 100644 --- a/src/device.rs +++ b/src/device.rs @@ -149,7 +149,7 @@ fn swap_rom(contents: Vec) -> Option> { } } -pub fn get_rom_contents(file_path: &std::path::Path) -> Option> { +pub fn get_rom_contents(file_path: &std::path::PathBuf) -> Option> { let mut contents = vec![]; if file_path .extension() diff --git a/src/lib.rs b/src/lib.rs index 598d82c8..78904bda 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -103,8 +103,8 @@ pub async fn run() -> std::io::Result<()> { let args = Args::parse(); if let Some(game) = args.game { - let file_path = std::path::Path::new(&game); - let Some(rom_contents) = device::get_rom_contents(file_path) else { + let file_path = std::path::Path::new(&game).to_path_buf(); + let Some(rom_contents) = device::get_rom_contents(&file_path) else { return Err(Error::other(format!( "Could not read ROM file: {}", file_path.display() diff --git a/src/ui/android.rs b/src/ui/android.rs index 9960c1b1..cd55ba3d 100644 --- a/src/ui/android.rs +++ b/src/ui/android.rs @@ -111,7 +111,11 @@ fn list_controllers_on_jvm(env: &mut Env<'_>) -> jni::errors::Result Option { + None +} + +pub async fn select_gb_rom(_player: i32) -> Option { + None +} + +pub async fn select_gb_ram(_player: i32) -> Option { + None +} diff --git a/src/ui/cheats.rs b/src/ui/cheats.rs index a94553fd..6f479a7c 100644 --- a/src/ui/cheats.rs +++ b/src/ui/cheats.rs @@ -1,96 +1,84 @@ use crate::ui; use crate::ui::gui::AppWindow; -#[cfg(not(target_os = "android"))] use crate::ui::gui::ErrorDialog; -#[cfg(not(target_os = "android"))] use crate::{cheats, device}; use slint::ComponentHandle; pub fn cheats_window(app: &AppWindow) { - #[cfg(not(target_os = "android"))] - { - let weak = app.as_weak(); - app.on_cheats_select_rom_clicked(move |rom_dir| { - let select_rom = if !rom_dir.is_empty() && std::fs::exists(&rom_dir).unwrap_or(false) { - 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(); - let weak = weak.clone(); - tokio::spawn(async move { - if let Some(file) = select_rom.await - && let Some(rom_contents) = device::get_rom_contents(file.path()) - { - let game_crc = ui::storage::get_game_crc(&rom_contents); - let game_name = ui::storage::get_game_name(&rom_contents); + let weak = app.as_weak(); + app.on_cheats_select_rom_clicked(move |rom_dir| { + let select_rom = ui::gui::select_rom(rom_dir); + let weak = weak.clone(); + tokio::spawn(async move { + if let Some(file) = select_rom.await + && let Some(rom_contents) = device::get_rom_contents(&file) + { + let game_crc = ui::storage::get_game_crc(&rom_contents); + let game_name = ui::storage::get_game_name(&rom_contents); + weak.upgrade_in_event_loop(move |handle| { + handle.set_cheat_game_name(game_name.into()); + }) + .unwrap(); + let cheats: cheats::Cheat = + serde_json::from_slice(include_bytes!("../../data/cheats.json")).unwrap(); + if let Some(cheat) = cheats.get(&game_crc) { + let cheat = cheat.clone(); weak.upgrade_in_event_loop(move |handle| { - handle.set_cheat_game_name(game_name.into()); - }) - .unwrap(); - let cheats: cheats::Cheat = - serde_json::from_slice(include_bytes!("../../data/cheats.json")).unwrap(); - if let Some(cheat) = cheats.get(&game_crc) { - let cheat = cheat.clone(); - weak.upgrade_in_event_loop(move |handle| { - let cheat_settings = ui::config::Cheats::new(); - let game_cheats = cheat_settings.cheats.get(&game_crc).cloned(); - handle.set_cheat_game_crc(game_crc.into()); - let cheats_vec = slint::VecModel::default(); - for item in cheat.iter() { - let mut cheat_enabled = false; - if let Some(game_cheat) = game_cheats.as_ref() - && game_cheat.contains_key(item.0) - { - cheat_enabled = true; - } - let options_vec = slint::VecModel::default(); - if let Some(options) = item.1.options.as_ref() { - for option in options.iter() { - let mut option_enabled = false; - if let Some(game_cheat) = game_cheats.as_ref() - && game_cheat.contains_key(item.0) - && let Some(opt) = game_cheat.get(item.0) - && let Some(opt) = opt - && opt == option.0 - { - option_enabled = true; - } - options_vec.push((option_enabled, option.0.into())); - } - } - let options = slint::ModelRc::from(std::rc::Rc::new(options_vec)); - cheats_vec.push(( - item.0.clone().into(), - cheat_enabled, - item.1.clone().note.into(), - options, - )); + let cheat_settings = ui::config::Cheats::new(); + let game_cheats = cheat_settings.cheats.get(&game_crc).cloned(); + handle.set_cheat_game_crc(game_crc.into()); + let cheats_vec = slint::VecModel::default(); + for item in cheat.iter() { + let mut cheat_enabled = false; + if let Some(game_cheat) = game_cheats.as_ref() + && game_cheat.contains_key(item.0) + { + cheat_enabled = true; } - handle.set_cheats(slint::ModelRc::from(std::rc::Rc::new(cheats_vec))); - }) - .unwrap(); - } else { - clear_cheats(&weak, false); - } - } else { - clear_cheats(&weak, true); - weak.upgrade_in_event_loop(move |_handle| { - let message_dialog = ErrorDialog::new().unwrap(); - let weak_dialog = message_dialog.as_weak(); - message_dialog.on_close_clicked(move || { - weak_dialog.unwrap().hide().unwrap(); - }); - message_dialog.set_text("Could not read ROM".into()); - message_dialog.show().unwrap(); + let options_vec = slint::VecModel::default(); + if let Some(options) = item.1.options.as_ref() { + for option in options.iter() { + let mut option_enabled = false; + if let Some(game_cheat) = game_cheats.as_ref() + && game_cheat.contains_key(item.0) + && let Some(opt) = game_cheat.get(item.0) + && let Some(opt) = opt + && opt == option.0 + { + option_enabled = true; + } + options_vec.push((option_enabled, option.0.into())); + } + } + let options = slint::ModelRc::from(std::rc::Rc::new(options_vec)); + cheats_vec.push(( + item.0.clone().into(), + cheat_enabled, + item.1.clone().note.into(), + options, + )); + } + handle.set_cheats(slint::ModelRc::from(std::rc::Rc::new(cheats_vec))); }) .unwrap(); + } else { + clear_cheats(&weak, false); } - }); + } else { + clear_cheats(&weak, true); + weak.upgrade_in_event_loop(move |_handle| { + let message_dialog = ErrorDialog::new().unwrap(); + let weak_dialog = message_dialog.as_weak(); + message_dialog.on_close_clicked(move || { + weak_dialog.unwrap().hide().unwrap(); + }); + message_dialog.set_text("Could not read ROM".into()); + message_dialog.show().unwrap(); + }) + .unwrap(); + } }); - } + }); let weak = app.as_weak(); app.on_cheats_clear_clicked(move || { diff --git a/src/ui/gui.rs b/src/ui/gui.rs index ffc79698..da541d5c 100644 --- a/src/ui/gui.rs +++ b/src/ui/gui.rs @@ -115,17 +115,14 @@ fn local_game_window(app: &AppWindow, config: &ui::config::Config) { ), ))); - #[cfg(not(target_os = "android"))] - { - let weak = app.as_weak(); - app.on_open_rom_button_clicked(move || { - weak.upgrade_in_event_loop(move |handle| { - save_settings(&handle); - open_rom(&handle) - }) - .unwrap(); - }); - } + let weak = app.as_weak(); + app.on_open_rom_button_clicked(move || { + weak.upgrade_in_event_loop(move |handle| { + save_settings(&handle); + open_rom(&handle) + }) + .unwrap(); + }); let weak = app.as_weak(); app.on_recent_rom_button_clicked(move |rom| { @@ -216,7 +213,6 @@ fn update_input_profiles(weak: &slint::Weak, config: &ui::config::Con .unwrap(); } -#[cfg(not(target_os = "android"))] fn clear_gb_paths(weak: &slint::Weak, player: i32) { weak.upgrade_in_event_loop(move |handle| { let rom_paths = handle.get_gb_rom_paths(); @@ -376,61 +372,49 @@ fn controller_window(app: &AppWindow, config: &ui::config::Config) { dialog.show().unwrap(); }); - #[cfg(not(target_os = "android"))] - { - let weak_app2 = app.as_weak(); - app.on_transferpak_toggled(move |player, enabled| { - if enabled { - let select_gb_rom = rfd::AsyncFileDialog::new() - .set_title(format!("GB ROM P{}", player + 1)) - .add_filter("GB ROM files", &["gb", "gbc", "GB", "GBC"]) - .pick_file(); + let weak_app2 = app.as_weak(); + app.on_transferpak_toggled(move |player, enabled| { + if enabled { + let select_gb_rom = select_gb_rom(player); - let weak_app3 = weak_app2.clone(); - tokio::spawn(async move { - if let Some(gb_rom) = select_gb_rom.await { - let weak_app4 = weak_app3.clone(); - weak_app3 - .upgrade_in_event_loop(move |_handle| { - let select_gb_ram = rfd::AsyncFileDialog::new() - .set_title(format!("GB RAM P{}", player + 1)) - .add_filter( - "GB RAM files", - &["sav", "ram", "srm", "SAV", "RAM", "SRM"], - ) - .pick_file(); + let weak_app3 = weak_app2.clone(); + tokio::spawn(async move { + if let Some(gb_rom) = select_gb_rom.await { + let weak_app4 = weak_app3.clone(); + weak_app3 + .upgrade_in_event_loop(move |_handle| { + let select_gb_ram = select_gb_ram(player); - tokio::spawn(async move { - if let Some(gb_ram) = select_gb_ram.await { - weak_app4 - .upgrade_in_event_loop(move |handle| { - let rom_paths = handle.get_gb_rom_paths(); - let ram_paths = handle.get_gb_ram_paths(); - rom_paths.set_row_data( - player as usize, - gb_rom.path().to_str().unwrap().into(), - ); - ram_paths.set_row_data( - player as usize, - gb_ram.path().to_str().unwrap().into(), - ); - handle.set_gb_rom_paths(rom_paths); - handle.set_gb_ram_paths(ram_paths); - }) - .unwrap(); - } else { - clear_gb_paths(&weak_app4, player); - } - }); - }) - .unwrap(); - } else { - clear_gb_paths(&weak_app3, player); - } - }); - } - }); - } + tokio::spawn(async move { + if let Some(gb_ram) = select_gb_ram.await { + weak_app4 + .upgrade_in_event_loop(move |handle| { + let rom_paths = handle.get_gb_rom_paths(); + let ram_paths = handle.get_gb_ram_paths(); + rom_paths.set_row_data( + player as usize, + gb_rom.to_str().unwrap().into(), + ); + ram_paths.set_row_data( + player as usize, + gb_ram.to_str().unwrap().into(), + ); + handle.set_gb_rom_paths(rom_paths); + handle.set_gb_ram_paths(ram_paths); + }) + .unwrap(); + } else { + clear_gb_paths(&weak_app4, player); + } + }); + }) + .unwrap(); + } else { + clear_gb_paths(&weak_app3, player); + } + }); + } + }); } pub fn save_settings(app: &AppWindow) { @@ -614,17 +598,60 @@ pub fn run_rom( }); } -#[cfg(not(target_os = "android"))] -fn open_rom(app: &AppWindow) { - let rom_dir = app.get_rom_dir(); - let select_rom = if !rom_dir.is_empty() && std::fs::exists(&rom_dir).unwrap_or(false) { - rfd::AsyncFileDialog::new().set_directory(rom_dir) - } else { - rfd::AsyncFileDialog::new() +pub async fn select_rom(rom_dir: slint::SharedString) -> Option { + #[cfg(not(target_os = "android"))] + { + if !rom_dir.is_empty() && std::fs::exists(&rom_dir).unwrap_or(false) { + rfd::AsyncFileDialog::new().set_directory(rom_dir) + } else { + rfd::AsyncFileDialog::new() + } + .set_title("Select ROM") + .add_filter("ROM files", &N64_EXTENSIONS) + .pick_file() + .await + .map(|file| file.path().to_path_buf()) } - .set_title("Select ROM") - .add_filter("ROM files", &N64_EXTENSIONS) - .pick_file(); + #[cfg(target_os = "android")] + { + ui::android::select_rom(rom_dir).await + } +} + +pub async fn select_gb_rom(player: i32) -> Option { + #[cfg(not(target_os = "android"))] + { + rfd::AsyncFileDialog::new() + .set_title(format!("GB ROM P{}", player + 1)) + .add_filter("GB ROM files", &["gb", "gbc", "GB", "GBC"]) + .pick_file() + .await + .map(|file| file.path().to_path_buf()) + } + #[cfg(target_os = "android")] + { + ui::android::select_gb_rom(player).await + } +} + +pub async fn select_gb_ram(player: i32) -> Option { + #[cfg(not(target_os = "android"))] + { + rfd::AsyncFileDialog::new() + .set_title(format!("GB RAM P{}", player + 1)) + .add_filter("GB RAM files", &["sav", "ram", "srm", "SAV", "RAM", "SRM"]) + .pick_file() + .await + .map(|file| file.path().to_path_buf()) + } + #[cfg(target_os = "android")] + { + ui::android::select_gb_ram(player).await + } +} + +fn open_rom(app: &AppWindow) { + let select_rom = select_rom(app.get_rom_dir()); let overclock = app.get_overclock_n64_cpu(); let disable_expansion_pak = app.get_disable_expansion_pak(); @@ -633,7 +660,7 @@ fn open_rom(app: &AppWindow) { tokio::spawn(async move { if let Some(file) = select_rom.await { run_rom( - file.path().to_path_buf(), + file, ui::GameSettings { overclock, disable_expansion_pak, diff --git a/src/ui/gui/appwindow.slint b/src/ui/gui/appwindow.slint index 0bf2e9d9..0e329504 100644 --- a/src/ui/gui/appwindow.slint +++ b/src/ui/gui/appwindow.slint @@ -220,7 +220,7 @@ export component AppWindow inherits Window { ra_show_profile_clicked => { ra_show_profile_clicked(); } - } + } if(side-bar.current-item == 5): Settings { width: 100%; height: 100%; diff --git a/src/ui/netplay.rs b/src/ui/netplay.rs index bb2ac303..1bf4f795 100644 --- a/src/ui/netplay.rs +++ b/src/ui/netplay.rs @@ -1,4 +1,3 @@ -#[cfg(not(target_os = "android"))] use crate::device; use crate::ui; use crate::ui::gui::{ @@ -48,13 +47,9 @@ pub struct NetplayMessage { trait NetplayPages { fn set_server_names(&self, names: slint::ModelRc); fn set_server_urls(&self, urls: slint::ModelRc); - #[cfg(not(target_os = "android"))] fn set_game_name(&self, game_name: slint::SharedString); - #[cfg(not(target_os = "android"))] fn set_game_hash(&self, game_hash: slint::SharedString); - #[cfg(not(target_os = "android"))] fn set_game_cheats(&self, game_cheats: slint::SharedString); - #[cfg(not(target_os = "android"))] fn set_rom_path(&self, rom_path: slint::SharedString); fn set_peer_addr(&self, peer_addr: slint::SharedString); fn refresh_sessions(&self) { @@ -69,19 +64,15 @@ impl NetplayPages for NetplayCreate { fn set_server_urls(&self, urls: slint::ModelRc) { self.set_server_urls(urls); } - #[cfg(not(target_os = "android"))] fn set_game_name(&self, game_name: slint::SharedString) { self.set_game_name(game_name); } - #[cfg(not(target_os = "android"))] fn set_game_hash(&self, game_hash: slint::SharedString) { self.set_game_hash(game_hash); } - #[cfg(not(target_os = "android"))] fn set_game_cheats(&self, game_cheats: slint::SharedString) { self.set_game_cheats(game_cheats); } - #[cfg(not(target_os = "android"))] fn set_rom_path(&self, rom_path: slint::SharedString) { self.set_rom_path(rom_path); } @@ -100,19 +91,15 @@ impl NetplayPages for NetplayJoin { fn refresh_sessions(&self) { self.invoke_refresh_session(); } - #[cfg(not(target_os = "android"))] fn set_game_name(&self, game_name: slint::SharedString) { self.set_game_name(game_name); } - #[cfg(not(target_os = "android"))] fn set_game_hash(&self, game_hash: slint::SharedString) { self.set_game_hash(game_hash); } - #[cfg(not(target_os = "android"))] fn set_game_cheats(&self, game_cheats: slint::SharedString) { self.set_game_cheats(game_cheats); } - #[cfg(not(target_os = "android"))] fn set_rom_path(&self, rom_path: slint::SharedString) { self.set_rom_path(rom_path); } @@ -186,22 +173,14 @@ fn populate_server_names(weak: slin }); } -#[cfg(not(target_os = "android"))] fn select_rom( weak: slint::Weak, rom_dir: slint::SharedString, ) { - let select_rom = if !rom_dir.is_empty() && std::fs::exists(&rom_dir).unwrap_or(false) { - 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(); + let select_rom = ui::gui::select_rom(rom_dir); tokio::spawn(async move { if let Some(file) = select_rom.await { - if let Some(rom_contents) = device::get_rom_contents(file.path()) { + if let Some(rom_contents) = device::get_rom_contents(&file) { let hash = device::cart::rom::calculate_hash(&rom_contents); let mut game_name = ui::storage::get_game_name(&rom_contents); let game_crc = ui::storage::get_game_crc(&rom_contents); @@ -213,19 +192,14 @@ fn select_rom( parsed_cheats = serde_json::to_string(game_cheats).unwrap(); } if game_name.is_empty() { - game_name = file - .path() - .file_name() - .unwrap() - .to_string_lossy() - .to_string(); + game_name = file.file_name().unwrap().to_string_lossy().to_string(); } weak.upgrade_in_event_loop(move |handle| { handle.set_game_name(game_name.into()); handle.set_game_hash(hash.into()); handle.set_game_cheats(parsed_cheats.into()); - handle.set_rom_path(file.path().to_str().unwrap().into()); + handle.set_rom_path(file.to_str().unwrap().into()); }) .unwrap(); } else { @@ -290,13 +264,10 @@ pub fn setup_create_window( .unwrap(); }); - #[cfg(not(target_os = "android"))] - { - let weak = create_window.as_weak(); - create_window.on_select_rom(move |rom_dir| { - select_rom(weak.clone(), rom_dir); - }); - } + let weak = create_window.as_weak(); + create_window.on_select_rom(move |rom_dir| { + select_rom(weak.clone(), rom_dir); + }); let weak = create_window.as_weak(); create_window.on_create_session( @@ -1183,13 +1154,10 @@ pub fn setup_join_window( join_window.set_rom_dir(rom_dir); populate_server_names(join_window.as_weak()); - #[cfg(not(target_os = "android"))] - { - let weak = join_window.as_weak(); - join_window.on_select_rom(move |rom_dir| { - select_rom(weak.clone(), rom_dir); - }); - } + let weak = join_window.as_weak(); + join_window.on_select_rom(move |rom_dir| { + select_rom(weak.clone(), rom_dir); + }); let sender = netplay_write_sender.clone(); join_window.window().on_close_requested(move || {