diff --git a/android/Build-Quest.ps1 b/android/Build-Quest.ps1 index 279f618..772d1a6 100644 --- a/android/Build-Quest.ps1 +++ b/android/Build-Quest.ps1 @@ -1,7 +1,7 @@ # Builds the standalone Meta Quest APK on a Windows host. # # powershell -ExecutionPolicy Bypass -File android/Build-Quest.ps1 [-Generated ] -# [-Configuration debug|release] [-Install] +# [-Headset modern|quest1] [-Configuration debug|release] [-Install] # # One app offers both games: the APK carries a kit for the base game, and for Retro Rewind too # when -Generated holds a translation that includes the mod. @@ -20,6 +20,7 @@ param( [string]$Generated = '', [string]$Dependencies = '', [string]$CMakeDir = '', + [ValidateSet('modern', 'quest1')] [string]$Headset = 'modern', [ValidateSet('debug', 'release')] [string]$Configuration = 'debug', [switch]$Install ) @@ -73,7 +74,8 @@ if (-not $Dependencies) { } $variant = (Get-Culture).TextInfo.ToTitleCase($Configuration) -$task = "app:assemble$variant" +$flavour = if ($Headset -eq 'quest1') { 'Quest1' } else { 'ModernQuest' } +$task = "app:assemble$flavour$variant" $gradleArgs = @( '--project-dir', $root, "-PmkwGeneratedDir=$Generated" @@ -84,7 +86,8 @@ Write-Host "gradlew $($gradleArgs -join ' ')" & (Join-Path $root 'gradlew.bat') @gradleArgs if ($LASTEXITCODE -ne 0) { throw "Gradle failed ($LASTEXITCODE)" } -$apkDir = Join-Path $root "app\build\outputs\apk\$Configuration" +$flavourDir = if ($Headset -eq 'quest1') { 'quest1' } else { 'modernQuest' } +$apkDir = Join-Path $root "app\build\outputs\apk\$flavourDir\$Configuration" $apk = Get-ChildItem -Path $apkDir -Filter '*.apk' | Select-Object -First 1 if (-not $apk) { throw "No APK under $apkDir" } Write-Host "APK: $($apk.FullName)" @@ -106,5 +109,9 @@ if ($Install) { $adb = Join-Path $sdkRoot 'platform-tools\adb.exe' & $adb install -r $apk.FullName if ($LASTEXITCODE -ne 0) { throw "adb install failed ($LASTEXITCODE)" } - Write-Host 'Installed. Build a game with Build on this Quest in the launcher, or on this PC with android/Build-QuestGame.ps1 -Install.' + if ($Headset -eq 'quest1') { + Write-Host 'Installed. Use WiiCompiled Settings for setup, then launch WiiCompiled VR directly from the library.' + } else { + Write-Host 'Installed. Build a game with Build on this Quest in the launcher, or on this PC with android/Build-QuestGame.ps1 -Install.' + } } diff --git a/android/app/build.gradle.kts b/android/app/build.gradle.kts index 84fedcc..d61670b 100644 --- a/android/app/build.gradle.kts +++ b/android/app/build.gradle.kts @@ -139,6 +139,32 @@ android { } } + flavorDimensions += "headset" + productFlavors { + create("modernQuest") { + dimension = "headset" + manifestPlaceholders["mkwQuestSupportedDevices"] = "quest2|quest3|quest3s|questpro" + buildConfigField("boolean", "QUEST1_DIRECT_LAUNCH", "false") + externalNativeBuild { + cmake { + // Snapdragon XR2 and newer. Keep this as the default build target. + arguments += "-DMKW_ANDROID_CPU=cortex-a77" + } + } + } + create("quest1") { + dimension = "headset" + manifestPlaceholders["mkwQuestSupportedDevices"] = "quest|quest2" + buildConfigField("boolean", "QUEST1_DIRECT_LAUNCH", "true") + externalNativeBuild { + cmake { + // Snapdragon 835. cortex-a77 binaries terminate with SIGILL on Quest 1. + arguments += "-DMKW_ANDROID_CPU=kryo" + } + } + } + } + externalNativeBuild { cmake { // aurora-main needs CMake 3.25+, newer than the SDK's bundled 3.22.1; diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index 11536b6..fcdebd2 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -37,12 +37,13 @@ android:label="@string/app_name" android:theme="@style/Theme.WiiCompiled.Quest"> - + - + - - - - @@ -84,11 +81,6 @@ - - - - - diff --git a/android/app/src/main/java/org/wiicompiled/quest/launcher/LauncherActivity.kt b/android/app/src/main/java/org/wiicompiled/quest/launcher/LauncherActivity.kt index b12b2a5..2d536c6 100644 --- a/android/app/src/main/java/org/wiicompiled/quest/launcher/LauncherActivity.kt +++ b/android/app/src/main/java/org/wiicompiled/quest/launcher/LauncherActivity.kt @@ -585,6 +585,10 @@ class LauncherActivity : Activity() { } private fun play() { + if (BuildConfig.QUEST1_DIRECT_LAUNCH) { + Toast.makeText(this, R.string.home_quest1_launch_from_library, Toast.LENGTH_LONG).show() + return + } if (launching) { return } diff --git a/android/app/src/main/res/values/strings.xml b/android/app/src/main/res/values/strings.xml index 2337104..6bb1b61 100644 --- a/android/app/src/main/res/values/strings.xml +++ b/android/app/src/main/res/values/strings.xml @@ -1,6 +1,7 @@ WiiCompiled VR + WiiCompiled Settings Game data not found Copy the extracted DATA directory of your own PAL RMCP01 Mario Kart Wii disc to:\n\n%1$s\n\nFor example with adb: adb push DATA /sdcard/Android/data/org.wiicompiled.quest/files/WiiCompiledOpenXRVR/DATA\n\nThen start the app again. @@ -77,6 +78,7 @@ Replace the game files? Your current DATA folder stays until the new disc image has been checked and completely extracted. The game could not be started. + Quest 1 cannot switch this settings panel into VR. Close it, then launch WiiCompiled VR from your library. Close the game first. Reset installation Reset the installation? diff --git a/android/app/src/modernQuest/AndroidManifest.xml b/android/app/src/modernQuest/AndroidManifest.xml new file mode 100644 index 0000000..3c40ec4 --- /dev/null +++ b/android/app/src/modernQuest/AndroidManifest.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/android/app/src/quest1/AndroidManifest.xml b/android/app/src/quest1/AndroidManifest.xml new file mode 100644 index 0000000..303d001 --- /dev/null +++ b/android/app/src/quest1/AndroidManifest.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/aurora-main/cmake/AuroraDawnProvider.cmake b/aurora-main/cmake/AuroraDawnProvider.cmake index 2cf1a36..90584d0 100644 --- a/aurora-main/cmake/AuroraDawnProvider.cmake +++ b/aurora-main/cmake/AuroraDawnProvider.cmake @@ -154,6 +154,13 @@ elseif (_aurora_dawn_provider STREQUAL "package") endif () set(AURORA_DAWN_PACKAGE_URL "https://github.com/theofficialgman/dawn-build/releases/download/${AURORA_DAWN_VERSION}/dawn-${_dawn_system}-${_dawn_arch}.tar.gz") + # Meta's Quest 1 firmware advertises VK_EXT_debug_utils but rejects it at + # vkCreateInstance. This pinned Android package disables that extension on + # Android; it is also the package validated on modern Quest headsets. + if (_dawn_system STREQUAL "android" AND _dawn_arch STREQUAL "aarch64") + set(AURORA_DAWN_PACKAGE_URL + "https://github.com/encounter/dawn-build/releases/download/${AURORA_DAWN_VERSION}/dawn-android-aarch64.tar.gz") + endif () # A release asset is mutable: the same tag has already served two different windows-amd64 archives, # and a cached extraction is never re-verified. Pin the digest for the combinations we ship. @@ -181,7 +188,7 @@ elseif (_aurora_dawn_provider STREQUAL "package") "SHA256=f97701d26fd1f25bbcc260b4c31736ede134c730c12556029e2470fde967f424") elseif (_dawn_system STREQUAL "android" AND _dawn_arch STREQUAL "aarch64") set(AURORA_DAWN_PACKAGE_URL_HASH - "SHA256=0e63e8cbf53551f703f582d1306f4257c0380353f66b53369d96952ce6d9f934") + "SHA256=27d910dee1201fd1e5b6ac567f0ba2306ebf2135e9f40b6929976c365d38b09b") endif () endif () endif () diff --git a/docs/quest-port.md b/docs/quest-port.md index fb65177..5c3f107 100644 --- a/docs/quest-port.md +++ b/docs/quest-port.md @@ -107,6 +107,22 @@ the result. Live RGB5A3 menu copies use a minimal RGBA passthrough shader for the same reason. Other Android devices retain the normal filtered and format-converting paths. +Quest 1 must be built with the `quest1` flavour (`Build-Quest.ps1 -Headset +quest1`). It targets the Snapdragon 835's Kryo CPU; the modern flavour targets +`cortex-a77`, whose instructions can terminate the game with `SIGILL` on Quest +1. Android builds use a pinned Dawn package which does not enable +`VK_EXT_debug_utils`: the old Quest firmware advertises that extension but +rejects it when Dawn creates the Vulkan instance. + +The final Quest 1 firmware also cannot reliably promote this app's 2D setup +panel into an immersive activity. Its APK therefore exposes two library +entries: **WiiCompiled VR** starts the game directly in VR, while +**WiiCompiled Settings** opens the setup/settings panel. After changing a +setting, close the panel and start WiiCompiled VR from the library. The Play +button in the settings panel explains this limitation instead of opening a +black panel. Modern Quest builds keep the normal single launcher, whose Play +button starts VR directly. + The workaround was isolated on a physical Quest 1: it changed the boot/menu output from flickering black or white frames to a complete menu with character and vehicle previews. It does intentionally skip Wii-era RGB5A3 quantization on @@ -459,7 +475,10 @@ Android facts this design rests on, all measured on a Quest 3: also learned `--target-os windows|macos|linux|android` for `generate-data-init` and `translate-mod`, for pipelines that generate on another host. -- `android/`: the Gradle project, one app with no flavours. +- `android/`: the Gradle project, with `modernQuest` (the default script + target) and `quest1` headset flavours. They share the application ID and + storage, but select the appropriate CPU baseline, supported-device manifest, + and launcher behavior. `app/src/main/cpp/CMakeLists.txt` adds the repository's `runtime/` as a subdirectory with those Android choices and builds both game kit probes (the Retro Rewind one only when the translation includes the mod), which @@ -481,6 +500,7 @@ installer's `BuildWorkspace/generated`, produced by the normal Windows pipeline) ```powershell powershell -ExecutionPolicy Bypass -File android/Prepare-QuestDependencies.ps1 # SDL3 3.4.4 AAR into android/app/libs powershell -ExecutionPolicy Bypass -File android/Build-Quest.ps1 -Install # the app, its game kit and toolchain, debug-signed +powershell -ExecutionPolicy Bypass -File android/Build-Quest.ps1 -Headset quest1 -Install # Quest 1: Kryo CPU and direct-VR library entry powershell -ExecutionPolicy Bypass -File android/Build-QuestGame.ps1 -Install # your game, against that kit, into Import (or WheelWizard VR's Build for Quest) powershell -ExecutionPolicy Bypass -File android/Build-QuestGame.ps1 -Product retro_rewind -Mod -Install # the mod and its pack (needs translate-mod output) adb push MarioKart.iso /sdcard/Download/ # then Select disc image in the launcher