From 2940069fe2cf8a4d421b39e6b6c4fe3441eb223d Mon Sep 17 00:00:00 2001 From: OpenSauce04 Date: Sun, 14 Jun 2026 21:20:04 +0100 Subject: [PATCH] android: Apply automatic kotlin formatting fixes --- src/android/app/build.gradle.kts | 14 +- .../org/citra/citra_emu/CitraApplication.kt | 2 +- .../java/org/citra/citra_emu/NativeLibrary.kt | 149 ++++--- .../citra_emu/activities/EmulationActivity.kt | 24 +- .../citra/citra_emu/adapters/DriverAdapter.kt | 10 +- .../citra/citra_emu/adapters/GameAdapter.kt | 248 ++++++++--- .../citra_emu/adapters/HomeSettingAdapter.kt | 7 +- .../citra/citra_emu/adapters/SetupAdapter.kt | 21 +- .../citra/citra_emu/applets/MiiSelector.kt | 4 +- .../citra_emu/applets/SoftwareKeyboard.kt | 16 +- .../contracts/OpenFileResultContract.kt | 5 +- .../citra_emu/display/ScreenAdjustmentUtil.kt | 22 +- .../citra/citra_emu/display/ScreenLayout.kt | 34 +- .../citra_emu/display/SecondaryDisplay.kt | 65 +-- .../features/cheats/model/CheatsViewModel.kt | 2 +- .../cheats/ui/CheatDetailsFragment.kt | 31 +- .../features/cheats/ui/CheatListFragment.kt | 2 +- .../features/cheats/ui/CheatsAdapter.kt | 3 +- .../features/cheats/ui/CheatsFragment.kt | 7 +- .../citra_emu/features/hotkeys/Hotkey.kt | 2 +- .../features/hotkeys/HotkeyUtility.kt | 16 +- .../features/settings/SettingKeys.kt | 2 +- .../features/settings/model/BooleanSetting.kt | 100 ++++- .../features/settings/model/FloatSetting.kt | 8 +- .../features/settings/model/IntListSetting.kt | 13 +- .../features/settings/model/IntSetting.kt | 54 ++- .../features/settings/model/SettingSection.kt | 4 +- .../features/settings/model/Settings.kt | 10 +- .../features/settings/model/StringSetting.kt | 12 +- .../settings/model/view/HeaderSetting.kt | 2 +- .../model/view/InputBindingSetting.kt | 412 ++++++++++++------ .../settings/model/view/MultiChoiceSetting.kt | 3 +- .../settings/model/view/SliderSetting.kt | 4 + .../features/settings/ui/SettingsActivity.kt | 10 +- .../settings/ui/SettingsActivityPresenter.kt | 12 +- .../features/settings/ui/SettingsAdapter.kt | 124 +++--- .../features/settings/ui/SettingsFragment.kt | 4 +- .../settings/ui/SettingsFragmentPresenter.kt | 115 +++-- .../ui/viewholder/DateTimeViewHolder.kt | 6 +- .../ui/viewholder/HeaderViewHolder.kt | 2 +- .../ui/viewholder/MultiChoiceViewHolder.kt | 8 +- .../ui/viewholder/SettingViewHolder.kt | 4 +- .../ui/viewholder/SliderViewHolder.kt | 2 + .../features/settings/utils/SettingsFile.kt | 38 +- .../citra_emu/fragments/AboutFragment.kt | 37 +- .../fragments/AutoMapDialogFragment.kt | 6 +- .../fragments/CitraDirectoryDialogFragment.kt | 4 +- .../CompressProgressDialogFragment.kt | 31 +- .../CopyDirProgressDialogFragment.kt | 7 +- .../fragments/DriverManagerFragment.kt | 61 ++- .../citra_emu/fragments/EmulationFragment.kt | 117 +++-- .../citra_emu/fragments/GamesFragment.kt | 73 ++-- ...rantMissingFilesystemPermissionFragment.kt | 2 - .../fragments/HomeSettingsFragment.kt | 71 +-- .../IndeterminateProgressDialogFragment.kt | 4 +- .../fragments/KeyboardDialogFragment.kt | 12 +- .../LicenseBottomSheetDialogFragment.kt | 4 +- .../citra_emu/fragments/LicensesFragment.kt | 37 +- .../fragments/MiiSelectorDialogFragment.kt | 17 +- .../MotionBottomSheetDialogFragment.kt | 2 +- .../citra_emu/fragments/SearchFragment.kt | 111 ++--- .../SelectUserDirectoryDialogFragment.kt | 19 +- .../citra_emu/fragments/SetupFragment.kt | 120 ++--- .../fragments/SystemFilesFragment.kt | 26 +- .../UpdateUserDirectoryDialogFragment.kt | 11 +- .../java/org/citra/citra_emu/model/Game.kt | 12 +- .../org/citra/citra_emu/model/SetupPage.kt | 4 +- .../citra/citra_emu/overlay/InputOverlay.kt | 98 +++-- .../overlay/InputOverlayDrawableButton.kt | 7 +- .../overlay/InputOverlayDrawableDpad.kt | 22 +- .../overlay/InputOverlayDrawableJoystick.kt | 40 +- .../citra/citra_emu/ui/main/MainActivity.kt | 66 +-- .../citra/citra_emu/utils/CiaInstallWorker.kt | 10 +- .../citra_emu/utils/CitraDirectoryHelper.kt | 16 +- .../citra_emu/utils/CitraDirectoryUtils.kt | 18 +- .../utils/ControllerMappingHelper.kt | 9 +- .../utils/DirectoryInitialization.kt | 25 +- .../utils/DiskShaderCacheProgress.kt | 3 +- .../citra/citra_emu/utils/DocumentsTree.kt | 31 +- .../citra_emu/utils/EmulationLifecycleUtil.kt | 9 +- .../citra_emu/utils/EmulationMenuSettings.kt | 9 +- .../org/citra/citra_emu/utils/FileUtil.kt | 64 ++- .../org/citra/citra_emu/utils/GameHelper.kt | 45 +- .../citra/citra_emu/utils/GameIconUtils.kt | 19 +- .../citra/citra_emu/utils/GpuDriverHelper.kt | 8 +- .../citra_emu/utils/GpuDriverMetadata.kt | 16 +- .../org/citra/citra_emu/utils/MemoryUtil.kt | 130 +++--- .../citra_emu/utils/PermissionsHandler.kt | 8 +- .../citra/citra_emu/utils/RefreshRateUtil.kt | 2 +- .../org/citra/citra_emu/utils/ThemeUtil.kt | 30 +- .../org/citra/citra_emu/utils/TurboHelper.kt | 4 +- .../CompressProgressDialogViewModel.kt | 4 +- .../citra_emu/viewmodel/DriverViewModel.kt | 2 +- .../citra_emu/viewmodel/HomeViewModel.kt | 8 +- 94 files changed, 1901 insertions(+), 1223 deletions(-) diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts index 2ee844985..28c8ae446 100644 --- a/src/android/app/build.gradle.kts +++ b/src/android/app/build.gradle.kts @@ -80,7 +80,7 @@ android { "-DENABLE_SDL2=0", // Don't use SDL "-DANDROID_ARM_NEON=true", // cryptopp requires Neon to work "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON", // Support Android 15 16KiB page sizes - "-DENABLE_GDBSTUB=OFF", // Disable GDB stub + "-DENABLE_GDBSTUB=OFF" // Disable GDB stub ) } } @@ -147,7 +147,7 @@ android { } lint { checkReleaseBuilds = false // Ditto - // The name of this property is misleading, this doesn't actually disable linting for the `release` build. + // ^- The name of this property is misleading, this doesn't actually disable linting for the `release` build. } } @@ -215,7 +215,9 @@ dependencies { // Download Vulkan Validation Layers from the KhronosGroup GitHub. val downloadVulkanValidationLayers = tasks.register("downloadVulkanValidationLayers") { - src("https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download/vulkan-sdk-1.4.313.0/android-binaries-1.4.313.0.zip") + src( + "https://github.com/KhronosGroup/Vulkan-ValidationLayers/releases/download/vulkan-sdk-1.4.313.0/android-binaries-1.4.313.0.zip" + ) dest(file("${layout.buildDirectory.get().asFile.path}/tmp/Vulkan-ValidationLayers.zip")) onlyIfModified(true) } @@ -266,7 +268,7 @@ fun getGitHash(): String = fun getBranch(): String = runGitCommand(ProcessBuilder("git", "rev-parse", "--abbrev-ref", "HEAD")) ?: "dummy-branch" -fun runGitCommand(command: ProcessBuilder) : String? { +fun runGitCommand(command: ProcessBuilder): String? { try { command.directory(project.rootDir) val process = command.start() @@ -292,7 +294,7 @@ android.applicationVariants.configureEach { val variant = this val capitalizedName = variant.name.capitalizeUS() - val copyTask = tasks.register("copyBundle${capitalizedName}") { + val copyTask = tasks.register("copyBundle$capitalizedName") { doLast { project.copy { from(variant.outputs.first().outputFile.parentFile) @@ -306,5 +308,5 @@ android.applicationVariants.configureEach { } } } - tasks.named("bundle${capitalizedName}").configure { finalizedBy(copyTask) } + tasks.named("bundle$capitalizedName").configure { finalizedBy(copyTask) } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/CitraApplication.kt b/src/android/app/src/main/java/org/citra/citra_emu/CitraApplication.kt index c4db63928..69ca11698 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/CitraApplication.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/CitraApplication.kt @@ -13,9 +13,9 @@ import android.os.Build import org.citra.citra_emu.utils.DirectoryInitialization import org.citra.citra_emu.utils.DocumentsTree import org.citra.citra_emu.utils.GpuDriverHelper -import org.citra.citra_emu.utils.PermissionsHandler import org.citra.citra_emu.utils.Log import org.citra.citra_emu.utils.MemoryUtil +import org.citra.citra_emu.utils.PermissionsHandler class CitraApplication : Application() { private fun createNotificationChannel() { diff --git a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt index 72035cae4..097b64e5e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/NativeLibrary.kt @@ -25,6 +25,8 @@ import androidx.core.net.toUri import androidx.fragment.app.DialogFragment import androidx.preference.PreferenceManager import com.google.android.material.dialog.MaterialAlertDialogBuilder +import java.lang.ref.WeakReference +import java.util.Date import org.citra.citra_emu.activities.EmulationActivity import org.citra.citra_emu.model.Game import org.citra.citra_emu.utils.BuildUtil @@ -32,8 +34,6 @@ import org.citra.citra_emu.utils.FileUtil import org.citra.citra_emu.utils.Log import org.citra.citra_emu.utils.RemovableStorageHelper import org.citra.citra_emu.viewmodel.CompressProgressDialogViewModel -import java.lang.ref.WeakReference -import java.util.Date /** * Class which contains methods that interact @@ -135,10 +135,7 @@ object NativeLibrary { */ external fun setUserDirectory(directory: String) - data class InstalledGame( - val path: String, - val mediaType: Game.MediaType - ) + data class InstalledGame(val path: String, val mediaType: Game.MediaType) fun getInstalledGamePaths(): Array { val games = getInstalledGamePathsImpl() @@ -253,9 +250,8 @@ object NativeLibrary { external fun playTimeManagerGetCurrentTitleId(): Long private external fun uninstallTitle(titleId: Long, mediaType: Int): Boolean - fun uninstallTitle(titleId: Long, mediaType: Game.MediaType): Boolean { - return uninstallTitle(titleId, mediaType.value) - } + fun uninstallTitle(titleId: Long, mediaType: Game.MediaType): Boolean = + uninstallTitle(titleId, mediaType.value) external fun nativeFileExists(path: String): Boolean @@ -352,7 +348,7 @@ object NativeLibrary { @get:JvmStatic val isPortraitMode: Boolean get() = CitraApplication.appContext.resources.configuration.orientation == - Configuration.ORIENTATION_PORTRAIT + Configuration.ORIENTATION_PORTRAIT @Keep @JvmStatic @@ -501,16 +497,20 @@ object NativeLibrary { else -> { title = getString(R.string.loader_error_generic_title) - message = getString(R.string.loader_error_generic, - getString(coreError.stringRes), coreError.value) + message = getString( + R.string.loader_error_generic, + getString(coreError.stringRes), + coreError.value + ) } } val alert = MaterialAlertDialogBuilder(requireContext()) .setTitle(title) .setMessage( - Html.fromHtml(message, - Html.FROM_HTML_MODE_LEGACY + Html.fromHtml( + message, + Html.FROM_HTML_MODE_LEGACY ) ) .setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int -> @@ -641,7 +641,7 @@ object NativeLibrary { fun loadStateIfAvailable(slot: Int): Boolean { var available = false getSavestateInfo()?.forEach { - if (it.slot == slot){ + if (it.slot == slot) { available = true return@forEach } @@ -679,19 +679,17 @@ object NativeLibrary { // Compression / Decompression private external fun compressFileNative(inputPath: String?, outputPath: String): Int - fun compressFile(inputPath: String?, outputPath: String): CompressStatus { - return CompressStatus.fromValue( + fun compressFile(inputPath: String?, outputPath: String): CompressStatus = + CompressStatus.fromValue( compressFileNative(inputPath, outputPath) ) - } private external fun decompressFileNative(inputPath: String?, outputPath: String): Int - fun decompressFile(inputPath: String?, outputPath: String): CompressStatus { - return CompressStatus.fromValue( + fun decompressFile(inputPath: String?, outputPath: String): CompressStatus = + CompressStatus.fromValue( decompressFileNative(inputPath, outputPath) ) - } external fun getRecommendedExtension(inputPath: String?, shouldCompress: Boolean): String @@ -725,21 +723,19 @@ object NativeLibrary { @Keep @JvmStatic - fun openContentUri(path: String, openMode: String): Int = - if (FileUtil.isNativePath(path)) { - CitraApplication.documentsTree.openContentUri(path, openMode) - } else { - FileUtil.openContentUri(path, openMode) - } + fun openContentUri(path: String, openMode: String): Int = if (FileUtil.isNativePath(path)) { + CitraApplication.documentsTree.openContentUri(path, openMode) + } else { + FileUtil.openContentUri(path, openMode) + } @Keep @JvmStatic - fun getFilesName(path: String): Array = - if (FileUtil.isNativePath(path)) { - CitraApplication.documentsTree.getFilesName(path) - } else { - FileUtil.getFilesName(path) - } + fun getFilesName(path: String): Array = if (FileUtil.isNativePath(path)) { + CitraApplication.documentsTree.getFilesName(path) + } else { + FileUtil.getFilesName(path) + } @Keep @JvmStatic @@ -765,10 +761,14 @@ object NativeLibrary { return primaryStoragePath + dirSep + virtualPath } else { // User directory probably located on a removable storage device val storageIdString = pathSegment.substringBefore(":") - val removablePath = RemovableStorageHelper.getRemovableStoragePath(CitraApplication.appContext, storageIdString) + val removablePath = RemovableStorageHelper.getRemovableStoragePath( + CitraApplication.appContext, + storageIdString + ) if (removablePath == null) { - android.util.Log.e("NativeLibrary", + android.util.Log.e( + "NativeLibrary", "Unknown mount location for storage device '$storageIdString' (URI: $uri)" ) return "" @@ -788,12 +788,11 @@ object NativeLibrary { @Keep @JvmStatic - fun getSize(path: String): Long = - if (FileUtil.isNativePath(path)) { - CitraApplication.documentsTree.getFileSize(path) - } else { - FileUtil.getFileSize(path) - } + fun getSize(path: String): Long = if (FileUtil.isNativePath(path)) { + CitraApplication.documentsTree.getFileSize(path) + } else { + FileUtil.getFileSize(path) + } @Keep @JvmStatic @@ -801,21 +800,19 @@ object NativeLibrary { @Keep @JvmStatic - fun fileExists(path: String): Boolean = - if (FileUtil.isNativePath(path)) { - CitraApplication.documentsTree.exists(path) - } else { - FileUtil.exists(path) - } + fun fileExists(path: String): Boolean = if (FileUtil.isNativePath(path)) { + CitraApplication.documentsTree.exists(path) + } else { + FileUtil.exists(path) + } @Keep @JvmStatic - fun isDirectory(path: String): Boolean = - if (FileUtil.isNativePath(path)) { - CitraApplication.documentsTree.isDirectory(path) - } else { - FileUtil.isDirectory(path) - } + fun isDirectory(path: String): Boolean = if (FileUtil.isNativePath(path)) { + CitraApplication.documentsTree.isDirectory(path) + } else { + FileUtil.isDirectory(path) + } @Keep @JvmStatic @@ -823,19 +820,18 @@ object NativeLibrary { sourcePath: String, destinationParentPath: String, destinationFilename: String - ): Boolean = - if (FileUtil.isNativePath(sourcePath) && - FileUtil.isNativePath(destinationParentPath) - ) { - CitraApplication.documentsTree - .copyFile(sourcePath, destinationParentPath, destinationFilename) - } else { - FileUtil.copyFile( - Uri.parse(sourcePath), - Uri.parse(destinationParentPath), - destinationFilename - ) - } + ): Boolean = if (FileUtil.isNativePath(sourcePath) && + FileUtil.isNativePath(destinationParentPath) + ) { + CitraApplication.documentsTree + .copyFile(sourcePath, destinationParentPath, destinationFilename) + } else { + FileUtil.copyFile( + Uri.parse(sourcePath), + Uri.parse(destinationParentPath), + destinationFilename + ) + } @Keep @JvmStatic @@ -870,12 +866,11 @@ object NativeLibrary { @Keep @JvmStatic - fun deleteDocument(path: String): Boolean = - if (FileUtil.isNativePath(path)) { - CitraApplication.documentsTree.deleteDocument(path) - } else { - FileUtil.deleteDocument(path) - } + fun deleteDocument(path: String): Boolean = if (FileUtil.isNativePath(path)) { + CitraApplication.documentsTree.deleteDocument(path) + } else { + FileUtil.deleteDocument(path) + } enum class CoreError(val value: Int, @StringRes val stringRes: Int) { Success(0, R.string.core_error_success), @@ -898,9 +893,7 @@ object NativeLibrary { ErrorUnknown(17, R.string.core_error_unknown); companion object { - fun fromInt(value: Int): CoreError { - return entries.find { it.value == value } ?: ErrorUnknown - } + fun fromInt(value: Int): CoreError = entries.find { it.value == value } ?: ErrorUnknown } } @@ -952,7 +945,11 @@ object NativeLibrary { const val MESSAGE = "message" const val CAN_CONTINUE = "canContinue" - fun newInstance(title: String, message: String, canContinue: Boolean): CoreErrorDialogFragment { + fun newInstance( + title: String, + message: String, + canContinue: Boolean + ): CoreErrorDialogFragment { val frag = CoreErrorDialogFragment() val args = Bundle() args.putString(TITLE, title) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.kt index 0991a8ecd..f0ac04047 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/activities/EmulationActivity.kt @@ -46,9 +46,9 @@ import org.citra.citra_emu.fragments.MessageDialogFragment import org.citra.citra_emu.model.Game import org.citra.citra_emu.utils.BuildUtil import org.citra.citra_emu.utils.ControllerMappingHelper -import org.citra.citra_emu.utils.FileBrowserHelper import org.citra.citra_emu.utils.EmulationLifecycleUtil import org.citra.citra_emu.utils.EmulationMenuSettings +import org.citra.citra_emu.utils.FileBrowserHelper import org.citra.citra_emu.utils.Log import org.citra.citra_emu.utils.RefreshRateUtil import org.citra.citra_emu.utils.ThemeUtil @@ -334,11 +334,13 @@ class EmulationActivity : AppCompatActivity() { } return hotkeyUtility.handleKeyPress(event) } + KeyEvent.ACTION_UP -> { return hotkeyUtility.handleKeyRelease(event) } + else -> { - return false; + return false } } } @@ -358,7 +360,8 @@ class EmulationActivity : AppCompatActivity() { // TODO: Move this check into native code - prevents crash if input pressed before starting emulation if (!NativeLibrary.isRunning() || (event.source and InputDevice.SOURCE_CLASS_JOYSTICK == 0) || - emulationFragment.isDrawerOpen()) { + emulationFragment.isDrawerOpen() + ) { return super.dispatchGenericMotionEvent(event) } @@ -387,7 +390,10 @@ class EmulationActivity : AppCompatActivity() { preferences.getInt(InputBindingSetting.getInputAxisButtonKey(axis), -1) val guestOrientation = preferences.getInt(InputBindingSetting.getInputAxisOrientationKey(axis), -1) - val inverted = preferences.getBoolean(InputBindingSetting.getInputAxisInvertedKey(axis),false); + val inverted = preferences.getBoolean( + InputBindingSetting.getInputAxisInvertedKey(axis), + false + ) if (nextMapping == -1 || guestOrientation == -1) { // Axis is unmapped continue @@ -396,7 +402,7 @@ class EmulationActivity : AppCompatActivity() { // Skip joystick wobble value = 0f } - if (inverted) value = -value; + if (inverted) value = -value when (nextMapping) { NativeLibrary.ButtonType.STICK_LEFT -> { @@ -573,7 +579,9 @@ class EmulationActivity : AppCompatActivity() { registerForActivityResult(OpenFileResultContract()) { result: Intent? -> if (result == null) return@registerForActivityResult val selectedFiles = FileBrowserHelper.getSelectedFiles( - result, applicationContext, listOf("bin") + result, + applicationContext, + listOf("bin") ) ?: return@registerForActivityResult if (BuildUtil.isGooglePlayBuild) { onAmiiboSelected(selectedFiles[0]) @@ -596,8 +604,6 @@ class EmulationActivity : AppCompatActivity() { companion object { private var instance: EmulationActivity? = null - fun isRunning(): Boolean { - return instance?.isEmulationRunning ?: false - } + fun isRunning(): Boolean = instance?.isEmulationRunning ?: false } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/adapters/DriverAdapter.kt b/src/android/app/src/main/java/org/citra/citra_emu/adapters/DriverAdapter.kt index 835c01524..ae97c1a7e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/adapters/DriverAdapter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/adapters/DriverAdapter.kt @@ -15,9 +15,9 @@ import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import org.citra.citra_emu.R import org.citra.citra_emu.databinding.CardDriverOptionBinding +import org.citra.citra_emu.utils.GpuDriverHelper import org.citra.citra_emu.utils.GpuDriverMetadata import org.citra.citra_emu.viewmodel.DriverViewModel -import org.citra.citra_emu.utils.GpuDriverHelper class DriverAdapter(private val driverViewModel: DriverViewModel) : ListAdapter, DriverAdapter.DriverViewHolder>( @@ -105,15 +105,11 @@ class DriverAdapter(private val driverViewModel: DriverViewModel) : override fun areItemsTheSame( oldItem: Pair, newItem: Pair - ): Boolean { - return oldItem.first == newItem.first - } + ): Boolean = oldItem.first == newItem.first override fun areContentsTheSame( oldItem: Pair, newItem: Pair - ): Boolean { - return oldItem.second == newItem.second - } + ): Boolean = oldItem.second == newItem.second } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/citra/citra_emu/adapters/GameAdapter.kt index 392f68661..c08e76c21 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/adapters/GameAdapter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/adapters/GameAdapter.kt @@ -4,24 +4,25 @@ package org.citra.citra_emu.adapters -import android.graphics.drawable.Icon +import android.content.Context import android.content.Intent +import android.content.SharedPreferences +import android.content.pm.ShortcutInfo +import android.content.pm.ShortcutManager +import android.graphics.Bitmap +import android.graphics.BitmapFactory +import android.graphics.drawable.BitmapDrawable +import android.graphics.drawable.Icon import android.net.Uri import android.os.SystemClock import android.text.TextUtils import android.view.LayoutInflater import android.view.View import android.view.ViewGroup -import android.content.Context -import android.content.SharedPreferences -import android.widget.TextView import android.widget.ImageView +import android.widget.PopupMenu +import android.widget.TextView import android.widget.Toast -import android.graphics.drawable.BitmapDrawable -import android.graphics.Bitmap -import android.content.pm.ShortcutInfo -import android.content.pm.ShortcutManager -import android.graphics.BitmapFactory import androidx.activity.result.ActivityResultLauncher import androidx.appcompat.app.AppCompatActivity import androidx.core.content.edit @@ -29,24 +30,23 @@ import androidx.core.graphics.scale import androidx.core.net.toUri import androidx.documentfile.provider.DocumentFile import androidx.lifecycle.ViewModelProvider +import androidx.lifecycle.lifecycleScope import androidx.navigation.findNavController import androidx.preference.PreferenceManager import androidx.recyclerview.widget.AsyncDifferConfig import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView -import android.widget.PopupMenu -import androidx.lifecycle.lifecycleScope import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialog import com.google.android.material.button.MaterialButton import com.google.android.material.color.MaterialColors import com.google.android.material.dialog.MaterialAlertDialogBuilder -import kotlinx.coroutines.launch -import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.CoroutineScope -import org.citra.citra_emu.HomeNavigationDirections +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.launch import org.citra.citra_emu.CitraApplication +import org.citra.citra_emu.HomeNavigationDirections import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.R import org.citra.citra_emu.adapters.GameAdapter.GameViewHolder @@ -65,10 +65,12 @@ class GameAdapter( private val activity: AppCompatActivity, private val inflater: LayoutInflater, private val openImageLauncher: ActivityResultLauncher?, - private val onRequestCompressOrDecompress: ((inputPath: String, suggestedName: String, shouldCompress: Boolean) -> Unit)? = null -) : - ListAdapter(AsyncDifferConfig.Builder(DiffCallback()).build()), - View.OnClickListener, View.OnLongClickListener { + private val onRequestCompressOrDecompress: ( + (inputPath: String, suggestedName: String, shouldCompress: Boolean) -> Unit + )? = null +) : ListAdapter(AsyncDifferConfig.Builder(DiffCallback()).build()), + View.OnClickListener, + View.OnLongClickListener { private var lastClickTime = 0L private var imagePath: String? = null private var dialogShortcutBinding: DialogShortcutBinding? = null @@ -212,15 +214,18 @@ class GameAdapter( binding.textGameTitle.text = game.title binding.textCompany.text = game.company binding.textGameRegion.text = game.regions - binding.imageCartridge.visibility = if (preferences.getString("insertedCartridge", "") != game.path) { - View.GONE - } else { - View.VISIBLE - } + binding.imageCartridge.visibility = + if (preferences.getString("insertedCartridge", "") != game.path) { + View.GONE + } else { + View.VISIBLE + } val backgroundColorId = if ( - isValidGame(game.filename.substring(game.filename.lastIndexOf(".") + 1).lowercase()) + isValidGame( + game.filename.substring(game.filename.lastIndexOf(".") + 1).lowercase() + ) ) { R.attr.colorSurface } else { @@ -263,13 +268,41 @@ class GameAdapter( val basePath = "sdmc/Nintendo 3DS/00000000000000000000000000000000/00000000000000000000000000000000" return GameDirectories( gameDir = game.path.substringBeforeLast("/"), - saveDir = basePath + "/title/${String.format("%016x", game.titleId).lowercase().substring(0, 8)}/${String.format("%016x", game.titleId).lowercase().substring(8)}/data/00000001", + saveDir = + basePath + + "/title/${String.format( + "%016x", + game.titleId + ).lowercase().substring( + 0, + 8 + )}/${String.format( + "%016x", + game.titleId + ).lowercase().substring(8)}/data/00000001", modsDir = "load/mods/${String.format("%016X", game.titleId)}", texturesDir = "load/textures/${String.format("%016X", game.titleId)}", - appDir = game.path.substringBeforeLast("/").split("/").filter { it.isNotEmpty() }.joinToString("/"), - dlcDir = basePath + "/title/0004008c/${String.format("%016x", game.titleId).lowercase().substring(8)}/content", - updatesDir = basePath + "/title/0004000e/${String.format("%016x", game.titleId).lowercase().substring(8)}/content", - extraDir = basePath + "/extdata/00000000/${String.format("%016X", game.titleId).substring(8, 14).padStart(8, '0')}" + appDir = game.path.substringBeforeLast("/").split("/").filter { + it.isNotEmpty() + }.joinToString("/"), + dlcDir = + basePath + + "/title/0004008c/${String.format( + "%016x", + game.titleId + ).lowercase().substring(8)}/content", + updatesDir = + basePath + + "/title/0004000e/${String.format( + "%016x", + game.titleId + ).lowercase().substring(8)}/content", + extraDir = + basePath + + "/extdata/00000000/${String.format( + "%016X", + game.titleId + ).substring(8, 14).padStart(8, '0')}" ) } @@ -299,13 +332,36 @@ class GameAdapter( .setType("*/*") val uri = when (menuItem.itemId) { - R.id.game_context_open_app -> CitraApplication.documentsTree.folderUriHelper(dirs.appDir) - R.id.game_context_open_save_dir -> CitraApplication.documentsTree.folderUriHelper(dirs.saveDir) - R.id.game_context_open_updates -> CitraApplication.documentsTree.folderUriHelper(dirs.updatesDir) - R.id.game_context_open_dlc -> CitraApplication.documentsTree.folderUriHelper(dirs.dlcDir) - R.id.game_context_open_extra -> CitraApplication.documentsTree.folderUriHelper(dirs.extraDir) - R.id.game_context_open_textures -> CitraApplication.documentsTree.folderUriHelper(dirs.texturesDir, true) - R.id.game_context_open_mods -> CitraApplication.documentsTree.folderUriHelper(dirs.modsDir, true) + R.id.game_context_open_app -> CitraApplication.documentsTree.folderUriHelper( + dirs.appDir + ) + + R.id.game_context_open_save_dir -> CitraApplication.documentsTree.folderUriHelper( + dirs.saveDir + ) + + R.id.game_context_open_updates -> CitraApplication.documentsTree.folderUriHelper( + dirs.updatesDir + ) + + R.id.game_context_open_dlc -> CitraApplication.documentsTree.folderUriHelper( + dirs.dlcDir + ) + + R.id.game_context_open_extra -> CitraApplication.documentsTree.folderUriHelper( + dirs.extraDir + ) + + R.id.game_context_open_textures -> CitraApplication.documentsTree.folderUriHelper( + dirs.texturesDir, + true + ) + + R.id.game_context_open_mods -> CitraApplication.documentsTree.folderUriHelper( + dirs.modsDir, + true + ) + else -> null } @@ -319,7 +375,11 @@ class GameAdapter( popup.show() } - private fun showUninstallContextMenu(view: View, game: Game, bottomSheetDialog: BottomSheetDialog) { + private fun showUninstallContextMenu( + view: View, + game: Game, + bottomSheetDialog: BottomSheetDialog + ) { val dirs = getGameDirectories(game) val popup = PopupMenu(view.context, view).apply { menuInflater.inflate(R.menu.game_context_menu_uninstall, menu) @@ -342,16 +402,38 @@ class GameAdapter( popup.setOnMenuItemClickListener { menuItem -> val uninstallAction: () -> Unit = { when (menuItem.itemId) { - R.id.game_context_uninstall -> NativeLibrary.uninstallTitle(titleId, game.mediaType) - R.id.game_context_uninstall_dlc -> NativeLibrary.uninstallTitle(dlcTitleId, Game.MediaType.SDMC) - R.id.game_context_uninstall_updates -> NativeLibrary.uninstallTitle(updateTitleId, Game.MediaType.SDMC) + R.id.game_context_uninstall -> NativeLibrary.uninstallTitle( + titleId, + game.mediaType + ) + + R.id.game_context_uninstall_dlc -> NativeLibrary.uninstallTitle( + dlcTitleId, + Game.MediaType.SDMC + ) + + R.id.game_context_uninstall_updates -> NativeLibrary.uninstallTitle( + updateTitleId, + Game.MediaType.SDMC + ) } ViewModelProvider(activity)[GamesViewModel::class.java].reloadGames(true) bottomSheetDialog.dismiss() } - if (menuItem.itemId in listOf(R.id.game_context_uninstall, R.id.game_context_uninstall_dlc, R.id.game_context_uninstall_updates)) { - IndeterminateProgressDialogFragment.newInstance(activity, R.string.uninstalling, false, uninstallAction) + if (menuItem.itemId in + listOf( + R.id.game_context_uninstall, + R.id.game_context_uninstall_dlc, + R.id.game_context_uninstall_updates + ) + ) { + IndeterminateProgressDialogFragment.newInstance( + activity, + R.string.uninstalling, + false, + uninstallAction + ) .show(activity.supportFragmentManager, IndeterminateProgressDialogFragment.TAG) true } else { @@ -362,7 +444,12 @@ class GameAdapter( popup.show() } - private fun showAboutGameDialog(context: Context, game: Game, holder: GameViewHolder, view: View) { + private fun showAboutGameDialog( + context: Context, + game: Game, + holder: GameViewHolder, + view: View + ) { val bottomSheetView = inflater.inflate(R.layout.dialog_about_game, null) val bottomSheetDialog = BottomSheetDialog(context) @@ -374,12 +461,22 @@ class GameAdapter( bottomSheetView.findViewById(R.id.about_game_title).text = game.title bottomSheetView.findViewById(R.id.about_game_company).text = game.company bottomSheetView.findViewById(R.id.about_game_region).text = game.regions - bottomSheetView.findViewById(R.id.about_game_id).text = context.getString(R.string.game_context_id) + " " + String.format("%016X", game.titleId) - bottomSheetView.findViewById(R.id.about_game_filename).text = context.getString(R.string.game_context_file) + " " + game.filename - bottomSheetView.findViewById(R.id.about_game_filetype).text = context.getString(R.string.game_context_type) + " " + game.fileType + bottomSheetView.findViewById(R.id.about_game_id).text = + context.getString(R.string.game_context_id) + " " + String.format("%016X", game.titleId) + bottomSheetView.findViewById(R.id.about_game_filename).text = + context.getString(R.string.game_context_file) + " " + game.filename + bottomSheetView.findViewById(R.id.about_game_filetype).text = + context.getString(R.string.game_context_type) + " " + game.fileType - val insertButton = bottomSheetView.findViewById(R.id.insert_cartridge_button) - insertButton.text = if (inserted) { context.getString(R.string.game_context_eject) } else { context.getString(R.string.game_context_insert) } + val insertButton = bottomSheetView.findViewById( + R.id.insert_cartridge_button + ) + insertButton.text = + if (inserted) { + context.getString(R.string.game_context_eject) + } else { + context.getString(R.string.game_context_insert) + } insertButton.visibility = if (insertable) View.VISIBLE else View.GONE insertButton.setOnClickListener { if (inserted) { @@ -420,7 +517,7 @@ class GameAdapter( val preferences = PreferenceManager.getDefaultSharedPreferences(context) // Default to false for zoomed in shortcut icons - preferences.edit() { + preferences.edit { putBoolean( "shouldStretchIcon", false @@ -452,7 +549,11 @@ class GameAdapter( .setPositiveButton(android.R.string.ok) { _, _ -> val shortcutName = dialogShortcutBinding!!.shortcutNameInput.text.toString() if (shortcutName.isEmpty()) { - Toast.makeText(context, R.string.shortcut_name_empty, Toast.LENGTH_LONG).show() + Toast.makeText( + context, + R.string.shortcut_name_empty, + Toast.LENGTH_LONG + ).show() return@setPositiveButton } val iconBitmap = (dialogShortcutBinding!!.shortcutIcon.drawable as BitmapDrawable).bitmap @@ -463,9 +564,11 @@ class GameAdapter( val shortcut = ShortcutInfo.Builder(context, shortcutName) .setShortLabel(shortcutName) .setIcon(icon) - .setIntent(game.launchIntent.apply { - putExtra("launchedFromShortcut", true) - }) + .setIntent( + game.launchIntent.apply { + putExtra("launchedFromShortcut", true) + } + ) .build() shortcutManager?.requestPinShortcut(shortcut, null) @@ -486,7 +589,9 @@ class GameAdapter( bottomSheetDialog.dismiss() } - val compressDecompressButton = bottomSheetView.findViewById(R.id.compress_decompress) + val compressDecompressButton = bottomSheetView.findViewById( + R.id.compress_decompress + ) if (game.isInstalled) { compressDecompressButton.setOnClickListener { Toast.makeText( @@ -499,31 +604,42 @@ class GameAdapter( } else { compressDecompressButton.setOnClickListener { val shouldCompress = !game.isCompressed - val recommendedExt = NativeLibrary.getRecommendedExtension(holder.game.path, shouldCompress) + val recommendedExt = NativeLibrary.getRecommendedExtension( + holder.game.path, + shouldCompress + ) val baseName = holder.game.filename.substringBeforeLast('.') - onRequestCompressOrDecompress?.invoke(holder.game.path, "$baseName.$recommendedExt", shouldCompress) + onRequestCompressOrDecompress?.invoke( + holder.game.path, + "$baseName.$recommendedExt", + shouldCompress + ) bottomSheetDialog.dismiss() } } - compressDecompressButton.text = context.getString(if (!game.isCompressed) R.string.compress else R.string.decompress) + compressDecompressButton.text = + context.getString(if (!game.isCompressed) R.string.compress else R.string.decompress) bottomSheetView.findViewById(R.id.menu_button_open).setOnClickListener { showOpenContextMenu(it, game) } - bottomSheetView.findViewById(R.id.menu_button_uninstall).setOnClickListener { + bottomSheetView.findViewById( + R.id.menu_button_uninstall + ).setOnClickListener { showUninstallContextMenu(it, game, bottomSheetDialog) } bottomSheetView.findViewById(R.id.delete_cache).setOnClickListener { - val options = arrayOf(context.getString(R.string.vulkan), context.getString(R.string.opengles)) + val options = + arrayOf(context.getString(R.string.vulkan), context.getString(R.string.opengles)) var selectedIndex = -1 val dialog = MaterialAlertDialogBuilder(context) .setTitle(R.string.delete_cache_select_backend) .setSingleChoiceItems(options, -1) { dialog, which -> selectedIndex = which } - .setPositiveButton(android.R.string.ok) {_, _ -> + .setPositiveButton(android.R.string.ok) { _, _ -> val progToast = Toast.makeText( CitraApplication.appContext, R.string.deleting_shader_cache, @@ -532,11 +648,11 @@ class GameAdapter( progToast.show() activity.lifecycleScope.launch(Dispatchers.IO) { - when (selectedIndex) { 0 -> { NativeLibrary.deleteVulkanShaderCache(game.titleId) } + 1 -> { NativeLibrary.deleteOpenGLShaderCache(game.titleId) } @@ -620,10 +736,8 @@ class GameAdapter( } } - private fun isValidGame(extension: String): Boolean { - return Game.badExtensions.stream() - .noneMatch { extension == it.lowercase() } - } + private fun isValidGame(extension: String): Boolean = Game.badExtensions.stream() + .noneMatch { extension == it.lowercase() } private class DiffCallback : DiffUtil.ItemCallback() { override fun areItemsTheSame(oldItem: Game, newItem: Game): Boolean { @@ -632,8 +746,6 @@ class GameAdapter( return oldItem.titleId == newItem.titleId && oldItem.title == newItem.title } - override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean { - return oldItem == newItem - } + override fun areContentsTheSame(oldItem: Game, newItem: Game): Boolean = oldItem == newItem } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/adapters/HomeSettingAdapter.kt b/src/android/app/src/main/java/org/citra/citra_emu/adapters/HomeSettingAdapter.kt index f90c65e77..8d3b5bf96 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/adapters/HomeSettingAdapter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/adapters/HomeSettingAdapter.kt @@ -29,7 +29,8 @@ class HomeSettingAdapter( private val activity: AppCompatActivity, private val viewLifecycle: LifecycleOwner, var options: List -) : RecyclerView.Adapter(), View.OnClickListener { +) : RecyclerView.Adapter(), + View.OnClickListener { override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): HomeOptionViewHolder { val binding = CardHomeOptionBinding.inflate(LayoutInflater.from(parent.context), parent, false) @@ -37,9 +38,7 @@ class HomeSettingAdapter( return HomeOptionViewHolder(binding) } - override fun getItemCount(): Int { - return options.size - } + override fun getItemCount(): Int = options.size override fun onBindViewHolder(holder: HomeOptionViewHolder, position: Int) { holder.bind(options[position]) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/adapters/SetupAdapter.kt b/src/android/app/src/main/java/org/citra/citra_emu/adapters/SetupAdapter.kt index 24761519c..017bfef7d 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/adapters/SetupAdapter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/adapters/SetupAdapter.kt @@ -14,12 +14,12 @@ import androidx.appcompat.app.AppCompatActivity import androidx.core.content.res.ResourcesCompat import androidx.recyclerview.widget.RecyclerView import com.google.android.material.button.MaterialButton +import org.citra.citra_emu.R import org.citra.citra_emu.databinding.PageSetupBinding import org.citra.citra_emu.model.ButtonState import org.citra.citra_emu.model.PageState import org.citra.citra_emu.model.SetupCallback import org.citra.citra_emu.model.SetupPage -import org.citra.citra_emu.R import org.citra.citra_emu.utils.ViewUtils class SetupAdapter(val activity: AppCompatActivity, val pages: List) : @@ -35,7 +35,8 @@ class SetupAdapter(val activity: AppCompatActivity, val pages: List) holder.bind(pages[position]) inner class SetupPageViewHolder(val binding: PageSetupBinding) : - RecyclerView.ViewHolder(binding.root), SetupCallback { + RecyclerView.ViewHolder(binding.root), + SetupCallback { lateinit var page: SetupPage init { @@ -49,7 +50,9 @@ class SetupAdapter(val activity: AppCompatActivity, val pages: List) onStepCompleted(0, pageFullyCompleted = true) } - if (page.pageButtons != null && page.pageSteps.invoke() != PageState.PAGE_STEPS_COMPLETE) { + if (page.pageButtons != null && + page.pageSteps.invoke() != PageState.PAGE_STEPS_COMPLETE + ) { for (pageButton in page.pageButtons) { val pageButtonView = LayoutInflater.from(activity) .inflate( @@ -108,9 +111,17 @@ class SetupAdapter(val activity: AppCompatActivity, val pages: List) .alpha(0.38f) .setDuration(200) .start() - button.setTextColor(button.context.getColor(com.google.android.material.R.color.material_on_surface_disabled)) + button.setTextColor( + button.context.getColor( + com.google.android.material.R.color.material_on_surface_disabled + ) + ) button.iconTint = - ColorStateList.valueOf(button.context.getColor(com.google.android.material.R.color.material_on_surface_disabled)) + ColorStateList.valueOf( + button.context.getColor( + com.google.android.material.R.color.material_on_surface_disabled + ) + ) } } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/applets/MiiSelector.kt b/src/android/app/src/main/java/org/citra/citra_emu/applets/MiiSelector.kt index e7dbfbf66..2bcaae279 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/applets/MiiSelector.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/applets/MiiSelector.kt @@ -5,9 +5,9 @@ package org.citra.citra_emu.applets import androidx.annotation.Keep +import java.io.Serializable import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.fragments.MiiSelectorDialogFragment -import java.io.Serializable @Keep object MiiSelector { @@ -43,5 +43,5 @@ object MiiSelector { lateinit var miiNames: Array } - class MiiSelectorData (var returnCode: Long, var index: Int) + class MiiSelectorData(var returnCode: Long, var index: Int) } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/applets/SoftwareKeyboard.kt b/src/android/app/src/main/java/org/citra/citra_emu/applets/SoftwareKeyboard.kt index f334366eb..dd91e9c7e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/applets/SoftwareKeyboard.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/applets/SoftwareKeyboard.kt @@ -7,13 +7,13 @@ package org.citra.citra_emu.applets import android.text.InputFilter import android.text.Spanned import androidx.annotation.Keep +import java.io.Serializable import org.citra.citra_emu.CitraApplication.Companion.appContext import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.R import org.citra.citra_emu.fragments.KeyboardDialogFragment import org.citra.citra_emu.fragments.MessageDialogFragment import org.citra.citra_emu.utils.Log -import java.io.Serializable @Keep object SoftwareKeyboard { @@ -81,17 +81,17 @@ object SoftwareKeyboard { private external fun ValidateFilters(text: String): ValidationError external fun ValidateInput(text: String): ValidationError - /// Corresponds to Frontend::ButtonConfig + // / Corresponds to Frontend::ButtonConfig interface ButtonConfig { companion object { - const val Single = 0 /// Ok button - const val Dual = 1 /// Cancel | Ok buttons - const val Triple = 2 /// Cancel | I Forgot | Ok buttons - const val None = 3 /// No button (returned by swkbdInputText in special cases) + const val Single = 0 // / Ok button + const val Dual = 1 // / Cancel | Ok buttons + const val Triple = 2 // / Cancel | I Forgot | Ok buttons + const val None = 3 // / No button (returned by swkbdInputText in special cases) } } - /// Corresponds to Frontend::ValidationError + // / Corresponds to Frontend::ValidationError enum class ValidationError { None, @@ -128,7 +128,7 @@ object SoftwareKeyboard { lateinit var buttonText: Array } - /// Corresponds to Frontend::KeyboardData + // / Corresponds to Frontend::KeyboardData class KeyboardData(var button: Int, var text: String) class Filter : InputFilter { override fun filter( diff --git a/src/android/app/src/main/java/org/citra/citra_emu/contracts/OpenFileResultContract.kt b/src/android/app/src/main/java/org/citra/citra_emu/contracts/OpenFileResultContract.kt index 401518093..c87ef4b5e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/contracts/OpenFileResultContract.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/contracts/OpenFileResultContract.kt @@ -9,11 +9,10 @@ import android.content.Intent import androidx.activity.result.contract.ActivityResultContract class OpenFileResultContract : ActivityResultContract() { - override fun createIntent(context: Context, input: Boolean?): Intent { - return Intent(Intent.ACTION_OPEN_DOCUMENT) + override fun createIntent(context: Context, input: Boolean?): Intent = + Intent(Intent.ACTION_OPEN_DOCUMENT) .setType("application/octet-stream") .putExtra(Intent.EXTRA_ALLOW_MULTIPLE, input) - } override fun parseResult(resultCode: Int, intent: Intent?): Intent? = intent } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt index d717e87e6..a48e2f3bf 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenAdjustmentUtil.kt @@ -4,15 +4,15 @@ package org.citra.citra_emu.display +import android.app.Activity import android.content.Context import android.content.pm.ActivityInfo -import android.app.Activity import android.view.WindowManager import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.BooleanSetting -import org.citra.citra_emu.features.settings.model.IntSetting import org.citra.citra_emu.features.settings.model.IntListSetting +import org.citra.citra_emu.features.settings.model.IntSetting import org.citra.citra_emu.features.settings.model.Settings import org.citra.citra_emu.features.settings.utils.SettingsFile import org.citra.citra_emu.utils.EmulationMenuSettings @@ -20,7 +20,7 @@ import org.citra.citra_emu.utils.EmulationMenuSettings class ScreenAdjustmentUtil( private val context: Context, private val windowManager: WindowManager, - private val settings: Settings, + private val settings: Settings ) { fun swapScreen() { val isEnabled = !EmulationMenuSettings.swapScreens @@ -34,14 +34,15 @@ class ScreenAdjustmentUtil( } fun cycleLayouts() { - - val landscapeLayoutsToCycle = IntListSetting.LAYOUTS_TO_CYCLE.list; + val landscapeLayoutsToCycle = IntListSetting.LAYOUTS_TO_CYCLE.list val landscapeValues = - if (landscapeLayoutsToCycle.isNotEmpty()) + if (landscapeLayoutsToCycle.isNotEmpty()) { landscapeLayoutsToCycle.toIntArray() - else context.resources.getIntArray( - R.array.landscapeValues - ) + } else { + context.resources.getIntArray( + R.array.landscapeValues + ) + } val portraitValues = context.resources.getIntArray(R.array.portraitValues) if (NativeLibrary.isPortraitMode) { @@ -73,7 +74,7 @@ class ScreenAdjustmentUtil( fun changeSecondaryOrientation(layoutOption: Int) { IntSetting.SECONDARY_DISPLAY_LAYOUT.int = layoutOption - settings.saveSetting(IntSetting.SECONDARY_DISPLAY_LAYOUT,SettingsFile.FILE_NAME_CONFIG) + settings.saveSetting(IntSetting.SECONDARY_DISPLAY_LAYOUT, SettingsFile.FILE_NAME_CONFIG) NativeLibrary.reloadSettings() NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) } @@ -102,6 +103,5 @@ class ScreenAdjustmentUtil( settings.saveSetting(BooleanSetting.UPRIGHT_SCREEN, SettingsFile.FILE_NAME_CONFIG) NativeLibrary.reloadSettings() NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) - } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt index 9e72f3894..09e1e3532 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/display/ScreenLayout.kt @@ -13,11 +13,8 @@ enum class ScreenLayout(val int: Int) { HYBRID_SCREEN(4), CUSTOM_LAYOUT(5); - companion object { - fun from(int: Int): ScreenLayout { - return entries.firstOrNull { it.int == int } ?: LARGE_SCREEN - } + fun from(int: Int): ScreenLayout = entries.firstOrNull { it.int == int } ?: LARGE_SCREEN } } @@ -32,9 +29,7 @@ enum class SmallScreenPosition(val int: Int) { BELOW(7); companion object { - fun from(int: Int): SmallScreenPosition { - return entries.firstOrNull { it.int == int } ?: TOP_RIGHT - } + fun from(int: Int): SmallScreenPosition = entries.firstOrNull { it.int == int } ?: TOP_RIGHT } } @@ -45,9 +40,8 @@ enum class PortraitScreenLayout(val int: Int) { ORIGINAL(2); companion object { - fun from(int: Int): PortraitScreenLayout { - return entries.firstOrNull { it.int == int } ?: TOP_FULL_WIDTH - } + fun from(int: Int): PortraitScreenLayout = + entries.firstOrNull { it.int == int } ?: TOP_FULL_WIDTH } } @@ -66,9 +60,7 @@ enum class SecondaryDisplayLayout(val int: Int) { ; companion object { - fun from(int: Int): SecondaryDisplayLayout { - return entries.firstOrNull { it.int == int } ?: NONE - } + fun from(int: Int): SecondaryDisplayLayout = entries.firstOrNull { it.int == int } ?: NONE } } @@ -81,26 +73,22 @@ enum class StereoWhichDisplay(val int: Int) { SECONDARY_ONLY(3); companion object { - fun from(int: Int): StereoWhichDisplay { - return entries.firstOrNull { it.int == int } ?: NONE - } + fun from(int: Int): StereoWhichDisplay = entries.firstOrNull { it.int == int } ?: NONE } } enum class StereoMode(val int: Int) { - // These must match what is defined in src/common/settings.h + // These must match what is defined in src/common/settings.h OFF(0), SIDE_BY_SIDE(1), SIDE_BY_SIDE_FULL(2), ANAGLYPH(3), INTERLACED(4), - REVERSE_INTERLACED (5), - CARDBOARD_VR (6); + REVERSE_INTERLACED(5), + CARDBOARD_VR(6); companion object { - fun from(int: Int): StereoMode { - return entries.firstOrNull { it.int == int } ?: OFF - } + fun from(int: Int): StereoMode = entries.firstOrNull { it.int == int } ?: OFF } -} \ No newline at end of file +} diff --git a/src/android/app/src/main/java/org/citra/citra_emu/display/SecondaryDisplay.kt b/src/android/app/src/main/java/org/citra/citra_emu/display/SecondaryDisplay.kt index 0a3eee316..335e715d6 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/display/SecondaryDisplay.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/display/SecondaryDisplay.kt @@ -15,9 +15,9 @@ import android.view.MotionEvent import android.view.SurfaceHolder import android.view.SurfaceView import android.view.WindowManager -import org.citra.citra_emu.features.settings.model.IntSetting import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.features.settings.model.BooleanSetting +import org.citra.citra_emu.features.settings.model.IntSetting import org.citra.citra_emu.utils.Log class SecondaryDisplay(val context: Context) : DisplayManager.DisplayListener { @@ -55,26 +55,27 @@ class SecondaryDisplay(val context: Context) : DisplayManager.DisplayListener { NativeLibrary.secondarySurfaceDestroyed() } - private fun getSecondaryDisplays(): List { - val dm = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager - val currentDisplayId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { - context.display.displayId - } else { - @Suppress("DEPRECATION") - (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager) - .defaultDisplay.displayId - } + private fun getSecondaryDisplays(): List { + val dm = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager + val currentDisplayId = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { + context.display.displayId + } else { + @Suppress("DEPRECATION") + (context.getSystemService(Context.WINDOW_SERVICE) as WindowManager) + .defaultDisplay.displayId + } val displays = dm.displays - val presDisplays = dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION); + val presDisplays = dm.getDisplays(DisplayManager.DISPLAY_CATEGORY_PRESENTATION) return displays.filter { val isPresentable = presDisplays.any { pd -> pd.displayId == it.displayId } - val isNotDefaultOrPresentable = (it != null && it.displayId != Display.DEFAULT_DISPLAY) || isPresentable + val isNotDefaultOrPresentable = + (it != null && it.displayId != Display.DEFAULT_DISPLAY) || isPresentable isNotDefaultOrPresentable && - it.displayId != currentDisplayId && - it.name != "HiddenDisplay" && - it.state != Display.STATE_OFF && - it.isValid + it.displayId != currentDisplayId && + it.name != "HiddenDisplay" && + it.state != Display.STATE_OFF && + it.isValid } } @@ -88,23 +89,26 @@ class SecondaryDisplay(val context: Context) : DisplayManager.DisplayListener { // Theoretically, the NONE option is no longer selectable, but // I am leaving this in for backwards compatibility IntSetting.SECONDARY_DISPLAY_LAYOUT.int == SecondaryDisplayLayout.NONE.int || - ! BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean + !BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean ) { currentDisplayId = -1 vd.display - } else if (preferredDisplayId >=0 && availableDisplays.any { it.displayId == preferredDisplayId }) { + } else if (preferredDisplayId >= 0 && + availableDisplays.any { it.displayId == preferredDisplayId } + ) { currentDisplayId = preferredDisplayId availableDisplays.first { it.displayId == preferredDisplayId } } else { val dm = context.getSystemService(Context.DISPLAY_SERVICE) as DisplayManager - val default = dm.displays.first {it.displayId == Display.DEFAULT_DISPLAY} + val default = dm.displays.first { it.displayId == Display.DEFAULT_DISPLAY } // prioritize displays that have a different name from the default display, as // some devices such as the Odin 2 create a permanent virtual display with the same // name as the default display that should be skipped in most cases - currentDisplayId = availableDisplays.firstOrNull{ - it.name != default.name && !it.name.contains("Built",true)}?.displayId ?: - availableDisplays[0].displayId - availableDisplays.first{ it.displayId == currentDisplayId } + currentDisplayId = availableDisplays.firstOrNull { + it.name != default.name && !it.name.contains("Built", true) + }?.displayId + ?: availableDisplays[0].displayId + availableDisplays.first { it.displayId == currentDisplayId } } // if our presentation is already on the right display, ignore @@ -151,7 +155,9 @@ class SecondaryDisplay(val context: Context) : DisplayManager.DisplayListener { } } class SecondaryDisplayPresentation( - context: Context, display: Display, val parent: SecondaryDisplay + context: Context, + display: Display, + val parent: SecondaryDisplay ) : Presentation(context, display) { private lateinit var surfaceView: SurfaceView private var touchscreenPointerId = -1 @@ -173,9 +179,12 @@ class SecondaryDisplayPresentation( } override fun surfaceChanged( - holder: SurfaceHolder, format: Int, width: Int, height: Int + holder: SurfaceHolder, + format: Int, + width: Int, + height: Int ) { - Log.debug("SecondaryDisplay Surface changed: ${width}x${height}") + Log.debug("SecondaryDisplay Surface changed: ${width}x$height") parent.updateSurface() } @@ -225,7 +234,5 @@ class SecondaryDisplayPresentation( } // Publicly accessible method to get the SurfaceHolder - fun getSurfaceHolder(): SurfaceHolder { - return surfaceView.holder - } + fun getSurfaceHolder(): SurfaceHolder = surfaceView.holder } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/model/CheatsViewModel.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/model/CheatsViewModel.kt index e794fe588..31b2e2531 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/model/CheatsViewModel.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/model/CheatsViewModel.kt @@ -53,7 +53,7 @@ class CheatsViewModel : ViewModel() { private var selectedCheatPosition = -1 fun initialize(titleId_: Long) { - titleId = titleId_; + titleId = titleId_ load() } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatDetailsFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatDetailsFragment.kt index 2357335a9..c75eeeebd 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatDetailsFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatDetailsFragment.kt @@ -170,24 +170,23 @@ class CheatDetailsFragment : Fragment() { binding.buttonOk.visibility = if (isEditing) View.VISIBLE else View.GONE } - private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener( - binding.root - ) { _: View?, windowInsets: WindowInsetsCompat -> - val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener( + binding.root + ) { _: View?, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) - val leftInsets = barInsets.left + cutoutInsets.left - val rightInsets = barInsets.right + cutoutInsets.right + val leftInsets = barInsets.left + cutoutInsets.left + val rightInsets = barInsets.right + cutoutInsets.right - val mlpAppBar = binding.toolbarCheatDetails.layoutParams as ViewGroup.MarginLayoutParams - mlpAppBar.leftMargin = leftInsets - mlpAppBar.rightMargin = rightInsets - binding.toolbarCheatDetails.layoutParams = mlpAppBar + val mlpAppBar = binding.toolbarCheatDetails.layoutParams as ViewGroup.MarginLayoutParams + mlpAppBar.leftMargin = leftInsets + mlpAppBar.rightMargin = rightInsets + binding.toolbarCheatDetails.layoutParams = mlpAppBar - binding.scrollView.updatePadding(left = leftInsets, right = rightInsets) - binding.buttonContainer.updatePadding(left = leftInsets, right = rightInsets) + binding.scrollView.updatePadding(left = leftInsets, right = rightInsets) + binding.buttonContainer.updatePadding(left = leftInsets, right = rightInsets) - windowInsets - } + windowInsets + } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatListFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatListFragment.kt index c71ba99fa..aaf998cb2 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatListFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatListFragment.kt @@ -128,7 +128,7 @@ class CheatListFragment : Fragment() { left = leftInsets, right = rightInsets, bottom = barInsets.bottom + - resources.getDimensionPixelSize(R.dimen.spacing_fab_list) + resources.getDimensionPixelSize(R.dimen.spacing_fab_list) ) val mlpFab = binding.fab.layoutParams as MarginLayoutParams diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatsAdapter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatsAdapter.kt index 960b14f1d..d5e20bfdb 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatsAdapter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatsAdapter.kt @@ -41,7 +41,8 @@ class CheatsAdapter( } inner class CheatViewHolder(private val binding: ListItemCheatBinding) : - RecyclerView.ViewHolder(binding.root), View.OnClickListener, + RecyclerView.ViewHolder(binding.root), + View.OnClickListener, CompoundButton.OnCheckedChangeListener { private lateinit var viewModel: CheatsViewModel private lateinit var cheat: Cheat diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatsFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatsFragment.kt index 0c446cfd8..f0a47b5d8 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatsFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/cheats/ui/CheatsFragment.kt @@ -32,7 +32,9 @@ import org.citra.citra_emu.ui.TwoPaneOnBackPressedCallback import org.citra.citra_emu.ui.main.MainActivity import org.citra.citra_emu.viewmodel.HomeViewModel -class CheatsFragment : Fragment(), SlidingPaneLayout.PanelSlideListener { +class CheatsFragment : + Fragment(), + SlidingPaneLayout.PanelSlideListener { private var cheatListLastFocus: View? = null private var cheatDetailsLastFocus: View? = null @@ -238,7 +240,8 @@ class CheatsFragment : Fragment(), SlidingPaneLayout.PanelSlideListener { binding.cheatDetailsContainer.layoutParams = mlpDetails return insets } - }) + } + ) } } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/Hotkey.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/Hotkey.kt index e2319a7e4..ac649d2b5 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/Hotkey.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/Hotkey.kt @@ -12,5 +12,5 @@ enum class Hotkey(val button: Int) { QUICKSAVE(10005), QUICKLOAD(10006), TURBO_LIMIT(10007), - ENABLE(10008); + ENABLE(10008) } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/HotkeyUtility.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/HotkeyUtility.kt index d01d5f769..80fd4e2eb 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/HotkeyUtility.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/hotkeys/HotkeyUtility.kt @@ -11,11 +11,11 @@ import androidx.preference.PreferenceManager import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.R +import org.citra.citra_emu.display.ScreenAdjustmentUtil +import org.citra.citra_emu.features.settings.model.Settings +import org.citra.citra_emu.features.settings.model.view.InputBindingSetting import org.citra.citra_emu.utils.EmulationLifecycleUtil import org.citra.citra_emu.utils.TurboHelper -import org.citra.citra_emu.display.ScreenAdjustmentUtil -import org.citra.citra_emu.features.settings.model.view.InputBindingSetting -import org.citra.citra_emu.features.settings.model.Settings class HotkeyUtility( private val screenAdjustmentUtil: ScreenAdjustmentUtil, @@ -41,7 +41,7 @@ class HotkeyUtility( // Now process all internal buttons associated with this keypress for (button in buttonSet) { currentlyPressedButtons.add(button) - //option 1 - this is the enable command, which was already handled + // option 1 - this is the enable command, which was already handled if (button == Hotkey.ENABLE.button) { handled = true } @@ -74,7 +74,8 @@ class HotkeyUtility( val thisKeyIsHotkey = !thisKeyIsEnableButton && Hotkey.entries.any { buttonSet.contains(it.button) } if (thisKeyIsEnableButton) { - handled = true; hotkeyIsEnabled = false + handled = true + hotkeyIsEnabled = false } for (button in buttonSet) { @@ -109,10 +110,15 @@ class HotkeyUtility( fun handleHotkey(bindedButton: Int): Boolean { when (bindedButton) { Hotkey.SWAP_SCREEN.button -> screenAdjustmentUtil.swapScreen() + Hotkey.CYCLE_LAYOUT.button -> screenAdjustmentUtil.cycleLayouts() + Hotkey.CLOSE_GAME.button -> EmulationLifecycleUtil.closeGame() + Hotkey.PAUSE_OR_RESUME.button -> EmulationLifecycleUtil.pauseOrResume() + Hotkey.TURBO_LIMIT.button -> TurboHelper.toggleTurbo(true) + Hotkey.QUICKSAVE.button -> { NativeLibrary.saveState(NativeLibrary.QUICKSAVE_SLOT) Toast.makeText( diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt index f9ff306f8..cd841b3f7 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/SettingKeys.kt @@ -142,4 +142,4 @@ object SettingKeys { external fun screen_orientation(): String external fun performance_overlay_position(): String external fun enable_secondary_display(): String -} \ No newline at end of file +} diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt index cda0a5f2f..c6ef0ae31 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/BooleanSetting.kt @@ -20,19 +20,63 @@ enum class BooleanSetting( SWAP_SCREEN(SettingKeys.swap_screen(), Settings.SECTION_LAYOUT, false), INSTANT_DEBUG_LOG(SettingKeys.instant_debug_log(), Settings.SECTION_DEBUG, false), ENABLE_RPC_SERVER(SettingKeys.enable_rpc_server(), Settings.SECTION_DEBUG, false), - TOGGLE_UNIQUE_DATA_CONSOLE_TYPE(SettingKeys.toggle_unique_data_console_type(), Settings.SECTION_DEBUG, false), - SWAP_EYES_3D(SettingKeys.swap_eyes_3d(),Settings.SECTION_RENDERER, false), + TOGGLE_UNIQUE_DATA_CONSOLE_TYPE( + SettingKeys.toggle_unique_data_console_type(), + Settings.SECTION_DEBUG, + false + ), + SWAP_EYES_3D(SettingKeys.swap_eyes_3d(), Settings.SECTION_RENDERER, false), PERF_OVERLAY_ENABLE(SettingKeys.performance_overlay_enable(), Settings.SECTION_LAYOUT, false), - PERF_OVERLAY_SHOW_FPS(SettingKeys.performance_overlay_show_fps(), Settings.SECTION_LAYOUT, true), - PERF_OVERLAY_SHOW_FRAMETIME(SettingKeys.performance_overlay_show_frame_time(), Settings.SECTION_LAYOUT, false), - PERF_OVERLAY_SHOW_SPEED(SettingKeys.performance_overlay_show_speed(), Settings.SECTION_LAYOUT, false), - PERF_OVERLAY_SHOW_APP_RAM_USAGE(SettingKeys.performance_overlay_show_app_ram_usage(), Settings.SECTION_LAYOUT, false), - PERF_OVERLAY_SHOW_AVAILABLE_RAM(SettingKeys.performance_overlay_show_available_ram(), Settings.SECTION_LAYOUT, false), - PERF_OVERLAY_SHOW_BATTERY_TEMP(SettingKeys.performance_overlay_show_battery_temp(), Settings.SECTION_LAYOUT, false), - PERF_OVERLAY_BACKGROUND(SettingKeys.performance_overlay_background(), Settings.SECTION_LAYOUT, false), - DELAY_START_LLE_MODULES(SettingKeys.delay_start_for_lle_modules(), Settings.SECTION_DEBUG, true), - DETERMINISTIC_ASYNC_OPERATIONS(SettingKeys.deterministic_async_operations(), Settings.SECTION_DEBUG, false), - REQUIRED_ONLINE_LLE_MODULES(SettingKeys.enable_required_online_lle_modules(), Settings.SECTION_SYSTEM, false), + PERF_OVERLAY_SHOW_FPS( + SettingKeys.performance_overlay_show_fps(), + Settings.SECTION_LAYOUT, + true + ), + PERF_OVERLAY_SHOW_FRAMETIME( + SettingKeys.performance_overlay_show_frame_time(), + Settings.SECTION_LAYOUT, + false + ), + PERF_OVERLAY_SHOW_SPEED( + SettingKeys.performance_overlay_show_speed(), + Settings.SECTION_LAYOUT, + false + ), + PERF_OVERLAY_SHOW_APP_RAM_USAGE( + SettingKeys.performance_overlay_show_app_ram_usage(), + Settings.SECTION_LAYOUT, + false + ), + PERF_OVERLAY_SHOW_AVAILABLE_RAM( + SettingKeys.performance_overlay_show_available_ram(), + Settings.SECTION_LAYOUT, + false + ), + PERF_OVERLAY_SHOW_BATTERY_TEMP( + SettingKeys.performance_overlay_show_battery_temp(), + Settings.SECTION_LAYOUT, + false + ), + PERF_OVERLAY_BACKGROUND( + SettingKeys.performance_overlay_background(), + Settings.SECTION_LAYOUT, + false + ), + DELAY_START_LLE_MODULES( + SettingKeys.delay_start_for_lle_modules(), + Settings.SECTION_DEBUG, + true + ), + DETERMINISTIC_ASYNC_OPERATIONS( + SettingKeys.deterministic_async_operations(), + Settings.SECTION_DEBUG, + false + ), + REQUIRED_ONLINE_LLE_MODULES( + SettingKeys.enable_required_online_lle_modules(), + Settings.SECTION_SYSTEM, + false + ), LLE_APPLETS(SettingKeys.lle_applets(), Settings.SECTION_SYSTEM, false), NEW_3DS(SettingKeys.is_new_3ds(), Settings.SECTION_SYSTEM, true), LINEAR_FILTERING(SettingKeys.filter_mode(), Settings.SECTION_RENDERER, true), @@ -44,23 +88,43 @@ enum class BooleanSetting( PRELOAD_TEXTURES(SettingKeys.preload_textures(), Settings.SECTION_UTILITY, false), ENABLE_AUDIO_STRETCHING(SettingKeys.enable_audio_stretching(), Settings.SECTION_AUDIO, true), ENABLE_REALTIME_AUDIO(SettingKeys.enable_realtime_audio(), Settings.SECTION_AUDIO, false), - SIMULATE_HEADPHONES_PLUGGED(SettingKeys.simulate_headphones_plugged(), Settings.SECTION_AUDIO, false), + SIMULATE_HEADPHONES_PLUGGED( + SettingKeys.simulate_headphones_plugged(), + Settings.SECTION_AUDIO, + false + ), CPU_JIT(SettingKeys.use_cpu_jit(), Settings.SECTION_CORE, true), HW_SHADER(SettingKeys.use_hw_shader(), Settings.SECTION_RENDERER, true), SHADER_JIT(SettingKeys.use_shader_jit(), Settings.SECTION_RENDERER, true), VSYNC(SettingKeys.use_vsync(), Settings.SECTION_RENDERER, false), USE_FRAME_LIMIT(SettingKeys.use_frame_limit(), Settings.SECTION_RENDERER, true), DEBUG_RENDERER(SettingKeys.renderer_debug(), Settings.SECTION_DEBUG, false), - DISABLE_RIGHT_EYE_RENDER(SettingKeys.disable_right_eye_render(), Settings.SECTION_RENDERER, false), - USE_ARTIC_BASE_CONTROLLER(SettingKeys.use_artic_base_controller(), Settings.SECTION_CONTROLS, false), + DISABLE_RIGHT_EYE_RENDER( + SettingKeys.disable_right_eye_render(), + Settings.SECTION_RENDERER, + false + ), + USE_ARTIC_BASE_CONTROLLER( + SettingKeys.use_artic_base_controller(), + Settings.SECTION_CONTROLS, + false + ), UPRIGHT_SCREEN(SettingKeys.upright_screen(), Settings.SECTION_LAYOUT, false), - COMPRESS_INSTALLED_CIA_CONTENT(SettingKeys.compress_cia_installs(), Settings.SECTION_STORAGE, false), + COMPRESS_INSTALLED_CIA_CONTENT( + SettingKeys.compress_cia_installs(), + Settings.SECTION_STORAGE, + false + ), ASYNC_FS_OPERATIONS(SettingKeys.async_fs_operations(), Settings.SECTION_STORAGE, true), ANDROID_HIDE_IMAGES(SettingKeys.android_hide_images(), Settings.SECTION_MISC, false), APPLY_REGION_FREE_PATCH(SettingKeys.apply_region_free_patch(), Settings.SECTION_SYSTEM, true), USE_INTEGER_SCALING(SettingKeys.use_integer_scaling(), Settings.SECTION_RENDERER, false), ENABLE_SECONDARY_DISPLAY(SettingKeys.enable_secondary_display(), Settings.SECTION_LAYOUT, true), - SIMULATE_3DS_GPU_TIMINGS(SettingKeys.simulate_3ds_gpu_timings(), Settings.SECTION_RENDERER, true); + SIMULATE_3DS_GPU_TIMINGS( + SettingKeys.simulate_3ds_gpu_timings(), + Settings.SECTION_RENDERER, + true + ); override var boolean: Boolean = defaultValue @@ -80,7 +144,7 @@ enum class BooleanSetting( companion object { private val NOT_RUNTIME_EDITABLE = listOf( PLUGIN_LOADER, - ALLOW_PLUGIN_LOADER, + ALLOW_PLUGIN_LOADER, ASYNC_SHADERS, DELAY_START_LLE_MODULES, DETERMINISTIC_ASYNC_OPERATIONS, diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/FloatSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/FloatSetting.kt index c192677bd..80f5cc658 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/FloatSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/FloatSetting.kt @@ -11,8 +11,12 @@ enum class FloatSetting( override val section: String, override val defaultValue: Float ) : AbstractFloatSetting { - LARGE_SCREEN_PROPORTION(SettingKeys.large_screen_proportion(),Settings.SECTION_LAYOUT,2.25f), - SECOND_SCREEN_OPACITY(SettingKeys.custom_second_layer_opacity(), Settings.SECTION_RENDERER, 100f), + LARGE_SCREEN_PROPORTION(SettingKeys.large_screen_proportion(), Settings.SECTION_LAYOUT, 2.25f), + SECOND_SCREEN_OPACITY( + SettingKeys.custom_second_layer_opacity(), + Settings.SECTION_RENDERER, + 100f + ), BACKGROUND_RED(SettingKeys.bg_red(), Settings.SECTION_RENDERER, 0f), BACKGROUND_BLUE(SettingKeys.bg_blue(), Settings.SECTION_RENDERER, 0f), BACKGROUND_GREEN(SettingKeys.bg_green(), Settings.SECTION_RENDERER, 0f); diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntListSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntListSetting.kt index 479d77ce1..427193542 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntListSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntListSetting.kt @@ -13,10 +13,15 @@ enum class IntListSetting( val canBeEmpty: Boolean = true ) : AbstractListSetting { - LAYOUTS_TO_CYCLE(SettingKeys.layouts_to_cycle(), Settings.SECTION_LAYOUT, listOf(0, 1, 2, 3, 4, 5), canBeEmpty = false); + LAYOUTS_TO_CYCLE( + SettingKeys.layouts_to_cycle(), + Settings.SECTION_LAYOUT, + listOf(0, 1, 2, 3, 4, 5), + canBeEmpty = false + ); private var backingList: List = defaultValue - private var lastValidList : List = defaultValue + private var lastValidList: List = defaultValue override var list: List get() = backingList @@ -32,7 +37,6 @@ enum class IntListSetting( override val valueAsString: String get() = list.joinToString() - override val isRuntimeEditable: Boolean get() { for (setting in NOT_RUNTIME_EDITABLE) { @@ -46,8 +50,7 @@ enum class IntListSetting( companion object { private val NOT_RUNTIME_EDITABLE: List = emptyList() - fun from(key: String): IntListSetting? = - values().firstOrNull { it.key == key } + fun from(key: String): IntListSetting? = values().firstOrNull { it.key == key } fun clear() = values().forEach { it.list = it.defaultValue } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt index 5eb8944d5..a5ec7ea5a 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/IntSetting.kt @@ -26,26 +26,30 @@ enum class IntSetting( CARDBOARD_X_SHIFT(SettingKeys.cardboard_x_shift(), Settings.SECTION_LAYOUT, 0), CARDBOARD_Y_SHIFT(SettingKeys.cardboard_y_shift(), Settings.SECTION_LAYOUT, 0), SCREEN_LAYOUT(SettingKeys.layout_option(), Settings.SECTION_LAYOUT, 0), - SMALL_SCREEN_POSITION(SettingKeys.small_screen_position(),Settings.SECTION_LAYOUT,0), - LANDSCAPE_TOP_X(SettingKeys.custom_top_x(),Settings.SECTION_LAYOUT,0), - LANDSCAPE_TOP_Y(SettingKeys.custom_top_y(),Settings.SECTION_LAYOUT,0), - LANDSCAPE_TOP_WIDTH(SettingKeys.custom_top_width(),Settings.SECTION_LAYOUT,800), - LANDSCAPE_TOP_HEIGHT(SettingKeys.custom_top_height(),Settings.SECTION_LAYOUT,480), - LANDSCAPE_BOTTOM_X(SettingKeys.custom_bottom_x(),Settings.SECTION_LAYOUT,80), - LANDSCAPE_BOTTOM_Y(SettingKeys.custom_bottom_y(),Settings.SECTION_LAYOUT,480), - LANDSCAPE_BOTTOM_WIDTH(SettingKeys.custom_bottom_width(),Settings.SECTION_LAYOUT,640), - LANDSCAPE_BOTTOM_HEIGHT(SettingKeys.custom_bottom_height(),Settings.SECTION_LAYOUT,480), - SCREEN_GAP(SettingKeys.screen_gap(),Settings.SECTION_LAYOUT,0), - PORTRAIT_SCREEN_LAYOUT(SettingKeys.portrait_layout_option(),Settings.SECTION_LAYOUT,0), - SECONDARY_DISPLAY_LAYOUT(SettingKeys.secondary_display_layout(),Settings.SECTION_LAYOUT,4), - PORTRAIT_TOP_X(SettingKeys.custom_portrait_top_x(),Settings.SECTION_LAYOUT,0), - PORTRAIT_TOP_Y(SettingKeys.custom_portrait_top_y(),Settings.SECTION_LAYOUT,0), - PORTRAIT_TOP_WIDTH(SettingKeys.custom_portrait_top_width(),Settings.SECTION_LAYOUT,800), - PORTRAIT_TOP_HEIGHT(SettingKeys.custom_portrait_top_height(),Settings.SECTION_LAYOUT,480), - PORTRAIT_BOTTOM_X(SettingKeys.custom_portrait_bottom_x(),Settings.SECTION_LAYOUT,80), - PORTRAIT_BOTTOM_Y(SettingKeys.custom_portrait_bottom_y(),Settings.SECTION_LAYOUT,480), - PORTRAIT_BOTTOM_WIDTH(SettingKeys.custom_portrait_bottom_width(),Settings.SECTION_LAYOUT,640), - PORTRAIT_BOTTOM_HEIGHT(SettingKeys.custom_portrait_bottom_height(),Settings.SECTION_LAYOUT,480), + SMALL_SCREEN_POSITION(SettingKeys.small_screen_position(), Settings.SECTION_LAYOUT, 0), + LANDSCAPE_TOP_X(SettingKeys.custom_top_x(), Settings.SECTION_LAYOUT, 0), + LANDSCAPE_TOP_Y(SettingKeys.custom_top_y(), Settings.SECTION_LAYOUT, 0), + LANDSCAPE_TOP_WIDTH(SettingKeys.custom_top_width(), Settings.SECTION_LAYOUT, 800), + LANDSCAPE_TOP_HEIGHT(SettingKeys.custom_top_height(), Settings.SECTION_LAYOUT, 480), + LANDSCAPE_BOTTOM_X(SettingKeys.custom_bottom_x(), Settings.SECTION_LAYOUT, 80), + LANDSCAPE_BOTTOM_Y(SettingKeys.custom_bottom_y(), Settings.SECTION_LAYOUT, 480), + LANDSCAPE_BOTTOM_WIDTH(SettingKeys.custom_bottom_width(), Settings.SECTION_LAYOUT, 640), + LANDSCAPE_BOTTOM_HEIGHT(SettingKeys.custom_bottom_height(), Settings.SECTION_LAYOUT, 480), + SCREEN_GAP(SettingKeys.screen_gap(), Settings.SECTION_LAYOUT, 0), + PORTRAIT_SCREEN_LAYOUT(SettingKeys.portrait_layout_option(), Settings.SECTION_LAYOUT, 0), + SECONDARY_DISPLAY_LAYOUT(SettingKeys.secondary_display_layout(), Settings.SECTION_LAYOUT, 4), + PORTRAIT_TOP_X(SettingKeys.custom_portrait_top_x(), Settings.SECTION_LAYOUT, 0), + PORTRAIT_TOP_Y(SettingKeys.custom_portrait_top_y(), Settings.SECTION_LAYOUT, 0), + PORTRAIT_TOP_WIDTH(SettingKeys.custom_portrait_top_width(), Settings.SECTION_LAYOUT, 800), + PORTRAIT_TOP_HEIGHT(SettingKeys.custom_portrait_top_height(), Settings.SECTION_LAYOUT, 480), + PORTRAIT_BOTTOM_X(SettingKeys.custom_portrait_bottom_x(), Settings.SECTION_LAYOUT, 80), + PORTRAIT_BOTTOM_Y(SettingKeys.custom_portrait_bottom_y(), Settings.SECTION_LAYOUT, 480), + PORTRAIT_BOTTOM_WIDTH(SettingKeys.custom_portrait_bottom_width(), Settings.SECTION_LAYOUT, 640), + PORTRAIT_BOTTOM_HEIGHT( + SettingKeys.custom_portrait_bottom_height(), + Settings.SECTION_LAYOUT, + 480 + ), AUDIO_INPUT_TYPE(SettingKeys.input_type(), Settings.SECTION_AUDIO, 0), CPU_CLOCK_SPEED(SettingKeys.cpu_clock_percentage(), Settings.SECTION_CORE, 100), TEXTURE_FILTER(SettingKeys.texture_filter(), Settings.SECTION_RENDERER, 0), @@ -54,8 +58,12 @@ enum class IntSetting( DELAY_RENDER_THREAD_US(SettingKeys.delay_game_render_thread_us(), Settings.SECTION_RENDERER, 0), ORIENTATION_OPTION(SettingKeys.screen_orientation(), Settings.SECTION_LAYOUT, 2), TURBO_LIMIT(SettingKeys.turbo_limit(), Settings.SECTION_CORE, 200), - PERFORMANCE_OVERLAY_POSITION(SettingKeys.performance_overlay_position(), Settings.SECTION_LAYOUT, 0), - RENDER_3D_WHICH_DISPLAY(SettingKeys.render_3d_which_display(),Settings.SECTION_RENDERER,0), + PERFORMANCE_OVERLAY_POSITION( + SettingKeys.performance_overlay_position(), + Settings.SECTION_LAYOUT, + 0 + ), + RENDER_3D_WHICH_DISPLAY(SettingKeys.render_3d_which_display(), Settings.SECTION_RENDERER, 0), ASPECT_RATIO(SettingKeys.aspect_ratio(), Settings.SECTION_LAYOUT, 0); override var int: Int = defaultValue @@ -78,7 +86,7 @@ enum class IntSetting( EMULATED_REGION, INIT_CLOCK, GRAPHICS_API, - AUDIO_INPUT_TYPE, + AUDIO_INPUT_TYPE ) fun from(key: String): IntSetting? = IntSetting.values().firstOrNull { it.key == key } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/SettingSection.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/SettingSection.kt index 02c5fa2d5..d0f8b52af 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/SettingSection.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/SettingSection.kt @@ -26,9 +26,7 @@ class SettingSection(val name: String) { * @param key Used to retrieve the Setting. * @return A Setting object (you should probably cast this before using) */ - fun getSetting(key: String): AbstractSetting? { - return settings[key] - } + fun getSetting(key: String): AbstractSetting? = settings[key] fun mergeSection(settingSection: SettingSection) { for (setting in settingSection.settings.values) { diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/Settings.kt index 547a53594..65485faf2 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/Settings.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/Settings.kt @@ -5,11 +5,11 @@ package org.citra.citra_emu.features.settings.model import android.text.TextUtils +import java.util.TreeMap import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.ui.SettingsActivityView import org.citra.citra_emu.features.settings.utils.SettingsFile -import java.util.TreeMap class Settings { private var gameId: String? = null @@ -33,9 +33,7 @@ class Settings { var sections: HashMap = SettingsSectionMap() - fun getSection(sectionName: String): SettingSection? { - return sections[sectionName] - } + fun getSection(sectionName: String): SettingSection? = sections[sectionName] val isEmpty: Boolean get() = sections.isEmpty() @@ -182,7 +180,7 @@ class Settings { KEY_BUTTON_RIGHT ) val axisTitles = listOf( - R.string.controller_axis_vertical, + R.string.controller_axis_vertical, R.string.controller_axis_horizontal ) val dPadTitles = listOf( @@ -250,4 +248,4 @@ class Settings { ) } } -} \ No newline at end of file +} diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/StringSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/StringSetting.kt index fe476a1fa..3ba066efd 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/StringSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/StringSetting.kt @@ -15,9 +15,17 @@ enum class StringSetting( CAMERA_INNER_NAME(SettingKeys.camera_inner_name(), Settings.SECTION_CAMERA, "ndk"), CAMERA_INNER_CONFIG(SettingKeys.camera_inner_config(), Settings.SECTION_CAMERA, "_front"), CAMERA_OUTER_LEFT_NAME(SettingKeys.camera_outer_left_name(), Settings.SECTION_CAMERA, "ndk"), - CAMERA_OUTER_LEFT_CONFIG(SettingKeys.camera_outer_left_config(), Settings.SECTION_CAMERA, "_back"), + CAMERA_OUTER_LEFT_CONFIG( + SettingKeys.camera_outer_left_config(), + Settings.SECTION_CAMERA, + "_back" + ), CAMERA_OUTER_RIGHT_NAME(SettingKeys.camera_outer_right_name(), Settings.SECTION_CAMERA, "ndk"), - CAMERA_OUTER_RIGHT_CONFIG(SettingKeys.camera_outer_right_config(), Settings.SECTION_CAMERA, "_back"); + CAMERA_OUTER_RIGHT_CONFIG( + SettingKeys.camera_outer_right_config(), + Settings.SECTION_CAMERA, + "_back" + ); override var string: String = defaultValue diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/HeaderSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/HeaderSetting.kt index d2a50f648..329aa21da 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/HeaderSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/HeaderSetting.kt @@ -4,6 +4,6 @@ package org.citra.citra_emu.features.settings.model.view -class HeaderSetting(titleId: Int,descId: Int = 0) : SettingsItem(null, titleId, descId) { +class HeaderSetting(titleId: Int, descId: Int = 0) : SettingsItem(null, titleId, descId) { override val type = TYPE_HEADER } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/InputBindingSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/InputBindingSetting.kt index 6ec851db1..4872f5061 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/InputBindingSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/InputBindingSetting.kt @@ -20,10 +20,8 @@ import org.citra.citra_emu.features.settings.model.AbstractSetting import org.citra.citra_emu.features.settings.model.AbstractStringSetting import org.citra.citra_emu.features.settings.model.Settings -class InputBindingSetting( - val abstractSetting: AbstractSetting, - titleId: Int -) : SettingsItem(abstractSetting, titleId, 0) { +class InputBindingSetting(val abstractSetting: AbstractSetting, titleId: Int) : + SettingsItem(abstractSetting, titleId, 0) { private val context: Context get() = CitraApplication.appContext private val preferences: SharedPreferences get() = PreferenceManager.getDefaultSharedPreferences(context) @@ -39,74 +37,66 @@ class InputBindingSetting( /** * Returns true if this key is for the 3DS Circle Pad */ - fun isCirclePad(): Boolean = - when (abstractSetting.key) { - Settings.KEY_CIRCLEPAD_AXIS_HORIZONTAL, - Settings.KEY_CIRCLEPAD_AXIS_VERTICAL -> true + fun isCirclePad(): Boolean = when (abstractSetting.key) { + Settings.KEY_CIRCLEPAD_AXIS_HORIZONTAL, + Settings.KEY_CIRCLEPAD_AXIS_VERTICAL -> true - else -> false - } + else -> false + } /** * Returns true if this key is for a horizontal axis for a 3DS analog stick or D-pad */ - fun isHorizontalOrientation(): Boolean = - when (abstractSetting.key) { - Settings.KEY_CIRCLEPAD_AXIS_HORIZONTAL, - Settings.KEY_CSTICK_AXIS_HORIZONTAL, - Settings.KEY_DPAD_AXIS_HORIZONTAL -> true + fun isHorizontalOrientation(): Boolean = when (abstractSetting.key) { + Settings.KEY_CIRCLEPAD_AXIS_HORIZONTAL, + Settings.KEY_CSTICK_AXIS_HORIZONTAL, + Settings.KEY_DPAD_AXIS_HORIZONTAL -> true - else -> false - } + else -> false + } /** * Returns true if this key is for the 3DS C-Stick */ - fun isCStick(): Boolean = - when (abstractSetting.key) { - Settings.KEY_CSTICK_AXIS_HORIZONTAL, - Settings.KEY_CSTICK_AXIS_VERTICAL -> true + fun isCStick(): Boolean = when (abstractSetting.key) { + Settings.KEY_CSTICK_AXIS_HORIZONTAL, + Settings.KEY_CSTICK_AXIS_VERTICAL -> true - else -> false - } + else -> false + } /** * Returns true if this key is for the 3DS D-Pad */ - fun isDPad(): Boolean = - when (abstractSetting.key) { - Settings.KEY_DPAD_AXIS_HORIZONTAL, - Settings.KEY_DPAD_AXIS_VERTICAL -> true + fun isDPad(): Boolean = when (abstractSetting.key) { + Settings.KEY_DPAD_AXIS_HORIZONTAL, + Settings.KEY_DPAD_AXIS_VERTICAL -> true + + else -> false + } - else -> false - } /** * Returns true if this key is for the 3DS L/R or ZL/ZR buttons. Note, these are not real * triggers on the 3DS, but we support them as such on a physical gamepad. */ - fun isTrigger(): Boolean = - when (abstractSetting.key) { - Settings.KEY_BUTTON_L, - Settings.KEY_BUTTON_R, - Settings.KEY_BUTTON_ZL, - Settings.KEY_BUTTON_ZR -> true + fun isTrigger(): Boolean = when (abstractSetting.key) { + Settings.KEY_BUTTON_L, + Settings.KEY_BUTTON_R, + Settings.KEY_BUTTON_ZL, + Settings.KEY_BUTTON_ZR -> true - else -> false - } + else -> false + } /** * Returns true if a gamepad axis can be used to map this key. */ - fun isAxisMappingSupported(): Boolean { - return isCirclePad() || isCStick() || isDPad() || isTrigger() - } + fun isAxisMappingSupported(): Boolean = isCirclePad() || isCStick() || isDPad() || isTrigger() /** * Returns true if a gamepad button can be used to map this key. */ - fun isButtonMappingSupported(): Boolean { - return !isAxisMappingSupported() || isTrigger() - } + fun isButtonMappingSupported(): Boolean = !isAxisMappingSupported() || isTrigger() /** * Returns the Citra button code for the settings key. @@ -177,10 +167,10 @@ class InputBindingSetting( } catch (e: ClassCastException) { // if this is an int pref, either old button or an axis, so just remove it preferences.edit().remove(oldKey).apply() - return; + return } - buttonCodes.remove(buttonCode.toString()); - preferences.edit().putStringSet(oldKey,buttonCodes).apply() + buttonCodes.remove(buttonCode.toString()) + preferences.edit().putStringSet(oldKey, buttonCodes).apply() } } @@ -197,7 +187,7 @@ class InputBindingSetting( // Cleanup old mapping for this setting removeOldMapping() - editor.putStringSet(key, buttonCodes.mapTo(mutableSetOf()) {it.toString()}) + editor.putStringSet(key, buttonCodes.mapTo(mutableSetOf()) { it.toString() }) // Write next reverse mapping for future cleanup editor.putString(reverseKey, key) @@ -217,7 +207,7 @@ class InputBindingSetting( preferences.edit() .putInt(getInputAxisOrientationKey(axis), if (isHorizontalOrientation()) 0 else 1) .putInt(getInputAxisButtonKey(axis), value) - .putBoolean(getInputAxisInvertedKey(axis),inverted) + .putBoolean(getInputAxisInvertedKey(axis), inverted) // Write next reverse mapping for future cleanup .putString(reverseKey, getInputAxisKey(axis)) .apply() @@ -271,9 +261,8 @@ class InputBindingSetting( companion object { private const val INPUT_MAPPING_PREFIX = "InputMapping" - private fun toTitleCase(raw: String): String = - raw.replace("_", " ").lowercase() - .split(" ").joinToString(" ") { it.replaceFirstChar { c -> c.uppercase() } } + private fun toTitleCase(raw: String): String = raw.replace("_", " ").lowercase() + .split(" ").joinToString(" ") { it.replaceFirstChar { c -> c.uppercase() } } private const val BUTTON_NAME_L3 = "Button L3" private const val BUTTON_NAME_R3 = "Button R3" @@ -287,15 +276,15 @@ class InputBindingSetting( LINUX_BTN_DPAD_RIGHT to "Dpad Right" ) - fun getButtonName(keyCode: Int): String = - buttonNameOverrides[keyCode] - ?: toTitleCase(KeyEvent.keyCodeToString(keyCode).removePrefix("KEYCODE_")) + fun getButtonName(keyCode: Int): String = buttonNameOverrides[keyCode] + ?: toTitleCase(KeyEvent.keyCodeToString(keyCode).removePrefix("KEYCODE_")) private data class DefaultButtonMapping( val settingKey: String, val hostKeyCode: Int, val guestButtonCode: Int ) + // Auto-map always sets inverted = false. Users needing inverted axes should remap manually. private data class DefaultAxisMapping( val settingKey: String, @@ -306,45 +295,153 @@ class InputBindingSetting( ) private val xboxFaceButtonMappings = listOf( - DefaultButtonMapping(Settings.KEY_BUTTON_A, KeyEvent.KEYCODE_BUTTON_B, NativeLibrary.ButtonType.BUTTON_A), - DefaultButtonMapping(Settings.KEY_BUTTON_B, KeyEvent.KEYCODE_BUTTON_A, NativeLibrary.ButtonType.BUTTON_B), - DefaultButtonMapping(Settings.KEY_BUTTON_X, KeyEvent.KEYCODE_BUTTON_Y, NativeLibrary.ButtonType.BUTTON_X), - DefaultButtonMapping(Settings.KEY_BUTTON_Y, KeyEvent.KEYCODE_BUTTON_X, NativeLibrary.ButtonType.BUTTON_Y) + DefaultButtonMapping( + Settings.KEY_BUTTON_A, + KeyEvent.KEYCODE_BUTTON_B, + NativeLibrary.ButtonType.BUTTON_A + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_B, + KeyEvent.KEYCODE_BUTTON_A, + NativeLibrary.ButtonType.BUTTON_B + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_X, + KeyEvent.KEYCODE_BUTTON_Y, + NativeLibrary.ButtonType.BUTTON_X + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_Y, + KeyEvent.KEYCODE_BUTTON_X, + NativeLibrary.ButtonType.BUTTON_Y + ) ) private val nintendoFaceButtonMappings = listOf( - DefaultButtonMapping(Settings.KEY_BUTTON_A, KeyEvent.KEYCODE_BUTTON_A, NativeLibrary.ButtonType.BUTTON_A), - DefaultButtonMapping(Settings.KEY_BUTTON_B, KeyEvent.KEYCODE_BUTTON_B, NativeLibrary.ButtonType.BUTTON_B), - DefaultButtonMapping(Settings.KEY_BUTTON_X, KeyEvent.KEYCODE_BUTTON_X, NativeLibrary.ButtonType.BUTTON_X), - DefaultButtonMapping(Settings.KEY_BUTTON_Y, KeyEvent.KEYCODE_BUTTON_Y, NativeLibrary.ButtonType.BUTTON_Y) + DefaultButtonMapping( + Settings.KEY_BUTTON_A, + KeyEvent.KEYCODE_BUTTON_A, + NativeLibrary.ButtonType.BUTTON_A + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_B, + KeyEvent.KEYCODE_BUTTON_B, + NativeLibrary.ButtonType.BUTTON_B + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_X, + KeyEvent.KEYCODE_BUTTON_X, + NativeLibrary.ButtonType.BUTTON_X + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_Y, + KeyEvent.KEYCODE_BUTTON_Y, + NativeLibrary.ButtonType.BUTTON_Y + ) ) private val commonButtonMappings = listOf( - DefaultButtonMapping(Settings.KEY_BUTTON_L, KeyEvent.KEYCODE_BUTTON_L1, NativeLibrary.ButtonType.TRIGGER_L), - DefaultButtonMapping(Settings.KEY_BUTTON_R, KeyEvent.KEYCODE_BUTTON_R1, NativeLibrary.ButtonType.TRIGGER_R), - DefaultButtonMapping(Settings.KEY_BUTTON_ZL, KeyEvent.KEYCODE_BUTTON_L2, NativeLibrary.ButtonType.BUTTON_ZL), - DefaultButtonMapping(Settings.KEY_BUTTON_ZR, KeyEvent.KEYCODE_BUTTON_R2, NativeLibrary.ButtonType.BUTTON_ZR), - DefaultButtonMapping(Settings.KEY_BUTTON_SELECT, KeyEvent.KEYCODE_BUTTON_SELECT, NativeLibrary.ButtonType.BUTTON_SELECT), - DefaultButtonMapping(Settings.KEY_BUTTON_START, KeyEvent.KEYCODE_BUTTON_START, NativeLibrary.ButtonType.BUTTON_START) + DefaultButtonMapping( + Settings.KEY_BUTTON_L, + KeyEvent.KEYCODE_BUTTON_L1, + NativeLibrary.ButtonType.TRIGGER_L + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_R, + KeyEvent.KEYCODE_BUTTON_R1, + NativeLibrary.ButtonType.TRIGGER_R + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_ZL, + KeyEvent.KEYCODE_BUTTON_L2, + NativeLibrary.ButtonType.BUTTON_ZL + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_ZR, + KeyEvent.KEYCODE_BUTTON_R2, + NativeLibrary.ButtonType.BUTTON_ZR + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_SELECT, + KeyEvent.KEYCODE_BUTTON_SELECT, + NativeLibrary.ButtonType.BUTTON_SELECT + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_START, + KeyEvent.KEYCODE_BUTTON_START, + NativeLibrary.ButtonType.BUTTON_START + ) ) private val dpadButtonMappings = listOf( - DefaultButtonMapping(Settings.KEY_BUTTON_UP, KeyEvent.KEYCODE_DPAD_UP, NativeLibrary.ButtonType.DPAD_UP), - DefaultButtonMapping(Settings.KEY_BUTTON_DOWN, KeyEvent.KEYCODE_DPAD_DOWN, NativeLibrary.ButtonType.DPAD_DOWN), - DefaultButtonMapping(Settings.KEY_BUTTON_LEFT, KeyEvent.KEYCODE_DPAD_LEFT, NativeLibrary.ButtonType.DPAD_LEFT), - DefaultButtonMapping(Settings.KEY_BUTTON_RIGHT, KeyEvent.KEYCODE_DPAD_RIGHT, NativeLibrary.ButtonType.DPAD_RIGHT) + DefaultButtonMapping( + Settings.KEY_BUTTON_UP, + KeyEvent.KEYCODE_DPAD_UP, + NativeLibrary.ButtonType.DPAD_UP + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_DOWN, + KeyEvent.KEYCODE_DPAD_DOWN, + NativeLibrary.ButtonType.DPAD_DOWN + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_LEFT, + KeyEvent.KEYCODE_DPAD_LEFT, + NativeLibrary.ButtonType.DPAD_LEFT + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_RIGHT, + KeyEvent.KEYCODE_DPAD_RIGHT, + NativeLibrary.ButtonType.DPAD_RIGHT + ) ) private val stickAxisMappings = listOf( - DefaultAxisMapping(Settings.KEY_CIRCLEPAD_AXIS_HORIZONTAL, MotionEvent.AXIS_X, NativeLibrary.ButtonType.STICK_LEFT, 0, false), - DefaultAxisMapping(Settings.KEY_CIRCLEPAD_AXIS_VERTICAL, MotionEvent.AXIS_Y, NativeLibrary.ButtonType.STICK_LEFT, 1, false), - DefaultAxisMapping(Settings.KEY_CSTICK_AXIS_HORIZONTAL, MotionEvent.AXIS_Z, NativeLibrary.ButtonType.STICK_C, 0, false), - DefaultAxisMapping(Settings.KEY_CSTICK_AXIS_VERTICAL, MotionEvent.AXIS_RZ, NativeLibrary.ButtonType.STICK_C, 1, false) + DefaultAxisMapping( + Settings.KEY_CIRCLEPAD_AXIS_HORIZONTAL, + MotionEvent.AXIS_X, + NativeLibrary.ButtonType.STICK_LEFT, + 0, + false + ), + DefaultAxisMapping( + Settings.KEY_CIRCLEPAD_AXIS_VERTICAL, + MotionEvent.AXIS_Y, + NativeLibrary.ButtonType.STICK_LEFT, + 1, + false + ), + DefaultAxisMapping( + Settings.KEY_CSTICK_AXIS_HORIZONTAL, + MotionEvent.AXIS_Z, + NativeLibrary.ButtonType.STICK_C, + 0, + false + ), + DefaultAxisMapping( + Settings.KEY_CSTICK_AXIS_VERTICAL, + MotionEvent.AXIS_RZ, + NativeLibrary.ButtonType.STICK_C, + 1, + false + ) ) private val dpadAxisMappings = listOf( - DefaultAxisMapping(Settings.KEY_DPAD_AXIS_HORIZONTAL, MotionEvent.AXIS_HAT_X, NativeLibrary.ButtonType.DPAD, 0, false), - DefaultAxisMapping(Settings.KEY_DPAD_AXIS_VERTICAL, MotionEvent.AXIS_HAT_Y, NativeLibrary.ButtonType.DPAD, 1, false) + DefaultAxisMapping( + Settings.KEY_DPAD_AXIS_HORIZONTAL, + MotionEvent.AXIS_HAT_X, + NativeLibrary.ButtonType.DPAD, + 0, + false + ), + DefaultAxisMapping( + Settings.KEY_DPAD_AXIS_VERTICAL, + MotionEvent.AXIS_HAT_Y, + NativeLibrary.ButtonType.DPAD, + 1, + false + ) ) // Nintendo Switch Joy-Con specific mappings. @@ -360,37 +457,93 @@ class InputBindingSetting( // KEYCODE_UNKNOWN with these scan codes because Android's input layer doesn't // translate them to KEYCODE_DPAD_*. translateEventToKeyId() falls back to // the scan code in that case. - private const val LINUX_BTN_DPAD_UP = 0x220 // 544 - private const val LINUX_BTN_DPAD_DOWN = 0x221 // 545 - private const val LINUX_BTN_DPAD_LEFT = 0x222 // 546 + private const val LINUX_BTN_DPAD_UP = 0x220 // 544 + private const val LINUX_BTN_DPAD_DOWN = 0x221 // 545 + private const val LINUX_BTN_DPAD_LEFT = 0x222 // 546 private const val LINUX_BTN_DPAD_RIGHT = 0x223 // 547 // Joy-Con face buttons: A/B are swapped by Android's evdev layer, but X/Y are not. // This is different from both the standard Xbox table (full swap) and the // Nintendo table (no swap). private val joyconFaceButtonMappings = listOf( - DefaultButtonMapping(Settings.KEY_BUTTON_A, KeyEvent.KEYCODE_BUTTON_B, NativeLibrary.ButtonType.BUTTON_A), - DefaultButtonMapping(Settings.KEY_BUTTON_B, KeyEvent.KEYCODE_BUTTON_A, NativeLibrary.ButtonType.BUTTON_B), - DefaultButtonMapping(Settings.KEY_BUTTON_X, KeyEvent.KEYCODE_BUTTON_X, NativeLibrary.ButtonType.BUTTON_X), - DefaultButtonMapping(Settings.KEY_BUTTON_Y, KeyEvent.KEYCODE_BUTTON_Y, NativeLibrary.ButtonType.BUTTON_Y) + DefaultButtonMapping( + Settings.KEY_BUTTON_A, + KeyEvent.KEYCODE_BUTTON_B, + NativeLibrary.ButtonType.BUTTON_A + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_B, + KeyEvent.KEYCODE_BUTTON_A, + NativeLibrary.ButtonType.BUTTON_B + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_X, + KeyEvent.KEYCODE_BUTTON_X, + NativeLibrary.ButtonType.BUTTON_X + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_Y, + KeyEvent.KEYCODE_BUTTON_Y, + NativeLibrary.ButtonType.BUTTON_Y + ) ) // Joy-Con D-pad: uses Linux scan codes because Android reports BTN_DPAD_* as KEYCODE_UNKNOWN private val joyconDpadButtonMappings = listOf( - DefaultButtonMapping(Settings.KEY_BUTTON_UP, LINUX_BTN_DPAD_UP, NativeLibrary.ButtonType.DPAD_UP), - DefaultButtonMapping(Settings.KEY_BUTTON_DOWN, LINUX_BTN_DPAD_DOWN, NativeLibrary.ButtonType.DPAD_DOWN), - DefaultButtonMapping(Settings.KEY_BUTTON_LEFT, LINUX_BTN_DPAD_LEFT, NativeLibrary.ButtonType.DPAD_LEFT), - DefaultButtonMapping(Settings.KEY_BUTTON_RIGHT, LINUX_BTN_DPAD_RIGHT, NativeLibrary.ButtonType.DPAD_RIGHT) + DefaultButtonMapping( + Settings.KEY_BUTTON_UP, + LINUX_BTN_DPAD_UP, + NativeLibrary.ButtonType.DPAD_UP + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_DOWN, + LINUX_BTN_DPAD_DOWN, + NativeLibrary.ButtonType.DPAD_DOWN + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_LEFT, + LINUX_BTN_DPAD_LEFT, + NativeLibrary.ButtonType.DPAD_LEFT + ), + DefaultButtonMapping( + Settings.KEY_BUTTON_RIGHT, + LINUX_BTN_DPAD_RIGHT, + NativeLibrary.ButtonType.DPAD_RIGHT + ) ) // Joy-Con sticks: left stick is AXIS_X/Y (standard), right stick is AXIS_RX/RY // (not Z/RZ like most controllers). The horizontal axis is inverted relative to // the standard orientation - verified empirically on paired Joy-Cons via Bluetooth. private val joyconStickAxisMappings = listOf( - DefaultAxisMapping(Settings.KEY_CIRCLEPAD_AXIS_HORIZONTAL, MotionEvent.AXIS_X, NativeLibrary.ButtonType.STICK_LEFT, 0, false), - DefaultAxisMapping(Settings.KEY_CIRCLEPAD_AXIS_VERTICAL, MotionEvent.AXIS_Y, NativeLibrary.ButtonType.STICK_LEFT, 1, false), - DefaultAxisMapping(Settings.KEY_CSTICK_AXIS_HORIZONTAL, MotionEvent.AXIS_RX, NativeLibrary.ButtonType.STICK_C, 0, true), - DefaultAxisMapping(Settings.KEY_CSTICK_AXIS_VERTICAL, MotionEvent.AXIS_RY, NativeLibrary.ButtonType.STICK_C, 1, false) + DefaultAxisMapping( + Settings.KEY_CIRCLEPAD_AXIS_HORIZONTAL, + MotionEvent.AXIS_X, + NativeLibrary.ButtonType.STICK_LEFT, + 0, + false + ), + DefaultAxisMapping( + Settings.KEY_CIRCLEPAD_AXIS_VERTICAL, + MotionEvent.AXIS_Y, + NativeLibrary.ButtonType.STICK_LEFT, + 1, + false + ), + DefaultAxisMapping( + Settings.KEY_CSTICK_AXIS_HORIZONTAL, + MotionEvent.AXIS_RX, + NativeLibrary.ButtonType.STICK_C, + 0, + true + ), + DefaultAxisMapping( + Settings.KEY_CSTICK_AXIS_VERTICAL, + MotionEvent.AXIS_RY, + NativeLibrary.ButtonType.STICK_C, + 1, + false + ) ) /** @@ -417,9 +570,11 @@ class InputBindingSetting( } private val allBindingKeys: Set by lazy { - (Settings.buttonKeys + Settings.triggerKeys + - Settings.circlePadKeys + Settings.cStickKeys + Settings.dPadAxisKeys + - Settings.dPadButtonKeys).toSet() + ( + Settings.buttonKeys + Settings.triggerKeys + + Settings.circlePadKeys + Settings.cStickKeys + Settings.dPadAxisKeys + + Settings.dPadButtonKeys + ).toSet() } fun clearAllBindings() { @@ -509,35 +664,37 @@ class InputBindingSetting( /** * Returns the settings key for the specified Citra button code. */ - private fun getButtonKey(buttonCode: Int): String = - when (buttonCode) { - NativeLibrary.ButtonType.BUTTON_A -> Settings.KEY_BUTTON_A - NativeLibrary.ButtonType.BUTTON_B -> Settings.KEY_BUTTON_B - NativeLibrary.ButtonType.BUTTON_X -> Settings.KEY_BUTTON_X - NativeLibrary.ButtonType.BUTTON_Y -> Settings.KEY_BUTTON_Y - NativeLibrary.ButtonType.TRIGGER_L -> Settings.KEY_BUTTON_L - NativeLibrary.ButtonType.TRIGGER_R -> Settings.KEY_BUTTON_R - NativeLibrary.ButtonType.BUTTON_ZL -> Settings.KEY_BUTTON_ZL - NativeLibrary.ButtonType.BUTTON_ZR -> Settings.KEY_BUTTON_ZR - NativeLibrary.ButtonType.BUTTON_SELECT -> Settings.KEY_BUTTON_SELECT - NativeLibrary.ButtonType.BUTTON_START -> Settings.KEY_BUTTON_START - NativeLibrary.ButtonType.BUTTON_HOME -> Settings.KEY_BUTTON_HOME - NativeLibrary.ButtonType.DPAD_UP -> Settings.KEY_BUTTON_UP - NativeLibrary.ButtonType.DPAD_DOWN -> Settings.KEY_BUTTON_DOWN - NativeLibrary.ButtonType.DPAD_LEFT -> Settings.KEY_BUTTON_LEFT - NativeLibrary.ButtonType.DPAD_RIGHT -> Settings.KEY_BUTTON_RIGHT - else -> "" - } + private fun getButtonKey(buttonCode: Int): String = when (buttonCode) { + NativeLibrary.ButtonType.BUTTON_A -> Settings.KEY_BUTTON_A + NativeLibrary.ButtonType.BUTTON_B -> Settings.KEY_BUTTON_B + NativeLibrary.ButtonType.BUTTON_X -> Settings.KEY_BUTTON_X + NativeLibrary.ButtonType.BUTTON_Y -> Settings.KEY_BUTTON_Y + NativeLibrary.ButtonType.TRIGGER_L -> Settings.KEY_BUTTON_L + NativeLibrary.ButtonType.TRIGGER_R -> Settings.KEY_BUTTON_R + NativeLibrary.ButtonType.BUTTON_ZL -> Settings.KEY_BUTTON_ZL + NativeLibrary.ButtonType.BUTTON_ZR -> Settings.KEY_BUTTON_ZR + NativeLibrary.ButtonType.BUTTON_SELECT -> Settings.KEY_BUTTON_SELECT + NativeLibrary.ButtonType.BUTTON_START -> Settings.KEY_BUTTON_START + NativeLibrary.ButtonType.BUTTON_HOME -> Settings.KEY_BUTTON_HOME + NativeLibrary.ButtonType.DPAD_UP -> Settings.KEY_BUTTON_UP + NativeLibrary.ButtonType.DPAD_DOWN -> Settings.KEY_BUTTON_DOWN + NativeLibrary.ButtonType.DPAD_LEFT -> Settings.KEY_BUTTON_LEFT + NativeLibrary.ButtonType.DPAD_RIGHT -> Settings.KEY_BUTTON_RIGHT + else -> "" + } + /** * Get the mutable set of int button values this key should map to given an event */ - fun getButtonSet(keyCode: KeyEvent):MutableSet { + fun getButtonSet(keyCode: KeyEvent): MutableSet { val key = getInputButtonKey(keyCode) - val preferences = PreferenceManager.getDefaultSharedPreferences(CitraApplication.appContext) + val preferences = PreferenceManager.getDefaultSharedPreferences( + CitraApplication.appContext + ) var buttonCodes = try { preferences.getStringSet(key, mutableSetOf()) } catch (e: ClassCastException) { - val prefInt = preferences.getInt(key, -1); + val prefInt = preferences.getInt(key, -1) val migratedSet = if (prefInt != -1) { mutableSetOf(prefInt.toString()) } else { @@ -549,15 +706,17 @@ class InputBindingSetting( return buttonCodes.mapNotNull { it.toIntOrNull() }.toMutableSet() } - private fun getInputButtonKey(keyId: Int): String = "${INPUT_MAPPING_PREFIX}_HostAxis_${keyId}" + private fun getInputButtonKey(keyId: Int): String = + "${INPUT_MAPPING_PREFIX}_HostAxis_$keyId" /** Falls back to the scan code when keyCode is KEYCODE_UNKNOWN. */ - fun getInputButtonKey(event: KeyEvent): String = getInputButtonKey(translateEventToKeyId(event)) + fun getInputButtonKey(event: KeyEvent): String = + getInputButtonKey(translateEventToKeyId(event)) /** * Helper function to get the settings key for an gamepad axis. */ - fun getInputAxisKey(axis: Int): String = "${INPUT_MAPPING_PREFIX}_HostAxis_${axis}" + fun getInputAxisKey(axis: Int): String = "${INPUT_MAPPING_PREFIX}_HostAxis_$axis" /** * Helper function to get the settings key for an gamepad axis button (stick or trigger). @@ -575,7 +734,6 @@ class InputBindingSetting( fun getInputAxisOrientationKey(axis: Int): String = "${getInputAxisKey(axis)}_GuestOrientation" - /** * This function translates a keyEvent into an "keyid" * This key id is either the keyCode from the event, or @@ -585,12 +743,10 @@ class InputBindingSetting( * This handles keys like the media-keys on google statia-controllers * that don't have a conventional "mapping" and report as "unknown" */ - fun translateEventToKeyId(event: KeyEvent): Int { - return if (event.keyCode == 0) { - event.scanCode - } else { - event.keyCode - } + fun translateEventToKeyId(event: KeyEvent): Int = if (event.keyCode == 0) { + event.scanCode + } else { + event.keyCode } } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/MultiChoiceSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/MultiChoiceSetting.kt index d097696e0..aab36c53f 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/MultiChoiceSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/MultiChoiceSetting.kt @@ -25,7 +25,7 @@ class MultiChoiceSetting( try { val setting = setting as IntListSetting return setting.list - }catch (_: ClassCastException) { + } catch (_: ClassCastException) { } return defaultValue!! } @@ -42,5 +42,4 @@ class MultiChoiceSetting( intSetting.list = selection return intSetting } - } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SliderSetting.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SliderSetting.kt index 46ed42905..32fd722a7 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SliderSetting.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/model/view/SliderSetting.kt @@ -29,8 +29,11 @@ class SliderSetting( val ret = when (setting) { is AbstractIntSetting -> setting.int.toFloat() + is FloatSetting -> setting.float + is ScaledFloatSetting -> setting.float + else -> { Log.error("[SliderSetting] Error casting setting type.") -1f @@ -38,6 +41,7 @@ class SliderSetting( } return ret.coerceIn(min.toFloat(), max.toFloat()) } + /** * Write a value to the backing int. If that int was previously null, * initializes a new one and returns it, so it can be added to the Hashmap. diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivity.kt index 064fa700e..d96cc81c0 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivity.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivity.kt @@ -22,11 +22,11 @@ import androidx.core.view.WindowInsetsCompat import androidx.core.view.updatePadding import androidx.preference.PreferenceManager import com.google.android.material.color.MaterialColors +import java.io.IOException import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.R import org.citra.citra_emu.databinding.ActivitySettingsBinding -import java.io.IOException import org.citra.citra_emu.features.settings.model.BooleanSetting import org.citra.citra_emu.features.settings.model.FloatSetting import org.citra.citra_emu.features.settings.model.IntSetting @@ -35,13 +35,15 @@ import org.citra.citra_emu.features.settings.model.Settings import org.citra.citra_emu.features.settings.model.SettingsViewModel import org.citra.citra_emu.features.settings.model.StringSetting import org.citra.citra_emu.features.settings.utils.SettingsFile -import org.citra.citra_emu.utils.SystemSaveGame import org.citra.citra_emu.utils.DirectoryInitialization import org.citra.citra_emu.utils.InsetsHelper import org.citra.citra_emu.utils.RefreshRateUtil +import org.citra.citra_emu.utils.SystemSaveGame import org.citra.citra_emu.utils.ThemeUtil -class SettingsActivity : AppCompatActivity(), SettingsActivityView { +class SettingsActivity : + AppCompatActivity(), + SettingsActivityView { private val presenter = SettingsActivityPresenter(this) private lateinit var binding: ActivitySettingsBinding @@ -205,7 +207,7 @@ class SettingsActivity : AppCompatActivity(), SettingsActivityView { presenter.onSettingsReset() val controllerKeys = Settings.buttonKeys + Settings.circlePadKeys + Settings.cStickKeys + - Settings.dPadAxisKeys + Settings.dPadButtonKeys + Settings.triggerKeys + Settings.dPadAxisKeys + Settings.dPadButtonKeys + Settings.triggerKeys val editor = PreferenceManager.getDefaultSharedPreferences(CitraApplication.appContext).edit() controllerKeys.forEach { editor.remove(it) } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivityPresenter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivityPresenter.kt index 33aea46f9..bc823066a 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivityPresenter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsActivityPresenter.kt @@ -12,11 +12,11 @@ import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.features.settings.model.BooleanSetting import org.citra.citra_emu.features.settings.model.Settings -import org.citra.citra_emu.utils.SystemSaveGame import org.citra.citra_emu.utils.DirectoryInitialization import org.citra.citra_emu.utils.FileUtil import org.citra.citra_emu.utils.Log import org.citra.citra_emu.utils.PermissionsHandler +import org.citra.citra_emu.utils.SystemSaveGame import org.citra.citra_emu.utils.TurboHelper class SettingsActivityPresenter(private val activityView: SettingsActivityView) { @@ -72,11 +72,15 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView) val nomediaFileExists: Boolean try { dataDirTreeUri = PermissionsHandler.citraDirectory - dataDirDocument = DocumentFile.fromTreeUri(CitraApplication.appContext, dataDirTreeUri)!! + dataDirDocument = + DocumentFile.fromTreeUri(CitraApplication.appContext, dataDirTreeUri)!! nomediaFileDocument = dataDirDocument.findFile(".nomedia") nomediaFileExists = (nomediaFileDocument != null) } catch (e: Exception) { - Log.error("[SettingsActivity]: Error occurred while trying to find .nomedia, error: " + e.message) + Log.error( + "[SettingsActivity]: Error occurred while trying to find .nomedia, error: " + + e.message + ) return } @@ -95,7 +99,7 @@ class SettingsActivityPresenter(private val activityView: SettingsActivityView) if (finishing && shouldSave) { Log.debug("[SettingsActivity] Settings activity stopping. Saving settings to INI...") settings.saveSettings(activityView) - //added to ensure that layout changes take effect as soon as settings window closes + // added to ensure that layout changes take effect as soon as settings window closes NativeLibrary.reloadSettings() NativeLibrary.updateFramebuffer(NativeLibrary.isPortraitMode) updateAndroidImageVisibility() diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsAdapter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsAdapter.kt index 43a1dcbbd..7fc724498 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsAdapter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsAdapter.kt @@ -29,6 +29,9 @@ import com.google.android.material.textfield.TextInputEditText import com.google.android.material.textfield.TextInputLayout import com.google.android.material.timepicker.MaterialTimePicker import com.google.android.material.timepicker.TimeFormat +import java.lang.NumberFormatException +import java.text.SimpleDateFormat +import kotlin.math.roundToInt import org.citra.citra_emu.R import org.citra.citra_emu.databinding.DialogSliderBinding import org.citra.citra_emu.databinding.DialogSoftwareKeyboardBinding @@ -39,16 +42,16 @@ import org.citra.citra_emu.features.settings.model.AbstractBooleanSetting import org.citra.citra_emu.features.settings.model.AbstractFloatSetting import org.citra.citra_emu.features.settings.model.AbstractIntSetting import org.citra.citra_emu.features.settings.model.AbstractSetting +import org.citra.citra_emu.features.settings.model.AbstractShortSetting import org.citra.citra_emu.features.settings.model.AbstractStringSetting import org.citra.citra_emu.features.settings.model.FloatSetting import org.citra.citra_emu.features.settings.model.IntListSetting import org.citra.citra_emu.features.settings.model.ScaledFloatSetting -import org.citra.citra_emu.features.settings.model.AbstractShortSetting import org.citra.citra_emu.features.settings.model.view.DateTimeSetting import org.citra.citra_emu.features.settings.model.view.InputBindingSetting +import org.citra.citra_emu.features.settings.model.view.MultiChoiceSetting import org.citra.citra_emu.features.settings.model.view.SettingsItem import org.citra.citra_emu.features.settings.model.view.SingleChoiceSetting -import org.citra.citra_emu.features.settings.model.view.MultiChoiceSetting import org.citra.citra_emu.features.settings.model.view.SliderSetting import org.citra.citra_emu.features.settings.model.view.StringInputSetting import org.citra.citra_emu.features.settings.model.view.StringSingleChoiceSetting @@ -69,14 +72,10 @@ import org.citra.citra_emu.fragments.AutoMapDialogFragment import org.citra.citra_emu.fragments.MessageDialogFragment import org.citra.citra_emu.fragments.MotionBottomSheetDialogFragment import org.citra.citra_emu.utils.SystemSaveGame -import java.lang.NumberFormatException -import java.text.SimpleDateFormat -import kotlin.math.roundToInt -class SettingsAdapter( - private val fragmentView: SettingsFragmentView, - public val context: Context -) : RecyclerView.Adapter(), DialogInterface.OnClickListener, +class SettingsAdapter(private val fragmentView: SettingsFragmentView, public val context: Context) : + RecyclerView.Adapter(), + DialogInterface.OnClickListener, DialogInterface.OnMultiChoiceClickListener { private var settings: ArrayList? = null private var clickedItem: SettingsItem? = null @@ -148,17 +147,11 @@ class SettingsAdapter( getItem(position)?.let { holder.bind(it) } } - private fun getItem(position: Int): SettingsItem? { - return settings?.get(position) - } + private fun getItem(position: Int): SettingsItem? = settings?.get(position) - override fun getItemCount(): Int { - return settings?.size ?: 0 - } + override fun getItemCount(): Int = settings?.size ?: 0 - override fun getItemViewType(position: Int): Int { - return getItem(position)?.type ?: -1 - } + override fun getItemViewType(position: Int): Int = getItem(position)?.type ?: -1 fun setSettingsList(newSettings: ArrayList?) { if (settings == null) { @@ -196,22 +189,28 @@ class SettingsAdapter( } SettingsItem.TYPE_SINGLE_CHOICE -> { - (oldItem as SingleChoiceSetting).isEnabled == (newItem as SingleChoiceSetting).isEnabled + (oldItem as SingleChoiceSetting).isEnabled == + (newItem as SingleChoiceSetting).isEnabled } + SettingsItem.TYPE_MULTI_CHOICE -> { - (oldItem as MultiChoiceSetting).isEnabled == (newItem as MultiChoiceSetting).isEnabled + (oldItem as MultiChoiceSetting).isEnabled == + (newItem as MultiChoiceSetting).isEnabled } SettingsItem.TYPE_DATETIME_SETTING -> { - (oldItem as DateTimeSetting).isEnabled == (newItem as DateTimeSetting).isEnabled + (oldItem as DateTimeSetting).isEnabled == + (newItem as DateTimeSetting).isEnabled } SettingsItem.TYPE_STRING_SINGLE_CHOICE -> { - (oldItem as StringSingleChoiceSetting).isEnabled == (newItem as StringSingleChoiceSetting).isEnabled + (oldItem as StringSingleChoiceSetting).isEnabled == + (newItem as StringSingleChoiceSetting).isEnabled } SettingsItem.TYPE_STRING_INPUT -> { - (oldItem as StringInputSetting).isEnabled == (newItem as StringInputSetting).isEnabled + (oldItem as StringInputSetting).isEnabled == + (newItem as StringInputSetting).isEnabled } else -> { @@ -231,9 +230,10 @@ class SettingsAdapter( fragmentView.onSettingChanged() // If statement is required otherwise the app will crash on activity recreate ex. theme settings - if (fragmentView.activityView != null) - // Reload the settings list to update the UI + if (fragmentView.activityView != null) { + // Reload the settings list to update the UI fragmentView.loadSettingsList() + } } private fun onSingleChoiceClick(item: SingleChoiceSetting) { @@ -253,7 +253,7 @@ class SettingsAdapter( private fun onMultiChoiceClick(item: MultiChoiceSetting) { clickedItem = item - val value: BooleanArray = getSelectionForMultiChoiceValue(item); + val value: BooleanArray = getSelectionForMultiChoiceValue(item) dialog = MaterialAlertDialogBuilder(context) .setTitle(item.nameId) .setMultiChoiceItems(item.choicesId, value, this) @@ -298,7 +298,7 @@ class SettingsAdapter( val time = item.value.substringAfter(" ") val formatter = SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZZZZ") - val gmt = formatter.parse("${date}T${time}+0000") + val gmt = formatter.parse("${date}T$time+0000") gmt!!.time } @@ -354,7 +354,6 @@ class SettingsAdapter( clickedPosition = position sliderProgress = (item.selectedFloat * 100f).roundToInt() / 100f - val inflater = LayoutInflater.from(context) val sliderBinding = DialogSliderBinding.inflate(inflater) textInputLayout = sliderBinding.textInput @@ -376,9 +375,9 @@ class SettingsAdapter( value = sliderProgress textSliderValue?.addTextChangedListener(object : TextWatcher { override fun afterTextChanged(s: Editable) { - var textValue = s.toString().toFloatOrNull(); + var textValue = s.toString().toFloatOrNull() if (item.setting !is FloatSetting) { - textValue = textValue?.roundToInt()?.toFloat(); + textValue = textValue?.roundToInt()?.toFloat() } if (textValue == null || textValue < valueFrom || textValue > valueTo) { textInputLayout?.error = "Inappropriate value" @@ -425,6 +424,7 @@ class SettingsAdapter( } is FloatSetting -> (item.setting as FloatSetting).defaultValue + else -> item.defaultValue ?: 0f } onClick(dialog, which) @@ -495,7 +495,9 @@ class SettingsAdapter( it.setSelectedValue(value) } - else -> throw IllegalStateException("Unrecognized type used for SingleChoiceSetting!") + else -> throw IllegalStateException( + "Unrecognized type used for SingleChoiceSetting!" + ) } fragmentView?.putSetting(setting) fragmentView.loadSettingsList() @@ -518,7 +520,9 @@ class SettingsAdapter( it.setSelectedValue(it.getValueAt(which)?.toShort() ?: 1) } - else -> throw IllegalStateException("Unrecognized type used for StringSingleChoiceSetting!") + else -> throw IllegalStateException( + "Unrecognized type used for StringSingleChoiceSetting!" + ) } fragmentView?.putSetting(setting) @@ -569,13 +573,22 @@ class SettingsAdapter( textInputValue = "" } - //onclick for multichoice + // onclick for multichoice override fun onClick(dialog: DialogInterface?, which: Int, isChecked: Boolean) { val mcsetting = clickedItem as? MultiChoiceSetting mcsetting?.let { val value = getValueForMultiChoiceSelection(it, which) if (it.selectedValues.contains(value) != isChecked) { - val setting = it.setSelectedValue((if (isChecked) it.selectedValues + value else it.selectedValues - value).sorted()) + val setting = it.setSelectedValue( + ( + if (isChecked) { + it.selectedValues + value + } else { + it.selectedValues - + value + } + ).sorted() + ) fragmentView?.putSetting(setting) fragmentView?.onSettingChanged() } @@ -583,13 +596,13 @@ class SettingsAdapter( } } - fun onLongClick(setting: AbstractSetting, position: Int): Boolean { MaterialAlertDialogBuilder(context) .setMessage(R.string.reset_setting_confirmation) .setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int -> when (setting) { is AbstractBooleanSetting -> setting.boolean = setting.defaultValue as Boolean + is AbstractFloatSetting -> { if (setting is ScaledFloatSetting) { setting.float = setting.defaultValue * setting.scale @@ -599,7 +612,9 @@ class SettingsAdapter( } is AbstractIntSetting -> setting.int = setting.defaultValue as Int + is AbstractStringSetting -> setting.string = setting.defaultValue as String + is AbstractShortSetting -> setting.short = setting.defaultValue as Short } notifyItemChanged(position) @@ -628,14 +643,16 @@ class SettingsAdapter( } fun onClickDisabledSetting(isRuntimeDisabled: Boolean) { - val titleId = if (isRuntimeDisabled) + val titleId = if (isRuntimeDisabled) { R.string.setting_not_editable - else + } else { R.string.setting_disabled - val messageId = if (isRuntimeDisabled) + } + val messageId = if (isRuntimeDisabled) { R.string.setting_not_editable_description - else + } else { R.string.setting_disabled_description + } MessageDialogFragment.newInstance( titleId, @@ -652,7 +669,10 @@ class SettingsAdapter( } fun onLongClickAutoMap(): Boolean { - showConfirmationDialog(R.string.controller_clear_all, R.string.controller_clear_all_confirm) { + showConfirmationDialog( + R.string.controller_clear_all, + R.string.controller_clear_all_confirm + ) { InputBindingSetting.clearAllBindings() fragmentView.loadSettingsList() fragmentView.onSettingChanged() @@ -661,14 +681,20 @@ class SettingsAdapter( } fun onClickRegenerateConsoleId() { - showConfirmationDialog(R.string.regenerate_console_id, R.string.regenerate_console_id_description) { + showConfirmationDialog( + R.string.regenerate_console_id, + R.string.regenerate_console_id_description + ) { SystemSaveGame.regenerateConsoleId() notifyDataSetChanged() } } fun onClickRegenerateMAC() { - showConfirmationDialog(R.string.regenerate_mac_address, R.string.regenerate_mac_address_description) { + showConfirmationDialog( + R.string.regenerate_mac_address, + R.string.regenerate_mac_address_description + ) { SystemSaveGame.regenerateMac() notifyDataSetChanged() } @@ -732,18 +758,18 @@ class SettingsAdapter( } private fun getSelectionForMultiChoiceValue(item: MultiChoiceSetting): BooleanArray { - val value = item.selectedValues; - val valuesId = item.valuesId; + val value = item.selectedValues + val valuesId = item.valuesId if (valuesId > 0) { - val valuesArray = context.resources.getIntArray(valuesId); - val res = BooleanArray(valuesArray.size){false} + val valuesArray = context.resources.getIntArray(valuesId) + val res = BooleanArray(valuesArray.size) { false } for (index in valuesArray.indices) { if (value.contains(valuesArray[index])) { - res[index] = true; + res[index] = true } } - return res; + return res } - return BooleanArray(1){false}; + return BooleanArray(1) { false } } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragment.kt index 96568a76a..e2d1ca51e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragment.kt @@ -19,7 +19,9 @@ import org.citra.citra_emu.databinding.FragmentSettingsBinding import org.citra.citra_emu.features.settings.model.AbstractSetting import org.citra.citra_emu.features.settings.model.view.SettingsItem -class SettingsFragment : Fragment(), SettingsFragmentView { +class SettingsFragment : + Fragment(), + SettingsFragmentView { override var activityView: SettingsActivityView? = null private val fragmentPresenter = SettingsFragmentPresenter(this) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt index ad3f9cb8c..df568e9a7 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/SettingsFragmentPresenter.kt @@ -27,8 +27,8 @@ import org.citra.citra_emu.features.settings.model.AbstractShortSetting import org.citra.citra_emu.features.settings.model.AbstractStringSetting import org.citra.citra_emu.features.settings.model.BooleanSetting import org.citra.citra_emu.features.settings.model.FloatSetting -import org.citra.citra_emu.features.settings.model.IntSetting import org.citra.citra_emu.features.settings.model.IntListSetting +import org.citra.citra_emu.features.settings.model.IntSetting import org.citra.citra_emu.features.settings.model.ScaledFloatSetting import org.citra.citra_emu.features.settings.model.Settings import org.citra.citra_emu.features.settings.model.StringSetting @@ -94,18 +94,31 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) } when (menuTag) { SettingsFile.FILE_NAME_CONFIG -> addConfigSettings(sl) + Settings.SECTION_CORE -> addGeneralSettings(sl) + Settings.SECTION_SYSTEM -> addSystemSettings(sl) + Settings.SECTION_CAMERA -> addCameraSettings(sl) + Settings.SECTION_CONTROLS -> addControlsSettings(sl) + Settings.SECTION_RENDERER -> addGraphicsSettings(sl) + Settings.SECTION_LAYOUT -> addLayoutSettings(sl) + Settings.SECTION_AUDIO -> addAudioSettings(sl) + Settings.SECTION_DEBUG -> addDebugSettings(sl) + Settings.SECTION_THEME -> addThemeSettings(sl) + Settings.SECTION_CUSTOM_LANDSCAPE -> addCustomLandscapeSettings(sl) + Settings.SECTION_CUSTOM_PORTRAIT -> addCustomPortraitSettings(sl) + Settings.SECTION_PERFORMANCE_OVERLAY -> addPerformanceOverlaySettings(sl) + else -> { fragmentView.showToastMessage("Unimplemented menu", false) return @@ -128,13 +141,9 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) } } - private fun getSmallerDimension(): Int { - return getDimensions().min() - } + private fun getSmallerDimension(): Int = getDimensions().min() - private fun getLargerDimension(): Int { - return getDimensions().max() - } + private fun getLargerDimension(): Int = getDimensions().max() private fun addConfigSettings(sl: ArrayList) { settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_settings)) @@ -360,7 +369,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) R.string.emulated_region, 0, R.array.regionNames, - R.array.regionValues, + R.array.regionValues ) ) add( @@ -377,7 +386,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) get() { val ret = SystemSaveGame.getCountryCode() checkCountryCompatibility() - return ret; + return ret } set(value) { SystemSaveGame.setCountryCode(value) @@ -626,20 +635,23 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY ) { - continue // Legacy cameras cannot be used with the NDK + continue // Legacy cameras cannot be used with the NDK } supportedCameraIdList.add(id) val facing = characteristics.get(CameraCharacteristics.LENS_FACING) var stringId: Int = R.string.camera_facing_external when (facing) { - CameraCharacteristics.LENS_FACING_FRONT -> stringId = - R.string.camera_facing_front + CameraCharacteristics.LENS_FACING_FRONT -> + stringId = + R.string.camera_facing_front - CameraCharacteristics.LENS_FACING_BACK -> stringId = - R.string.camera_facing_back + CameraCharacteristics.LENS_FACING_BACK -> + stringId = + R.string.camera_facing_back - CameraCharacteristics.LENS_FACING_EXTERNAL -> stringId = - R.string.camera_facing_external + CameraCharacteristics.LENS_FACING_EXTERNAL -> + stringId = + R.string.camera_facing_external } supportedCameraNameList.add( String.format("%1\$s (%2\$s)", id, settingsActivity.getString(stringId)) @@ -816,12 +828,22 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) add(InputBindingSetting(button, Settings.axisTitles[i])) } - add(HeaderSetting(R.string.controller_dpad_axis,R.string.controller_dpad_axis_description)) + add( + HeaderSetting( + R.string.controller_dpad_axis, + R.string.controller_dpad_axis_description + ) + ) Settings.dPadAxisKeys.forEachIndexed { i: Int, key: String -> val button = getInputObject(key) add(InputBindingSetting(button, Settings.axisTitles[i])) } - add(HeaderSetting(R.string.controller_dpad_button,R.string.controller_dpad_button_description)) + add( + HeaderSetting( + R.string.controller_dpad_button, + R.string.controller_dpad_button_description + ) + ) Settings.dPadButtonKeys.forEachIndexed { i: Int, key: String -> val button = getInputObject(key) add(InputBindingSetting(button, Settings.dPadTitles[i])) @@ -833,7 +855,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) add(InputBindingSetting(button, Settings.triggerTitles[i])) } - add(HeaderSetting(R.string.controller_hotkeys,R.string.controller_hotkeys_description)) + add(HeaderSetting(R.string.controller_hotkeys, R.string.controller_hotkeys_description)) Settings.hotKeys.forEachIndexed { i: Int, key: String -> val button = getInputObject(key) add(InputBindingSetting(button, Settings.hotkeyTitles[i])) @@ -851,8 +873,8 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) } } - private fun getInputObject(key: String): AbstractStringSetting { - return object : AbstractStringSetting { + private fun getInputObject(key: String): AbstractStringSetting = + object : AbstractStringSetting { override var string: String get() = preferences.getString(key, "")!! set(value) { @@ -866,7 +888,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) override val valueAsString = preferences.getString(key, "")!! override val defaultValue = "" } - } private fun addGraphicsSettings(sl: ArrayList) { settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_graphics)) @@ -889,7 +910,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) R.string.spirv_shader_gen, R.string.spirv_shader_gen_description, BooleanSetting.SPIRV_SHADER_GEN.key, - BooleanSetting.SPIRV_SHADER_GEN.defaultValue, + BooleanSetting.SPIRV_SHADER_GEN.defaultValue ) ) add( @@ -898,7 +919,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) R.string.disable_spirv_optimizer, R.string.disable_spirv_optimizer_description, BooleanSetting.DISABLE_SPIRV_OPTIMIZER.key, - BooleanSetting.DISABLE_SPIRV_OPTIMIZER.defaultValue, + BooleanSetting.DISABLE_SPIRV_OPTIMIZER.defaultValue ) ) add( @@ -921,7 +942,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) IntSetting.RESOLUTION_FACTOR.defaultValue ) ) - add( + add( SwitchSetting( BooleanSetting.USE_INTEGER_SCALING, R.string.use_integer_scaling, @@ -1002,7 +1023,8 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) R.array.render3dValues, IntSetting.STEREOSCOPIC_3D_MODE.key, IntSetting.STEREOSCOPIC_3D_MODE.defaultValue, - isEnabled = IntSetting.RENDER_3D_WHICH_DISPLAY.int != StereoWhichDisplay.NONE.int + isEnabled = + IntSetting.RENDER_3D_WHICH_DISPLAY.int != StereoWhichDisplay.NONE.int ) ) @@ -1035,7 +1057,8 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) R.string.swap_eyes_3d_description, BooleanSetting.SWAP_EYES_3D.key, BooleanSetting.SWAP_EYES_3D.defaultValue, - isEnabled = IntSetting.RENDER_3D_WHICH_DISPLAY.int != StereoWhichDisplay.NONE.int + isEnabled = + IntSetting.RENDER_3D_WHICH_DISPLAY.int != StereoWhichDisplay.NONE.int ) ) @@ -1201,7 +1224,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) IntSetting.PORTRAIT_SCREEN_LAYOUT.defaultValue ) ) - add ( + add( SwitchSetting( BooleanSetting.ENABLE_SECONDARY_DISPLAY, R.string.emulation_secondary_display_enable, @@ -1231,7 +1254,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) R.array.aspectRatioValues, IntSetting.ASPECT_RATIO.key, IntSetting.ASPECT_RATIO.defaultValue, - isEnabled = IntSetting.SCREEN_LAYOUT.int == ScreenLayout.SINGLE_SCREEN.int, + isEnabled = IntSetting.SCREEN_LAYOUT.int == ScreenLayout.SINGLE_SCREEN.int ) ) add( @@ -1288,7 +1311,10 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) get() = (FloatSetting.BACKGROUND_RED.float * 255).toInt() set(value) { FloatSetting.BACKGROUND_RED.float = value.toFloat() / 255 - settings.saveSetting(FloatSetting.BACKGROUND_RED, SettingsFile.FILE_NAME_CONFIG) + settings.saveSetting( + FloatSetting.BACKGROUND_RED, + SettingsFile.FILE_NAME_CONFIG + ) } override val key = null override val section = null @@ -1311,7 +1337,10 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) get() = (FloatSetting.BACKGROUND_GREEN.float * 255).toInt() set(value) { FloatSetting.BACKGROUND_GREEN.float = value.toFloat() / 255 - settings.saveSetting(FloatSetting.BACKGROUND_GREEN, SettingsFile.FILE_NAME_CONFIG) + settings.saveSetting( + FloatSetting.BACKGROUND_GREEN, + SettingsFile.FILE_NAME_CONFIG + ) } override val key = null override val section = null @@ -1334,7 +1363,10 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) get() = (FloatSetting.BACKGROUND_BLUE.float * 255).toInt() set(value) { FloatSetting.BACKGROUND_BLUE.float = value.toFloat() / 255 - settings.saveSetting(FloatSetting.BACKGROUND_BLUE, SettingsFile.FILE_NAME_CONFIG) + settings.saveSetting( + FloatSetting.BACKGROUND_BLUE, + SettingsFile.FILE_NAME_CONFIG + ) } override val key = null override val section = null @@ -1380,9 +1412,10 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) } private fun addPerformanceOverlaySettings(sl: ArrayList) { - settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.performance_overlay_options)) + settingsActivity.setToolbarTitle( + settingsActivity.getString(R.string.performance_overlay_options) + ) sl.apply { - add(HeaderSetting(R.string.visibility)) add( @@ -1411,11 +1444,10 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) R.string.performance_overlay_position, R.string.performance_overlay_position_description, R.array.statsPosition, - R.array.statsPositionValues, + R.array.statsPositionValues ) ) - add(HeaderSetting(R.string.information)) add( @@ -1481,7 +1513,9 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) } private fun addCustomLandscapeSettings(sl: ArrayList) { - settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.emulation_landscape_custom_layout)) + settingsActivity.setToolbarTitle( + settingsActivity.getString(R.string.emulation_landscape_custom_layout) + ) sl.apply { add(HeaderSetting(R.string.emulation_top_screen)) add( @@ -1582,11 +1616,12 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) ) ) } - } private fun addCustomPortraitSettings(sl: ArrayList) { - settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.emulation_portrait_custom_layout)) + settingsActivity.setToolbarTitle( + settingsActivity.getString(R.string.emulation_portrait_custom_layout) + ) sl.apply { add(HeaderSetting(R.string.emulation_top_screen)) add( @@ -1687,7 +1722,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) ) ) } - } private fun addAudioSettings(sl: ArrayList) { @@ -1881,7 +1915,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView) BooleanSetting.DETERMINISTIC_ASYNC_OPERATIONS.defaultValue ) ) - } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt index 7eb2dae97..58cbded3e 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/DateTimeViewHolder.kt @@ -6,16 +6,16 @@ package org.citra.citra_emu.features.settings.ui.viewholder import android.annotation.SuppressLint import android.view.View -import org.citra.citra_emu.databinding.ListItemSettingBinding +import java.text.SimpleDateFormat import java.time.Instant import java.time.ZoneId import java.time.ZonedDateTime import java.time.format.DateTimeFormatter import java.time.format.FormatStyle +import org.citra.citra_emu.databinding.ListItemSettingBinding import org.citra.citra_emu.features.settings.model.view.DateTimeSetting import org.citra.citra_emu.features.settings.model.view.SettingsItem import org.citra.citra_emu.features.settings.ui.SettingsAdapter -import java.text.SimpleDateFormat class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : SettingViewHolder(binding.root, adapter) { @@ -39,7 +39,7 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA val time = setting.value.substringAfter(" ") val formatter = SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ssZZZZ") - val gmt = formatter.parse("${date}T${time}+0000") + val gmt = formatter.parse("${date}T$time+0000") gmt!!.time / 1000 } val instant = Instant.ofEpochMilli(epochTime * 1000) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/HeaderViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/HeaderViewHolder.kt index ed794fcfb..1041f23cd 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/HeaderViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/HeaderViewHolder.kt @@ -21,7 +21,7 @@ class HeaderViewHolder(val binding: ListItemSettingsHeaderBinding, adapter: Sett if (item.descriptionId != 0) { binding.textHeaderDescription.visibility = View.VISIBLE binding.textHeaderDescription.setText(item.descriptionId) - }else { + } else { binding.textHeaderDescription.visibility = View.GONE } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/MultiChoiceViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/MultiChoiceViewHolder.kt index 8493115a4..3c44cb800 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/MultiChoiceViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/MultiChoiceViewHolder.kt @@ -6,8 +6,8 @@ package org.citra.citra_emu.features.settings.ui.viewholder import android.view.View import org.citra.citra_emu.databinding.ListItemSettingBinding -import org.citra.citra_emu.features.settings.model.view.SettingsItem import org.citra.citra_emu.features.settings.model.view.MultiChoiceSetting +import org.citra.citra_emu.features.settings.model.view.SettingsItem import org.citra.citra_emu.features.settings.ui.SettingsAdapter class MultiChoiceViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAdapter) : @@ -42,13 +42,13 @@ class MultiChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Settin is MultiChoiceSetting -> { val resMgr = binding.textSettingDescription.context.resources val values = resMgr.getIntArray(item.valuesId) - var resList:List = emptyList(); + var resList: List = emptyList() values.forEachIndexed { i: Int, value: Int -> if ((setting as MultiChoiceSetting).selectedValues.contains(value)) { - resList = resList + resMgr.getStringArray(item.choicesId)[i]; + resList = resList + resMgr.getStringArray(item.choicesId)[i] } } - return resList.joinToString(); + return resList.joinToString() } else -> return "" diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SettingViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SettingViewHolder.kt index 5b4d39cf4..351f788bc 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SettingViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SettingViewHolder.kt @@ -10,7 +10,9 @@ import org.citra.citra_emu.features.settings.model.view.SettingsItem import org.citra.citra_emu.features.settings.ui.SettingsAdapter abstract class SettingViewHolder(itemView: View, protected val adapter: SettingsAdapter) : - RecyclerView.ViewHolder(itemView), View.OnClickListener, View.OnLongClickListener { + RecyclerView.ViewHolder(itemView), + View.OnClickListener, + View.OnLongClickListener { init { itemView.setOnClickListener(this) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SliderViewHolder.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SliderViewHolder.kt index 726d8c96f..ca91edada 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SliderViewHolder.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/ui/viewholder/SliderViewHolder.kt @@ -31,7 +31,9 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda binding.textSettingValue.text = when (setting.setting) { is ScaledFloatSetting -> "${(setting.setting as ScaledFloatSetting).float.toInt()}${setting.units}" + is FloatSetting -> "${(setting.setting as AbstractFloatSetting).float}${setting.units}" + else -> "${(setting.setting as AbstractIntSetting).int}${setting.units}" } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/utils/SettingsFile.kt b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/utils/SettingsFile.kt index a9e1d4743..c99e8378d 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/features/settings/utils/SettingsFile.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/features/settings/utils/SettingsFile.kt @@ -7,6 +7,11 @@ package org.citra.citra_emu.features.settings.utils import android.content.Context import android.net.Uri import androidx.documentfile.provider.DocumentFile +import java.io.BufferedReader +import java.io.FileNotFoundException +import java.io.IOException +import java.io.InputStreamReader +import java.util.TreeMap import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.AbstractSetting @@ -23,12 +28,6 @@ import org.citra.citra_emu.utils.BiMap import org.citra.citra_emu.utils.DirectoryInitialization.userDirectory import org.citra.citra_emu.utils.Log import org.ini4j.Wini -import java.io.BufferedReader -import java.io.FileNotFoundException -import java.io.IOException -import java.io.InputStreamReader -import java.util.TreeMap - /** * Contains static methods for interacting with .ini files in which settings are stored. @@ -90,9 +89,8 @@ object SettingsFile { return sections } - fun readFile(fileName: String, view: SettingsActivityView?): HashMap { - return readFile(getSettingsFile(fileName), false, view) - } + fun readFile(fileName: String, view: SettingsActivityView?): HashMap = + readFile(getSettingsFile(fileName), false, view) fun readFile(fileName: String): HashMap = readFile(fileName, null) @@ -107,9 +105,7 @@ object SettingsFile { fun readCustomGameSettings( gameId: String, view: SettingsActivityView? - ): HashMap { - return readFile(getCustomGameSettingsFile(gameId), true, view) - } + ): HashMap = readFile(getCustomGameSettingsFile(gameId), true, view) /** * Saves a Settings HashMap to a given .ini file on disk. If unsuccessful, outputs an error @@ -143,15 +139,13 @@ object SettingsFile { Log.error("[SettingsFile] File not found: $fileName.ini: ${e.message}") view.showToastMessage( CitraApplication.appContext - .getString(R.string.error_saving, fileName, e.message), false + .getString(R.string.error_saving, fileName, e.message), + false ) } } - fun saveFile( - fileName: String, - setting: AbstractSetting - ) { + fun saveFile(fileName: String, setting: AbstractSetting) { val ini = getSettingsFile(fileName) try { val context: Context = CitraApplication.appContext @@ -168,21 +162,19 @@ object SettingsFile { } } - private fun mapSectionNameFromIni(generalSectionName: String): String? { - return if (sectionsMap.getForward(generalSectionName) != null) { + private fun mapSectionNameFromIni(generalSectionName: String): String? = + if (sectionsMap.getForward(generalSectionName) != null) { sectionsMap.getForward(generalSectionName) } else { generalSectionName } - } - private fun mapSectionNameToIni(generalSectionName: String): String { - return if (sectionsMap.getBackward(generalSectionName) != null) { + private fun mapSectionNameToIni(generalSectionName: String): String = + if (sectionsMap.getBackward(generalSectionName) != null) { sectionsMap.getBackward(generalSectionName).toString() } else { generalSectionName } - } fun getSettingsFile(fileName: String): DocumentFile { val root = DocumentFile.fromTreeUri(CitraApplication.appContext, Uri.parse(userDirectory)) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/AboutFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/AboutFragment.kt index 3943aa23d..9ea904b00 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/AboutFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/AboutFragment.kt @@ -96,28 +96,27 @@ class AboutFragment : Fragment() { startActivity(intent) } - private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener( - binding.root - ) { _: View, windowInsets: WindowInsetsCompat -> - val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener( + binding.root + ) { _: View, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) - val leftInsets = barInsets.left + cutoutInsets.left - val rightInsets = barInsets.right + cutoutInsets.right + val leftInsets = barInsets.left + cutoutInsets.left + val rightInsets = barInsets.right + cutoutInsets.right - val mlpAppBar = binding.toolbarAbout.layoutParams as MarginLayoutParams - mlpAppBar.leftMargin = leftInsets - mlpAppBar.rightMargin = rightInsets - binding.toolbarAbout.layoutParams = mlpAppBar + val mlpAppBar = binding.toolbarAbout.layoutParams as MarginLayoutParams + mlpAppBar.leftMargin = leftInsets + mlpAppBar.rightMargin = rightInsets + binding.toolbarAbout.layoutParams = mlpAppBar - val mlpScrollAbout = binding.scrollAbout.layoutParams as MarginLayoutParams - mlpScrollAbout.leftMargin = leftInsets - mlpScrollAbout.rightMargin = rightInsets - binding.scrollAbout.layoutParams = mlpScrollAbout + val mlpScrollAbout = binding.scrollAbout.layoutParams as MarginLayoutParams + mlpScrollAbout.leftMargin = leftInsets + mlpScrollAbout.rightMargin = rightInsets + binding.scrollAbout.layoutParams = mlpScrollAbout - binding.contentAbout.updatePadding(bottom = barInsets.bottom) + binding.contentAbout.updatePadding(bottom = barInsets.bottom) - windowInsets - } + windowInsets + } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/AutoMapDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/AutoMapDialogFragment.kt index 569a0caca..8face55b8 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/AutoMapDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/AutoMapDialogFragment.kt @@ -90,7 +90,9 @@ class AutoMapDialogFragment : BottomSheetDialogFragment() { // Nintendo layout: east position sends KEYCODE_BUTTON_A (96) val isNintendoLayout = when (keyCode) { KeyEvent.KEYCODE_BUTTON_A -> true + KeyEvent.KEYCODE_BUTTON_B -> false + else -> { // Unrecognized button - ignore and wait for a valid press Log.warning("[AutoMap] Ignoring unrecognized keycode $keyCode, waiting for A or B") @@ -117,9 +119,7 @@ class AutoMapDialogFragment : BottomSheetDialogFragment() { companion object { const val TAG = "AutoMapDialogFragment" - fun newInstance( - onComplete: () -> Unit - ): AutoMapDialogFragment { + fun newInstance(onComplete: () -> Unit): AutoMapDialogFragment { val dialog = AutoMapDialogFragment() dialog.onComplete = onComplete return dialog diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/CitraDirectoryDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/CitraDirectoryDialogFragment.kt index e663d290b..8145d7102 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/CitraDirectoryDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/CitraDirectoryDialogFragment.kt @@ -60,7 +60,9 @@ class CitraDirectoryDialogFragment : DialogFragment() { } .setNegativeButton(android.R.string.cancel) { _: DialogInterface?, _: Int -> if (!PermissionsHandler.hasWriteAccess(requireContext())) { - PermissionsHandler.compatibleSelectDirectory((requireActivity() as MainActivity).openCitraDirectory) + PermissionsHandler.compatibleSelectDirectory( + (requireActivity() as MainActivity).openCitraDirectory + ) } } .show() diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/CompressProgressDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/CompressProgressDialogFragment.kt index bcd97ae03..496ab8aef 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/CompressProgressDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/CompressProgressDialogFragment.kt @@ -9,16 +9,16 @@ import android.os.Bundle import android.view.View import android.widget.ProgressBar import androidx.fragment.app.DialogFragment +import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope import androidx.lifecycle.repeatOnLifecycle -import androidx.lifecycle.Lifecycle import com.google.android.material.dialog.MaterialAlertDialogBuilder import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.flow.combine import kotlinx.coroutines.launch +import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.R import org.citra.citra_emu.viewmodel.CompressProgressDialogViewModel -import org.citra.citra_emu.NativeLibrary class CompressProgressDialogFragment : DialogFragment() { private lateinit var progressBar: ProgressBar @@ -37,14 +37,27 @@ class CompressProgressDialogFragment : DialogFragment() { val view = layoutInflater.inflate(R.layout.dialog_compress_progress, null) progressBar = view.findViewById(R.id.compress_progress) val label = view.findViewById(R.id.compress_label) - label.text = if (isCompressing) getString(R.string.compressing) else getString(R.string.decompressing) + label.text = + if (isCompressing) { + getString( + R.string.compressing + ) + } else { + getString(R.string.decompressing) + } isCancelable = false progressBar.isIndeterminate = true lifecycleScope.launch { repeatOnLifecycle(Lifecycle.State.STARTED) { - combine(CompressProgressDialogViewModel.total, CompressProgressDialogViewModel.progress) { total, progress -> + combine( + CompressProgressDialogViewModel.total, + CompressProgressDialogViewModel.progress + ) { + total, + progress + -> total to progress }.collectLatest { (total, progress) -> if (total <= 0) { @@ -63,7 +76,10 @@ class CompressProgressDialogFragment : DialogFragment() { val builder = MaterialAlertDialogBuilder(requireContext()) .setView(view) .setCancelable(false) - .setNegativeButton(android.R.string.cancel) { _: android.content.DialogInterface, _: Int -> + .setNegativeButton(android.R.string.cancel) { + _: android.content.DialogInterface, + _: Int + -> outputPath?.let { path -> NativeLibrary.deleteDocument(path) } @@ -77,7 +93,10 @@ class CompressProgressDialogFragment : DialogFragment() { private const val ARG_IS_COMPRESSING = "isCompressing" private const val ARG_OUTPUT_PATH = "outputPath" - fun newInstance(isCompressing: Boolean, outputPath: String?): CompressProgressDialogFragment { + fun newInstance( + isCompressing: Boolean, + outputPath: String? + ): CompressProgressDialogFragment { val frag = CompressProgressDialogFragment() val args = Bundle() args.putBoolean(ARG_IS_COMPRESSING, isCompressing) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/CopyDirProgressDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/CopyDirProgressDialogFragment.kt index 14111de51..f6d912468 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/CopyDirProgressDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/CopyDirProgressDialogFragment.kt @@ -52,9 +52,7 @@ class CopyDirProgressDialog : DialogFragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View { - return binding.root - } + ): View = binding.root override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) @@ -144,7 +142,8 @@ class CopyDirProgressDialog : DialogFragment() { callback?.onStepCompleted(0, false) viewModel.setCopyComplete(true) } - }) + } + ) } } return CopyDirProgressDialog() diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/DriverManagerFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/DriverManagerFragment.kt index 016ba34ae..81d027ee0 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/DriverManagerFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/DriverManagerFragment.kt @@ -19,6 +19,7 @@ import androidx.lifecycle.lifecycleScope import androidx.navigation.findNavController import androidx.recyclerview.widget.GridLayoutManager import com.google.android.material.transition.MaterialSharedAxis +import java.io.IOException import kotlinx.coroutines.flow.collectLatest import kotlinx.coroutines.launch import org.citra.citra_emu.R @@ -27,9 +28,8 @@ import org.citra.citra_emu.databinding.FragmentDriverManagerBinding import org.citra.citra_emu.utils.FileUtil.asDocumentFile import org.citra.citra_emu.utils.FileUtil.inputStream import org.citra.citra_emu.utils.GpuDriverHelper -import org.citra.citra_emu.viewmodel.HomeViewModel import org.citra.citra_emu.viewmodel.DriverViewModel -import java.io.IOException +import org.citra.citra_emu.viewmodel.HomeViewModel class DriverManagerFragment : Fragment() { private var _binding: FragmentDriverManagerBinding? = null @@ -110,41 +110,40 @@ class DriverManagerFragment : Fragment() { driverViewModel.onCloseDriverManager() } - private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener( - binding.root - ) { _: View, windowInsets: WindowInsetsCompat -> - val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener( + binding.root + ) { _: View, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) - val leftInsets = barInsets.left + cutoutInsets.left - val rightInsets = barInsets.right + cutoutInsets.right + val leftInsets = barInsets.left + cutoutInsets.left + val rightInsets = barInsets.right + cutoutInsets.right - val mlpAppBar = binding.toolbarDrivers.layoutParams as ViewGroup.MarginLayoutParams - mlpAppBar.leftMargin = leftInsets - mlpAppBar.rightMargin = rightInsets - binding.toolbarDrivers.layoutParams = mlpAppBar + val mlpAppBar = binding.toolbarDrivers.layoutParams as ViewGroup.MarginLayoutParams + mlpAppBar.leftMargin = leftInsets + mlpAppBar.rightMargin = rightInsets + binding.toolbarDrivers.layoutParams = mlpAppBar - val mlplistDrivers = binding.listDrivers.layoutParams as ViewGroup.MarginLayoutParams - mlplistDrivers.leftMargin = leftInsets - mlplistDrivers.rightMargin = rightInsets - binding.listDrivers.layoutParams = mlplistDrivers + val mlplistDrivers = binding.listDrivers.layoutParams as ViewGroup.MarginLayoutParams + mlplistDrivers.leftMargin = leftInsets + mlplistDrivers.rightMargin = rightInsets + binding.listDrivers.layoutParams = mlplistDrivers - val fabSpacing = resources.getDimensionPixelSize(R.dimen.spacing_fab) - val mlpFab = - binding.buttonInstall.layoutParams as ViewGroup.MarginLayoutParams - mlpFab.leftMargin = leftInsets + fabSpacing - mlpFab.rightMargin = rightInsets + fabSpacing - mlpFab.bottomMargin = barInsets.bottom + fabSpacing - binding.buttonInstall.layoutParams = mlpFab + val fabSpacing = resources.getDimensionPixelSize(R.dimen.spacing_fab) + val mlpFab = + binding.buttonInstall.layoutParams as ViewGroup.MarginLayoutParams + mlpFab.leftMargin = leftInsets + fabSpacing + mlpFab.rightMargin = rightInsets + fabSpacing + mlpFab.bottomMargin = barInsets.bottom + fabSpacing + binding.buttonInstall.layoutParams = mlpFab - binding.listDrivers.updatePadding( - bottom = barInsets.bottom + - resources.getDimensionPixelSize(R.dimen.spacing_bottom_list_fab) - ) + binding.listDrivers.updatePadding( + bottom = barInsets.bottom + + resources.getDimensionPixelSize(R.dimen.spacing_bottom_list_fab) + ) - windowInsets - } + windowInsets + } private val getDriver = registerForActivityResult(ActivityResultContracts.OpenDocument()) { result -> diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt index ca3e3c386..25fc8014c 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/EmulationFragment.kt @@ -38,9 +38,9 @@ import androidx.activity.OnBackPressedCallback import androidx.coordinatorlayout.widget.CoordinatorLayout import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.Insets -import androidx.core.view.get import androidx.core.view.ViewCompat import androidx.core.view.WindowInsetsCompat +import androidx.core.view.get import androidx.drawerlayout.widget.DrawerLayout import androidx.drawerlayout.widget.DrawerLayout.DrawerListener import androidx.fragment.app.Fragment @@ -78,15 +78,18 @@ import org.citra.citra_emu.model.Game import org.citra.citra_emu.utils.BuildUtil import org.citra.citra_emu.utils.DirectoryInitialization import org.citra.citra_emu.utils.DirectoryInitialization.DirectoryInitializationState +import org.citra.citra_emu.utils.EmulationLifecycleUtil import org.citra.citra_emu.utils.EmulationMenuSettings import org.citra.citra_emu.utils.GameHelper import org.citra.citra_emu.utils.GameIconUtils -import org.citra.citra_emu.utils.EmulationLifecycleUtil import org.citra.citra_emu.utils.Log import org.citra.citra_emu.utils.ViewUtils import org.citra.citra_emu.viewmodel.EmulationViewModel -class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.FrameCallback { +class EmulationFragment : + Fragment(), + SurfaceHolder.Callback, + Choreographer.FrameCallback { private val preferences: SharedPreferences get() = PreferenceManager.getDefaultSharedPreferences(CitraApplication.appContext) @@ -117,7 +120,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram override fun onAttach(context: Context) { super.onAttach(context) if (context is EmulationActivity) { - NativeLibrary.setEmulationActivity(context) + NativeLibrary.setEmulationActivity(context) } else { throw IllegalStateException("EmulationFragment must have EmulationActivity parent") } @@ -145,10 +148,16 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram if (!BuildUtil.isGooglePlayBuild) { val intentUriString = intentUri.toString() // We need to build a special path as the incoming URI may be SAF exclusive - Log.warning("[EmulationFragment] Cannot determine native path of URI \"" + - intentUriString + "\", using file descriptor instead.") + Log.warning( + "[EmulationFragment] Cannot determine native path of URI \"" + + intentUriString + "\", using file descriptor instead." + ) if (!intentUriString.startsWith("!")) { - gameFd = requireContext().contentResolver.openFileDescriptor(intentUri, "r")?.detachFd() + gameFd = + requireContext().contentResolver.openFileDescriptor( + intentUri, + "r" + )?.detachFd() intentUri = if (gameFd != null) { Uri.parse("fd://" + gameFd.toString()) } else { @@ -159,7 +168,12 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram intentGame = intentUri?.let { // isInstalled, addedToLibrary and mediaType do not matter here - GameHelper.getGame(it, isInstalled = false, addedToLibrary = false, mediaType = Game.MediaType.GAME_CARD) + GameHelper.getGame( + it, + isInstalled = false, + addedToLibrary = false, + mediaType = Game.MediaType.GAME_CARD + ) } } @@ -199,10 +213,10 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram emulationActivity.secondaryDisplayManager.availableDisplays.isNotEmpty() binding.inGameMenu.menu.findItem(R.id.menu_landscape_screen_layout).isVisible = CitraApplication.appContext.resources.configuration.orientation != - Configuration.ORIENTATION_PORTRAIT + Configuration.ORIENTATION_PORTRAIT binding.inGameMenu.menu.findItem(R.id.menu_portrait_screen_layout).isVisible = CitraApplication.appContext.resources.configuration.orientation == - Configuration.ORIENTATION_PORTRAIT + Configuration.ORIENTATION_PORTRAIT return binding.root } @@ -486,7 +500,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram ViewUtils.showView(binding.surfaceInputOverlay) binding.inGameMenu.menu.findItem(R.id.menu_emulation_savestates) .setVisible(NativeLibrary.getSavestateInfo() != null) - binding.drawerLayout.setDrawerLockMode(EmulationMenuSettings.drawerLockMode) + binding.drawerLayout.setDrawerLockMode( + EmulationMenuSettings.drawerLockMode + ) } } } @@ -496,9 +512,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram setInsets() } - fun isDrawerOpen(): Boolean { - return binding.drawerLayout.isOpen - } + fun isDrawerOpen(): Boolean = binding.drawerLayout.isOpen private fun togglePause() { if (emulationState.isPaused) { @@ -612,7 +626,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram } private fun showStateSubmenu(isSaving: Boolean) { - val savestates = NativeLibrary.getSavestateInfo() val popupMenu = PopupMenu( @@ -1023,7 +1036,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram else -> R.id.menu_portrait_layout_top_full - } popupMenu.menu.findItem(layoutOptionMenuItem).setChecked(true) @@ -1031,12 +1043,16 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram popupMenu.setOnMenuItemClickListener { when (it.itemId) { R.id.menu_portrait_layout_top_full -> { - screenAdjustmentUtil.changePortraitOrientation(PortraitScreenLayout.TOP_FULL_WIDTH.int) + screenAdjustmentUtil.changePortraitOrientation( + PortraitScreenLayout.TOP_FULL_WIDTH.int + ) true } R.id.menu_portrait_layout_original -> { - screenAdjustmentUtil.changePortraitOrientation(PortraitScreenLayout.ORIGINAL.int) + screenAdjustmentUtil.changePortraitOrientation( + PortraitScreenLayout.ORIGINAL.int + ) true } @@ -1046,7 +1062,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram R.string.emulation_adjust_custom_layout, Toast.LENGTH_LONG ).show() - screenAdjustmentUtil.changePortraitOrientation(PortraitScreenLayout.CUSTOM_PORTRAIT_LAYOUT.int) + screenAdjustmentUtil.changePortraitOrientation( + PortraitScreenLayout.CUSTOM_PORTRAIT_LAYOUT.int + ) true } @@ -1071,12 +1089,13 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram val displays = emulationActivity.secondaryDisplayManager.availableDisplays - if (selectedLayout == SecondaryDisplayLayout.NONE.int || !BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean) { + if (selectedLayout == SecondaryDisplayLayout.NONE.int || + !BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean + ) { BooleanSetting.ENABLE_SECONDARY_DISPLAY.boolean = false enableSecondaryCheckbox.isChecked = false chooserMenu.isVisible = false popupMenu.menu.setGroupEnabled(R.id.menu_secondary_layout_group, false) - } else { popupMenu.menu.setGroupEnabled(R.id.menu_secondary_layout_group, true) chooserMenu.isVisible = (displays.size > 1) @@ -1144,37 +1163,51 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram } R.id.menu_secondary_layout_opposite -> { - screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.REVERSE_PRIMARY.int) + screenAdjustmentUtil.changeSecondaryOrientation( + SecondaryDisplayLayout.REVERSE_PRIMARY.int + ) true } R.id.menu_secondary_layout_top -> { - screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.TOP_SCREEN.int) + screenAdjustmentUtil.changeSecondaryOrientation( + SecondaryDisplayLayout.TOP_SCREEN.int + ) true } R.id.menu_secondary_layout_bottom -> { - screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.BOTTOM_SCREEN.int) + screenAdjustmentUtil.changeSecondaryOrientation( + SecondaryDisplayLayout.BOTTOM_SCREEN.int + ) true } R.id.menu_secondary_layout_side_by_side -> { - screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.SIDE_BY_SIDE.int) + screenAdjustmentUtil.changeSecondaryOrientation( + SecondaryDisplayLayout.SIDE_BY_SIDE.int + ) true } R.id.menu_secondary_layout_hybrid -> { - screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.HYBRID.int) + screenAdjustmentUtil.changeSecondaryOrientation( + SecondaryDisplayLayout.HYBRID.int + ) true } R.id.menu_secondary_layout_original -> { - screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.ORIGINAL.int) + screenAdjustmentUtil.changeSecondaryOrientation( + SecondaryDisplayLayout.ORIGINAL.int + ) true } R.id.menu_secondary_layout_largescreen -> { - screenAdjustmentUtil.changeSecondaryOrientation(SecondaryDisplayLayout.LARGE_SCREEN.int) + screenAdjustmentUtil.changeSecondaryOrientation( + SecondaryDisplayLayout.LARGE_SCREEN.int + ) true } @@ -1222,7 +1255,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram val dialog = MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.emulation_toggle_controls) .setMultiChoiceItems( - R.array.n3dsButtons, enabledButtons + R.array.n3dsButtons, + enabledButtons ) { _: DialogInterface?, indexSelected: Int, isChecked: Boolean -> editor.putBoolean("buttonToggle$indexSelected", isChecked) } @@ -1267,14 +1301,18 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} }) slider.addOnChangeListener( - Slider.OnChangeListener { slider: Slider, progress: Float, _: Boolean -> + Slider.OnChangeListener { + slider: Slider, + progress: Float, + _: Boolean + -> if (textValue.text.toString() != (slider.value + 50).toInt().toString()) { textValue.setText((slider.value + 50).toInt().toString()) textValue.setSelection(textValue.length()) setControlScale(slider.value.toInt(), target) } - - }) + } + ) textInput.suffixText = "%" } val previousProgress = sliderBinding.slider.value.toInt() @@ -1318,7 +1356,6 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram override fun onTextChanged(p0: CharSequence?, p1: Int, p2: Int, p3: Int) {} }) - slider.addOnChangeListener { _: Slider, value: Float, _: Boolean -> if (textValue.text.toString() != slider.value.toInt().toString()) { @@ -1451,7 +1488,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram (perfStats[TIME_SWAP] * 1000.0f).toFloat(), (perfStats[TIME_IPC] * 1000.0f).toFloat(), (perfStats[TIME_SVC] * 1000.0f).toFloat(), - (perfStats[TIME_REM] * 1000.0f).toFloat(), + (perfStats[TIME_REM] * 1000.0f).toFloat() ) ) } @@ -1469,7 +1506,8 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram if (BooleanSetting.PERF_OVERLAY_SHOW_APP_RAM_USAGE.boolean) { if (sb.isNotEmpty()) sb.append(dividerString) val appRamUsage = - File("/proc/self/statm").readLines()[0].split(' ')[1].toLong() * 4096 / 1000000 + File("/proc/self/statm").readLines()[0].split(' ')[1].toLong() * 4096 / + 1000000 sb.append("Process\u00A0RAM:\u00A0$appRamUsage\u00A0MB") } @@ -1494,7 +1532,9 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram } if (BooleanSetting.PERF_OVERLAY_BACKGROUND.boolean) { - binding.performanceOverlayShowText.setBackgroundResource(R.color.citra_transparent_black) + binding.performanceOverlayShowText.setBackgroundResource( + R.color.citra_transparent_black + ) } else { binding.performanceOverlayShowText.setBackgroundResource(0) } @@ -1558,10 +1598,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback, Choreographer.Fram } } - private fun celsiusToFahrenheit(celsius: Float): Float { - return (celsius * 9 / 5) + 32 - } - + private fun celsiusToFahrenheit(celsius: Float): Float = (celsius * 9 / 5) + 32 override fun surfaceCreated(holder: SurfaceHolder) { // We purposely don't do anything here. diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/GamesFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/GamesFragment.kt index 8ea17ab7e..41c1fb28c 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/GamesFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/GamesFragment.kt @@ -59,7 +59,13 @@ class GamesFragment : Fragment() { private var pendingCompressInvocation: String? = null companion object { - fun doCompression(fragment: Fragment, gamesViewModel: GamesViewModel, inputPath: String?, outputUri: Uri?, shouldCompress: Boolean) { + fun doCompression( + fragment: Fragment, + gamesViewModel: GamesViewModel, + inputPath: String?, + outputUri: Uri?, + shouldCompress: Boolean + ) { if (outputUri != null) { val outputPath: String = if (!BuildUtil.isGooglePlayBuild) { @@ -247,41 +253,40 @@ class GamesFragment : Fragment() { } } - private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener( - binding.root - ) { view: View, windowInsets: WindowInsetsCompat -> - val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) - val extraListSpacing = resources.getDimensionPixelSize(R.dimen.spacing_large) - val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) - val spacingNavigationRail = - resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) + private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener( + binding.root + ) { view: View, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + val extraListSpacing = resources.getDimensionPixelSize(R.dimen.spacing_large) + val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) + val spacingNavigationRail = + resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) - binding.gridGames.updatePadding( - top = barInsets.top + extraListSpacing, - bottom = barInsets.bottom + spacingNavigation + extraListSpacing - ) + binding.gridGames.updatePadding( + top = barInsets.top + extraListSpacing, + bottom = barInsets.bottom + spacingNavigation + extraListSpacing + ) - binding.swipeRefresh.setProgressViewEndTarget( - false, - barInsets.top + resources.getDimensionPixelSize(R.dimen.spacing_refresh_end) - ) + binding.swipeRefresh.setProgressViewEndTarget( + false, + barInsets.top + resources.getDimensionPixelSize(R.dimen.spacing_refresh_end) + ) - val leftInsets = barInsets.left + cutoutInsets.left - val rightInsets = barInsets.right + cutoutInsets.right - val mlpSwipe = binding.swipeRefresh.layoutParams as MarginLayoutParams - if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { - mlpSwipe.leftMargin = leftInsets + spacingNavigationRail - mlpSwipe.rightMargin = rightInsets - } else { - mlpSwipe.leftMargin = leftInsets - mlpSwipe.rightMargin = rightInsets + spacingNavigationRail - } - binding.swipeRefresh.layoutParams = mlpSwipe - - binding.noticeText.updatePadding(bottom = spacingNavigation) - - windowInsets + val leftInsets = barInsets.left + cutoutInsets.left + val rightInsets = barInsets.right + cutoutInsets.right + val mlpSwipe = binding.swipeRefresh.layoutParams as MarginLayoutParams + if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { + mlpSwipe.leftMargin = leftInsets + spacingNavigationRail + mlpSwipe.rightMargin = rightInsets + } else { + mlpSwipe.leftMargin = leftInsets + mlpSwipe.rightMargin = rightInsets + spacingNavigationRail } + binding.swipeRefresh.layoutParams = mlpSwipe + + binding.noticeText.updatePadding(bottom = spacingNavigation) + + windowInsets + } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/GrantMissingFilesystemPermissionFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/GrantMissingFilesystemPermissionFragment.kt index e07787c52..8371e62ee 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/GrantMissingFilesystemPermissionFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/GrantMissingFilesystemPermissionFragment.kt @@ -44,8 +44,6 @@ class GrantMissingFilesystemPermissionFragment : DialogFragment() { { permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE) } } - - return MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.filesystem_permission_warning) .setMessage(R.string.filesystem_permission_lost) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/HomeSettingsFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/HomeSettingsFragment.kt index ceecc7572..9a49eb8d5 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/HomeSettingsFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/HomeSettingsFragment.kt @@ -32,19 +32,19 @@ import org.citra.citra_emu.R import org.citra.citra_emu.adapters.HomeSettingAdapter import org.citra.citra_emu.databinding.DialogSoftwareKeyboardBinding import org.citra.citra_emu.databinding.FragmentHomeSettingsBinding -import org.citra.citra_emu.features.settings.model.Settings import org.citra.citra_emu.features.settings.SettingKeys +import org.citra.citra_emu.features.settings.model.Settings import org.citra.citra_emu.features.settings.ui.SettingsActivity import org.citra.citra_emu.features.settings.utils.SettingsFile import org.citra.citra_emu.model.Game import org.citra.citra_emu.model.HomeSetting import org.citra.citra_emu.ui.main.MainActivity import org.citra.citra_emu.utils.GameHelper -import org.citra.citra_emu.utils.PermissionsHandler -import org.citra.citra_emu.viewmodel.HomeViewModel import org.citra.citra_emu.utils.GpuDriverHelper import org.citra.citra_emu.utils.Log +import org.citra.citra_emu.utils.PermissionsHandler import org.citra.citra_emu.viewmodel.DriverViewModel +import org.citra.citra_emu.viewmodel.HomeViewModel class HomeSettingsFragment : Fragment() { private var _binding: FragmentHomeSettingsBinding? = null @@ -89,7 +89,10 @@ class HomeSettingsFragment : Fragment() { { val inflater = LayoutInflater.from(context) val inputBinding = DialogSoftwareKeyboardBinding.inflate(inflater) - var textInputValue: String = preferences.getString(SettingKeys.last_artic_base_addr(), "")!! + var textInputValue: String = preferences.getString( + SettingKeys.last_artic_base_addr(), + "" + )!! inputBinding.editTextInput.setText(textInputValue) inputBinding.editTextInput.doOnTextChanged { text, _, _, _ -> @@ -103,7 +106,10 @@ class HomeSettingsFragment : Fragment() { .setPositiveButton(android.R.string.ok) { _, _ -> if (textInputValue.isNotEmpty()) { preferences.edit() - .putString(SettingKeys.last_artic_base_addr(), textInputValue) + .putString( + SettingKeys.last_artic_base_addr(), + textInputValue + ) .apply() val menu = Game( title = getString(R.string.artic_base), @@ -115,7 +121,7 @@ class HomeSettingsFragment : Fragment() { binding.root.findNavController().navigate(action) } } - .setNegativeButton(android.R.string.cancel) {_, _ -> } + .setNegativeButton(android.R.string.cancel) { _, _ -> } .show() } } @@ -267,37 +273,36 @@ class HomeSettingsFragment : Fragment() { } } - private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener( - binding.root - ) { view: View, windowInsets: WindowInsetsCompat -> - val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) - val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) - val spacingNavigationRail = - resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) + private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener( + binding.root + ) { view: View, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) + val spacingNavigationRail = + resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) - val leftInsets = barInsets.left + cutoutInsets.left - val rightInsets = barInsets.right + cutoutInsets.right + val leftInsets = barInsets.left + cutoutInsets.left + val rightInsets = barInsets.right + cutoutInsets.right - binding.scrollViewSettings.updatePadding( - top = barInsets.top, - bottom = barInsets.bottom - ) + binding.scrollViewSettings.updatePadding( + top = barInsets.top, + bottom = barInsets.bottom + ) - val mlpScrollSettings = binding.scrollViewSettings.layoutParams as MarginLayoutParams - mlpScrollSettings.leftMargin = leftInsets - mlpScrollSettings.rightMargin = rightInsets - binding.scrollViewSettings.layoutParams = mlpScrollSettings + val mlpScrollSettings = binding.scrollViewSettings.layoutParams as MarginLayoutParams + mlpScrollSettings.leftMargin = leftInsets + mlpScrollSettings.rightMargin = rightInsets + binding.scrollViewSettings.layoutParams = mlpScrollSettings - binding.linearLayoutSettings.updatePadding(bottom = spacingNavigation) + binding.linearLayoutSettings.updatePadding(bottom = spacingNavigation) - if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { - binding.linearLayoutSettings.updatePadding(left = spacingNavigationRail) - } else { - binding.linearLayoutSettings.updatePadding(right = spacingNavigationRail) - } - - windowInsets + if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { + binding.linearLayoutSettings.updatePadding(left = spacingNavigationRail) + } else { + binding.linearLayoutSettings.updatePadding(right = spacingNavigationRail) } + + windowInsets + } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/IndeterminateProgressDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/IndeterminateProgressDialogFragment.kt index 31b01e636..663f4c650 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/IndeterminateProgressDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/IndeterminateProgressDialogFragment.kt @@ -56,9 +56,7 @@ class IndeterminateProgressDialogFragment : DialogFragment() { inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle? - ): View { - return binding.root - } + ): View = binding.root override fun onViewCreated(view: View, savedInstanceState: Bundle?) { super.onViewCreated(view, savedInstanceState) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/KeyboardDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/KeyboardDialogFragment.kt index b4f581441..db913a3a8 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/KeyboardDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/KeyboardDialogFragment.kt @@ -78,21 +78,27 @@ class KeyboardDialogFragment : DialogFragment() { return@setOnClickListener } dismiss() - synchronized(SoftwareKeyboard.finishLock) { SoftwareKeyboard.finishLock.notifyAll() } + synchronized(SoftwareKeyboard.finishLock) { + SoftwareKeyboard.finishLock.notifyAll() + } } } if (alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL) != null) { alertDialog.getButton(DialogInterface.BUTTON_NEUTRAL).setOnClickListener { SoftwareKeyboard.data.button = 1 dismiss() - synchronized(SoftwareKeyboard.finishLock) { SoftwareKeyboard.finishLock.notifyAll() } + synchronized(SoftwareKeyboard.finishLock) { + SoftwareKeyboard.finishLock.notifyAll() + } } } if (alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE) != null) { alertDialog.getButton(DialogInterface.BUTTON_NEGATIVE).setOnClickListener { SoftwareKeyboard.data.button = 0 dismiss() - synchronized(SoftwareKeyboard.finishLock) { SoftwareKeyboard.finishLock.notifyAll() } + synchronized(SoftwareKeyboard.finishLock) { + SoftwareKeyboard.finishLock.notifyAll() + } } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/LicenseBottomSheetDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/LicenseBottomSheetDialogFragment.kt index 9cbea1b9b..3d8e48a63 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/LicenseBottomSheetDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/LicenseBottomSheetDialogFragment.kt @@ -57,9 +57,7 @@ class LicenseBottomSheetDialogFragment : BottomSheetDialogFragment() { const val LICENSE = "License" - fun newInstance( - license: License - ): LicenseBottomSheetDialogFragment { + fun newInstance(license: License): LicenseBottomSheetDialogFragment { val dialog = LicenseBottomSheetDialogFragment() val bundle = Bundle() bundle.putParcelable(LICENSE, license) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/LicensesFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/LicensesFragment.kt index a8f767907..9c56b27a8 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/LicensesFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/LicensesFragment.kt @@ -174,28 +174,27 @@ class LicensesFragment : Fragment() { setInsets() } - private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener( - binding.root - ) { _: View, windowInsets: WindowInsetsCompat -> - val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener( + binding.root + ) { _: View, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) - val leftInsets = barInsets.left + cutoutInsets.left - val rightInsets = barInsets.right + cutoutInsets.right + val leftInsets = barInsets.left + cutoutInsets.left + val rightInsets = barInsets.right + cutoutInsets.right - val mlpAppBar = binding.toolbarLicenses.layoutParams as MarginLayoutParams - mlpAppBar.leftMargin = leftInsets - mlpAppBar.rightMargin = rightInsets - binding.toolbarLicenses.layoutParams = mlpAppBar + val mlpAppBar = binding.toolbarLicenses.layoutParams as MarginLayoutParams + mlpAppBar.leftMargin = leftInsets + mlpAppBar.rightMargin = rightInsets + binding.toolbarLicenses.layoutParams = mlpAppBar - val mlpScrollAbout = binding.listLicenses.layoutParams as MarginLayoutParams - mlpScrollAbout.leftMargin = leftInsets - mlpScrollAbout.rightMargin = rightInsets - binding.listLicenses.layoutParams = mlpScrollAbout + val mlpScrollAbout = binding.listLicenses.layoutParams as MarginLayoutParams + mlpScrollAbout.leftMargin = leftInsets + mlpScrollAbout.rightMargin = rightInsets + binding.listLicenses.layoutParams = mlpScrollAbout - binding.listLicenses.updatePadding(bottom = barInsets.bottom) + binding.listLicenses.updatePadding(bottom = barInsets.bottom) - windowInsets - } + windowInsets + } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/MiiSelectorDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/MiiSelectorDialogFragment.kt index fa1e1ae99..7f040ec19 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/MiiSelectorDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/MiiSelectorDialogFragment.kt @@ -23,11 +23,22 @@ class MiiSelectorDialogFragment : DialogFragment() { list.add(getString(R.string.standard_mii)) list.addAll(config.miiNames) val initialIndex = - if (config.initiallySelectedMiiIndex < list.size) config.initiallySelectedMiiIndex.toInt() else 0 + if (config.initiallySelectedMiiIndex < + list.size + ) { + config.initiallySelectedMiiIndex.toInt() + } else { + 0 + } MiiSelector.data.index = initialIndex val builder = MaterialAlertDialogBuilder(requireActivity()) - .setTitle(if (config.title!!.isEmpty()) getString(R.string.mii_selector) else config.title) - .setSingleChoiceItems(list.toTypedArray(), initialIndex) { _: DialogInterface?, which: Int -> + .setTitle( + if (config.title!!.isEmpty()) getString(R.string.mii_selector) else config.title + ) + .setSingleChoiceItems(list.toTypedArray(), initialIndex) { + _: DialogInterface?, + which: Int + -> MiiSelector.data.index = which } .setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int -> diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/MotionBottomSheetDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/MotionBottomSheetDialogFragment.kt index cf42bed12..6e0813266 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/MotionBottomSheetDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/MotionBottomSheetDialogFragment.kt @@ -14,11 +14,11 @@ import android.view.View import android.view.ViewGroup import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.android.material.bottomsheet.BottomSheetDialogFragment +import kotlin.math.abs import org.citra.citra_emu.R import org.citra.citra_emu.databinding.DialogInputBinding import org.citra.citra_emu.features.settings.model.view.InputBindingSetting import org.citra.citra_emu.utils.Log -import kotlin.math.abs class MotionBottomSheetDialogFragment : BottomSheetDialogFragment() { private var _binding: DialogInputBinding? = null diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/SearchFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/SearchFragment.kt index dab5ea745..ca7cd21f5 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/SearchFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/SearchFragment.kt @@ -28,19 +28,19 @@ import androidx.preference.PreferenceManager import androidx.recyclerview.widget.GridLayoutManager import info.debatty.java.stringsimilarity.Jaccard import info.debatty.java.stringsimilarity.JaroWinkler +import java.time.temporal.ChronoField +import java.util.Locale import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import org.citra.citra_emu.CitraApplication -import org.citra.citra_emu.R import org.citra.citra_emu.NativeLibrary +import org.citra.citra_emu.R import org.citra.citra_emu.adapters.GameAdapter import org.citra.citra_emu.databinding.FragmentSearchBinding import org.citra.citra_emu.model.Game import org.citra.citra_emu.viewmodel.CompressProgressDialogViewModel import org.citra.citra_emu.viewmodel.GamesViewModel import org.citra.citra_emu.viewmodel.HomeViewModel -import java.time.temporal.ChronoField -import java.util.Locale class SearchFragment : Fragment() { private var _binding: FragmentSearchBinding? = null @@ -61,7 +61,13 @@ class SearchFragment : Fragment() { private val onCompressDecompressLauncher = registerForActivityResult( ActivityResultContracts.CreateDocument("application/octet-stream") ) { uri: Uri? -> - GamesFragment.doCompression(this, gamesViewModel, pendingCompressInvocation, uri, shouldCompress) + GamesFragment.doCompression( + this, + gamesViewModel, + pendingCompressInvocation, + uri, + shouldCompress + ) pendingCompressInvocation = null } @@ -184,14 +190,16 @@ class SearchFragment : Fragment() { R.id.chip_recently_played -> { baseList.filter { val lastPlayedTime = preferences.getLong(it.keyLastPlayedTime, 0L) - lastPlayedTime > (System.currentTimeMillis() - ChronoField.MILLI_OF_DAY.range().maximum) + lastPlayedTime > + (System.currentTimeMillis() - ChronoField.MILLI_OF_DAY.range().maximum) } } R.id.chip_recently_added -> { baseList.filter { val addedTime = preferences.getLong(it.keyAddedToLibraryTime, 0L) - addedTime > (System.currentTimeMillis() - ChronoField.MILLI_OF_DAY.range().maximum) + addedTime > + (System.currentTimeMillis() - ChronoField.MILLI_OF_DAY.range().maximum) } } @@ -242,54 +250,53 @@ class SearchFragment : Fragment() { } } - private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener( - binding.root - ) { view: View, windowInsets: WindowInsetsCompat -> - val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) - val extraListSpacing = resources.getDimensionPixelSize(R.dimen.spacing_med) - val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) - val spacingNavigationRail = - resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) - val chipSpacing = resources.getDimensionPixelSize(R.dimen.spacing_chip) + private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener( + binding.root + ) { view: View, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + val extraListSpacing = resources.getDimensionPixelSize(R.dimen.spacing_med) + val spacingNavigation = resources.getDimensionPixelSize(R.dimen.spacing_navigation) + val spacingNavigationRail = + resources.getDimensionPixelSize(R.dimen.spacing_navigation_rail) + val chipSpacing = resources.getDimensionPixelSize(R.dimen.spacing_chip) - binding.constraintSearch.updatePadding( - left = barInsets.left + cutoutInsets.left, - top = barInsets.top, - right = barInsets.right + cutoutInsets.right + binding.constraintSearch.updatePadding( + left = barInsets.left + cutoutInsets.left, + top = barInsets.top, + right = barInsets.right + cutoutInsets.right + ) + + binding.gridGamesSearch.updatePadding( + top = extraListSpacing, + bottom = barInsets.bottom + spacingNavigation + extraListSpacing + ) + binding.noResultsView.updatePadding(bottom = spacingNavigation + barInsets.bottom) + + val mlpDivider = binding.divider.layoutParams as ViewGroup.MarginLayoutParams + if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { + binding.frameSearch.updatePadding(left = spacingNavigationRail) + binding.gridGamesSearch.updatePadding(left = spacingNavigationRail) + binding.noResultsView.updatePadding(left = spacingNavigationRail) + binding.chipGroup.updatePadding( + left = chipSpacing + spacingNavigationRail, + right = chipSpacing ) - - binding.gridGamesSearch.updatePadding( - top = extraListSpacing, - bottom = barInsets.bottom + spacingNavigation + extraListSpacing + mlpDivider.leftMargin = chipSpacing + spacingNavigationRail + mlpDivider.rightMargin = chipSpacing + } else { + binding.frameSearch.updatePadding(right = spacingNavigationRail) + binding.gridGamesSearch.updatePadding(right = spacingNavigationRail) + binding.noResultsView.updatePadding(right = spacingNavigationRail) + binding.chipGroup.updatePadding( + left = chipSpacing, + right = chipSpacing + spacingNavigationRail ) - binding.noResultsView.updatePadding(bottom = spacingNavigation + barInsets.bottom) - - val mlpDivider = binding.divider.layoutParams as ViewGroup.MarginLayoutParams - if (ViewCompat.getLayoutDirection(view) == ViewCompat.LAYOUT_DIRECTION_LTR) { - binding.frameSearch.updatePadding(left = spacingNavigationRail) - binding.gridGamesSearch.updatePadding(left = spacingNavigationRail) - binding.noResultsView.updatePadding(left = spacingNavigationRail) - binding.chipGroup.updatePadding( - left = chipSpacing + spacingNavigationRail, - right = chipSpacing - ) - mlpDivider.leftMargin = chipSpacing + spacingNavigationRail - mlpDivider.rightMargin = chipSpacing - } else { - binding.frameSearch.updatePadding(right = spacingNavigationRail) - binding.gridGamesSearch.updatePadding(right = spacingNavigationRail) - binding.noResultsView.updatePadding(right = spacingNavigationRail) - binding.chipGroup.updatePadding( - left = chipSpacing, - right = chipSpacing + spacingNavigationRail - ) - mlpDivider.leftMargin = chipSpacing - mlpDivider.rightMargin = chipSpacing + spacingNavigationRail - } - binding.divider.layoutParams = mlpDivider - - windowInsets + mlpDivider.leftMargin = chipSpacing + mlpDivider.rightMargin = chipSpacing + spacingNavigationRail } + binding.divider.layoutParams = mlpDivider + + windowInsets + } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/SelectUserDirectoryDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/SelectUserDirectoryDialogFragment.kt index f0f945860..7792b12b2 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/SelectUserDirectoryDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/SelectUserDirectoryDialogFragment.kt @@ -16,11 +16,15 @@ import org.citra.citra_emu.ui.main.MainActivity import org.citra.citra_emu.utils.PermissionsHandler import org.citra.citra_emu.viewmodel.HomeViewModel -class SelectUserDirectoryDialogFragment(titleOverride: Int? = null, descriptionOverride: Int? = null) : DialogFragment() { +class SelectUserDirectoryDialogFragment( + titleOverride: Int? = null, + descriptionOverride: Int? = null +) : DialogFragment() { private lateinit var mainActivity: MainActivity private val title = titleOverride ?: R.string.select_citra_user_folder - private val description = descriptionOverride ?: R.string.selecting_user_directory_without_write_permissions + private val description = + descriptionOverride ?: R.string.selecting_user_directory_without_write_permissions override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { mainActivity = requireActivity() as MainActivity @@ -31,7 +35,9 @@ class SelectUserDirectoryDialogFragment(titleOverride: Int? = null, descriptionO .setTitle(title) .setMessage(description) .setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int -> - PermissionsHandler.compatibleSelectDirectory(mainActivity.openCitraDirectoryLostPermission) + PermissionsHandler.compatibleSelectDirectory( + mainActivity.openCitraDirectoryLostPermission + ) } .show() } @@ -39,8 +45,11 @@ class SelectUserDirectoryDialogFragment(titleOverride: Int? = null, descriptionO companion object { const val TAG = "SelectUserDirectoryDialogFragment" - fun newInstance(activity: FragmentActivity, titleOverride: Int? = null, descriptionOverride: Int? = null): - SelectUserDirectoryDialogFragment { + fun newInstance( + activity: FragmentActivity, + titleOverride: Int? = null, + descriptionOverride: Int? = null + ): SelectUserDirectoryDialogFragment { ViewModelProvider(activity)[HomeViewModel::class.java].setPickingUserDir(true) return SelectUserDirectoryDialogFragment(titleOverride, descriptionOverride) } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/SetupFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/SetupFragment.kt index 17bd32dc4..057e1acad 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/SetupFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/SetupFragment.kt @@ -162,7 +162,9 @@ class SetupFragment : Fragment() { ) ) } else { - permissionLauncher.launch(Manifest.permission.WRITE_EXTERNAL_STORAGE) + permissionLauncher.launch( + Manifest.permission.WRITE_EXTERNAL_STORAGE + ) } }, buttonState = { @@ -187,7 +189,7 @@ class SetupFragment : Fragment() { isUnskippable = true, hasWarning = true, R.string.filesystem_permission_warning, - R.string.filesystem_permission_warning_description, + R.string.filesystem_permission_warning_description ) ) } @@ -199,7 +201,9 @@ class SetupFragment : Fragment() { R.string.notifications_description, buttonAction = { pageButtonCallback = it - permissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS) + permissionLauncher.launch( + Manifest.permission.POST_NOTIFICATIONS + ) }, buttonState = { if (NotificationManagerCompat.from(requireContext()) @@ -213,7 +217,7 @@ class SetupFragment : Fragment() { isUnskippable = false, hasWarning = true, R.string.notification_warning, - R.string.notification_warning_description, + R.string.notification_warning_description ) ) } @@ -236,7 +240,7 @@ class SetupFragment : Fragment() { } else { ButtonState.BUTTON_ACTION_INCOMPLETE } - }, + } ) ) add( @@ -258,10 +262,10 @@ class SetupFragment : Fragment() { } else { ButtonState.BUTTON_ACTION_INCOMPLETE } - }, + } ) ) - }, + } ) { var permissionsComplete = // Microphone @@ -269,14 +273,14 @@ class SetupFragment : Fragment() { requireContext(), Manifest.permission.RECORD_AUDIO ) == PackageManager.PERMISSION_GRANTED && - // Camera - ContextCompat.checkSelfPermission( - requireContext(), - Manifest.permission.CAMERA - ) == PackageManager.PERMISSION_GRANTED && - // Notifications - NotificationManagerCompat.from(requireContext()) - .areNotificationsEnabled() + // Camera + ContextCompat.checkSelfPermission( + requireContext(), + Manifest.permission.CAMERA + ) == PackageManager.PERMISSION_GRANTED && + // Notifications + NotificationManagerCompat.from(requireContext()) + .areNotificationsEnabled() // External Storage if (!BuildUtil.isGooglePlayBuild) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { @@ -284,10 +288,12 @@ class SetupFragment : Fragment() { (permissionsComplete && Environment.isExternalStorageManager()) } else { permissionsComplete = - (permissionsComplete && ContextCompat.checkSelfPermission( - requireContext(), - Manifest.permission.WRITE_EXTERNAL_STORAGE - ) == PackageManager.PERMISSION_GRANTED) + ( + permissionsComplete && ContextCompat.checkSelfPermission( + requireContext(), + Manifest.permission.WRITE_EXTERNAL_STORAGE + ) == PackageManager.PERMISSION_GRANTED + ) } } @@ -315,7 +321,9 @@ class SetupFragment : Fragment() { R.string.select_citra_user_folder_description, buttonAction = { pageButtonCallback = it - PermissionsHandler.compatibleSelectDirectory(mainActivity.setupOpenCitraDirectory) + PermissionsHandler.compatibleSelectDirectory( + mainActivity.setupOpenCitraDirectory + ) }, buttonState = { if (PermissionsHandler.hasWriteAccess(requireContext())) { @@ -344,7 +352,11 @@ class SetupFragment : Fragment() { ) }, buttonState = { - if (preferences.getString(GameHelper.KEY_GAME_PATH, "")!!.isNotEmpty()) { + if (preferences.getString( + GameHelper.KEY_GAME_PATH, + "" + )!!.isNotEmpty() + ) { ButtonState.BUTTON_ACTION_COMPLETE } else { ButtonState.BUTTON_ACTION_INCOMPLETE @@ -353,17 +365,16 @@ class SetupFragment : Fragment() { isUnskippable = false, hasWarning = true, R.string.add_games_warning, - R.string.add_games_warning_description, + R.string.add_games_warning_description ) ) - }, + } ) { if ( PermissionsHandler.hasWriteAccess(requireContext()) && preferences.getString(GameHelper.KEY_GAME_PATH, "")!!.isNotEmpty() ) { PageState.PAGE_STEPS_COMPLETE - } else { PageState.PAGE_STEPS_INCOMPLETE } @@ -483,7 +494,8 @@ class SetupFragment : Fragment() { if (savedInstanceState == null) { hasBeenWarned = BooleanArray(pages.size) } else { - hasBeenWarned = savedInstanceState.getBooleanArray(KEY_HAS_BEEN_WARNED) ?: BooleanArray(pages.size) + hasBeenWarned = + savedInstanceState.getBooleanArray(KEY_HAS_BEEN_WARNED) ?: BooleanArray(pages.size) } updateNavigationButtons(binding.viewPager2.currentItem) @@ -590,8 +602,11 @@ class SetupFragment : Fragment() { } } - CitraDirectoryHelper(requireActivity(), true).showCitraDirectoryDialog(result, - null, checkForButtonState) + CitraDirectoryHelper(requireActivity(), true).showCitraDirectoryDialog( + result, + null, + checkForButtonState + ) } private fun onGetGamesDirectory(result: Uri) { @@ -632,33 +647,32 @@ class SetupFragment : Fragment() { hasBeenWarned[page] = true } - private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener( - binding.root - ) { _: View, windowInsets: WindowInsetsCompat -> - val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) + private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener( + binding.root + ) { _: View, windowInsets: WindowInsetsCompat -> + val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout()) - val leftPadding = barInsets.left + cutoutInsets.left - val topPadding = barInsets.top + cutoutInsets.top - val rightPadding = barInsets.right + cutoutInsets.right - val bottomPadding = barInsets.bottom + cutoutInsets.bottom + val leftPadding = barInsets.left + cutoutInsets.left + val topPadding = barInsets.top + cutoutInsets.top + val rightPadding = barInsets.right + cutoutInsets.right + val bottomPadding = barInsets.bottom + cutoutInsets.bottom - if (resources.getBoolean(R.bool.small_layout)) { - binding.viewPager2 - .updatePadding(left = leftPadding, top = topPadding, right = rightPadding) - binding.constraintButtons - .updatePadding(left = leftPadding, right = rightPadding, bottom = bottomPadding) - } else { - binding.viewPager2.updatePadding(top = topPadding, bottom = bottomPadding) - binding.constraintButtons - .setPadding( - leftPadding + rightPadding, - topPadding, - rightPadding + leftPadding, - bottomPadding - ) - } - windowInsets + if (resources.getBoolean(R.bool.small_layout)) { + binding.viewPager2 + .updatePadding(left = leftPadding, top = topPadding, right = rightPadding) + binding.constraintButtons + .updatePadding(left = leftPadding, right = rightPadding, bottom = bottomPadding) + } else { + binding.viewPager2.updatePadding(top = topPadding, bottom = bottomPadding) + binding.constraintButtons + .setPadding( + leftPadding + rightPadding, + topPadding, + rightPadding + leftPadding, + bottomPadding + ) } + windowInsets + } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/SystemFilesFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/SystemFilesFragment.kt index fdf644687..8e2b66a3d 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/SystemFilesFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/SystemFilesFragment.kt @@ -38,8 +38,8 @@ import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.R import org.citra.citra_emu.databinding.DialogSoftwareKeyboardBinding import org.citra.citra_emu.databinding.FragmentSystemFilesBinding -import org.citra.citra_emu.features.settings.model.Settings import org.citra.citra_emu.features.settings.SettingKeys +import org.citra.citra_emu.features.settings.model.Settings import org.citra.citra_emu.model.Game import org.citra.citra_emu.utils.SystemSaveGame import org.citra.citra_emu.viewmodel.GamesViewModel @@ -163,10 +163,12 @@ class SystemFilesFragment : Fragment() { binding.buttonUnlinkConsoleData.setOnClickListener { MaterialAlertDialogBuilder(requireContext()) .setTitle(R.string.delete_system_files) - .setMessage(HtmlCompat.fromHtml( - requireContext().getString(R.string.delete_system_files_description), - HtmlCompat.FROM_HTML_MODE_COMPACT - )) + .setMessage( + HtmlCompat.fromHtml( + requireContext().getString(R.string.delete_system_files_description), + HtmlCompat.FROM_HTML_MODE_COMPACT + ) + ) .setPositiveButton(android.R.string.ok) { _: DialogInterface, _: Int -> NativeLibrary.unlinkConsole() binding.buttonUnlinkConsoleData.isEnabled = NativeLibrary.isFullConsoleLinked() @@ -178,7 +180,10 @@ class SystemFilesFragment : Fragment() { binding.buttonSetUpSystemFiles.setOnClickListener { val inflater = LayoutInflater.from(context) val inputBinding = DialogSoftwareKeyboardBinding.inflate(inflater) - var textInputValue: String = preferences.getString(SettingKeys.last_artic_base_addr(), "")!! + var textInputValue: String = preferences.getString( + SettingKeys.last_artic_base_addr(), + "" + )!! val progressDialog = showProgressDialog( getText(R.string.setup_system_files), @@ -273,9 +278,14 @@ class SystemFilesFragment : Fragment() { .setView(inputBinding.root) .setTitle(getString(R.string.setup_system_files_enter_address)) .setPositiveButton(android.R.string.ok) { diag, _ -> - if (textInputValue.isNotEmpty() && !(!buttonO3ds.isChecked && !buttonN3ds.isChecked)) { + if (textInputValue.isNotEmpty() && + !(!buttonO3ds.isChecked && !buttonN3ds.isChecked) + ) { preferences.edit() - .putString(SettingKeys.last_artic_base_addr(), textInputValue) + .putString( + SettingKeys.last_artic_base_addr(), + textInputValue + ) .apply() val menu = Game( title = getString(R.string.artic_base), diff --git a/src/android/app/src/main/java/org/citra/citra_emu/fragments/UpdateUserDirectoryDialogFragment.kt b/src/android/app/src/main/java/org/citra/citra_emu/fragments/UpdateUserDirectoryDialogFragment.kt index db8e772e2..5c7ab104f 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/fragments/UpdateUserDirectoryDialogFragment.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/fragments/UpdateUserDirectoryDialogFragment.kt @@ -37,8 +37,8 @@ class UpdateUserDirectoryDialogFragment : DialogFragment() { isCancelable = false val preferences: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(CitraApplication.appContext) - val ld = preferences.getString("LIME3DS_DIRECTORY","") - val cd = preferences.getString("CITRA_DIRECTORY","") + val ld = preferences.getString("LIME3DS_DIRECTORY", "") + val cd = preferences.getString("CITRA_DIRECTORY", "") val dialogView = LayoutInflater.from(requireContext()) .inflate(R.layout.dialog_select_which_directory, null) @@ -97,7 +97,12 @@ class UpdateUserDirectoryDialogFragment : DialogFragment() { } ViewModelProvider(mainActivity)[HomeViewModel::class.java].setPickingUserDir(false) - ViewModelProvider(mainActivity)[HomeViewModel::class.java].setUserDir(this.requireActivity(),PermissionsHandler.citraDirectory.path!!) + ViewModelProvider( + mainActivity + )[HomeViewModel::class.java].setUserDir( + this.requireActivity(), + PermissionsHandler.citraDirectory.path!! + ) } .show() } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/model/Game.kt b/src/android/app/src/main/java/org/citra/citra_emu/model/Game.kt index 4148a7a3f..eae8469c9 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/model/Game.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/model/Game.kt @@ -4,9 +4,9 @@ package org.citra.citra_emu.model -import android.os.Parcelable import android.content.Intent import android.net.Uri +import android.os.Parcelable import androidx.core.net.toUri import java.io.File import java.io.IOException @@ -36,7 +36,7 @@ class Game( val icon: IntArray? = null, val fileType: String = "", val isCompressed: Boolean = false, - val filename: String, + val filename: String ) : Parcelable { val keyAddedToLibraryTime get() = "${filename}_AddedToLibraryTime" val keyLastPlayedTime get() = "${filename}_LastPlayed" @@ -51,7 +51,9 @@ class Game( val nativePath = NativeLibrary.getUserDirectory() + "/" + path val nativeFile = File(nativePath) if (!nativeFile.exists()) { - throw IOException("Attempting to create shortcut for an executable that doesn't exist: $nativePath") + throw IOException( + "Attempting to create shortcut for an executable that doesn't exist: $nativePath" + ) } appUri = Uri.fromFile(nativeFile) } @@ -89,9 +91,7 @@ class Game( GAME_CARD(2); companion object { - fun fromInt(value: Int): MediaType? { - return MediaType.entries.find { it.value == value } - } + fun fromInt(value: Int): MediaType? = MediaType.entries.find { it.value == value } } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/model/SetupPage.kt b/src/android/app/src/main/java/org/citra/citra_emu/model/SetupPage.kt index 9302c4662..49cb59c82 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/model/SetupPage.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/model/SetupPage.kt @@ -12,7 +12,7 @@ data class SetupPage( val leftAlignedIcon: Boolean, val buttonTextId: Int, val pageButtons: List? = null, - val pageSteps: () -> PageState = { PageState.PAGE_STEPS_UNDEFINED }, + val pageSteps: () -> PageState = { PageState.PAGE_STEPS_UNDEFINED } ) data class PageButton( @@ -29,7 +29,7 @@ data class PageButton( ) interface SetupCallback { - fun onStepCompleted(pageButtonId : Int, pageFullyCompleted: Boolean) + fun onStepCompleted(pageButtonId: Int, pageFullyCompleted: Boolean) } enum class PageState { diff --git a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.kt b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.kt index f7519bb81..116dc4528 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlay.kt @@ -21,13 +21,13 @@ import android.view.View import android.view.View.OnTouchListener import androidx.core.content.ContextCompat import androidx.preference.PreferenceManager +import java.lang.NullPointerException +import kotlin.math.min import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.R import org.citra.citra_emu.utils.EmulationMenuSettings import org.citra.citra_emu.utils.TurboHelper -import java.lang.NullPointerException -import kotlin.math.min /** * Draws the interactive input overlay on top of the @@ -36,7 +36,8 @@ import kotlin.math.min * @param context The current [Context]. * @param attrs [AttributeSet] for parsing XML attributes. */ -class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(context, attrs), +class InputOverlay(context: Context?, attrs: AttributeSet?) : + SurfaceView(context, attrs), OnTouchListener { private val overlayButtons: MutableSet = HashSet() private val overlayDpads: MutableSet = HashSet() @@ -87,9 +88,10 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex ) } - fun hapticFeedback(type:Int){ - if(EmulationMenuSettings.hapticFeedback) + fun hapticFeedback(type: Int) { + if (EmulationMenuSettings.hapticFeedback) { performHapticFeedback(type) + } } override fun onTouch(v: View, event: MotionEvent): Boolean { @@ -138,7 +140,7 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex } var hasActiveJoystick = false - if(!hasActiveButtons && !hasActiveDpad){ + if (!hasActiveButtons && !hasActiveDpad) { for (joystick in overlayJoysticks) { if (joystick.trackId == pointerId) { hasActiveJoystick = true @@ -161,18 +163,26 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex var anyOverlayStateChanged = false var shouldUpdateView = false - if(!hasActiveDpad && !hasActiveJoystick) { + if (!hasActiveDpad && !hasActiveJoystick) { for (button in overlayButtons) { - val stateChanged = button.updateStatus(event, pointerIndex, hasActiveButtons, this) + val stateChanged = button.updateStatus( + event, + pointerIndex, + hasActiveButtons, + this + ) if (!stateChanged) { continue } anyOverlayStateChanged = true - if (button.id == NativeLibrary.ButtonType.BUTTON_SWAP && button.status == NativeLibrary.ButtonState.PRESSED) { + if (button.id == NativeLibrary.ButtonType.BUTTON_SWAP && + button.status == NativeLibrary.ButtonState.PRESSED + ) { swapScreen() - } - else if (button.id == NativeLibrary.ButtonType.BUTTON_TURBO && button.status == NativeLibrary.ButtonState.PRESSED) { + } else if (button.id == NativeLibrary.ButtonType.BUTTON_TURBO && + button.status == NativeLibrary.ButtonState.PRESSED + ) { TurboHelper.toggleTurbo(true) } @@ -186,7 +196,7 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex } } - if(!hasActiveButtons && !hasActiveJoystick) { + if (!hasActiveButtons && !hasActiveJoystick) { for (dpad in overlayDpads) { val stateChanged = dpad.updateStatus( event, @@ -225,9 +235,14 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex } } - if(!hasActiveDpad && !hasActiveButtons) { + if (!hasActiveDpad && !hasActiveButtons) { for (joystick in overlayJoysticks) { - val stateChanged = joystick.updateStatus(event, pointerIndex, hasActiveJoystick, this) + val stateChanged = joystick.updateStatus( + event, + pointerIndex, + hasActiveJoystick, + this + ) if (!stateChanged) { continue } @@ -281,7 +296,6 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex if (!isActionMove) { break } - } return true } @@ -291,7 +305,13 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex val fingerPositionX = event.getX(pointerIndex).toInt() val fingerPositionY = event.getY(pointerIndex).toInt() val orientation = - if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) "-Portrait" else "" + if (resources.configuration.orientation == + Configuration.ORIENTATION_PORTRAIT + ) { + "-Portrait" + } else { + "" + } // Maybe combine Button and Joystick as subclasses of the same parent? // Or maybe create an interface like IMoveableHUDControl? @@ -313,12 +333,15 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex return true } - MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> if (buttonBeingConfigured == it) { + MotionEvent.ACTION_UP, MotionEvent.ACTION_POINTER_UP -> if (buttonBeingConfigured == + it + ) { // Persist button position by saving new place. saveControlPosition( buttonBeingConfigured!!.id, buttonBeingConfigured!!.bounds.left, - buttonBeingConfigured!!.bounds.top, orientation + buttonBeingConfigured!!.bounds.top, + orientation ) buttonBeingConfigured = null } @@ -347,7 +370,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex // Persist button position by saving new place. saveControlPosition( dpadBeingConfigured!!.upId, - dpadBeingConfigured!!.bounds.left, dpadBeingConfigured!!.bounds.top, + dpadBeingConfigured!!.bounds.left, + dpadBeingConfigured!!.bounds.top, orientation ) dpadBeingConfigured = null @@ -374,7 +398,8 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex saveControlPosition( joystickBeingConfigured!!.joystickId, joystickBeingConfigured!!.bounds.left, - joystickBeingConfigured!!.bounds.top, orientation + joystickBeingConfigured!!.bounds.top, + orientation ) joystickBeingConfigured = null } @@ -935,9 +960,7 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex .apply() } - override fun isInEditMode(): Boolean { - return isInEditMode - } + override fun isInEditMode(): Boolean = isInEditMode companion object { private val preferences @@ -1044,6 +1067,7 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex NativeLibrary.ButtonType.BUTTON_START, NativeLibrary.ButtonType.BUTTON_SELECT, NativeLibrary.ButtonType.BUTTON_SWAP -> 0.08f + NativeLibrary.ButtonType.BUTTON_TURBO -> 0.10f NativeLibrary.ButtonType.TRIGGER_L, @@ -1056,17 +1080,22 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex scale *= (preferences.getInt("controlScale", 50) + 50).toFloat() scale /= 100f - scale *= (preferences.getInt("controlScale-$buttonId", 50) + 50).toFloat() scale /= 100f - + val opacity: Int = preferences.getInt("controlOpacity", 50) * 255 / 100 // Initialize the InputOverlayDrawableButton. val defaultStateBitmap = getBitmap(context, defaultResId, scale) val pressedStateBitmap = getBitmap(context, pressedResId, scale) val overlayDrawable = - InputOverlayDrawableButton(res, defaultStateBitmap, pressedStateBitmap, buttonId, opacity) + InputOverlayDrawableButton( + res, + defaultStateBitmap, + pressedStateBitmap, + buttonId, + opacity + ) // The X and Y coordinates of the InputOverlayDrawableButton on the InputOverlay. // These were set in the input overlay configuration menu. @@ -1118,19 +1147,22 @@ class InputOverlay(context: Context?, attrs: AttributeSet?) : SurfaceView(contex scale *= (preferences.getInt("controlScale", 50) + 50).toFloat() scale /= 100f - scale *= (preferences.getInt( - "controlScale-" + NativeLibrary.ButtonType.DPAD, - 50 - ) + 50).toFloat() - + scale *= ( + preferences.getInt( + "controlScale-" + NativeLibrary.ButtonType.DPAD, + 50 + ) + 50 + ).toFloat() + scale /= 100f - + val opacity: Int = preferences.getInt("controlOpacity", 50) * 255 / 100 // Initialize the InputOverlayDrawableDpad. val defaultStateBitmap = getBitmap(context, defaultResId, scale) val pressedOneDirectionStateBitmap = getBitmap(context, pressedOneDirectionResId, scale) - val pressedTwoDirectionsStateBitmap = getBitmap(context, pressedTwoDirectionsResId, scale) + val pressedTwoDirectionsStateBitmap = + getBitmap(context, pressedTwoDirectionsResId, scale) val overlayDrawable = InputOverlayDrawableDpad( res, defaultStateBitmap, diff --git a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableButton.kt b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableButton.kt index 0899074fe..b891e0018 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableButton.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableButton.kt @@ -70,7 +70,12 @@ class InputOverlayDrawableButton( * * @return true if value was changed */ - fun updateStatus(event: MotionEvent, pointerIndex: Int, hasActiveButtons: Boolean, overlay: InputOverlay): Boolean { + fun updateStatus( + event: MotionEvent, + pointerIndex: Int, + hasActiveButtons: Boolean, + overlay: InputOverlay + ): Boolean { val buttonSliding = EmulationMenuSettings.buttonSlide val xPosition = event.getX(pointerIndex).toInt() val yPosition = event.getY(pointerIndex).toInt() diff --git a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableDpad.kt b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableDpad.kt index 5e902c99b..05db8eac2 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableDpad.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableDpad.kt @@ -63,7 +63,13 @@ class InputOverlayDrawableDpad( trackId = -1 } - fun updateStatus(event: MotionEvent, pointerIndex: Int, hasActiveButtons: Boolean, dpadSlide: Boolean, overlay: InputOverlay): Boolean { + fun updateStatus( + event: MotionEvent, + pointerIndex: Int, + hasActiveButtons: Boolean, + dpadSlide: Boolean, + overlay: InputOverlay + ): Boolean { var isDown = false val xPosition = event.getX(pointerIndex).toInt() val yPosition = event.getY(pointerIndex).toInt() @@ -125,12 +131,16 @@ class InputOverlayDrawableDpad( leftButtonState = xAxis < -VIRT_AXIS_DEADZONE rightButtonState = xAxis > VIRT_AXIS_DEADZONE - val stateChanged = upState != upButtonState || downState != downButtonState || leftState != leftButtonState || rightState != rightButtonState + val stateChanged = + upState != upButtonState || downState != downButtonState || + leftState != leftButtonState || + rightState != rightButtonState - if(stateChanged) + if (stateChanged) { overlay.hapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY) - else if(isDown) + } else if (isDown) { overlay.hapticFeedback(HapticFeedbackConstants.CLOCK_TICK) + } return stateChanged } @@ -259,7 +269,9 @@ class InputOverlayDrawableDpad( controlPositionX += fingerPositionX - previousTouchX controlPositionY += fingerPositionY - previousTouchY setBounds( - controlPositionX, controlPositionY, width + controlPositionX, + controlPositionX, + controlPositionY, + width + controlPositionX, height + controlPositionY ) previousTouchX = fingerPositionX diff --git a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableJoystick.kt b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableJoystick.kt index 3cc871d30..c0286b00d 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableJoystick.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/overlay/InputOverlayDrawableJoystick.kt @@ -11,12 +11,12 @@ import android.graphics.Rect import android.graphics.drawable.BitmapDrawable import android.view.HapticFeedbackConstants import android.view.MotionEvent -import org.citra.citra_emu.NativeLibrary -import org.citra.citra_emu.utils.EmulationMenuSettings import kotlin.math.atan2 import kotlin.math.cos import kotlin.math.sin import kotlin.math.sqrt +import org.citra.citra_emu.NativeLibrary +import org.citra.citra_emu.utils.EmulationMenuSettings /** * Custom [BitmapDrawable] that is capable @@ -93,7 +93,12 @@ class InputOverlayDrawableJoystick( currentStateBitmapDrawable.draw(canvas) } - fun updateStatus(event: MotionEvent, pointerIndex: Int, hasActiveButtons: Boolean, overlay: InputOverlay): Boolean { + fun updateStatus( + event: MotionEvent, + pointerIndex: Int, + hasActiveButtons: Boolean, + overlay: InputOverlay + ): Boolean { val xPosition = event.getX(pointerIndex).toInt() val yPosition = event.getY(pointerIndex).toInt() val pointerId = event.getPointerId(pointerIndex) @@ -171,8 +176,9 @@ class InputOverlayDrawableJoystick( this.yAxis = sin(angle.toDouble()).toFloat() * radius setInnerBounds() - if (kotlin.math.abs(oldRadius - radius) > .34f - || radius > .5f && kotlin.math.abs(oldAngle - angle) > kotlin.math.PI / 8) { + if (kotlin.math.abs(oldRadius - radius) > .34f || + radius > .5f && kotlin.math.abs(oldAngle - angle) > kotlin.math.PI / 8 + ) { this.radius = radius this.angle = angle @@ -237,14 +243,22 @@ class InputOverlayDrawableJoystick( private fun setInnerBounds() { var x = virtBounds.centerX() + (xAxis * (virtBounds.width() / 2)).toInt() var y = virtBounds.centerY() + (yAxis * (virtBounds.height() / 2)).toInt() - if (x > virtBounds.centerX() + virtBounds.width() / 2) x = - virtBounds.centerX() + virtBounds.width() / 2 - if (x < virtBounds.centerX() - virtBounds.width() / 2) x = - virtBounds.centerX() - virtBounds.width() / 2 - if (y > virtBounds.centerY() + virtBounds.height() / 2) y = - virtBounds.centerY() + virtBounds.height() / 2 - if (y < virtBounds.centerY() - virtBounds.height() / 2) y = - virtBounds.centerY() - virtBounds.height() / 2 + if (x > virtBounds.centerX() + virtBounds.width() / 2) { + x = + virtBounds.centerX() + virtBounds.width() / 2 + } + if (x < virtBounds.centerX() - virtBounds.width() / 2) { + x = + virtBounds.centerX() - virtBounds.width() / 2 + } + if (y > virtBounds.centerY() + virtBounds.height() / 2) { + y = + virtBounds.centerY() + virtBounds.height() / 2 + } + if (y < virtBounds.centerY() - virtBounds.height() / 2) { + y = + virtBounds.centerY() - virtBounds.height() / 2 + } val width = pressedStateInnerBitmap.bounds.width() / 2 val height = pressedStateInnerBitmap.bounds.height() / 2 defaultStateInnerBitmap.setBounds(x - width, y - height, x + width, y + height) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/citra/citra_emu/ui/main/MainActivity.kt index 91df60632..1545476ec 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/ui/main/MainActivity.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/ui/main/MainActivity.kt @@ -61,13 +61,15 @@ import org.citra.citra_emu.utils.CitraDirectoryUtils import org.citra.citra_emu.utils.DirectoryInitialization import org.citra.citra_emu.utils.FileBrowserHelper import org.citra.citra_emu.utils.InsetsHelper -import org.citra.citra_emu.utils.RefreshRateUtil import org.citra.citra_emu.utils.PermissionsHandler +import org.citra.citra_emu.utils.RefreshRateUtil import org.citra.citra_emu.utils.ThemeUtil import org.citra.citra_emu.viewmodel.GamesViewModel import org.citra.citra_emu.viewmodel.HomeViewModel -class MainActivity : AppCompatActivity(), ThemeProvider { +class MainActivity : + AppCompatActivity(), + ThemeProvider { private lateinit var binding: ActivityMainBinding private val homeViewModel: HomeViewModel by viewModels() @@ -87,14 +89,14 @@ class MainActivity : AppCompatActivity(), ThemeProvider { CitraDirectoryUtils.attemptAutomaticUpdateDirectory() splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areCitraDirectoriesReady() && - PermissionsHandler.hasWriteAccess(this) && - !CitraDirectoryUtils.needToUpdateManually() + PermissionsHandler.hasWriteAccess(this) && + !CitraDirectoryUtils.needToUpdateManually() } - if (PermissionsHandler.hasWriteAccess(applicationContext) && DirectoryInitialization.areCitraDirectoriesReady() && - !CitraDirectoryUtils.needToUpdateManually()) { + !CitraDirectoryUtils.needToUpdateManually() + ) { settingsViewModel.settings.loadSettings() } @@ -152,7 +154,9 @@ class MainActivity : AppCompatActivity(), ThemeProvider { gamesViewModel.setShouldScrollToTop(true) } + R.id.searchFragment -> gamesViewModel.setSearchFocused(true) + R.id.homeSettingsFragment -> SettingsActivity.launch( this, SettingsFile.FILE_NAME_CONFIG, @@ -229,7 +233,11 @@ class MainActivity : AppCompatActivity(), ThemeProvider { GrantMissingFilesystemPermissionFragment.newInstance() .show(supportFragmentManager, GrantMissingFilesystemPermissionFragment.TAG) - if (supportFragmentManager.findFragmentByTag(GrantMissingFilesystemPermissionFragment.TAG) == null) { + if (supportFragmentManager.findFragmentByTag( + GrantMissingFilesystemPermissionFragment.TAG + ) == + null + ) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (!Environment.isExternalStorageManager()) { requestMissingFilesystemPermission() @@ -256,12 +264,14 @@ class MainActivity : AppCompatActivity(), ThemeProvider { return } else if (CitraDirectoryUtils.needToUpdateManually()) { UpdateUserDirectoryDialogFragment.newInstance(this) - .show(supportFragmentManager,UpdateUserDirectoryDialogFragment.TAG) + .show(supportFragmentManager, UpdateUserDirectoryDialogFragment.TAG) return } if (!BuildUtil.isGooglePlayBuild) { - if (supportFragmentManager.findFragmentByTag(SelectUserDirectoryDialogFragment.TAG) == null) { + if (supportFragmentManager.findFragmentByTag(SelectUserDirectoryDialogFragment.TAG) == + null + ) { if (NativeLibrary.getUserDirectory() == "") { SelectUserDirectoryDialogFragment.newInstance(this) .show(supportFragmentManager, SelectUserDirectoryDialogFragment.TAG) @@ -365,28 +375,29 @@ class MainActivity : AppCompatActivity(), ThemeProvider { }.start() } - private fun setInsets() = - ViewCompat.setOnApplyWindowInsetsListener( - binding.root - ) { _: View, windowInsets: WindowInsetsCompat -> - val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) - val mlpStatusShade = binding.statusBarShade.layoutParams as MarginLayoutParams - mlpStatusShade.height = insets.top - binding.statusBarShade.layoutParams = mlpStatusShade + private fun setInsets() = ViewCompat.setOnApplyWindowInsetsListener( + binding.root + ) { _: View, windowInsets: WindowInsetsCompat -> + val insets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars()) + val mlpStatusShade = binding.statusBarShade.layoutParams as MarginLayoutParams + mlpStatusShade.height = insets.top + binding.statusBarShade.layoutParams = mlpStatusShade - // The only situation where we care to have a nav bar shade is when it's at the bottom - // of the screen where scrolling list elements can go behind it. - val mlpNavShade = binding.navigationBarShade.layoutParams as MarginLayoutParams - mlpNavShade.height = insets.bottom - binding.navigationBarShade.layoutParams = mlpNavShade + // The only situation where we care to have a nav bar shade is when it's at the bottom + // of the screen where scrolling list elements can go behind it. + val mlpNavShade = binding.navigationBarShade.layoutParams as MarginLayoutParams + mlpNavShade.height = insets.bottom + binding.navigationBarShade.layoutParams = mlpNavShade - windowInsets - } + windowInsets + } private fun createOpenCitraDirectoryLauncher( permissionsLost: Boolean ): ActivityResultLauncher { - return registerForActivityResult(ActivityResultContracts.OpenDocumentTree()) { result: Uri? -> + return registerForActivityResult( + ActivityResultContracts.OpenDocumentTree() + ) { result: Uri? -> if (result == null) { return@registerForActivityResult } @@ -427,7 +438,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider { val workManager = WorkManager.getInstance(applicationContext) workManager.enqueueUniqueWork( - "installCiaWork", ExistingWorkPolicy.APPEND_OR_REPLACE, + "installCiaWork", + ExistingWorkPolicy.APPEND_OR_REPLACE, OneTimeWorkRequest.Builder(CiaInstallWorker::class.java) .setInputData( Data.Builder().putStringArray("CIA_FILES", selectedFiles) @@ -439,7 +451,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider { } val setupOpenCitraDirectory = registerForActivityResult( - ActivityResultContracts.OpenDocumentTree(), + ActivityResultContracts.OpenDocumentTree() ) { result: Uri? -> homeViewModel.selectedCitraDirectory = result } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/CiaInstallWorker.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/CiaInstallWorker.kt index 5dd7821f8..ee2d23d49 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/CiaInstallWorker.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/CiaInstallWorker.kt @@ -9,6 +9,7 @@ import android.content.Context import android.net.Uri import android.widget.Toast import androidx.core.app.NotificationCompat +import androidx.core.net.toUri import androidx.work.ForegroundInfo import androidx.work.Worker import androidx.work.WorkerParameters @@ -16,12 +17,8 @@ import org.citra.citra_emu.NativeLibrary import org.citra.citra_emu.NativeLibrary.InstallStatus import org.citra.citra_emu.R import org.citra.citra_emu.utils.FileUtil.getFilename -import androidx.core.net.toUri -class CiaInstallWorker( - val context: Context, - params: WorkerParameters -) : Worker(context, params) { +class CiaInstallWorker(val context: Context, params: WorkerParameters) : Worker(context, params) { private val GROUP_KEY_CIA_INSTALL_STATUS = "org.citra.citra_emu.CIA_INSTALL_STATUS" private var lastNotifiedTime: Long = 0 private val SUMMARY_NOTIFICATION_ID = 0xC1A0000 @@ -123,7 +120,8 @@ class CiaInstallWorker( val selectedFiles = inputData.getStringArray("CIA_FILES")!! val toastText: CharSequence = context.resources.getQuantityString( R.plurals.cia_install_toast, - selectedFiles.size, selectedFiles.size + selectedFiles.size, + selectedFiles.size ) context.mainExecutor.execute { Toast.makeText(context, toastText, Toast.LENGTH_LONG).show() diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/CitraDirectoryHelper.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/CitraDirectoryHelper.kt index 58eb5cc22..3fea8a6ea 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/CitraDirectoryHelper.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/CitraDirectoryHelper.kt @@ -16,8 +16,15 @@ import org.citra.citra_emu.viewmodel.HomeViewModel /** * Citra directory initialization ui flow controller. */ -class CitraDirectoryHelper(private val fragmentActivity: FragmentActivity, private val lostPermission: Boolean) { - fun showCitraDirectoryDialog(result: Uri, callback: SetupCallback? = null, buttonState: () -> Unit) { +class CitraDirectoryHelper( + private val fragmentActivity: FragmentActivity, + private val lostPermission: Boolean +) { + fun showCitraDirectoryDialog( + result: Uri, + callback: SetupCallback? = null, + buttonState: () -> Unit + ) { val citraDirectoryDialog = CitraDirectoryDialogFragment.newInstance( fragmentActivity, result.toString(), @@ -29,7 +36,7 @@ class CitraDirectoryHelper(private val fragmentActivity: FragmentActivity, priva } val takeFlags = Intent.FLAG_GRANT_WRITE_URI_PERMISSION or - Intent.FLAG_GRANT_READ_URI_PERMISSION + Intent.FLAG_GRANT_READ_URI_PERMISSION fragmentActivity.contentResolver.takePersistableUriPermission( path, takeFlags @@ -46,7 +53,8 @@ class CitraDirectoryHelper(private val fragmentActivity: FragmentActivity, priva // If user check move data, show copy progress dialog. CopyDirProgressDialog.newInstance(fragmentActivity, previous, path, callback) ?.show(fragmentActivity.supportFragmentManager, CopyDirProgressDialog.TAG) - }) + } + ) citraDirectoryDialog.show( fragmentActivity.supportFragmentManager, CitraDirectoryDialogFragment.TAG diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/CitraDirectoryUtils.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/CitraDirectoryUtils.kt index 1f59ca841..e474efbad 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/CitraDirectoryUtils.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/CitraDirectoryUtils.kt @@ -16,24 +16,26 @@ object CitraDirectoryUtils { fun needToUpdateManually(): Boolean { val directoryString = preferences.getString(CITRA_DIRECTORY, "") - val limeDirectoryString = preferences.getString(LIME3DS_DIRECTORY,"") - return (directoryString != "" && limeDirectoryString != "" && directoryString != limeDirectoryString) + val limeDirectoryString = preferences.getString(LIME3DS_DIRECTORY, "") + return ( + directoryString != "" && limeDirectoryString != "" && + directoryString != limeDirectoryString + ) } fun attemptAutomaticUpdateDirectory() { val directoryString = preferences.getString(CITRA_DIRECTORY, "") - val limeDirectoryString = preferences.getString(LIME3DS_DIRECTORY,"") + val limeDirectoryString = preferences.getString(LIME3DS_DIRECTORY, "") if (needToUpdateManually()) { - return; + return } - if (directoryString == "" && limeDirectoryString != "") { + if (directoryString == "" && limeDirectoryString != "") { // Upgrade from Lime3DS to Azahar - PermissionsHandler.setCitraDirectory(limeDirectoryString) + PermissionsHandler.setCitraDirectory(limeDirectoryString) removeLimeDirectoryPreference() DirectoryInitialization.resetCitraDirectoryState() DirectoryInitialization.start() - - } else if (directoryString != "" && directoryString == limeDirectoryString) { + } else if (directoryString != "" && directoryString == limeDirectoryString) { // Both the Lime3DS and Azahar directories are the same, // so delete the obsolete Lime3DS value. removeLimeDirectoryPreference() diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/ControllerMappingHelper.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/ControllerMappingHelper.kt index 7bba904b5..cd3fcb440 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/ControllerMappingHelper.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/ControllerMappingHelper.kt @@ -15,13 +15,14 @@ object ControllerMappingHelper { /** * Some controllers report extra button presses that can be ignored. */ - fun shouldKeyBeIgnored(inputDevice: InputDevice, keyCode: Int): Boolean { - return if (isDualShock4(inputDevice)) { + fun shouldKeyBeIgnored(inputDevice: InputDevice, keyCode: Int): Boolean = + if (isDualShock4(inputDevice)) { // The two analog triggers generate analog motion events as well as a keycode. // We always prefer to use the analog values, so throw away the button press keyCode == KeyEvent.KEYCODE_BUTTON_L2 || keyCode == KeyEvent.KEYCODE_BUTTON_R2 - } else false - } + } else { + false + } /** * Scale an axis to be zero-centered with a proper range. diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/DirectoryInitialization.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/DirectoryInitialization.kt index e41b7c6db..b4cfbb949 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/DirectoryInitialization.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/DirectoryInitialization.kt @@ -7,16 +7,16 @@ package org.citra.citra_emu.utils import android.content.Context import android.net.Uri import androidx.preference.PreferenceManager -import org.citra.citra_emu.BuildConfig -import org.citra.citra_emu.CitraApplication -import org.citra.citra_emu.NativeLibrary -import org.citra.citra_emu.utils.PermissionsHandler.hasWriteAccess import java.io.File import java.io.FileOutputStream import java.io.IOException import java.io.InputStream import java.io.OutputStream import java.util.concurrent.atomic.AtomicBoolean +import org.citra.citra_emu.BuildConfig +import org.citra.citra_emu.CitraApplication +import org.citra.citra_emu.NativeLibrary +import org.citra.citra_emu.utils.PermissionsHandler.hasWriteAccess /** * A service that spawns its own thread in order to copy several binary and shader files @@ -70,9 +70,8 @@ object DirectoryInitialization { } @JvmStatic - fun areCitraDirectoriesReady(): Boolean { - return directoryState == DirectoryInitializationState.CITRA_DIRECTORIES_INITIALIZED - } + fun areCitraDirectoriesReady(): Boolean = + directoryState == DirectoryInitializationState.CITRA_DIRECTORIES_INITIALIZED fun resetCitraDirectoryState() { directoryState = null @@ -130,18 +129,22 @@ object DirectoryInitialization { createdFolder = true } copyAssetFolder( - assetFolder + File.separator + file, File(outputFolder, file), - overwrite, context + assetFolder + File.separator + file, + File(outputFolder, file), + overwrite, + context ) copyAsset( - assetFolder + File.separator + file, File(outputFolder, file), overwrite, + assetFolder + File.separator + file, + File(outputFolder, file), + overwrite, context ) } } catch (e: IOException) { Log.error( "[DirectoryInitialization] Failed to copy asset folder: $assetFolder" + - e.message + e.message ) } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/DiskShaderCacheProgress.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/DiskShaderCacheProgress.kt index 15ea56d3c..676af576a 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/DiskShaderCacheProgress.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/DiskShaderCacheProgress.kt @@ -33,6 +33,7 @@ object DiskShaderCacheProgress { emulationActivity.runOnUiThread { when (stage) { LoadCallbackStage.Prepare -> prepareViewModel() + LoadCallbackStage.Decompile -> emulationViewModel.updateProgress( emulationActivity.getString(R.string.preparing_shaders), progress, @@ -40,7 +41,7 @@ object DiskShaderCacheProgress { ) LoadCallbackStage.Build -> emulationViewModel.updateProgress( - emulationActivity.getString(R.string.building_shaders, obj ), + emulationActivity.getString(R.string.building_shaders, obj), progress, max ) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/DocumentsTree.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/DocumentsTree.kt index de5881db7..4f39a01ea 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/DocumentsTree.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/DocumentsTree.kt @@ -8,14 +8,14 @@ import android.net.Uri import android.provider.DocumentsContract import androidx.core.net.toUri import androidx.documentfile.provider.DocumentFile -import org.citra.citra_emu.CitraApplication -import org.citra.citra_emu.model.CheapDocument -import org.citra.citra_emu.utils.BuildUtil import java.io.IOException import java.net.URLDecoder import java.nio.file.Paths import java.util.StringTokenizer import java.util.concurrent.ConcurrentHashMap +import org.citra.citra_emu.CitraApplication +import org.citra.citra_emu.model.CheapDocument +import org.citra.citra_emu.utils.BuildUtil /** * A cached document tree for Citra user directory. @@ -127,7 +127,8 @@ class DocumentsTree { // Create directory if it doesn't exist and creation is enabled if (child == null && createIfNotExists) { try { - val createdDir = FileUtil.createDir(current.uri.toString(), component) ?: return null + val createdDir = + FileUtil.createDir(current.uri.toString(), component) ?: return null child = DocumentsNode(createdDir, true).apply { parent = current } @@ -152,9 +153,7 @@ class DocumentsTree { } @Synchronized - fun exists(filepath: String): Boolean { - return resolvePath(filepath) != null - } + fun exists(filepath: String): Boolean = resolvePath(filepath) != null @Synchronized fun copyFile( @@ -200,7 +199,11 @@ class DocumentsTree { val node = resolvePath(filepath) ?: return false try { val filename = URLDecoder.decode(destinationFilename, FileUtil.DECODE_METHOD) - val newUri = DocumentsContract.renameDocument(context.contentResolver, node.uri!!, filename) + val newUri = DocumentsContract.renameDocument( + context.contentResolver, + node.uri!!, + filename + ) node.rename(filename, newUri) return true } catch (e: Exception) { @@ -214,7 +217,12 @@ class DocumentsTree { val sourceDirNode = resolvePath(sourceDirPath) ?: return false val destDirNode = resolvePath(destDirPath) ?: return false try { - val newUri = DocumentsContract.moveDocument(context.contentResolver, sourceFileNode.uri!!, sourceDirNode.uri!!, destDirNode.uri!!) + val newUri = DocumentsContract.moveDocument( + context.contentResolver, + sourceFileNode.uri!!, + sourceDirNode.uri!!, + destDirNode.uri!! + ) updateDocumentLocation("$sourceDirPath/$filename", "$destDirPath/$filename") return true } catch (e: Exception) { @@ -359,8 +367,7 @@ class DocumentsTree { fun findChild(filename: String) = children[filename.lowercase()] @Synchronized - fun getChildNames(): Array = - children.mapNotNull { it.value!!.name }.toTypedArray() + fun getChildNames(): Array = children.mapNotNull { it.value!!.name }.toTypedArray() } companion object { @@ -368,7 +375,7 @@ class DocumentsTree { val kotlinDirectoryAccessWhitelist = arrayOf( "/config/", "/log/", - "/gpu_drivers/", + "/gpu_drivers/" ) } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/EmulationLifecycleUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/EmulationLifecycleUtil.kt index 5fafb7bed..1abe41bb1 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/EmulationLifecycleUtil.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/EmulationLifecycleUtil.kt @@ -8,7 +8,6 @@ object EmulationLifecycleUtil { private var shutdownHooks: MutableList = ArrayList() private var pauseResumeHooks: MutableList = ArrayList() - fun closeGame() { shutdownHooks.forEach(Runnable::run) } @@ -19,7 +18,9 @@ object EmulationLifecycleUtil { fun addShutdownHook(hook: Runnable) { if (shutdownHooks.contains(hook)) { - Log.warning("[EmulationLifecycleUtil] Tried to add shutdown hook for function that already existed. Skipping.") + Log.warning( + "[EmulationLifecycleUtil] Tried to add shutdown hook for function that already existed. Skipping." + ) } else { shutdownHooks.add(hook) } @@ -27,7 +28,9 @@ object EmulationLifecycleUtil { fun addPauseResumeHook(hook: Runnable) { if (pauseResumeHooks.contains(hook)) { - Log.warning("[EmulationLifecycleUtil] Tried to add pause resume hook for function that already existed. Skipping.") + Log.warning( + "[EmulationLifecycleUtil] Tried to add pause resume hook for function that already existed. Skipping." + ) } else { pauseResumeHooks.add(hook) } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/EmulationMenuSettings.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/EmulationMenuSettings.kt index 6ff08fa37..4dd12acf7 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/EmulationMenuSettings.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/EmulationMenuSettings.kt @@ -28,7 +28,10 @@ object EmulationMenuSettings { .apply() } var buttonSlide: Int - get() = preferences.getInt("EmulationMenuSettings_ButtonSlideMode", ButtonSlidingMode.Disabled.int) + get() = preferences.getInt( + "EmulationMenuSettings_ButtonSlideMode", + ButtonSlidingMode.Disabled.int + ) set(value) { preferences.edit() .putInt("EmulationMenuSettings_ButtonSlideMode", value) @@ -39,8 +42,8 @@ object EmulationMenuSettings { get() = preferences.getBoolean("EmulationMenuSettings_HapticFeedback", true) set(value) { preferences.edit() - .putBoolean("EmulationMenuSettings_HapticFeedback", value) - .apply() + .putBoolean("EmulationMenuSettings_HapticFeedback", value) + .apply() } var swapScreens: Boolean get() = preferences.getBoolean("EmulationMenuSettings_SwapScreens", false) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/FileUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/FileUtil.kt index 237fe1258..d58e281fe 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/FileUtil.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/FileUtil.kt @@ -4,7 +4,6 @@ package org.citra.citra_emu.utils -import okio.ByteString.Companion.readByteString import android.content.Context import android.database.Cursor import android.net.Uri @@ -13,8 +12,6 @@ import android.system.Os import android.util.Pair import androidx.core.net.toUri import androidx.documentfile.provider.DocumentFile -import org.citra.citra_emu.CitraApplication -import org.citra.citra_emu.model.CheapDocument import java.io.BufferedInputStream import java.io.File import java.io.FileOutputStream @@ -25,6 +22,9 @@ import java.net.URLDecoder import java.nio.charset.StandardCharsets import java.util.zip.ZipEntry import java.util.zip.ZipInputStream +import okio.ByteString.Companion.readByteString +import org.citra.citra_emu.CitraApplication +import org.citra.citra_emu.model.CheapDocument object FileUtil { const val PATH_TREE = "tree" @@ -228,7 +228,7 @@ object FileUtil { if (uri.scheme == "file") { BuildUtil.assertNotGooglePlay() - val file = File(uri.path!!); + val file = File(uri.path!!) return file.name } @@ -289,11 +289,7 @@ object FileUtil { } @JvmStatic - fun copyFile( - sourceUri: Uri, - destinationUri: Uri, - destinationFilename: String - ): Boolean { + fun copyFile(sourceUri: Uri, destinationUri: Uri, destinationFilename: String): Boolean { try { val destinationParent = DocumentFile.fromTreeUri(context, destinationUri) ?: return false @@ -362,11 +358,7 @@ object FileUtil { return false } - fun copyDir( - sourcePath: String, - destinationPath: String, - listener: CopyDirListener? - ) { + fun copyDir(sourcePath: String, destinationPath: String, listener: CopyDirListener?) { try { val sourceUri = Uri.parse(sourcePath) val destinationUri = Uri.parse(destinationPath) @@ -451,7 +443,12 @@ object FileUtil { val sourceFileUri = ("$sourceDirUriString%2F$filename").toUri() val sourceDirUri = sourceDirUriString.toUri() val destDirUri = destDirUriString.toUri() - DocumentsContract.moveDocument(context.contentResolver, sourceFileUri, sourceDirUri, destDirUri) + DocumentsContract.moveDocument( + context.contentResolver, + sourceFileUri, + sourceDirUri, + destDirUri + ) return true } catch (e: Exception) { Log.error("[FileUtil]: Cannot move file, error: " + e.message) @@ -529,10 +526,7 @@ object FileUtil { } } - fun copyToExternalStorage( - sourceFile: Uri, - destinationDir: DocumentFile - ): DocumentFile? { + fun copyToExternalStorage(sourceFile: Uri, destinationDir: DocumentFile): DocumentFile? { val filename = getFilename(sourceFile) val destinationFile = destinationDir.createFile("application/zip", filename)!! destinationFile.outputStream().use { os -> @@ -555,21 +549,20 @@ object FileUtil { false } - fun getFreeSpace(context: Context, uri: Uri?): Double = - try { - val docTreeUri = DocumentsContract.buildDocumentUriUsingTree( - uri, - DocumentsContract.getTreeDocumentId(uri) - ) - val pfd = context.contentResolver.openFileDescriptor(docTreeUri, "r")!! - val stats = Os.fstatvfs(pfd.fileDescriptor) - val spaceInGigaBytes = stats.f_bavail * stats.f_bsize / 1024.0 / 1024 / 1024 - pfd.close() - spaceInGigaBytes - } catch (e: Exception) { - Log.error("[FileUtil] Cannot get storage size.") - 0.0 - } + fun getFreeSpace(context: Context, uri: Uri?): Double = try { + val docTreeUri = DocumentsContract.buildDocumentUriUsingTree( + uri, + DocumentsContract.getTreeDocumentId(uri) + ) + val pfd = context.contentResolver.openFileDescriptor(docTreeUri, "r")!! + val stats = Os.fstatvfs(pfd.fileDescriptor) + val spaceInGigaBytes = stats.f_bavail * stats.f_bsize / 1024.0 / 1024 / 1024 + pfd.close() + spaceInGigaBytes + } catch (e: Exception) { + Log.error("[FileUtil] Cannot get storage size.") + 0.0 + } fun closeQuietly(closeable: AutoCloseable?) { if (closeable != null) { @@ -589,8 +582,7 @@ object FileUtil { } @Throws(IOException::class) - fun getStringFromFile(file: File): String = - String(file.readBytes(), StandardCharsets.UTF_8) + fun getStringFromFile(file: File): String = String(file.readBytes(), StandardCharsets.UTF_8) @Throws(IOException::class) fun getStringFromInputStream(stream: InputStream, length: Long = 0L): String = diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/GameHelper.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/GameHelper.kt index 1c55e1616..82c8656de 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/GameHelper.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/GameHelper.kt @@ -7,6 +7,7 @@ package org.citra.citra_emu.utils import android.content.SharedPreferences import android.net.Uri import androidx.preference.PreferenceManager +import java.io.IOException import kotlinx.serialization.encodeToString import kotlinx.serialization.json.Json import org.citra.citra_emu.CitraApplication @@ -15,7 +16,6 @@ import org.citra.citra_emu.R import org.citra.citra_emu.model.CheapDocument import org.citra.citra_emu.model.Game import org.citra.citra_emu.model.GameInfo -import java.io.IOException object GameHelper { const val KEY_GAME_PATH = "game_path" @@ -32,7 +32,9 @@ object GameHelper { addGamesRecursive(games, FileUtil.listFiles(gamesUri), 3) NativeLibrary.getInstalledGamePaths().forEach { - games.add(getGame(Uri.parse(it.path), isInstalled = true, addedToLibrary = true, it.mediaType)) + games.add( + getGame(Uri.parse(it.path), isInstalled = true, addedToLibrary = true, it.mediaType) + ) } // Cache list of games found on disk @@ -62,24 +64,38 @@ object GameHelper { addGamesRecursive(games, FileUtil.listFiles(it.uri), depth - 1) } else { if (Game.allExtensions.contains(FileUtil.getExtension(it.uri))) { - games.add(getGame(it.uri, isInstalled = false, addedToLibrary = true, Game.MediaType.GAME_CARD)) + games.add( + getGame( + it.uri, + isInstalled = false, + addedToLibrary = true, + Game.MediaType.GAME_CARD + ) + ) } } } } - fun getGame(uri: Uri, isInstalled: Boolean, addedToLibrary: Boolean, mediaType: Game.MediaType): Game { + fun getGame( + uri: Uri, + isInstalled: Boolean, + addedToLibrary: Boolean, + mediaType: Game.MediaType + ): Game { val filePath = uri.toString() var nativePath: String? = null var gameInfo: GameInfo? - if (BuildUtil.isGooglePlayBuild || FileUtil.isNativePath(filePath) || filePath.startsWith("!")) { + if (BuildUtil.isGooglePlayBuild || FileUtil.isNativePath(filePath) || + filePath.startsWith("!") + ) { gameInfo = GameInfo(filePath) } else { nativePath = if (uri.scheme == "fd") { uri.toString() } else { "!" + NativeLibrary.getNativePath(uri) - }; + } gameInfo = GameInfo(nativePath) } @@ -92,10 +108,16 @@ object GameHelper { val newGame = Game( valid, - (gameInfo?.getTitle() ?: FileUtil.getFilename(uri)).replace("[\\t\\n\\r]+".toRegex(), " "), + ( + gameInfo?.getTitle() ?: FileUtil.getFilename( + uri + ) + ).replace("[\\t\\n\\r]+".toRegex(), " "), filePath.replace("\n", " "), // TODO: This next line can be deduplicated but I don't want to right now -OS - if (BuildUtil.isGooglePlayBuild || FileUtil.isNativePath(filePath) || filePath.startsWith("!")) { + if (BuildUtil.isGooglePlayBuild || FileUtil.isNativePath(filePath) || + filePath.startsWith("!") + ) { filePath } else { nativePath!! @@ -103,7 +125,12 @@ object GameHelper { gameInfo?.getTitleID() ?: 0, mediaType, gameInfo?.getCompany() ?: "", - if (isEncrypted) { CitraApplication.appContext.getString(R.string.unsupported_encrypted) } else { gameInfo?.getRegions() ?: "" }, + if (isEncrypted) { + CitraApplication.appContext.getString(R.string.unsupported_encrypted) + } else { + gameInfo?.getRegions() + ?: "" + }, isInstalled, gameInfo?.isSystemTitle() ?: false, gameInfo?.getIsVisibleSystemTitle() ?: false, diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/GameIconUtils.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/GameIconUtils.kt index 6ba803ca8..fe0a55947 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/GameIconUtils.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/GameIconUtils.kt @@ -18,21 +18,16 @@ import coil.memory.MemoryCache import coil.request.ImageRequest import coil.request.Options import coil.transform.RoundedCornersTransformation +import java.nio.IntBuffer import org.citra.citra_emu.R import org.citra.citra_emu.model.Game -import java.nio.IntBuffer -class GameIconFetcher( - private val game: Game, - private val options: Options -) : Fetcher { - override suspend fun fetch(): FetchResult { - return DrawableResult( - drawable = getGameIcon(game.icon)!!.toDrawable(options.context.resources), - isSampled = false, - dataSource = DataSource.DISK - ) - } +class GameIconFetcher(private val game: Game, private val options: Options) : Fetcher { + override suspend fun fetch(): FetchResult = DrawableResult( + drawable = getGameIcon(game.icon)!!.toDrawable(options.context.resources), + isSampled = false, + dataSource = DataSource.DISK + ) private fun getGameIcon(vector: IntArray?): Bitmap? { val bitmap = Bitmap.createBitmap(48, 48, Bitmap.Config.RGB_565) diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/GpuDriverHelper.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/GpuDriverHelper.kt index 8ed7cd2e1..7c0e887d4 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/GpuDriverHelper.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/GpuDriverHelper.kt @@ -7,10 +7,6 @@ package org.citra.citra_emu.utils import android.net.Uri import android.os.Build import androidx.documentfile.provider.DocumentFile -import org.citra.citra_emu.CitraApplication -import org.citra.citra_emu.NativeLibrary -import org.citra.citra_emu.utils.FileUtil.asDocumentFile -import org.citra.citra_emu.utils.FileUtil.inputStream import java.io.BufferedInputStream import java.io.File import java.io.IOException @@ -19,6 +15,10 @@ import java.lang.IllegalStateException import java.util.zip.ZipEntry import java.util.zip.ZipException import java.util.zip.ZipInputStream +import org.citra.citra_emu.CitraApplication +import org.citra.citra_emu.NativeLibrary +import org.citra.citra_emu.utils.FileUtil.asDocumentFile +import org.citra.citra_emu.utils.FileUtil.inputStream object GpuDriverHelper { private const val META_JSON_FILENAME = "meta.json" diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/GpuDriverMetadata.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/GpuDriverMetadata.kt index 2da0ccf92..0203b0c68 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/GpuDriverMetadata.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/GpuDriverMetadata.kt @@ -4,11 +4,11 @@ package org.citra.citra_emu.utils +import java.io.File import java.io.IOException +import java.io.InputStream import org.json.JSONException import org.json.JSONObject -import java.io.File -import java.io.InputStream class GpuDriverMetadata { /** @@ -76,12 +76,12 @@ class GpuDriverMetadata { } return other.name == name && - other.description == description && - other.author == author && - other.vendor == vendor && - other.version == version && - other.minApi == minApi && - other.libraryName == libraryName + other.description == description && + other.author == author && + other.vendor == vendor && + other.version == version && + other.minApi == minApi && + other.libraryName == libraryName } override fun hashCode(): Int { diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/MemoryUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/MemoryUtil.kt index 4bf1d88c7..3e58484e8 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/MemoryUtil.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/MemoryUtil.kt @@ -6,10 +6,10 @@ package org.citra.citra_emu.utils import android.app.ActivityManager import android.content.Context import android.os.Build -import org.citra.citra_emu.CitraApplication -import org.citra.citra_emu.R import java.util.Locale import kotlin.math.ceil +import org.citra.citra_emu.CitraApplication +import org.citra.citra_emu.R object MemoryUtil { private val context get() = CitraApplication.appContext @@ -24,59 +24,64 @@ object MemoryUtil { const val Pb = Tb * 1024 const val Eb = Pb * 1024 - fun bytesToSizeUnit(size: Float, roundUp: Boolean = false): String = - when { - size < Kb -> { - context.getString( - R.string.memory_formatted, - size.hundredths, - context.getString(R.string.memory_byte_shorthand) - ) - } - size < Mb -> { - context.getString( - R.string.memory_formatted, - if (roundUp) ceil(size / Kb) else (size / Kb).hundredths, - context.getString(R.string.memory_kilobyte) - ) - } - size < Gb -> { - context.getString( - R.string.memory_formatted, - if (roundUp) ceil(size / Mb) else (size / Mb).hundredths, - context.getString(R.string.memory_megabyte) - ) - } - size < Tb -> { - context.getString( - R.string.memory_formatted, - if (roundUp) ceil(size / Gb) else (size / Gb).hundredths, - context.getString(R.string.memory_gigabyte) - ) - } - size < Pb -> { - context.getString( - R.string.memory_formatted, - if (roundUp) ceil(size / Tb) else (size / Tb).hundredths, - context.getString(R.string.memory_terabyte) - ) - } - size < Eb -> { - context.getString( - R.string.memory_formatted, - if (roundUp) ceil(size / Pb) else (size / Pb).hundredths, - context.getString(R.string.memory_petabyte) - ) - } - else -> { - context.getString( - R.string.memory_formatted, - if (roundUp) ceil(size / Eb) else (size / Eb).hundredths, - context.getString(R.string.memory_exabyte) - ) - } + fun bytesToSizeUnit(size: Float, roundUp: Boolean = false): String = when { + size < Kb -> { + context.getString( + R.string.memory_formatted, + size.hundredths, + context.getString(R.string.memory_byte_shorthand) + ) } + size < Mb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Kb) else (size / Kb).hundredths, + context.getString(R.string.memory_kilobyte) + ) + } + + size < Gb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Mb) else (size / Mb).hundredths, + context.getString(R.string.memory_megabyte) + ) + } + + size < Tb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Gb) else (size / Gb).hundredths, + context.getString(R.string.memory_gigabyte) + ) + } + + size < Pb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Tb) else (size / Tb).hundredths, + context.getString(R.string.memory_terabyte) + ) + } + + size < Eb -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Pb) else (size / Pb).hundredths, + context.getString(R.string.memory_petabyte) + ) + } + + else -> { + context.getString( + R.string.memory_formatted, + if (roundUp) ceil(size / Eb) else (size / Eb).hundredths, + context.getString(R.string.memory_exabyte) + ) + } + } + val totalMemory: Float get() { val memInfo = ActivityManager.MemoryInfo() @@ -91,16 +96,15 @@ object MemoryUtil { } } - fun isLessThan(minimum: Int, size: Float): Boolean = - when (size) { - Kb -> totalMemory < Mb && totalMemory < minimum - Mb -> totalMemory < Gb && (totalMemory / Mb) < minimum - Gb -> totalMemory < Tb && (totalMemory / Gb) < minimum - Tb -> totalMemory < Pb && (totalMemory / Tb) < minimum - Pb -> totalMemory < Eb && (totalMemory / Pb) < minimum - Eb -> totalMemory / Eb < minimum - else -> totalMemory < Kb && totalMemory < minimum - } + fun isLessThan(minimum: Int, size: Float): Boolean = when (size) { + Kb -> totalMemory < Mb && totalMemory < minimum + Mb -> totalMemory < Gb && (totalMemory / Mb) < minimum + Gb -> totalMemory < Tb && (totalMemory / Gb) < minimum + Tb -> totalMemory < Pb && (totalMemory / Tb) < minimum + Pb -> totalMemory < Eb && (totalMemory / Pb) < minimum + Eb -> totalMemory / Eb < minimum + else -> totalMemory < Kb && totalMemory < minimum + } // Devices are unlikely to have 0.5GB increments of memory so we'll just round up to account for // the potential error created by memInfo.totalMem diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/PermissionsHandler.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/PermissionsHandler.kt index 6ea04c779..9cba76155 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/PermissionsHandler.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/PermissionsHandler.kt @@ -11,8 +11,8 @@ import android.net.Uri import android.os.Build import android.provider.DocumentsContract import androidx.activity.result.ActivityResultLauncher -import androidx.preference.PreferenceManager import androidx.documentfile.provider.DocumentFile +import androidx.preference.PreferenceManager import org.citra.citra_emu.CitraApplication object PermissionsHandler { @@ -38,7 +38,10 @@ object PermissionsHandler { context.contentResolver.releasePersistableUriPermission(uri, takeFlags) } catch (e: Exception) { // Do not use native library logging, as the native library may not be loaded yet - android.util.Log.e("PermissionsHandler", "Cannot check citra data directory permission, error: ${e.message}") + android.util.Log.e( + "PermissionsHandler", + "Cannot check citra data directory permission, error: ${e.message}" + ) } return false } @@ -62,6 +65,5 @@ object PermissionsHandler { ) activityLauncher.launch(initialUri) } - } } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/RefreshRateUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/RefreshRateUtil.kt index 675fe6702..58380fc41 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/RefreshRateUtil.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/RefreshRateUtil.kt @@ -50,4 +50,4 @@ object RefreshRateUtil { window.attributes.preferredDisplayModeId = newModeId } } -} \ No newline at end of file +} diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/ThemeUtil.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/ThemeUtil.kt index c673b4e00..5d8b07124 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/ThemeUtil.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/ThemeUtil.kt @@ -16,11 +16,11 @@ import androidx.lifecycle.DefaultLifecycleObserver import androidx.lifecycle.Lifecycle import androidx.lifecycle.LifecycleOwner import androidx.preference.PreferenceManager +import kotlin.math.roundToInt import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.R import org.citra.citra_emu.features.settings.model.Settings import org.citra.citra_emu.ui.main.ThemeProvider -import kotlin.math.roundToInt object ThemeUtil { const val SYSTEM_BAR_ALPHA = 0.9f @@ -75,18 +75,19 @@ object ThemeUtil { false -> setLightModeSystemBars(windowController) true -> setDarkModeSystemBars(windowController) } + AppCompatDelegate.MODE_NIGHT_NO -> setLightModeSystemBars(windowController) + AppCompatDelegate.MODE_NIGHT_YES -> setDarkModeSystemBars(windowController) } } - private fun isNightMode(activity: AppCompatActivity): Boolean { - return when (activity.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { + private fun isNightMode(activity: AppCompatActivity): Boolean = + when (activity.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK) { Configuration.UI_MODE_NIGHT_NO -> false Configuration.UI_MODE_NIGHT_YES -> true else -> false } - } private fun setLightModeSystemBars(windowController: WindowInsetsControllerCompat) { windowController.isAppearanceLightStatusBars = true @@ -107,21 +108,24 @@ object ThemeUtil { } @ColorInt - fun getColorWithOpacity(@ColorInt color: Int, alphaFactor: Float): Int { - return Color.argb( - (alphaFactor * Color.alpha(color)).roundToInt(), - Color.red(color), - Color.green(color), - Color.blue(color) - ) - } + fun getColorWithOpacity(@ColorInt color: Int, alphaFactor: Float): Int = Color.argb( + (alphaFactor * Color.alpha(color)).roundToInt(), + Color.red(color), + Color.green(color), + Color.blue(color) + ) // Listener that detects if the theme keys are being changed from the setting menu and recreates the activity private var listener: SharedPreferences.OnSharedPreferenceChangeListener? = null fun ThemeChangeListener(activity: AppCompatActivity) { listener = SharedPreferences.OnSharedPreferenceChangeListener { _, key -> - val relevantKeys = listOf(Settings.PREF_STATIC_THEME_COLOR, Settings.PREF_MATERIAL_YOU, Settings.PREF_BLACK_BACKGROUNDS) + val relevantKeys = + listOf( + Settings.PREF_STATIC_THEME_COLOR, + Settings.PREF_MATERIAL_YOU, + Settings.PREF_BLACK_BACKGROUNDS + ) if (key in relevantKeys) { activity.recreate() } diff --git a/src/android/app/src/main/java/org/citra/citra_emu/utils/TurboHelper.kt b/src/android/app/src/main/java/org/citra/citra_emu/utils/TurboHelper.kt index 26ac69a75..2065740dd 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/utils/TurboHelper.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/utils/TurboHelper.kt @@ -13,9 +13,7 @@ import org.citra.citra_emu.features.settings.model.IntSetting object TurboHelper { private var turboSpeedEnabled = false - fun isTurboSpeedEnabled(): Boolean { - return turboSpeedEnabled - } + fun isTurboSpeedEnabled(): Boolean = turboSpeedEnabled fun reloadTurbo(showToast: Boolean) { val context = CitraApplication.appContext diff --git a/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/CompressProgressDialogViewModel.kt b/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/CompressProgressDialogViewModel.kt index 7a6e71e52..426fbc80b 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/CompressProgressDialogViewModel.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/CompressProgressDialogViewModel.kt @@ -8,7 +8,7 @@ import androidx.lifecycle.ViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.asStateFlow -object CompressProgressDialogViewModel: ViewModel() { +object CompressProgressDialogViewModel : ViewModel() { private val _progress = MutableStateFlow(0) val progress = _progress.asStateFlow() @@ -30,4 +30,4 @@ object CompressProgressDialogViewModel: ViewModel() { _total.value = 0 _message.value = "" } -} \ No newline at end of file +} diff --git a/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/DriverViewModel.kt b/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/DriverViewModel.kt index 44fb8e8c4..7964cadba 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/DriverViewModel.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/DriverViewModel.kt @@ -16,8 +16,8 @@ import kotlinx.coroutines.withContext import org.citra.citra_emu.CitraApplication import org.citra.citra_emu.R import org.citra.citra_emu.utils.FileUtil.asDocumentFile -import org.citra.citra_emu.utils.GpuDriverMetadata import org.citra.citra_emu.utils.GpuDriverHelper +import org.citra.citra_emu.utils.GpuDriverMetadata class DriverViewModel : ViewModel() { val areDriversLoading get() = _areDriversLoading.asStateFlow() diff --git a/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/HomeViewModel.kt b/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/HomeViewModel.kt index 739075522..0261a27a6 100644 --- a/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/HomeViewModel.kt +++ b/src/android/app/src/main/java/org/citra/citra_emu/viewmodel/HomeViewModel.kt @@ -70,13 +70,17 @@ class HomeViewModel : ViewModel() { val selectedCitraDirectoryLiveData: LiveData = _selectedCitraDirectory var selectedCitraDirectory: Uri? get() = _selectedCitraDirectory.value - set(value) { _selectedCitraDirectory.value = value } + set(value) { + _selectedCitraDirectory.value = value + } private val _selectedGamesDirectory = MutableLiveData() val selectedGamesDirectoryLiveData: LiveData = _selectedGamesDirectory var selectedGamesDirectory: Uri? get() = _selectedGamesDirectory.value - set(value) { _selectedGamesDirectory.value = value } + set(value) { + _selectedGamesDirectory.value = value + } fun setNavigationVisibility(visible: Boolean, animated: Boolean) { if (_navigationVisible.value.first == visible) {