diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cea23e6..151c0f4 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -267,9 +267,9 @@ jobs: cache: ${{ github.ref_type != 'tag' }} - name: Build run: | - cargo install cargo-apk cargo-ndk + cargo install cargo-apk2 cargo-ndk source <(cargo ndk-env --target ${{ matrix.target }}) - cargo apk build --profile ${{ env.BUILD_PROFILE }} --target ${{ matrix.target }} --lib + cargo apk2 build --profile ${{ env.BUILD_PROFILE }} --target ${{ matrix.target }} --lib collect-artifacts: name: Collect release artifacts diff --git a/Cargo.toml b/Cargo.toml index 49e130a..e256b78 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,7 +12,6 @@ gui = ["dep:rfd", "dep:slint", "dep:slint-build"] crate-type = ["cdylib", "rlib"] [dependencies] -dirs = "6.0" zip = "8.0" sevenz-rust2 = "0.21" chrono = "0.4" @@ -43,6 +42,7 @@ discord-rich-presence = "1.1" [target.'cfg(not(target_os = "android"))'.dependencies] slint = { version = "1.16", default-features = false, features = ["compat-1-2", "std", "unstable-winit-030", "backend-winit", "renderer-femtovg-wgpu", "accessibility"], optional = true } rfd = {version = "0.17", optional = true } +dirs = "6.0" [target.'cfg(target_os = "android")'.dependencies] slint = { version = "1.16", default-features = false, features = ["compat-1-2", "std", "backend-android-activity-06", "accessibility"], optional = true } @@ -73,10 +73,22 @@ osx_frameworks = ["/opt/homebrew/opt/molten-vk/lib/libMoltenVK.dylib"] osx_minimum_system_version = "15.0" [package.metadata.android] +use_aapt2 = true package = "io.github.gopher64.gopher64" build_targets = ["aarch64-linux-android"] resources = "data/android/res" +[[package.metadata.android.application.activity]] +name = "android.app.NativeActivity" + +[[package.metadata.android.application.activity.intent_filter]] +actions = ["android.intent.action.MAIN"] +categories = ["android.intent.category.LAUNCHER"] + +[[package.metadata.android.application.activity.meta_data]] +name = "android.app.lib_name" +value = "gopher64" + [package.metadata.android.application] icon = "@mipmap/ic_launcher" label = "Gopher64" diff --git a/src/lib.rs b/src/lib.rs index 54a19eb..18503de 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -317,8 +317,18 @@ pub async fn run() -> std::io::Result<()> { #[cfg(target_os = "android")] #[unsafe(no_mangle)] -fn android_main(app: slint::android::AndroidApp) { - slint::android::init(app).unwrap(); +#[tokio::main(worker_threads = 4)] +async fn android_main(app: slint::android::AndroidApp) { + slint::android::init(app.clone()).unwrap(); + + ui::ANDROID_APP.set(app).unwrap(); + + let dirs = ui::get_dirs(); + + std::fs::create_dir_all(dirs.config_dir).unwrap(); + std::fs::create_dir_all(dirs.cache_dir).unwrap(); + std::fs::create_dir_all(dirs.data_dir.join("saves")).unwrap(); + std::fs::create_dir_all(dirs.data_dir.join("states")).unwrap(); ui::gui::app_window(); } diff --git a/src/ui.rs b/src/ui.rs index 4d8992a..b191a1b 100644 --- a/src/ui.rs +++ b/src/ui.rs @@ -15,6 +15,10 @@ pub mod video; #[cfg(feature = "gui")] pub mod vru; +#[cfg(target_os = "android")] +pub static ANDROID_APP: std::sync::OnceLock = + std::sync::OnceLock::new(); + pub static WEB_CLIENT: std::sync::LazyLock = std::sync::LazyLock::new(|| { reqwest::Client::builder() .user_agent(format!( @@ -125,6 +129,7 @@ pub fn sdl_close() { } } +#[cfg(not(target_os = "android"))] pub fn get_dirs() -> Dirs { let exe_path = std::env::current_exe().unwrap(); let portable_dir = exe_path.parent(); @@ -144,6 +149,19 @@ pub fn get_dirs() -> Dirs { } } +#[cfg(target_os = "android")] +pub fn get_dirs() -> Dirs { + if let Some(android_app) = ANDROID_APP.get() { + Dirs { + config_dir: android_app.internal_data_path().unwrap().join("config"), + data_dir: android_app.external_data_path().unwrap().join("data"), + cache_dir: android_app.internal_data_path().unwrap().join("cache"), + } + } else { + panic!("Android app not initialized"); + } +} + impl Ui { pub fn new() -> Ui { let dirs = get_dirs(); diff --git a/src/ui/gui.rs b/src/ui/gui.rs index ec2b34a..07f1d01 100644 --- a/src/ui/gui.rs +++ b/src/ui/gui.rs @@ -152,6 +152,7 @@ fn local_game_window(app: &AppWindow, config: &ui::config::Config) { file_dropped(app); } +#[cfg(not(target_os = "android"))] fn input_profiles(config: &ui::config::Config) -> Vec { let mut profiles = vec![]; for key in config.input.input_profiles.keys() { @@ -190,6 +191,7 @@ fn settings_window(app: &AppWindow, config: &ui::config::Config) { } } +#[cfg(not(target_os = "android"))] fn update_input_profiles(weak: &slint::Weak, config: &ui::config::Config) { let profiles = input_profiles(config); let config_bindings = config.input.input_profile_binding.clone(); @@ -235,6 +237,7 @@ fn clear_gb_paths(weak: &slint::Weak, player: i32) { .unwrap(); } +#[cfg(not(target_os = "android"))] fn controller_window(app: &AppWindow, config: &ui::config::Config) { ui::sdl_init(sdl3_sys::init::SDL_INIT_GAMEPAD); @@ -533,6 +536,7 @@ pub fn app_window() { { let config = ui::config::Config::new(); settings_window(&app, &config); + #[cfg(not(target_os = "android"))] controller_window(&app, &config); local_game_window(&app, &config); } diff --git a/src/ui/input.rs b/src/ui/input.rs index f94f6eb..76a0fd5 100644 --- a/src/ui/input.rs +++ b/src/ui/input.rs @@ -359,6 +359,7 @@ pub fn get_controller_names() -> Vec { controllers } +#[cfg(not(target_os = "android"))] #[cfg(feature = "gui")] pub fn get_controller_paths() -> Vec { let mut controller_paths: Vec = vec![];