From 7c05cfd1173c80ed7eef5d3961b6f1bb1e8626c9 Mon Sep 17 00:00:00 2001 From: jpolo1224 Date: Sun, 26 Jul 2026 14:53:11 -0400 Subject: [PATCH] Android: make the settings usable again, and declutter the library menus MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CollapsibleSection had stopped collapsing. Its own comment describes "a tappable header that shows or hides its content ... to de-bloat long settings lists", but the body rendered a plain title and called content() unconditionally, with initiallyExpanded marked UNUSED_PARAMETER. All 20 sections across Pad, Renderer, Performance and Fixes were therefore permanently open, which is why the settings became unusable in landscape: not too many options, but every option in a tab on screen at once. Restoring it shortens four tabs at a stroke. State is rememberSaveable so a rotation no longer re-collapses what was just opened, landscape being where the long lists hurt most; Renderer opens on Display & Resolution and Performance on Speedhacks so neither looks empty. The Fixes tab is now Advanced, and absorbed the GameDB fixes from Performance and the whole Recompiler tab. Both are debugging controls that the GameDB already applies per game, so they do not belong in the tab people open to change speed. Fourteen tabs become twelve; the search index and the per-tab reset ownership moved with the settings, so searching "Skip MPEG" lands on Advanced and resetting Performance no longer resets fixes it does not show. Skip BIOS now defaults on. "How do I skip the boot animation" is one of the most-asked questions in the Discord and desktop PCSX2 fast-boots too. Only fresh installs change: the saved JSON always carries the key, so nobody's boot behaviour is altered by an update. The library overflow menu drops from eleven rows to eight with separators. Open navigation goes entirely (the hamburger is on the same toolbar) and Game names in grid moves to App settings beside cover size and opacity, where every other library-appearance preference already lives. Setup / Change Folders and Exit MOVE to the drawer rather than being deleted - each had exactly one entry point, so removing them would have stranded anyone needing to change their ROM folder and left no in-app quit. Exit keeps its confirmation and gets a real power-symbol drawable: the "⏻" glyph is absent from most Android system fonts and rendered as tofu. About leaves the settings tab strip for the drawer, next to the other links. It is a read-only page that was costing a tab slot on every visit. Installed patches and cheats can be collapsed, so a pnach carrying hundreds of downloaded codes can be folded away. Reported by a community member on Discord. --- .../main/java/com/armsx2/config/Settings.kt | 9 ++- .../java/com/armsx2/navigation/AppRoute.kt | 1 - .../com/armsx2/navigation/NavigationDrawer.kt | 42 ++++++++++ .../java/com/armsx2/ui/home/HomeScreen.kt | 26 +++---- .../armsx2/ui/patches/PatchManagerScreen.kt | 26 ++++++- .../java/com/armsx2/ui/settings/AppTab.kt | 9 +++ .../java/com/armsx2/ui/settings/FixesTab.kt | 78 +++++++++++++++++++ .../com/armsx2/ui/settings/PerformanceTab.kt | 26 +------ .../com/armsx2/ui/settings/RecompilerTab.kt | 65 ---------------- .../com/armsx2/ui/settings/RendererTab.kt | 2 +- .../com/armsx2/ui/settings/SettingsWidgets.kt | 33 +++++++- .../ui/settingshub/SettingsResetFields.kt | 18 +++-- .../armsx2/ui/settingshub/SettingsScreen.kt | 7 +- .../ui/settingshub/SettingsSearchIndex.kt | 53 ++++++------- .../app/src/main/res/drawable/ic_power.xml | 25 ++++++ 15 files changed, 266 insertions(+), 154 deletions(-) delete mode 100644 platforms/android/app/src/main/java/com/armsx2/ui/settings/RecompilerTab.kt create mode 100644 platforms/android/app/src/main/res/drawable/ic_power.xml diff --git a/platforms/android/app/src/main/java/com/armsx2/config/Settings.kt b/platforms/android/app/src/main/java/com/armsx2/config/Settings.kt index d237d37bbe..f2ba33f377 100644 --- a/platforms/android/app/src/main/java/com/armsx2/config/Settings.kt +++ b/platforms/android/app/src/main/java/com/armsx2/config/Settings.kt @@ -167,8 +167,13 @@ data class Settings( val enableWideScreenPatches: Boolean = false, /** EmuCore/EnableNoInterlacingPatches — no-interlacing patches. */ val enableNoInterlacingPatches: Boolean = false, - /** EmuCore/EnableFastBoot — skip BIOS splash and boot straight to the game. */ - val enableFastBoot: Boolean = false, + /** EmuCore/EnableFastBoot — skip BIOS splash and boot straight to the game. + * + * Default ON: "how do I skip the boot animation" is one of the most-asked questions in the + * Discord, and desktop PCSX2 fast-boots by default too. Only fresh installs are affected — + * the saved JSON always carries this key, so anyone who already has a value keeps it rather + * than having their boot behaviour changed under them by an update. */ + val enableFastBoot: Boolean = true, /** EmuCore/HostFs — host: filesystem access in the VM, for ELF/homebrew and mods * (e.g. modded Persona 3 FES). Per-game capable; applies on the next game boot. */ val hostFs: Boolean = false, diff --git a/platforms/android/app/src/main/java/com/armsx2/navigation/AppRoute.kt b/platforms/android/app/src/main/java/com/armsx2/navigation/AppRoute.kt index dc18dffe96..c32faa172d 100644 --- a/platforms/android/app/src/main/java/com/armsx2/navigation/AppRoute.kt +++ b/platforms/android/app/src/main/java/com/armsx2/navigation/AppRoute.kt @@ -35,7 +35,6 @@ enum class SettingsCategory { OnScreen, Skins, Advanced, - Recompiler, Patches, About, } diff --git a/platforms/android/app/src/main/java/com/armsx2/navigation/NavigationDrawer.kt b/platforms/android/app/src/main/java/com/armsx2/navigation/NavigationDrawer.kt index ef32528bdd..dbbd263e90 100644 --- a/platforms/android/app/src/main/java/com/armsx2/navigation/NavigationDrawer.kt +++ b/platforms/android/app/src/main/java/com/armsx2/navigation/NavigationDrawer.kt @@ -68,6 +68,10 @@ import com.armsx2.ui.settings.controllerFocusable // gold trophy rather than the flat monochrome nav glyphs. private val TrophyGold = Color(0xFFFFC93C) +// Exit is the only row here that ends your session, so it gets the standard power-red rather +// than the neutral row tint — the same reason the trophy keeps its gold. +private val ExitRed = Color(0xFFE60012) + // Community/project links for the drawer's About section. Plain https on purpose: Android App // Links hand these to the Discord/GitHub apps when they're installed and fall back to the // browser when they aren't, so there's no app-specific scheme to special-case. @@ -162,6 +166,27 @@ fun NavigationDrawer( private fun DrawerContent(selected: AppRoute, onNavigate: (AppRoute) -> Unit, onDismiss: () -> Unit) { val isLandscape = LocalConfiguration.current.orientation == Configuration.ORIENTATION_LANDSCAPE val context = LocalContext.current + // Exit moved here from the library overflow menu; it keeps its confirmation, which is the whole + // point of the row — quitting mid-session without one loses whatever is not saved. + val exitConfirm = androidx.compose.runtime.remember { androidx.compose.runtime.mutableStateOf(false) } + if (exitConfirm.value) { + androidx.compose.material3.AlertDialog( + onDismissRequest = { exitConfirm.value = false }, + title = { androidx.compose.material3.Text(str("games.exit.title")) }, + text = { androidx.compose.material3.Text(str("games.exit.message")) }, + confirmButton = { + androidx.compose.material3.TextButton(onClick = { + exitConfirm.value = false + MainActivityRuntime.exitApp() + }) { androidx.compose.material3.Text(str("games.toolbar.exit")) } + }, + dismissButton = { + androidx.compose.material3.TextButton(onClick = { exitConfirm.value = false }) { + androidx.compose.material3.Text(str("action.cancel")) + } + }, + ) + } // Intuitive glyphs that read as what they do — matching the in-game overlay's emoji-icon style // (the old box-drawing characters like ▦ ◉ ⌁ ✦ were unclear per tester feedback). val primary = listOf( @@ -174,6 +199,10 @@ private fun DrawerContent(selected: AppRoute, onNavigate: (AppRoute) -> Unit, on DrawerItem("action.settings", "⚙️", AppRoute.Settings()), ) val managers = listOf( + // Moved off the library overflow menu, which was its only entry point. Sits first, beside + // BIOS Location: both answer "where are my files". + DrawerItem("games.overflow.setup", "📂", + onAction = { MainActivityRuntime.reopenSetup(); onDismiss() }), DrawerItem("setup.step.bios.title", "📀", AppRoute.BiosManager()), DrawerItem("memcard.title", "💾", AppRoute.MemoryCardManager), DrawerItem("savestate.title.loadManage", "📥", AppRoute.SaveManager), @@ -189,6 +218,15 @@ private fun DrawerContent(selected: AppRoute, onNavigate: (AppRoute) -> Unit, on DrawerItem("about.github", "🐙", iconRes = com.armsx2.R.drawable.ic_github, onAction = { openExternalUrl(context, GithubUrl); onDismiss() }), DrawerItem("about.website", "🌐", onAction = { openExternalUrl(context, WebsiteUrl); onDismiss() }), + // About left the settings tab strip: it is a read-only page, not a setting, and it sat in + // the tab row costing a slot on every settings visit. + DrawerItem("about.title", "ℹ️", AppRoute.About), + ) + // Exit gets its own trailing section. It was briefly filed under ABOUT, next to the Discord and + // GitHub links, where nobody would think to look for "quit". + val session = listOf( + DrawerItem("games.toolbar.exit", "⏻", iconRes = com.armsx2.R.drawable.ic_power, + iconTint = ExitRed, onAction = { exitConfirm.value = true }), ) Column( @@ -216,6 +254,10 @@ private fun DrawerContent(selected: AppRoute, onNavigate: (AppRoute) -> Unit, on HorizontalDivider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.45f)) Spacer(Modifier.height(14.dp)) DrawerSection(str("about.section.header"), about, selected, onNavigate) + Spacer(Modifier.height(14.dp)) + HorizontalDivider(color = MaterialTheme.colorScheme.outline.copy(alpha = 0.45f)) + Spacer(Modifier.height(14.dp)) + DrawerSection(str("games.section.app"), session, selected, onNavigate) } } diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/home/HomeScreen.kt b/platforms/android/app/src/main/java/com/armsx2/ui/home/HomeScreen.kt index 25c70f63f3..86ff5de10b 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/home/HomeScreen.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/home/HomeScreen.kt @@ -758,9 +758,6 @@ private fun LibraryOverflowMenu( color = MaterialTheme.colorScheme.primary, fontWeight = FontWeight.Bold, ) - LibraryOverflowItem("☰", str("games.overflow.openNavigation")) { - closeThen(onOpenNavigation) - } LibraryOverflowItem( glyph = "A–Z", label = str("games.overflow.sortTitle"), @@ -775,6 +772,7 @@ private fun LibraryOverflowMenu( ) { closeThen { onSort(HomeSort.RecentlyPlayed) } } + OverflowSeparator() LibraryOverflowItem( glyph = if (use3dCovers) "3D" else "2D", label = str("games.overflow.coverStyle"), @@ -782,13 +780,6 @@ private fun LibraryOverflowMenu( ) { closeThen(onToggleCoverStyle) } - LibraryOverflowItem( - glyph = "Aa", - label = str("games.overflow.gridNames"), - trailing = if (showGridNames) str("common.on") else str("common.off"), - ) { - closeThen(onToggleGridNames) - } LibraryOverflowItem( glyph = "Aa", label = str("games.overflow.customNames"), @@ -810,6 +801,7 @@ private fun LibraryOverflowMenu( ) { closeThen(onToggleShowHidden) } + OverflowSeparator() LibraryOverflowItem("▧", str("games.background.choose")) { closeThen(onChooseBackground) } @@ -818,15 +810,17 @@ private fun LibraryOverflowMenu( closeThen(onClearBackground) } } - LibraryOverflowItem("↻", str("games.overflow.setup")) { - closeThen { MainActivityRuntime.reopenSetup() } - } - LibraryOverflowItem("⏻", str("games.toolbar.exit")) { - closeThen(onExitApp) - } } } +@Composable +private fun OverflowSeparator() { + androidx.compose.material3.HorizontalDivider( + modifier = Modifier.padding(horizontal = 18.dp, vertical = 6.dp), + color = MaterialTheme.colorScheme.outline.copy(alpha = 0.30f), + ) +} + @Composable private fun LibraryOverflowItem( glyph: String, diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/patches/PatchManagerScreen.kt b/platforms/android/app/src/main/java/com/armsx2/ui/patches/PatchManagerScreen.kt index 3a12a04b9f..eff4f0d08a 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/patches/PatchManagerScreen.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/patches/PatchManagerScreen.kt @@ -401,11 +401,33 @@ private fun CollapsibleOnlineSection( @Composable private fun PatchFiles(state: PatchManagerUiState, viewModel: PatchManagerViewModel, modifier: Modifier) { + // The whole installed list folds away. A pnach pulled from the downloader can carry hundreds of + // codes, and with the list open there was no way past it to the rest of the screen. + var listOpen by androidx.compose.runtime.saveable.rememberSaveable { mutableStateOf(true) } Column(modifier) { - SectionTitle(str("patches.installedHeader"), state.files.size.toString()) + Row( + modifier = Modifier + .fillMaxWidth() + .clickable { listOpen = !listOpen }, + verticalAlignment = Alignment.CenterVertically, + ) { + SectionTitle( + str("patches.installedHeader"), + state.files.size.toString(), + Modifier.weight(1f), + ) + if (state.files.isNotEmpty()) { + Text( + if (listOpen) "▾" else "▸", + style = MaterialTheme.typography.titleLarge, + color = MaterialTheme.colorScheme.primary, + modifier = Modifier.padding(horizontal = 8.dp), + ) + } + } if (state.files.isEmpty()) { PatchFilesEmptyState() - } else { + } else if (listOpen) { Column(verticalArrangement = Arrangement.spacedBy(8.dp)) { state.files.forEach { file -> val expanded = state.localExpandedPath == file.absolutePath diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/settings/AppTab.kt b/platforms/android/app/src/main/java/com/armsx2/ui/settings/AppTab.kt index 911b2dd88a..aa5e639ce5 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/settings/AppTab.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/settings/AppTab.kt @@ -501,6 +501,15 @@ fun AppTab() { onChange = LibraryChromePreferences::setShowRecents, ) + // Moved off the library overflow menu, where it was the odd one out: every other + // library-appearance preference already lives here beside cover size and opacity. + ToggleRow( + label = str("games.overflow.gridNames"), + value = com.armsx2.GridLabels.show.value, + description = str("app.library.gridNames.desc"), + onChange = { com.armsx2.GridLabels.set(it) }, + ) + IntSliderRow( label = str("app.library.coverSize"), value = (com.armsx2.ui.UiScale.coverScale.value * 100f).toInt().coerceIn(75, 250), diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/settings/FixesTab.kt b/platforms/android/app/src/main/java/com/armsx2/ui/settings/FixesTab.kt index f755f2652b..a17d11e9d5 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/settings/FixesTab.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/settings/FixesTab.kt @@ -11,7 +11,10 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import com.armsx2.config.Settings @@ -449,9 +452,84 @@ fun FixesTab(state: MutableState) { onChange = { apply(s.copy(swThreadsHeight = it)) }, ) } + SettingsDivider() + // GameDB fixes moved here from Performance: they are per-game compatibility switches the + // GameDB already applies automatically, so they belong with the other advanced knobs + // rather than in the tab people open to change speed settings. + CollapsibleSection(str("perf.gamedbFixes.title")) { + HelpText(str("perf.gamedbFixes.help")) + ToggleRow(str("perf.fix.skipBios"), s.enableFastBoot, description = str("perf.fix.skipBios.desc")) { apply(s.copy(enableFastBoot = it)) } + ToggleRow(str("perf.fix.gamedbFixes"), s.enableGameFixes, description = str("perf.fix.gamedbFixes.desc")) { apply(s.copy(enableGameFixes = it)) } + ToggleRow(str("perf.fix.skipMpeg"), s.gamefixSkipMpeg, description = str("perf.fix.skipMpeg.desc")) { apply(s.copy(enableGameFixes = true, gamefixSkipMpeg = it)) } + if (s.gamefixSkipMpeg) HelpText(str("perf.fix.skipMpeg.warning")) + ToggleRow(str("perf.fix.fmvSoftware"), s.gamefixSoftwareRendererFmv, description = str("perf.fix.fmvSoftware.desc")) { apply(s.copy(enableGameFixes = true, gamefixSoftwareRendererFmv = it)) } + ToggleRow(str("perf.fix.eeTiming"), s.gamefixEETiming, description = str("perf.fix.eeTiming.desc")) { apply(s.copy(enableGameFixes = true, gamefixEETiming = it)) } + ToggleRow(str("perf.fix.instantDma"), s.gamefixInstantDma, description = str("perf.fix.instantDma.desc")) { apply(s.copy(enableGameFixes = true, gamefixInstantDma = it)) } + ToggleRow(str("perf.fix.blitFps"), s.gamefixBlitInternalFps, description = str("perf.fix.blitFps.desc")) { apply(s.copy(enableGameFixes = true, gamefixBlitInternalFps = it)) } + ToggleRow(str("perf.fix.fpuMultiply"), s.gamefixFpuMul, description = str("perf.fix.fpuMultiply.desc")) { apply(s.copy(enableGameFixes = true, gamefixFpuMul = it)) } + ToggleRow(str("perf.fix.ophFlag"), s.gamefixOphFlag, description = str("perf.fix.ophFlag.desc")) { apply(s.copy(enableGameFixes = true, gamefixOphFlag = it)) } + ToggleRow(str("perf.fix.gifFifo"), s.gamefixGifFifo, description = str("perf.fix.gifFifo.desc")) { apply(s.copy(enableGameFixes = true, gamefixGifFifo = it)) } + ToggleRow(str("perf.fix.dmaBusy"), s.gamefixDmaBusy, description = str("perf.fix.dmaBusy.desc")) { apply(s.copy(enableGameFixes = true, gamefixDmaBusy = it)) } + ToggleRow(str("perf.fix.vif1Stall"), s.gamefixVif1Stall, description = str("perf.fix.vif1Stall.desc")) { apply(s.copy(enableGameFixes = true, gamefixVif1Stall = it)) } + ToggleRow(str("perf.fix.iBit"), s.gamefixIbit, description = str("perf.fix.iBit.desc")) { apply(s.copy(enableGameFixes = true, gamefixIbit = it)) } + ToggleRow(str("perf.fix.fullVu0Sync"), s.gamefixFullVu0Sync, description = str("perf.fix.fullVu0Sync.desc")) { apply(s.copy(enableGameFixes = true, gamefixFullVu0Sync = it)) } + ToggleRow(str("perf.fix.vuAddSub"), s.gamefixVuAddSub, description = str("perf.fix.vuAddSub.desc")) { apply(s.copy(enableGameFixes = true, gamefixVuAddSub = it)) } + ToggleRow(str("perf.fix.vuOverflow"), s.gamefixVuOverflow, description = str("perf.fix.vuOverflow.desc")) { apply(s.copy(enableGameFixes = true, gamefixVuOverflow = it)) } + ToggleRow(str("perf.fix.extraXgkick"), s.gamefixXgkick, description = str("perf.fix.extraXgkick.desc")) { apply(s.copy(enableGameFixes = true, gamefixXgkick = it)) } + ToggleRow(str("perf.fix.goemonTlb"), s.gamefixGoemonTlb, description = str("perf.fix.goemonTlb.desc")) { apply(s.copy(enableGameFixes = true, gamefixGoemonTlb = it)) } + ToggleRow(str("perf.fix.vuSync"), s.gamefixVuSync, description = str("perf.fix.vuSync.desc")) { apply(s.copy(enableGameFixes = true, gamefixVuSync = it)) } + } + SettingsDivider() + RecompilerSection(state) Spacer(Modifier.height(8.dp)) } } // CollapsibleSection now lives in SettingsWidgets.kt (shared by the Fixes / Pad / // Performance / Renderer tabs). + +/** The former standalone Recompiler tab, folded in as a section. Turning a recompiler off drops + * that processor to an interpreter — correct but far slower — so it is a debugging control, not + * something to browse past on the way to a speed setting. */ +@Composable +private fun RecompilerSection(state: MutableState) { + val settings = state.value + fun apply(updated: Settings) = InGameOverlay.saveSettings(updated) + + CollapsibleSection(str("tab.recompiler")) { + Text( + str("jit.recompiler.warning"), + color = MaterialTheme.colorScheme.onSurfaceVariant, + style = MaterialTheme.typography.bodyMedium, + modifier = Modifier.padding(horizontal = 8.dp, vertical = 8.dp), + ) + ToggleRow("EE (R5900)", settings.recEE) { apply(settings.copy(recEE = it)) } + ToggleRow("IOP (R3000)", settings.recIOP) { apply(settings.copy(recIOP = it)) } + ToggleRow("VU0", settings.recVU0) { apply(settings.copy(recVU0 = it)) } + ToggleRow("VU1", settings.recVU1) { apply(settings.copy(recVU1 = it)) } + ToggleRow("Fastmem", settings.enableFastmem) { apply(settings.copy(enableFastmem = it)) } + + Spacer(Modifier.height(14.dp)) + Text( + str("jit.diagnostics.header"), + color = MaterialTheme.colorScheme.onSurfaceVariant, + style = MaterialTheme.typography.titleSmall, + modifier = Modifier.padding(horizontal = 8.dp, vertical = 4.dp), + ) + // Seed from the REAL native flag: a plain `remember { false }` meant leaving the screen + // destroyed the state and the switch came back OFF while the native flag was still on. + var eeDiff by remember { + mutableStateOf( + runCatching { kr.co.iefriends.pcsx2.NativeApp.isEeDiffVerify() }.getOrDefault(false) + ) + } + ToggleRow( + label = str("jit.eeDiffVerify.label"), + value = eeDiff, + description = str("jit.eeDiffVerify.description"), + ) { + eeDiff = it + runCatching { kr.co.iefriends.pcsx2.NativeApp.setEeDiffVerify(it) } + } + } +} diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/settings/PerformanceTab.kt b/platforms/android/app/src/main/java/com/armsx2/ui/settings/PerformanceTab.kt index 217a8d60e4..304ff1de1d 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/settings/PerformanceTab.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/settings/PerformanceTab.kt @@ -212,7 +212,7 @@ fun PerformanceTab(state: MutableState) { onChange = { apply(s.copy(affinityMode = it)) }, ) SettingsDivider() - CollapsibleSection(str("perf.speedhacks.title"), initiallyExpanded = false) { + CollapsibleSection(str("perf.speedhacks.title"), initiallyExpanded = true) { IntSliderRow( label = str("perf.eeCycleRate.label"), value = s.eeCycleRate, @@ -348,30 +348,6 @@ fun PerformanceTab(state: MutableState) { ) } SettingsDivider() - CollapsibleSection(str("perf.gamedbFixes.title")) { - HelpText(str("perf.gamedbFixes.help")) - ToggleRow(str("perf.fix.skipBios"), s.enableFastBoot, description = str("perf.fix.skipBios.desc")) { apply(s.copy(enableFastBoot = it)) } - ToggleRow(str("perf.fix.gamedbFixes"), s.enableGameFixes, description = str("perf.fix.gamedbFixes.desc")) { apply(s.copy(enableGameFixes = it)) } - ToggleRow(str("perf.fix.skipMpeg"), s.gamefixSkipMpeg, description = str("perf.fix.skipMpeg.desc")) { apply(s.copy(enableGameFixes = true, gamefixSkipMpeg = it)) } - if (s.gamefixSkipMpeg) HelpText(str("perf.fix.skipMpeg.warning")) - ToggleRow(str("perf.fix.fmvSoftware"), s.gamefixSoftwareRendererFmv, description = str("perf.fix.fmvSoftware.desc")) { apply(s.copy(enableGameFixes = true, gamefixSoftwareRendererFmv = it)) } - ToggleRow(str("perf.fix.eeTiming"), s.gamefixEETiming, description = str("perf.fix.eeTiming.desc")) { apply(s.copy(enableGameFixes = true, gamefixEETiming = it)) } - ToggleRow(str("perf.fix.instantDma"), s.gamefixInstantDma, description = str("perf.fix.instantDma.desc")) { apply(s.copy(enableGameFixes = true, gamefixInstantDma = it)) } - ToggleRow(str("perf.fix.blitFps"), s.gamefixBlitInternalFps, description = str("perf.fix.blitFps.desc")) { apply(s.copy(enableGameFixes = true, gamefixBlitInternalFps = it)) } - ToggleRow(str("perf.fix.fpuMultiply"), s.gamefixFpuMul, description = str("perf.fix.fpuMultiply.desc")) { apply(s.copy(enableGameFixes = true, gamefixFpuMul = it)) } - ToggleRow(str("perf.fix.ophFlag"), s.gamefixOphFlag, description = str("perf.fix.ophFlag.desc")) { apply(s.copy(enableGameFixes = true, gamefixOphFlag = it)) } - ToggleRow(str("perf.fix.gifFifo"), s.gamefixGifFifo, description = str("perf.fix.gifFifo.desc")) { apply(s.copy(enableGameFixes = true, gamefixGifFifo = it)) } - ToggleRow(str("perf.fix.dmaBusy"), s.gamefixDmaBusy, description = str("perf.fix.dmaBusy.desc")) { apply(s.copy(enableGameFixes = true, gamefixDmaBusy = it)) } - ToggleRow(str("perf.fix.vif1Stall"), s.gamefixVif1Stall, description = str("perf.fix.vif1Stall.desc")) { apply(s.copy(enableGameFixes = true, gamefixVif1Stall = it)) } - ToggleRow(str("perf.fix.iBit"), s.gamefixIbit, description = str("perf.fix.iBit.desc")) { apply(s.copy(enableGameFixes = true, gamefixIbit = it)) } - ToggleRow(str("perf.fix.fullVu0Sync"), s.gamefixFullVu0Sync, description = str("perf.fix.fullVu0Sync.desc")) { apply(s.copy(enableGameFixes = true, gamefixFullVu0Sync = it)) } - ToggleRow(str("perf.fix.vuAddSub"), s.gamefixVuAddSub, description = str("perf.fix.vuAddSub.desc")) { apply(s.copy(enableGameFixes = true, gamefixVuAddSub = it)) } - ToggleRow(str("perf.fix.vuOverflow"), s.gamefixVuOverflow, description = str("perf.fix.vuOverflow.desc")) { apply(s.copy(enableGameFixes = true, gamefixVuOverflow = it)) } - ToggleRow(str("perf.fix.extraXgkick"), s.gamefixXgkick, description = str("perf.fix.extraXgkick.desc")) { apply(s.copy(enableGameFixes = true, gamefixXgkick = it)) } - ToggleRow(str("perf.fix.goemonTlb"), s.gamefixGoemonTlb, description = str("perf.fix.goemonTlb.desc")) { apply(s.copy(enableGameFixes = true, gamefixGoemonTlb = it)) } - ToggleRow(str("perf.fix.vuSync"), s.gamefixVuSync, description = str("perf.fix.vuSync.desc")) { apply(s.copy(enableGameFixes = true, gamefixVuSync = it)) } - } - SettingsDivider() CollapsibleSection(str("perf.advancedSpeedhacks.title")) { Spacer(Modifier.height(8.dp)) ToggleRow(str("perf.hack.mtvu"), s.mtvu, description = str("perf.hack.mtvu.desc")) { apply(s.copy(mtvu = it)) } diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/settings/RecompilerTab.kt b/platforms/android/app/src/main/java/com/armsx2/ui/settings/RecompilerTab.kt deleted file mode 100644 index bf736bbb7a..0000000000 --- a/platforms/android/app/src/main/java/com/armsx2/ui/settings/RecompilerTab.kt +++ /dev/null @@ -1,65 +0,0 @@ -package com.armsx2.ui.settings - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Spacer -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.height -import androidx.compose.foundation.layout.padding -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.runtime.MutableState -import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember -import androidx.compose.runtime.setValue -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import com.armsx2.config.Settings -import com.armsx2.i18n.str -import com.armsx2.ui.InGameOverlay -import kr.co.iefriends.pcsx2.NativeApp - -@Composable -fun RecompilerTab(state: MutableState) { - val settings = state.value - ControllerAutoScroll(settingsScrollState()) - - fun apply(updated: Settings) = InGameOverlay.saveSettings(updated) - - Column(Modifier.fillMaxWidth()) { - Text( - str("jit.recompiler.warning"), - color = MaterialTheme.colorScheme.onSurfaceVariant, - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier.padding(bottom = 8.dp), - ) - ToggleRow("EE (R5900)", settings.recEE) { apply(settings.copy(recEE = it)) } - ToggleRow("IOP (R3000)", settings.recIOP) { apply(settings.copy(recIOP = it)) } - ToggleRow("VU0", settings.recVU0) { apply(settings.copy(recVU0 = it)) } - ToggleRow("VU1", settings.recVU1) { apply(settings.copy(recVU1 = it)) } - ToggleRow("Fastmem", settings.enableFastmem) { apply(settings.copy(enableFastmem = it)) } - - Spacer(Modifier.height(14.dp)) - Text( - str("jit.diagnostics.header"), - color = MaterialTheme.colorScheme.onSurfaceVariant, - style = MaterialTheme.typography.titleSmall, - modifier = Modifier.padding(horizontal = 4.dp, vertical = 4.dp), - ) - // Seed from the REAL native flag. This was a plain `remember { false }`, so leaving the - // screen destroyed the state and the switch came back showing OFF while the native flag - // was still on — the toggle was reporting fiction. - var eeDiff by remember { - mutableStateOf(runCatching { NativeApp.isEeDiffVerify() }.getOrDefault(false)) - } - ToggleRow( - label = str("jit.eeDiffVerify.label"), - value = eeDiff, - description = str("jit.eeDiffVerify.description"), - ) { - eeDiff = it - runCatching { NativeApp.setEeDiffVerify(it) } - } - } -} diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/settings/RendererTab.kt b/platforms/android/app/src/main/java/com/armsx2/ui/settings/RendererTab.kt index 549ef8eaa5..ed6647d702 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/settings/RendererTab.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/settings/RendererTab.kt @@ -102,7 +102,7 @@ fun RendererTab(state: MutableState) { modifier = Modifier .fillMaxWidth(), ) { - CollapsibleSection(str("renderer.section.displayResolution"), initiallyExpanded = false) { + CollapsibleSection(str("renderer.section.displayResolution"), initiallyExpanded = true) { // Graphics API (OpenGL / Vulkan) + Vulkan custom-driver picker. // from the removed first-run setup renderer page into settings. RendererBackendSection(state) diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/settings/SettingsWidgets.kt b/platforms/android/app/src/main/java/com/armsx2/ui/settings/SettingsWidgets.kt index 58e353399b..1412b556dd 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/settings/SettingsWidgets.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/settings/SettingsWidgets.kt @@ -515,18 +515,37 @@ fun SettingsDivider() { /** Collapsible settings section: a tappable header (▸ collapsed / ▾ expanded) that * shows or hides its content. Controller-focusable so a gamepad can open it. Shared * by the Fixes / Pad / Performance / Renderer tabs to de-bloat long settings lists. - * [initiallyExpanded] lets a tab open its most-used section by default. */ + * [initiallyExpanded] lets a tab open its most-used section by default. + * + * This is the de-bloating that the settings screens were built around, and it had stopped + * happening: the header rendered as plain text and `content()` was called unconditionally, with + * `initiallyExpanded` marked UNUSED_PARAMETER. Every tab was therefore one flat list of every + * option it owns — the reason the settings became unusable in landscape. Restoring it shortens + * Pad / Renderer / Performance / Advanced all at once. + * + * State is [rememberSaveable] so a rotation does not re-collapse what the user just opened — + * landscape being exactly where the long lists hurt most. */ @Composable fun CollapsibleSection( title: String, - @Suppress("UNUSED_PARAMETER") initiallyExpanded: Boolean = false, content: @Composable () -> Unit, ) { + var expanded by androidx.compose.runtime.saveable.rememberSaveable(title) { + mutableStateOf(initiallyExpanded) + } + val toggle = { + expanded = !expanded + com.armsx2.MenuSfx.play( + if (expanded) com.armsx2.MenuSfx.Event.TOGGLE_ON else com.armsx2.MenuSfx.Event.TOGGLE_OFF + ) + } Spacer(Modifier.height(12.dp)) Row( modifier = Modifier .fillMaxWidth() + .controllerFocusable("section.$title", onConfirm = toggle) + .clickable(onClick = toggle) .padding(horizontal = 8.dp, vertical = 10.dp), verticalAlignment = Alignment.CenterVertically, ) { @@ -537,8 +556,16 @@ fun CollapsibleSection( fontWeight = FontWeight.Bold, modifier = Modifier.weight(1f), ) + Text( + if (expanded) "▾" else "▸", + color = MaterialTheme.colorScheme.primary, + fontSize = 18.sp, + fontWeight = FontWeight.Bold, + ) } - content() + // Collapsed content is not composed at all, so its rows also drop out of the controller-focus + // registry — a pad cannot land on a setting the user cannot see. + if (expanded) content() } @Composable diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsResetFields.kt b/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsResetFields.kt index c794b14738..b17c080090 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsResetFields.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsResetFields.kt @@ -25,8 +25,8 @@ import org.json.JSONObject internal val SETTINGS_CATEGORY_FIELDS: Map> = mapOf( // PerformanceTab.kt SettingsCategory.Performance to listOf( - "eeClampMode", "eeCycleRate", "eeCycleSkip", "eeFpuRoundMode", "enableFastBoot", - "enableGameFixes", "fastCDVD", "fpsLimit", "frameSkip", "framerateNtsc", "frameratePal", + "eeClampMode", "eeCycleRate", "eeCycleSkip", "eeFpuRoundMode", + "fastCDVD", "fpsLimit", "frameSkip", "framerateNtsc", "frameratePal", "intcStat", "mtvu", "nominalSpeedPercent", "skipDuplicateFrames", "vu0RoundMode", "vu1Instant", "vu1RoundMode", "vuClampMode", "vuDeferredWrites", "vuFlagHack", "vuNeonFusions", "vuSkipStallSim", "waitLoop", @@ -65,8 +65,16 @@ internal val SETTINGS_CATEGORY_FIELDS: Map> = map "osdShowMessages", "osdShowResolution", "osdShowSettings", "osdShowSpeed", "osdShowVersion", "osdShowVps", ), - // FixesTab.kt + // FixesTab.kt — also owns the GameDB fixes and the recompiler toggles, which moved here + // from Performance and from the retired Recompiler tab. SettingsCategory.Advanced to listOf( + "enableFastBoot", "enableGameFixes", + "gamefixBlitInternalFps", "gamefixDmaBusy", "gamefixEETiming", "gamefixFpuMul", + "gamefixFullVu0Sync", "gamefixGifFifo", "gamefixGoemonTlb", "gamefixIbit", + "gamefixInstantDma", "gamefixOphFlag", "gamefixSkipMpeg", + "gamefixSoftwareRendererFmv", "gamefixVif1Stall", "gamefixVuAddSub", + "gamefixVuOverflow", "gamefixVuSync", "gamefixXgkick", + "enableFastmem", "recEE", "recIOP", "recVU0", "recVU1", "alignSprite", "antiBlur", "autoFlush", "autoFlushSw", "bilinearUpscale", "cpuClutRender", "cpuFramebufferConversion", "cpuSpriteRenderBw", "cpuSpriteRenderLevel", "cropBottom", "cropLeft", "cropRight", "cropTop", "displayZoom", "disableDepthEmulation", "disableFramebufferFetch", @@ -81,10 +89,6 @@ internal val SETTINGS_CATEGORY_FIELDS: Map> = map "syncToHostRefresh", "textureInsideRt", "textureOffsetX", "textureOffsetY", "unscaledPaletteDraw", "useBlitSwapChain", "vsyncQueueSize", ), - // RecompilerTab.kt - SettingsCategory.Recompiler to listOf( - "enableFastmem", "recEE", "recIOP", "recVU0", "recVU1", - ), // Controls / Hotkeys / Skins / General / Info / Patches / About own no Settings fields — // Controls keeps its binds and tunables in ControllerMappings and has its own reset row. ) diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsScreen.kt b/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsScreen.kt index a166eea0e4..319d2ab750 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsScreen.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsScreen.kt @@ -67,7 +67,6 @@ import com.armsx2.ui.settings.NetworkTab import com.armsx2.ui.settings.OverlayTab import com.armsx2.ui.settings.PadTab import com.armsx2.ui.settings.PerformanceTab -import com.armsx2.ui.settings.RecompilerTab import com.armsx2.ui.settings.RendererTab import com.armsx2.ui.settings.SegmentedRow import com.armsx2.ui.settings.SkinsTab @@ -338,7 +337,7 @@ private fun SettingsCategoryBar( ) { // Row + horizontalScroll (NOT LazyRow): controllerFocusable registers each tab via a // SideEffect that only runs for COMPOSED children. A LazyRow leaves every off-screen - // tab (Skins / Fixes / Recompiler, past On-Screen) unregistered and unreachable, so + // tab (Skins / Advanced, past On-Screen) unregistered and unreachable, so // the controller got stuck at the last visible tab. A plain Row composes them all; // each selected chip's bringIntoView then scrolls it into view as the selector moves. val sections = settingsSections().filterNot { @@ -417,9 +416,7 @@ private fun settingsSections() = listOf( SettingsSection(SettingsCategory.OnScreen, "tab.overlay", "⊕"), SettingsSection(SettingsCategory.Skins, "tab.skins", "◈"), SettingsSection(SettingsCategory.Advanced, "tab.fixes", "⌘"), - SettingsSection(SettingsCategory.Recompiler, "tab.recompiler", "⚙"), SettingsSection(SettingsCategory.Patches, "tab.patches", "✦"), - SettingsSection(SettingsCategory.About, "about.title", "ⓘ"), ) @Composable @@ -436,7 +433,6 @@ private fun CategoryContent(category: SettingsCategory, viewModel: SettingsViewM SettingsCategory.OnScreen -> OverlayTab(viewModel.settings) SettingsCategory.Skins -> SkinsTab(viewModel.settings) SettingsCategory.Advanced -> FixesTab(viewModel.settings) - SettingsCategory.Recompiler -> RecompilerTab(viewModel.settings) SettingsCategory.Patches -> com.armsx2.ui.patches.PatchesSettingsTab(viewModel.uiState.value.game) SettingsCategory.About -> Unit } @@ -455,7 +451,6 @@ internal fun categoryTitle(category: SettingsCategory): String = when (category) SettingsCategory.OnScreen -> str("tab.overlay") SettingsCategory.Skins -> str("tab.skins") SettingsCategory.Advanced -> str("tab.fixes") - SettingsCategory.Recompiler -> str("tab.recompiler") SettingsCategory.Patches -> str("patches.dialog.patchesAndCheats") SettingsCategory.About -> str("about.title") } diff --git a/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsSearchIndex.kt b/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsSearchIndex.kt index cab62c1733..aa9fc136c0 100644 --- a/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsSearchIndex.kt +++ b/platforms/android/app/src/main/java/com/armsx2/ui/settingshub/SettingsSearchIndex.kt @@ -17,6 +17,7 @@ internal val SETTINGS_SEARCH_INDEX: List = listOf( SettingsSearchEntry("app.library.search", true, SettingsCategory.General), SettingsSearchEntry("app.library.recents", true, SettingsCategory.General), SettingsSearchEntry("app.library.coverSize", true, SettingsCategory.General), + SettingsSearchEntry("games.overflow.gridNames", true, SettingsCategory.General), SettingsSearchEntry("app.backup.export", true, SettingsCategory.General), SettingsSearchEntry("app.backup.import", true, SettingsCategory.General), SettingsSearchEntry("app.blockHome", true, SettingsCategory.General), @@ -26,25 +27,25 @@ internal val SETTINGS_SEARCH_INDEX: List = listOf( SettingsSearchEntry("app.bgColor", true, SettingsCategory.General), SettingsSearchEntry("app.menuSfx", true, SettingsCategory.General), SettingsSearchEntry("update.includeNightly", true, SettingsCategory.General), - SettingsSearchEntry("perf.fix.skipBios", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.gamedbFixes", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.skipMpeg", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.fmvSoftware", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.eeTiming", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.instantDma", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.blitFps", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.fpuMultiply", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.ophFlag", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.gifFifo", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.dmaBusy", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.vif1Stall", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.iBit", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.fullVu0Sync", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.vuAddSub", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.vuOverflow", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.extraXgkick", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.goemonTlb", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.fix.vuSync", true, SettingsCategory.Performance), + SettingsSearchEntry("perf.fix.skipBios", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.gamedbFixes", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.skipMpeg", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.fmvSoftware", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.eeTiming", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.instantDma", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.blitFps", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.fpuMultiply", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.ophFlag", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.gifFifo", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.dmaBusy", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.vif1Stall", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.iBit", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.fullVu0Sync", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.vuAddSub", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.vuOverflow", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.extraXgkick", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.goemonTlb", true, SettingsCategory.Advanced), + SettingsSearchEntry("perf.fix.vuSync", true, SettingsCategory.Advanced), SettingsSearchEntry("perf.hack.mtvu", true, SettingsCategory.Performance), SettingsSearchEntry("perf.hack.instantVu1", true, SettingsCategory.Performance), SettingsSearchEntry("perf.hack.vuFlagHack", true, SettingsCategory.Performance), @@ -74,7 +75,7 @@ internal val SETTINGS_SEARCH_INDEX: List = listOf( SettingsSearchEntry("perf.vu0RoundMode.label", true, SettingsCategory.Performance), SettingsSearchEntry("perf.vu1RoundMode.label", true, SettingsCategory.Performance), SettingsSearchEntry("perf.speedhacks.title", true, SettingsCategory.Performance), - SettingsSearchEntry("perf.gamedbFixes.title", true, SettingsCategory.Performance), + SettingsSearchEntry("perf.gamedbFixes.title", true, SettingsCategory.Advanced), SettingsSearchEntry("perf.advancedSpeedhacks.title", true, SettingsCategory.Performance), SettingsSearchEntry("VSync", false, SettingsCategory.Graphics), SettingsSearchEntry("renderer.shadeboost.label", true, SettingsCategory.Graphics), @@ -248,12 +249,12 @@ internal val SETTINGS_SEARCH_INDEX: List = listOf( SettingsSearchEntry("fixes.section.upscaling", true, SettingsCategory.Advanced), SettingsSearchEntry("fixes.section.hardware", true, SettingsCategory.Advanced), SettingsSearchEntry("fixes.section.software", true, SettingsCategory.Advanced), - SettingsSearchEntry("EE (R5900)", false, SettingsCategory.Recompiler), - SettingsSearchEntry("IOP (R3000)", false, SettingsCategory.Recompiler), - SettingsSearchEntry("VU0", false, SettingsCategory.Recompiler), - SettingsSearchEntry("VU1", false, SettingsCategory.Recompiler), - SettingsSearchEntry("Fastmem", false, SettingsCategory.Recompiler), - SettingsSearchEntry("jit.eeDiffVerify.label", true, SettingsCategory.Recompiler), + SettingsSearchEntry("EE (R5900)", false, SettingsCategory.Advanced), + SettingsSearchEntry("IOP (R3000)", false, SettingsCategory.Advanced), + SettingsSearchEntry("VU0", false, SettingsCategory.Advanced), + SettingsSearchEntry("VU1", false, SettingsCategory.Advanced), + SettingsSearchEntry("Fastmem", false, SettingsCategory.Advanced), + SettingsSearchEntry("jit.eeDiffVerify.label", true, SettingsCategory.Advanced), SettingsSearchEntry("patches.enablePatches.label", true, SettingsCategory.Patches), SettingsSearchEntry("patches.cheats.label", true, SettingsCategory.Patches), SettingsSearchEntry("patches.widescreen.label", true, SettingsCategory.Patches), diff --git a/platforms/android/app/src/main/res/drawable/ic_power.xml b/platforms/android/app/src/main/res/drawable/ic_power.xml new file mode 100644 index 0000000000..3dff20e934 --- /dev/null +++ b/platforms/android/app/src/main/res/drawable/ic_power.xml @@ -0,0 +1,25 @@ + + + + +