diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f8a66a64..502560eb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -63,6 +63,7 @@ Usability: - App icons in the app picker are now sorted by the display name of the app, case-insensitively. (@hikari-no-yume) - The accelerometer (tilt controls) can now be simulated using a mouse, instead of a game controller or real accelerometer. Simply hold down the right mouse button and move the mouse cursor. (@alborrajo) - The new `--disable-analog-stick-tilt-controls` option can be used to disable the use of the game controller's analog sticks for accelerometer simulation. This is useful on devices with both an integrated game controller and an integrated accelerometer, as touchHLE by default will only use the real accelerometer if no game controller is detected. (@hikari-no-yume) +- Android builds and releases of touchHLE now have an icon and meaningful version metadata. They also now use a different package name for preview builds versus releases, which means you can install them side-by-side. (@hikari-no-yume) - macOS builds and releases of touchHLE now come as an application bundle (`.app` directory) rather than as a bare “Unix executable” file. This should fix problems some users encountered with running touchHLE outside of a terminal, and allows putting touchHLE in the Applications folder like a normal graphical app. To support this, user data (apps, options, etc) is now stored in “Application Support” rather than the current directory, and the bundled files (fonts, dylibs, etc) are now part of the app bundle. If you prefer the old layout, you can still get it if you move all the files out of the bundle. (@hikari-no-yume) - The new `--force-composition=` option has been added, which is a workaround that may solve rendering issues in some games, at the cost of performance. For some games it is applied by the default options. (@ciciplusplus) - touchHLE now writes log messages to a file on all platforms, not just on Android. The file has been renamed from `log.txt` to `touchHLE_log.txt`. (@hikari-no-yume) diff --git a/android/app/build.gradle b/android/app/build.gradle index 34cc5088b..5fc32a847 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -12,11 +12,41 @@ apply plugin: 'com.android.application' apply plugin: "com.github.willir.rust.cargo-ndk-android" apply plugin: 'org.jetbrains.kotlin.android' +static def runTouchHLEVersionTool(boolean wantBranding) { + return ('cargo run --package touchHLE_version' + (wantBranding ? ' -- --branding' : '')).execute().text.trim() +} + +static def getTouchHLEBranding() { + return runTouchHLEVersionTool(/* wantBranding: */ true) +} + +static def getTouchHLEVersionName() { + return runTouchHLEVersionTool(/* wantBranding: */ false) +} + +static def join(String prefix, String separator, String branding) { + if (branding.isEmpty()) { + return prefix + } else { + return prefix + separator + branding + } +} + android { ndkVersion "25.2.9519653" compileSdkVersion 31 defaultConfig { - applicationId "org.touchhle.android" + def branding = getTouchHLEBranding() + applicationId 'org.touchhle.android' + applicationIdSuffix(branding.isEmpty() ? null : branding.toLowerCase()) + resValue 'string', 'app_name', join('touchHLE', ' ', branding) + buildConfigField 'String', 'APP_NAME', ('"' + join('touchHLE', ' ', branding) + '"') + manifestPlaceholders = [ + icon: join('@drawable/icon', '_', branding.toLowerCase()) + ] + buildConfigField 'int', 'APP_ICON', join('R.drawable.icon', '_', branding.toLowerCase()) + versionName join(getTouchHLEVersionName(), ' ', branding) + minSdkVersion 21 // first version with AArch64 targetSdkVersion 31 externalNativeBuild { @@ -96,14 +126,14 @@ cargoNdk { if (!clangXXPath.toFile().exists()) { throw new GradleException("NDK clang++ compiler not found at expected location: $clangXXPath") } - + extraCargoEnv.putAll([ - "CC": clangPath.toString(), - "CXX": clangXXPath.toString(), - // The default generator on Windows (Visual Studio) does not respect - // the CC and CXX environment variables. Using Ninja ensures that - // the specified compilers are used - "CMAKE_GENERATOR": "Ninja" + "CC" : clangPath.toString(), + "CXX" : clangXXPath.toString(), + // The default generator on Windows (Visual Studio) does not respect + // the CC and CXX environment variables. Using Ninja ensures that + // the specified compilers are used + "CMAKE_GENERATOR": "Ninja" ]) } // The default feature, "static", makes us use static linking for SDL2 and OpenAL Soft. diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 65507e586..22e44bb1d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -11,8 +11,7 @@ --> + android:versionCode="1"> @@ -95,9 +95,10 @@ diff --git a/android/app/src/main/java/org/touchhle/android/DocumentsProvider.kt b/android/app/src/main/java/org/touchhle/android/DocumentsProvider.kt index f9d32d49d..c42d64dfd 100644 --- a/android/app/src/main/java/org/touchhle/android/DocumentsProvider.kt +++ b/android/app/src/main/java/org/touchhle/android/DocumentsProvider.kt @@ -32,7 +32,7 @@ class DocumentsProvider : DocumentsProvider() { //private val baseDirectory = Environment.getExternalStorageDirectory() // private val baseDirectory = touchHLEApplication.getContext().getExternalFilesDir(null)!! //private val applicationName = SkylineApplication.instance.applicationInfo.loadLabel(SkylineApplication.instance.packageManager).toString() - private val applicationName = "touchHLE" + private val applicationName = BuildConfig.APP_NAME companion object { private val DEFAULT_ROOT_PROJECTION : Array = arrayOf( @@ -55,9 +55,6 @@ class DocumentsProvider : DocumentsProvider() { DocumentsContract.Document.COLUMN_SIZE ) - //const val AUTHORITY : String = BuildConfig.APPLICATION_ID + ".provider" - const val AUTHORITY : String = "org.touchhle.android.provider" - const val ROOT_ID : String = "root" } @@ -96,7 +93,7 @@ class DocumentsProvider : DocumentsProvider() { add(DocumentsContract.Root.COLUMN_DOCUMENT_ID, getDocumentId(getBaseDirectory())) add(DocumentsContract.Root.COLUMN_MIME_TYPES, "*/*") add(DocumentsContract.Root.COLUMN_AVAILABLE_BYTES, getBaseDirectory().freeSpace) - //add(DocumentsContract.Root.COLUMN_ICON, R.drawable.logo_skyline) + add(DocumentsContract.Root.COLUMN_ICON, BuildConfig.APP_ICON) } return cursor diff --git a/android/app/src/main/res/drawable-nodpi/icon.png b/android/app/src/main/res/drawable-nodpi/icon.png new file mode 120000 index 000000000..53c80fab3 --- /dev/null +++ b/android/app/src/main/res/drawable-nodpi/icon.png @@ -0,0 +1 @@ +../../../../../../res/icon.png \ No newline at end of file diff --git a/android/app/src/main/res/drawable-nodpi/icon_preview.png b/android/app/src/main/res/drawable-nodpi/icon_preview.png new file mode 120000 index 000000000..a69ada9ad --- /dev/null +++ b/android/app/src/main/res/drawable-nodpi/icon_preview.png @@ -0,0 +1 @@ +../../../../../../res/icon_preview.png \ No newline at end of file diff --git a/android/app/src/main/res/drawable-nodpi/icon_unofficial.png b/android/app/src/main/res/drawable-nodpi/icon_unofficial.png new file mode 120000 index 000000000..3d0ade6a8 --- /dev/null +++ b/android/app/src/main/res/drawable-nodpi/icon_unofficial.png @@ -0,0 +1 @@ +../../../../../../res/icon_unofficial.png \ No newline at end of file diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml deleted file mode 100644 index 707290bac..000000000 --- a/android/app/src/main/res/values/strings.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - touchHLE - diff --git a/res/icon-preview.png b/res/icon_preview.png similarity index 100% rename from res/icon-preview.png rename to res/icon_preview.png diff --git a/res/icon-unofficial.png b/res/icon_unofficial.png similarity index 100% rename from res/icon-unofficial.png rename to res/icon_unofficial.png diff --git a/src/app_picker.rs b/src/app_picker.rs index 8e2360c66..36efd4737 100644 --- a/src/app_picker.rs +++ b/src/app_picker.rs @@ -270,10 +270,10 @@ fn show_app_picker_gui( "" => include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/res/icon.png")), "UNOFFICIAL" => include_bytes!(concat!( env!("CARGO_MANIFEST_DIR"), - "/res/icon-unofficial.png" + "/res/icon_unofficial.png" )), "PREVIEW" => { - include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/res/icon-preview.png")) + include_bytes!(concat!(env!("CARGO_MANIFEST_DIR"), "/res/icon_preview.png")) } _ => panic!(), }; diff --git a/src/paths.rs b/src/paths.rs index c85c2f234..d0ab20b85 100644 --- a/src/paths.rs +++ b/src/paths.rs @@ -152,8 +152,13 @@ pub fn user_data_base_path() -> Cow<'static, Path> { /// that [user_data_base_path] represents. pub fn url_for_opening_user_data_dir() -> Result { if std::env::consts::OS == "android" { - // See DocumentsProvider.kt and AndroidManifest.xml - Ok("content://org.touchhle.android.provider/root/root".to_string()) + // See DocumentsProvider.kt, app/build.gradle and AndroidManifest.xml + let brand = crate::branding(); + Ok(format!( + "content://org.touchhle.android{}{}.provider/root/root", + if brand.is_empty() { "" } else { "." }, + brand.to_lowercase() + )) } else { let path = user_data_base_path() .join(".")