From f14536635cb60386aa436326414285aff003ad17 Mon Sep 17 00:00:00 2001
From: SSimco <37044560+SSimco@users.noreply.github.com>
Date: Wed, 18 Jun 2025 19:07:29 +0300
Subject: [PATCH] Add emulation settings
---
.../cemu/cemu/emulation/EmulationActivity.kt | 16 ++++++--
.../cemu/guicore/components/DrawerLayout.kt | 37 +++++++++++------
.../cemu/cemu/settings/SettingsManager.kt | 40 +++++++++++++++++++
.../settings/general/GeneralSettingsScreen.kt | 16 +++++++-
.../general/GeneralSettingsViewModel.kt | 29 ++++++++++++++
.../app/src/main/res/values/strings.xml | 2 +
6 files changed, 124 insertions(+), 16 deletions(-)
create mode 100644 src/android/app/src/main/java/info/cemu/cemu/settings/SettingsManager.kt
create mode 100644 src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsViewModel.kt
diff --git a/src/android/app/src/main/java/info/cemu/cemu/emulation/EmulationActivity.kt b/src/android/app/src/main/java/info/cemu/cemu/emulation/EmulationActivity.kt
index fa575032..0b8468b4 100644
--- a/src/android/app/src/main/java/info/cemu/cemu/emulation/EmulationActivity.kt
+++ b/src/android/app/src/main/java/info/cemu/cemu/emulation/EmulationActivity.kt
@@ -38,6 +38,8 @@ import info.cemu.cemu.inputoverlay.OverlaySettings
import info.cemu.cemu.nativeinterface.NativeEmulation
import info.cemu.cemu.nativeinterface.NativeException
import info.cemu.cemu.nativeinterface.NativeSwkbd.setCurrentInputText
+import info.cemu.cemu.settings.EmulationScreenSettings
+import info.cemu.cemu.settings.SettingsManager
import java.lang.ref.WeakReference
import kotlin.system.exitProcess
@@ -80,6 +82,7 @@ class EmulationActivity : AppCompatActivity() {
private lateinit var binding: ActivityEmulationBinding
private var isMotionEnabled = false
private lateinit var overlaySettings: OverlaySettings
+ private lateinit var emulationScreenSettings: EmulationScreenSettings
private lateinit var inputOverlaySurfaceView: InputOverlaySurfaceView
private lateinit var sensorManager: SensorManager
private var hasEmulationError = false
@@ -118,8 +121,8 @@ class EmulationActivity : AppCompatActivity() {
super.onCreate(savedInstanceState)
emulationActivityInstance = WeakReference(this)
- val inputOverlaySettingsManager = InputOverlaySettingsManager(this)
- overlaySettings = inputOverlaySettingsManager.overlaySettings
+ overlaySettings = InputOverlaySettingsManager(this).overlaySettings
+ emulationScreenSettings = SettingsManager(this).emulationScreenSettings
sensorManager = SensorManager(this)
sensorManager.setDeviceRotationProvider(deviceRotationProvider = { display.rotation })
@@ -240,7 +243,14 @@ class EmulationActivity : AppCompatActivity() {
binding.editInputsLayout.visibility = View.GONE
toastMessage(R.string.input_mode_default)
}
- binding.emulationSettingsButton.setOnClickListener { binding.drawerLayout.open() }
+
+ if (emulationScreenSettings.isDrawerButtonVisible) {
+ binding.emulationSettingsButton.setOnClickListener { binding.drawerLayout.open() }
+ binding.drawerLayout.setLockedMode(true)
+ } else {
+ binding.emulationSettingsButton.visibility = View.GONE
+ }
+
val mainCanvas = binding.mainCanvas
try {
val testSurfaceTexture = SurfaceTexture(0)
diff --git a/src/android/app/src/main/java/info/cemu/cemu/guicore/components/DrawerLayout.kt b/src/android/app/src/main/java/info/cemu/cemu/guicore/components/DrawerLayout.kt
index 137e33e7..d66426a8 100644
--- a/src/android/app/src/main/java/info/cemu/cemu/guicore/components/DrawerLayout.kt
+++ b/src/android/app/src/main/java/info/cemu/cemu/guicore/components/DrawerLayout.kt
@@ -8,21 +8,34 @@ import androidx.drawerlayout.widget.DrawerLayout as AndroidxDrawerLayout
class DrawerLayout @JvmOverloads constructor(
context: Context, attrs: AttributeSet? = null,
) : AndroidxDrawerLayout(context, attrs) {
- init {
- setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED)
- addDrawerListener(object : DrawerListener {
- override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
+ private var isLocked = false
+ private val lockedModeDrawerListener = object : DrawerListener {
+ override fun onDrawerSlide(drawerView: View, slideOffset: Float) {}
- override fun onDrawerOpened(drawerView: View) {
- setDrawerLockMode(LOCK_MODE_UNLOCKED)
- }
+ override fun onDrawerOpened(drawerView: View) {
+ setDrawerLockMode(LOCK_MODE_UNLOCKED)
+ }
- override fun onDrawerClosed(drawerView: View) {
- setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED)
- }
+ override fun onDrawerClosed(drawerView: View) {
+ setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED)
+ }
- override fun onDrawerStateChanged(newState: Int) {}
- })
+ override fun onDrawerStateChanged(newState: Int) {}
}
+ fun setLockedMode(isLocked: Boolean) {
+ if (this.isLocked == isLocked) {
+ return
+ }
+
+ this.isLocked = isLocked
+ if (isLocked) {
+ setDrawerLockMode(LOCK_MODE_LOCKED_CLOSED)
+ addDrawerListener(lockedModeDrawerListener)
+ return
+ }
+
+ setDrawerLockMode(LOCK_MODE_UNLOCKED)
+ removeDrawerListener(lockedModeDrawerListener)
+ }
}
\ No newline at end of file
diff --git a/src/android/app/src/main/java/info/cemu/cemu/settings/SettingsManager.kt b/src/android/app/src/main/java/info/cemu/cemu/settings/SettingsManager.kt
new file mode 100644
index 00000000..105bd832
--- /dev/null
+++ b/src/android/app/src/main/java/info/cemu/cemu/settings/SettingsManager.kt
@@ -0,0 +1,40 @@
+package info.cemu.cemu.settings
+
+import android.content.Context
+import android.content.SharedPreferences
+
+class EmulationScreenSettings(
+ var isDrawerButtonVisible: Boolean,
+) {
+ companion object {
+ private const val IS_BUTTON_VISIBLE_KEY = "IS_BUTTON_VISIBLE"
+ }
+
+ constructor(sharedPreferences: SharedPreferences) : this(
+ isDrawerButtonVisible = sharedPreferences.getBoolean(
+ IS_BUTTON_VISIBLE_KEY,
+ false
+ ),
+ )
+
+ fun save(sharedPreferences: SharedPreferences) {
+ sharedPreferences.edit().apply {
+ putBoolean(IS_BUTTON_VISIBLE_KEY, isDrawerButtonVisible)
+ apply()
+ }
+ }
+}
+
+class SettingsManager(context: Context) {
+ private val sharedPreferences: SharedPreferences =
+ context.getSharedPreferences(SETTINGS_NAME, Context.MODE_PRIVATE)
+
+ var emulationScreenSettings: EmulationScreenSettings
+ get() = EmulationScreenSettings(sharedPreferences)
+ set(value) = value.save(sharedPreferences)
+
+
+ companion object {
+ private const val SETTINGS_NAME = "SETTINGS"
+ }
+}
diff --git a/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsScreen.kt b/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsScreen.kt
index 85c73f74..eb76c824 100644
--- a/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsScreen.kt
+++ b/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsScreen.kt
@@ -3,15 +3,21 @@ package info.cemu.cemu.settings.general
import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.lifecycle.compose.dropUnlessResumed
+import androidx.lifecycle.viewmodel.compose.viewModel
import info.cemu.cemu.R
import info.cemu.cemu.guicore.components.Button
import info.cemu.cemu.guicore.components.ScreenContent
import info.cemu.cemu.guicore.components.SingleSelection
+import info.cemu.cemu.guicore.components.Toggle
import info.cemu.cemu.guicore.nativeenummapper.consoleLanguageToStringId
import info.cemu.cemu.nativeinterface.NativeSettings
@Composable
-fun GeneralSettingsScreen(navigateBack: () -> Unit, goToGamePathsSettings: () -> Unit) {
+fun GeneralSettingsScreen(
+ navigateBack: () -> Unit,
+ goToGamePathsSettings: () -> Unit,
+ generalSettingsViewModel: GeneralSettingsViewModel = viewModel(factory = GeneralSettingsViewModel.Factory),
+) {
ScreenContent(
appBarText = stringResource(R.string.general_settings),
navigateBack = navigateBack,
@@ -41,5 +47,13 @@ fun GeneralSettingsScreen(navigateBack: () -> Unit, goToGamePathsSettings: () ->
NativeSettings.CONSOLE_LANGUAGE_TAIWANESE,
),
)
+ Toggle(
+ label = stringResource(R.string.side_menu_button),
+ description = stringResource(R.string.side_menu_button_description),
+ initialCheckedState = { generalSettingsViewModel.emulationScreenSettings.isDrawerButtonVisible },
+ onCheckedChanged = {
+ generalSettingsViewModel.emulationScreenSettings.isDrawerButtonVisible = it
+ }
+ )
}
}
\ No newline at end of file
diff --git a/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsViewModel.kt b/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsViewModel.kt
new file mode 100644
index 00000000..c71fad12
--- /dev/null
+++ b/src/android/app/src/main/java/info/cemu/cemu/settings/general/GeneralSettingsViewModel.kt
@@ -0,0 +1,29 @@
+package info.cemu.cemu.settings.general
+
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewmodel.initializer
+import androidx.lifecycle.viewmodel.viewModelFactory
+import info.cemu.cemu.CemuApplication
+import info.cemu.cemu.settings.SettingsManager
+
+class GeneralSettingsViewModel(
+ private val settingsManager: SettingsManager,
+) : ViewModel() {
+ val emulationScreenSettings = settingsManager.emulationScreenSettings
+
+ override fun onCleared() {
+ super.onCleared()
+ settingsManager.emulationScreenSettings = emulationScreenSettings
+ }
+
+ companion object {
+ val Factory: ViewModelProvider.Factory = viewModelFactory {
+ initializer {
+ GeneralSettingsViewModel(
+ SettingsManager(CemuApplication.Application)
+ )
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index ceb598d5..5ba96cfa 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -335,4 +335,6 @@
Setup all inputs
No controllers available
Select a controller
+ Side menu button
+ Show the emulation side menu button
\ No newline at end of file