From 257aad24318bd5855a9593eec1cb22c157b9d2ed Mon Sep 17 00:00:00 2001 From: Zephyron Date: Wed, 30 Apr 2025 15:25:57 +1000 Subject: [PATCH] chore: Make firmware optional rather than required This commit makes firmware non-mandatory for the emulator to function. Changes include: - Converting firmware errors to warnings in loader - Removing firmware requirement checks in Android - Removing firmware and title.keys setup screens - Adding --allow-unsupported flag for Android vcpkg - Updating vcpkg baseline - Enforce software keyboard in Android Signed-off-by: Zephyron --- CMakeLists.txt | 3 +- .../activities/EmulationActivity.kt | 34 ++----- .../citron_emu/fragments/SetupFragment.kt | 91 ------------------- src/core/loader/loader.cpp | 6 +- vcpkg.json | 2 +- 5 files changed, 11 insertions(+), 125 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9cde23779..0540415eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,7 +164,8 @@ endif() if (CITRON_USE_BUNDLED_VCPKG) if (ANDROID) - set(ENV{ANDROID_NDK_HOME} "${ANDROID_NDK}") + set(ENV{ANDROID_NDK_HOME} ${ANDROID_NDK}) + set(VCPKG_ADDITIONAL_FLAGS "--allow-unsupported") list(APPEND VCPKG_MANIFEST_FEATURES "android") if (CMAKE_ANDROID_ARCH_ABI STREQUAL "arm64-v8a") diff --git a/src/android/app/src/main/java/org/citron/citron_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/citron/citron_emu/activities/EmulationActivity.kt index c4c2c1ed1..dee584378 100644 --- a/src/android/app/src/main/java/org/citron/citron_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/citron/citron_emu/activities/EmulationActivity.kt @@ -83,19 +83,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { super.onCreate(savedInstanceState) - // Check if firmware is available - if (!NativeLibrary.isFirmwareAvailable()) { - AlertDialog.Builder(this) - .setTitle(R.string.firmware_missing_title) - .setMessage(R.string.firmware_missing_message) - .setPositiveButton(R.string.ok) { _, _ -> - finish() - } - .setCancelable(false) - .show() - return - } - // Add license verification at the start LicenseVerifier.verifyLicense(this) @@ -168,22 +155,13 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener { override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { if (event.action == KeyEvent.ACTION_DOWN) { - if (keyCode == KeyEvent.KEYCODE_ENTER) { - // Special case, we do not support multiline input, dismiss the keyboard. - val overlayView: View = - this.findViewById(R.id.surface_input_overlay) - val im = - overlayView.context.getSystemService(INPUT_METHOD_SERVICE) as InputMethodManager - im.hideSoftInputFromWindow(overlayView.windowToken, 0) + val textChar = event.unicodeChar + if (textChar == 0) { + // No text, button input. + NativeLibrary.submitInlineKeyboardInput(keyCode) } else { - val textChar = event.unicodeChar - if (textChar == 0) { - // No text, button input. - NativeLibrary.submitInlineKeyboardInput(keyCode) - } else { - // Text submitted. - NativeLibrary.submitInlineKeyboardText(textChar.toChar().toString()) - } + // Text submitted. + NativeLibrary.submitInlineKeyboardText(textChar.toChar().toString()) } } return super.onKeyDown(keyCode, event) diff --git a/src/android/app/src/main/java/org/citron/citron_emu/fragments/SetupFragment.kt b/src/android/app/src/main/java/org/citron/citron_emu/fragments/SetupFragment.kt index 962fa709a..d7c759507 100644 --- a/src/android/app/src/main/java/org/citron/citron_emu/fragments/SetupFragment.kt +++ b/src/android/app/src/main/java/org/citron/citron_emu/fragments/SetupFragment.kt @@ -181,61 +181,6 @@ class SetupFragment : Fragment() { ) ) - // Add title.keys installation page - add( - SetupPage( - R.drawable.ic_key, - R.string.install_title_keys, - R.string.install_title_keys_description, - R.drawable.ic_add, - true, - R.string.select_keys, - { - titleKeyCallback = it - getTitleKey.launch(arrayOf("*/*")) - }, - true, - R.string.install_title_keys_warning, - R.string.install_title_keys_warning_description, - R.string.install_title_keys_warning_help, - { - val file = File(DirectoryInitialization.userDirectory + "/keys/title.keys") - if (file.exists()) { - StepState.COMPLETE - } else { - StepState.INCOMPLETE - } - } - ) - ) - - // Add firmware installation page (mandatory) - add( - SetupPage( - R.drawable.ic_key, - R.string.install_firmware, - R.string.install_firmware_description, - R.drawable.ic_add, - true, - R.string.select_firmware, - { - firmwareCallback = it - getFirmware.launch(arrayOf("application/zip")) - }, - true, - R.string.install_firmware_warning, - R.string.install_firmware_warning_description, - R.string.install_firmware_warning_help, - { - if (NativeLibrary.isFirmwareAvailable()) { - StepState.COMPLETE - } else { - StepState.INCOMPLETE - } - } - ) - ) - add( SetupPage( R.drawable.ic_controller, @@ -324,18 +269,6 @@ class SetupFragment : Fragment() { return@setOnClickListener } - // Special handling for firmware page - don't allow skipping - if (currentPage.titleId == R.string.install_firmware && !NativeLibrary.isFirmwareAvailable()) { - SetupWarningDialogFragment.newInstance( - currentPage.warningTitleId, - currentPage.warningDescriptionId, - currentPage.warningHelpLinkId, - index, - allowSkip = false - ).show(childFragmentManager, SetupWarningDialogFragment.TAG) - return@setOnClickListener - } - if (!hasBeenWarned[index]) { SetupWarningDialogFragment.newInstance( currentPage.warningTitleId, @@ -414,30 +347,6 @@ class SetupFragment : Fragment() { } } - private lateinit var titleKeyCallback: SetupCallback - - val getTitleKey = - registerForActivityResult(ActivityResultContracts.OpenDocument()) { result -> - if (result != null) { - mainActivity.processTitleKey(result) - titleKeyCallback.onStepCompleted() - } - } - - private lateinit var firmwareCallback: SetupCallback - - val getFirmware = - registerForActivityResult(ActivityResultContracts.OpenDocument()) { result -> - if (result != null) { - mainActivity.getFirmware.launch(arrayOf("application/zip")) - binding.root.postDelayed({ - if (NativeLibrary.isFirmwareAvailable()) { - firmwareCallback.onStepCompleted() - } - }, 1000) - } - } - private lateinit var gamesDirCallback: SetupCallback val getGamesDirectory = diff --git a/src/core/loader/loader.cpp b/src/core/loader/loader.cpp index 0135d6f81..e2956b73a 100644 --- a/src/core/loader/loader.cpp +++ b/src/core/loader/loader.cpp @@ -260,12 +260,10 @@ std::unique_ptr GetLoader(Core::System& system, FileSys::VirtualFile if (bis_system) { auto mii_applet_nca = bis_system->GetEntry(MiiEditId, FileSys::ContentRecordType::Program); if (!mii_applet_nca) { - LOG_ERROR(Loader, "Firmware is required to launch games but is not available"); - return nullptr; + LOG_WARNING(Loader, "Firmware is not available. Some games may not function correctly."); } } else { - LOG_ERROR(Loader, "System NAND contents not available"); - return nullptr; + LOG_WARNING(Loader, "System NAND contents not available"); } FileType type = IdentifyFile(file); diff --git a/vcpkg.json b/vcpkg.json index b6dd63612..3c57e651d 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -1,7 +1,7 @@ { "$schema": "https://raw.githubusercontent.com/microsoft/vcpkg-tool/main/docs/vcpkg.schema.json", "name": "citron", - "builtin-baseline": "bc994510d2eb11aac7b43b03f67a7751d5bfe0e4", + "builtin-baseline": "c82f74667287d3dc386bce81e44964370c91a289", "version": "1.0", "dependencies": [ "boost-algorithm",