summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/AbstractSetting.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt235
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt34
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt265
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt4
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt2
-rw-r--r--src/android/app/src/main/jni/native_config.cpp15
9 files changed, 335 insertions, 241 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/AbstractSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/AbstractSetting.kt
index 724a2ecb8..73215c247 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/AbstractSetting.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/AbstractSetting.kt
@@ -6,14 +6,17 @@ package org.yuzu.yuzu_emu.features.settings.model
6import org.yuzu.yuzu_emu.utils.NativeConfig 6import org.yuzu.yuzu_emu.utils.NativeConfig
7 7
8interface AbstractSetting { 8interface AbstractSetting {
9 val key: String? 9 val key: String
10 val category: Settings.Category 10 val category: Settings.Category
11 val defaultValue: Any 11 val defaultValue: Any
12 val valueAsString: String 12 val valueAsString: String
13 get() = "" 13 get() = ""
14 14
15 val isRuntimeModifiable: Boolean 15 val isRuntimeModifiable: Boolean
16 get() = NativeConfig.getIsRuntimeModifiable(key!!) 16 get() = NativeConfig.getIsRuntimeModifiable(key)
17
18 val pairedSettingKey: String
19 get() = NativeConfig.getPairedSettingKey(key)
17 20
18 fun reset() 21 fun reset()
19} 22}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
index 3bdcc5bca..b3b3fc209 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SettingsItem.kt
@@ -4,8 +4,15 @@
4package org.yuzu.yuzu_emu.features.settings.model.view 4package org.yuzu.yuzu_emu.features.settings.model.view
5 5
6import org.yuzu.yuzu_emu.NativeLibrary 6import org.yuzu.yuzu_emu.NativeLibrary
7import org.yuzu.yuzu_emu.R
8import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
7import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting 9import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
10import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
11import org.yuzu.yuzu_emu.features.settings.model.ByteSetting
12import org.yuzu.yuzu_emu.features.settings.model.IntSetting
13import org.yuzu.yuzu_emu.features.settings.model.LongSetting
8import org.yuzu.yuzu_emu.features.settings.model.Settings 14import org.yuzu.yuzu_emu.features.settings.model.Settings
15import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
9 16
10/** 17/**
11 * ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments. 18 * ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments.
@@ -37,11 +44,239 @@ abstract class SettingsItem(
37 const val TYPE_DATETIME_SETTING = 6 44 const val TYPE_DATETIME_SETTING = 6
38 const val TYPE_RUNNABLE = 7 45 const val TYPE_RUNNABLE = 7
39 46
47 const val FASTMEM_COMBINED = "fastmem_combined"
48
40 val emptySetting = object : AbstractSetting { 49 val emptySetting = object : AbstractSetting {
41 override val key: String = "" 50 override val key: String = ""
42 override val category: Settings.Category = Settings.Category.Ui 51 override val category: Settings.Category = Settings.Category.Ui
43 override val defaultValue: Any = false 52 override val defaultValue: Any = false
44 override fun reset() {} 53 override fun reset() {}
45 } 54 }
55
56 // Extension for putting SettingsItems into a hashmap without repeating yourself
57 fun HashMap<String, SettingsItem>.put(item: SettingsItem) {
58 put(item.setting.key, item)
59 }
60
61 // List of all general
62 val settingsItems = HashMap<String, SettingsItem>().apply {
63 put(
64 SwitchSetting(
65 BooleanSetting.RENDERER_USE_SPEED_LIMIT,
66 R.string.frame_limit_enable,
67 R.string.frame_limit_enable_description
68 )
69 )
70 put(
71 SliderSetting(
72 ShortSetting.RENDERER_SPEED_LIMIT,
73 R.string.frame_limit_slider,
74 R.string.frame_limit_slider_description,
75 1,
76 200,
77 "%"
78 )
79 )
80 put(
81 SingleChoiceSetting(
82 IntSetting.CPU_ACCURACY,
83 R.string.cpu_accuracy,
84 0,
85 R.array.cpuAccuracyNames,
86 R.array.cpuAccuracyValues
87 )
88 )
89 put(
90 SwitchSetting(
91 BooleanSetting.PICTURE_IN_PICTURE,
92 R.string.picture_in_picture,
93 R.string.picture_in_picture_description
94 )
95 )
96 put(
97 SwitchSetting(
98 BooleanSetting.USE_DOCKED_MODE,
99 R.string.use_docked_mode,
100 R.string.use_docked_mode_description
101 )
102 )
103 put(
104 SingleChoiceSetting(
105 IntSetting.REGION_INDEX,
106 R.string.emulated_region,
107 0,
108 R.array.regionNames,
109 R.array.regionValues
110 )
111 )
112 put(
113 SingleChoiceSetting(
114 IntSetting.LANGUAGE_INDEX,
115 R.string.emulated_language,
116 0,
117 R.array.languageNames,
118 R.array.languageValues
119 )
120 )
121 put(
122 SwitchSetting(
123 BooleanSetting.USE_CUSTOM_RTC,
124 R.string.use_custom_rtc,
125 R.string.use_custom_rtc_description
126 )
127 )
128 put(DateTimeSetting(LongSetting.CUSTOM_RTC, R.string.set_custom_rtc, 0))
129 put(
130 SingleChoiceSetting(
131 IntSetting.RENDERER_ACCURACY,
132 R.string.renderer_accuracy,
133 0,
134 R.array.rendererAccuracyNames,
135 R.array.rendererAccuracyValues
136 )
137 )
138 put(
139 SingleChoiceSetting(
140 IntSetting.RENDERER_RESOLUTION,
141 R.string.renderer_resolution,
142 0,
143 R.array.rendererResolutionNames,
144 R.array.rendererResolutionValues
145 )
146 )
147 put(
148 SingleChoiceSetting(
149 IntSetting.RENDERER_VSYNC,
150 R.string.renderer_vsync,
151 0,
152 R.array.rendererVSyncNames,
153 R.array.rendererVSyncValues
154 )
155 )
156 put(
157 SingleChoiceSetting(
158 IntSetting.RENDERER_SCALING_FILTER,
159 R.string.renderer_scaling_filter,
160 0,
161 R.array.rendererScalingFilterNames,
162 R.array.rendererScalingFilterValues
163 )
164 )
165 put(
166 SingleChoiceSetting(
167 IntSetting.RENDERER_ANTI_ALIASING,
168 R.string.renderer_anti_aliasing,
169 0,
170 R.array.rendererAntiAliasingNames,
171 R.array.rendererAntiAliasingValues
172 )
173 )
174 put(
175 SingleChoiceSetting(
176 IntSetting.RENDERER_SCREEN_LAYOUT,
177 R.string.renderer_screen_layout,
178 0,
179 R.array.rendererScreenLayoutNames,
180 R.array.rendererScreenLayoutValues
181 )
182 )
183 put(
184 SingleChoiceSetting(
185 IntSetting.RENDERER_ASPECT_RATIO,
186 R.string.renderer_aspect_ratio,
187 0,
188 R.array.rendererAspectRatioNames,
189 R.array.rendererAspectRatioValues
190 )
191 )
192 put(
193 SwitchSetting(
194 BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE,
195 R.string.use_disk_shader_cache,
196 R.string.use_disk_shader_cache_description
197 )
198 )
199 put(
200 SwitchSetting(
201 BooleanSetting.RENDERER_FORCE_MAX_CLOCK,
202 R.string.renderer_force_max_clock,
203 R.string.renderer_force_max_clock_description
204 )
205 )
206 put(
207 SwitchSetting(
208 BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS,
209 R.string.renderer_asynchronous_shaders,
210 R.string.renderer_asynchronous_shaders_description
211 )
212 )
213 put(
214 SwitchSetting(
215 BooleanSetting.RENDERER_REACTIVE_FLUSHING,
216 R.string.renderer_reactive_flushing,
217 R.string.renderer_reactive_flushing_description
218 )
219 )
220 put(
221 SingleChoiceSetting(
222 IntSetting.AUDIO_OUTPUT_ENGINE,
223 R.string.audio_output_engine,
224 0,
225 R.array.outputEngineEntries,
226 R.array.outputEngineValues
227 )
228 )
229 put(
230 SliderSetting(
231 ByteSetting.AUDIO_VOLUME,
232 R.string.audio_volume,
233 R.string.audio_volume_description,
234 0,
235 100,
236 "%"
237 )
238 )
239 put(
240 SingleChoiceSetting(
241 IntSetting.RENDERER_BACKEND,
242 R.string.renderer_api,
243 0,
244 R.array.rendererApiNames,
245 R.array.rendererApiValues
246 )
247 )
248 put(
249 SwitchSetting(
250 BooleanSetting.RENDERER_DEBUG,
251 R.string.renderer_debug,
252 R.string.renderer_debug_description
253 )
254 )
255 put(
256 SwitchSetting(
257 BooleanSetting.CPU_DEBUG_MODE,
258 R.string.cpu_debug_mode,
259 R.string.cpu_debug_mode_description
260 )
261 )
262
263 val fastmem = object : AbstractBooleanSetting {
264 override val boolean: Boolean
265 get() =
266 BooleanSetting.FASTMEM.boolean && BooleanSetting.FASTMEM_EXCLUSIVES.boolean
267
268 override fun setBoolean(value: Boolean) {
269 BooleanSetting.FASTMEM.setBoolean(value)
270 BooleanSetting.FASTMEM_EXCLUSIVES.setBoolean(value)
271 }
272
273 override val key: String = FASTMEM_COMBINED
274 override val category = Settings.Category.Cpu
275 override val isRuntimeModifiable: Boolean = false
276 override val defaultValue: Boolean = true
277 override fun reset() = setBoolean(defaultValue)
278 }
279 put(SwitchSetting(fastmem, R.string.fastmem, 0))
280 }
46 } 281 }
47} 282}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
index 9883c2ec7..ff1e64e0a 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsAdapter.kt
@@ -14,7 +14,9 @@ import android.widget.TextView
14import androidx.appcompat.app.AlertDialog 14import androidx.appcompat.app.AlertDialog
15import androidx.lifecycle.ViewModelProvider 15import androidx.lifecycle.ViewModelProvider
16import androidx.navigation.findNavController 16import androidx.navigation.findNavController
17import androidx.recyclerview.widget.RecyclerView 17import androidx.recyclerview.widget.AsyncDifferConfig
18import androidx.recyclerview.widget.DiffUtil
19import androidx.recyclerview.widget.ListAdapter
18import com.google.android.material.datepicker.MaterialDatePicker 20import com.google.android.material.datepicker.MaterialDatePicker
19import com.google.android.material.dialog.MaterialAlertDialogBuilder 21import com.google.android.material.dialog.MaterialAlertDialogBuilder
20import com.google.android.material.slider.Slider 22import com.google.android.material.slider.Slider
@@ -37,8 +39,8 @@ import org.yuzu.yuzu_emu.model.SettingsViewModel
37class SettingsAdapter( 39class SettingsAdapter(
38 private val fragment: SettingsFragment, 40 private val fragment: SettingsFragment,
39 private val context: Context 41 private val context: Context
40) : RecyclerView.Adapter<SettingViewHolder?>(), DialogInterface.OnClickListener { 42) : ListAdapter<SettingsItem, SettingViewHolder>(AsyncDifferConfig.Builder(DiffCallback()).build()),
41 private var settings = ArrayList<SettingsItem>() 43 DialogInterface.OnClickListener {
42 private var clickedItem: SettingsItem? = null 44 private var clickedItem: SettingsItem? = null
43 private var clickedPosition: Int 45 private var clickedPosition: Int
44 private var dialog: AlertDialog? = null 46 private var dialog: AlertDialog? = null
@@ -94,24 +96,18 @@ class SettingsAdapter(
94 } 96 }
95 97
96 override fun onBindViewHolder(holder: SettingViewHolder, position: Int) { 98 override fun onBindViewHolder(holder: SettingViewHolder, position: Int) {
97 holder.bind(getItem(position)) 99 holder.bind(currentList[position])
98 } 100 }
99 101
100 private fun getItem(position: Int): SettingsItem = settings[position] 102 override fun getItemCount(): Int = currentList.size
101
102 override fun getItemCount(): Int = settings.size
103 103
104 override fun getItemViewType(position: Int): Int { 104 override fun getItemViewType(position: Int): Int {
105 return getItem(position).type 105 return currentList[position].type
106 }
107
108 fun setSettingsList(settings: ArrayList<SettingsItem>) {
109 this.settings = settings
110 notifyDataSetChanged()
111 } 106 }
112 107
113 fun onBooleanClick(item: SwitchSetting, position: Int, checked: Boolean) { 108 fun onBooleanClick(item: SwitchSetting, checked: Boolean) {
114 item.checked = checked 109 item.checked = checked
110 settingsViewModel.setShouldReloadSettingsList(true)
115 settingsViewModel.shouldSave = true 111 settingsViewModel.shouldSave = true
116 } 112 }
117 113
@@ -338,4 +334,14 @@ class SettingsAdapter(
338 } 334 }
339 return -1 335 return -1
340 } 336 }
337
338 private class DiffCallback : DiffUtil.ItemCallback<SettingsItem>() {
339 override fun areItemsTheSame(oldItem: SettingsItem, newItem: SettingsItem): Boolean {
340 return oldItem.setting.key == newItem.setting.key
341 }
342
343 override fun areContentsTheSame(oldItem: SettingsItem, newItem: SettingsItem): Boolean {
344 return oldItem.setting.key == newItem.setting.key
345 }
346 }
341} 347}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
index de6aebd9d..5890b0642 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt
@@ -77,6 +77,13 @@ class SettingsFragment : Fragment() {
77 if (it.isNotEmpty()) binding.toolbarSettingsLayout.title = it 77 if (it.isNotEmpty()) binding.toolbarSettingsLayout.title = it
78 } 78 }
79 79
80 settingsViewModel.shouldReloadSettingsList.observe(viewLifecycleOwner) {
81 if (it) {
82 settingsViewModel.setShouldReloadSettingsList(false)
83 presenter.loadSettingsList()
84 }
85 }
86
80 presenter.onViewCreated() 87 presenter.onViewCreated()
81 88
82 setInsets() 89 setInsets()
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
index ba45c317d..22a529b1b 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt
@@ -22,6 +22,7 @@ import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
22import org.yuzu.yuzu_emu.features.settings.model.view.* 22import org.yuzu.yuzu_emu.features.settings.model.view.*
23import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile 23import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
24import org.yuzu.yuzu_emu.model.SettingsViewModel 24import org.yuzu.yuzu_emu.model.SettingsViewModel
25import org.yuzu.yuzu_emu.utils.NativeConfig
25 26
26class SettingsFragmentPresenter( 27class SettingsFragmentPresenter(
27 private val settingsViewModel: SettingsViewModel, 28 private val settingsViewModel: SettingsViewModel,
@@ -36,11 +37,22 @@ class SettingsFragmentPresenter(
36 37
37 private val context: Context get() = YuzuApplication.appContext 38 private val context: Context get() = YuzuApplication.appContext
38 39
40 // Extension for populating settings list based on paired settings
41 fun ArrayList<SettingsItem>.add(key: String) {
42 val item = SettingsItem.settingsItems[key]!!
43 val pairedSettingKey = item.setting.pairedSettingKey
44 if (pairedSettingKey.isNotEmpty()) {
45 val pairedSettingValue = NativeConfig.getBoolean(pairedSettingKey, false)
46 if (!pairedSettingValue) return
47 }
48 add(item)
49 }
50
39 fun onViewCreated() { 51 fun onViewCreated() {
40 loadSettingsList() 52 loadSettingsList()
41 } 53 }
42 54
43 private fun loadSettingsList() { 55 fun loadSettingsList() {
44 if (!TextUtils.isEmpty(gameId)) { 56 if (!TextUtils.isEmpty(gameId)) {
45 settingsViewModel.setToolbarTitle( 57 settingsViewModel.setToolbarTitle(
46 context.getString( 58 context.getString(
@@ -70,7 +82,7 @@ class SettingsFragmentPresenter(
70 } 82 }
71 } 83 }
72 settingsList = sl 84 settingsList = sl
73 adapter.setSettingsList(settingsList) 85 adapter.submitList(settingsList)
74 } 86 }
75 87
76 private fun addConfigSettings(sl: ArrayList<SettingsItem>) { 88 private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
@@ -92,200 +104,46 @@ class SettingsFragmentPresenter(
92 private fun addGeneralSettings(sl: ArrayList<SettingsItem>) { 104 private fun addGeneralSettings(sl: ArrayList<SettingsItem>) {
93 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_general)) 105 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_general))
94 sl.apply { 106 sl.apply {
95 add( 107 add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key)
96 SwitchSetting( 108 add(ShortSetting.RENDERER_SPEED_LIMIT.key)
97 BooleanSetting.RENDERER_USE_SPEED_LIMIT, 109 add(IntSetting.CPU_ACCURACY.key)
98 R.string.frame_limit_enable, 110 add(BooleanSetting.PICTURE_IN_PICTURE.key)
99 R.string.frame_limit_enable_description
100 )
101 )
102 add(
103 SliderSetting(
104 ShortSetting.RENDERER_SPEED_LIMIT,
105 R.string.frame_limit_slider,
106 R.string.frame_limit_slider_description,
107 1,
108 200,
109 "%"
110 )
111 )
112 add(
113 SingleChoiceSetting(
114 IntSetting.CPU_ACCURACY,
115 R.string.cpu_accuracy,
116 0,
117 R.array.cpuAccuracyNames,
118 R.array.cpuAccuracyValues
119 )
120 )
121 add(
122 SwitchSetting(
123 BooleanSetting.PICTURE_IN_PICTURE,
124 R.string.picture_in_picture,
125 R.string.picture_in_picture_description
126 )
127 )
128 } 111 }
129 } 112 }
130 113
131 private fun addSystemSettings(sl: ArrayList<SettingsItem>) { 114 private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
132 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_system)) 115 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_system))
133 sl.apply { 116 sl.apply {
134 add( 117 add(BooleanSetting.USE_DOCKED_MODE.key)
135 SwitchSetting( 118 add(IntSetting.REGION_INDEX.key)
136 BooleanSetting.USE_DOCKED_MODE, 119 add(IntSetting.LANGUAGE_INDEX.key)
137 R.string.use_docked_mode, 120 add(BooleanSetting.USE_CUSTOM_RTC.key)
138 R.string.use_docked_mode_description 121 add(LongSetting.CUSTOM_RTC.key)
139 )
140 )
141 add(
142 SingleChoiceSetting(
143 IntSetting.REGION_INDEX,
144 R.string.emulated_region,
145 0,
146 R.array.regionNames,
147 R.array.regionValues
148 )
149 )
150 add(
151 SingleChoiceSetting(
152 IntSetting.LANGUAGE_INDEX,
153 R.string.emulated_language,
154 0,
155 R.array.languageNames,
156 R.array.languageValues
157 )
158 )
159 add(
160 SwitchSetting(
161 BooleanSetting.USE_CUSTOM_RTC,
162 R.string.use_custom_rtc,
163 R.string.use_custom_rtc_description
164 )
165 )
166 add(DateTimeSetting(LongSetting.CUSTOM_RTC, R.string.set_custom_rtc, 0))
167 } 122 }
168 } 123 }
169 124
170 private fun addGraphicsSettings(sl: ArrayList<SettingsItem>) { 125 private fun addGraphicsSettings(sl: ArrayList<SettingsItem>) {
171 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_graphics)) 126 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_graphics))
172 sl.apply { 127 sl.apply {
173 add( 128 add(IntSetting.RENDERER_ACCURACY.key)
174 SingleChoiceSetting( 129 add(IntSetting.RENDERER_RESOLUTION.key)
175 IntSetting.RENDERER_ACCURACY, 130 add(IntSetting.RENDERER_VSYNC.key)
176 R.string.renderer_accuracy, 131 add(IntSetting.RENDERER_SCALING_FILTER.key)
177 0, 132 add(IntSetting.RENDERER_ANTI_ALIASING.key)
178 R.array.rendererAccuracyNames, 133 add(IntSetting.RENDERER_SCREEN_LAYOUT.key)
179 R.array.rendererAccuracyValues 134 add(IntSetting.RENDERER_ASPECT_RATIO.key)
180 ) 135 add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key)
181 ) 136 add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
182 add( 137 add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
183 SingleChoiceSetting( 138 add(BooleanSetting.RENDERER_REACTIVE_FLUSHING.key)
184 IntSetting.RENDERER_RESOLUTION,
185 R.string.renderer_resolution,
186 0,
187 R.array.rendererResolutionNames,
188 R.array.rendererResolutionValues
189 )
190 )
191 add(
192 SingleChoiceSetting(
193 IntSetting.RENDERER_VSYNC,
194 R.string.renderer_vsync,
195 0,
196 R.array.rendererVSyncNames,
197 R.array.rendererVSyncValues
198 )
199 )
200 add(
201 SingleChoiceSetting(
202 IntSetting.RENDERER_SCALING_FILTER,
203 R.string.renderer_scaling_filter,
204 0,
205 R.array.rendererScalingFilterNames,
206 R.array.rendererScalingFilterValues
207 )
208 )
209 add(
210 SingleChoiceSetting(
211 IntSetting.RENDERER_ANTI_ALIASING,
212 R.string.renderer_anti_aliasing,
213 0,
214 R.array.rendererAntiAliasingNames,
215 R.array.rendererAntiAliasingValues
216 )
217 )
218 add(
219 SingleChoiceSetting(
220 IntSetting.RENDERER_SCREEN_LAYOUT,
221 R.string.renderer_screen_layout,
222 0,
223 R.array.rendererScreenLayoutNames,
224 R.array.rendererScreenLayoutValues
225 )
226 )
227 add(
228 SingleChoiceSetting(
229 IntSetting.RENDERER_ASPECT_RATIO,
230 R.string.renderer_aspect_ratio,
231 0,
232 R.array.rendererAspectRatioNames,
233 R.array.rendererAspectRatioValues
234 )
235 )
236 add(
237 SwitchSetting(
238 BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE,
239 R.string.use_disk_shader_cache,
240 R.string.use_disk_shader_cache_description
241 )
242 )
243 add(
244 SwitchSetting(
245 BooleanSetting.RENDERER_FORCE_MAX_CLOCK,
246 R.string.renderer_force_max_clock,
247 R.string.renderer_force_max_clock_description
248 )
249 )
250 add(
251 SwitchSetting(
252 BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS,
253 R.string.renderer_asynchronous_shaders,
254 R.string.renderer_asynchronous_shaders_description
255 )
256 )
257 add(
258 SwitchSetting(
259 BooleanSetting.RENDERER_REACTIVE_FLUSHING,
260 R.string.renderer_reactive_flushing,
261 R.string.renderer_reactive_flushing_description
262 )
263 )
264 } 139 }
265 } 140 }
266 141
267 private fun addAudioSettings(sl: ArrayList<SettingsItem>) { 142 private fun addAudioSettings(sl: ArrayList<SettingsItem>) {
268 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_audio)) 143 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_audio))
269 sl.apply { 144 sl.apply {
270 add( 145 add(IntSetting.AUDIO_OUTPUT_ENGINE.key)
271 SingleChoiceSetting( 146 add(ByteSetting.AUDIO_VOLUME.key)
272 IntSetting.AUDIO_OUTPUT_ENGINE,
273 R.string.audio_output_engine,
274 0,
275 R.array.outputEngineEntries,
276 R.array.outputEngineValues
277 )
278 )
279 add(
280 SliderSetting(
281 ByteSetting.AUDIO_VOLUME,
282 R.string.audio_volume,
283 R.string.audio_volume_description,
284 0,
285 100,
286 "%"
287 )
288 )
289 } 147 }
290 } 148 }
291 149
@@ -303,7 +161,7 @@ class SettingsFragmentPresenter(
303 settingsViewModel.setShouldRecreate(true) 161 settingsViewModel.setShouldRecreate(true)
304 } 162 }
305 163
306 override val key: String? = null 164 override val key: String = Settings.PREF_THEME
307 override val category = Settings.Category.UiGeneral 165 override val category = Settings.Category.UiGeneral
308 override val isRuntimeModifiable: Boolean = false 166 override val isRuntimeModifiable: Boolean = false
309 override val defaultValue: Int = 0 167 override val defaultValue: Int = 0
@@ -347,7 +205,7 @@ class SettingsFragmentPresenter(
347 settingsViewModel.setShouldRecreate(true) 205 settingsViewModel.setShouldRecreate(true)
348 } 206 }
349 207
350 override val key: String? = null 208 override val key: String = Settings.PREF_THEME_MODE
351 override val category = Settings.Category.UiGeneral 209 override val category = Settings.Category.UiGeneral
352 override val isRuntimeModifiable: Boolean = false 210 override val isRuntimeModifiable: Boolean = false
353 override val defaultValue: Int = -1 211 override val defaultValue: Int = -1
@@ -380,7 +238,7 @@ class SettingsFragmentPresenter(
380 settingsViewModel.setShouldRecreate(true) 238 settingsViewModel.setShouldRecreate(true)
381 } 239 }
382 240
383 override val key: String? = null 241 override val key: String = Settings.PREF_BLACK_BACKGROUNDS
384 override val category = Settings.Category.UiGeneral 242 override val category = Settings.Category.UiGeneral
385 override val isRuntimeModifiable: Boolean = false 243 override val isRuntimeModifiable: Boolean = false
386 override val defaultValue: Boolean = false 244 override val defaultValue: Boolean = false
@@ -406,49 +264,12 @@ class SettingsFragmentPresenter(
406 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_debug)) 264 settingsViewModel.setToolbarTitle(context.getString(R.string.preferences_debug))
407 sl.apply { 265 sl.apply {
408 add(HeaderSetting(R.string.gpu)) 266 add(HeaderSetting(R.string.gpu))
409 add( 267 add(IntSetting.RENDERER_BACKEND.key)
410 SingleChoiceSetting( 268 add(BooleanSetting.RENDERER_DEBUG.key)
411 IntSetting.RENDERER_BACKEND,
412 R.string.renderer_api,
413 0,
414 R.array.rendererApiNames,
415 R.array.rendererApiValues
416 )
417 )
418 add(
419 SwitchSetting(
420 BooleanSetting.RENDERER_DEBUG,
421 R.string.renderer_debug,
422 R.string.renderer_debug_description
423 )
424 )
425 269
426 add(HeaderSetting(R.string.cpu)) 270 add(HeaderSetting(R.string.cpu))
427 add( 271 add(BooleanSetting.CPU_DEBUG_MODE.key)
428 SwitchSetting( 272 add(SettingsItem.FASTMEM_COMBINED)
429 BooleanSetting.CPU_DEBUG_MODE,
430 R.string.cpu_debug_mode,
431 R.string.cpu_debug_mode_description
432 )
433 )
434
435 val fastmem = object : AbstractBooleanSetting {
436 override val boolean: Boolean
437 get() =
438 BooleanSetting.FASTMEM.boolean && BooleanSetting.FASTMEM_EXCLUSIVES.boolean
439
440 override fun setBoolean(value: Boolean) {
441 BooleanSetting.FASTMEM.setBoolean(value)
442 BooleanSetting.FASTMEM_EXCLUSIVES.setBoolean(value)
443 }
444
445 override val key: String? = null
446 override val category = Settings.Category.Cpu
447 override val isRuntimeModifiable: Boolean = false
448 override val defaultValue: Boolean = true
449 override fun reset() = setBoolean(defaultValue)
450 }
451 add(SwitchSetting(fastmem, R.string.fastmem, 0))
452 } 273 }
453 } 274 }
454} 275}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt
index 25b689d66..0a37d3624 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SwitchSettingViewHolder.kt
@@ -29,7 +29,7 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter
29 binding.switchWidget.setOnCheckedChangeListener(null) 29 binding.switchWidget.setOnCheckedChangeListener(null)
30 binding.switchWidget.isChecked = setting.checked 30 binding.switchWidget.isChecked = setting.checked
31 binding.switchWidget.setOnCheckedChangeListener { _: CompoundButton, _: Boolean -> 31 binding.switchWidget.setOnCheckedChangeListener { _: CompoundButton, _: Boolean ->
32 adapter.onBooleanClick(item, bindingAdapterPosition, binding.switchWidget.isChecked) 32 adapter.onBooleanClick(item, binding.switchWidget.isChecked)
33 } 33 }
34 34
35 setStyle(setting.isEditable, binding) 35 setStyle(setting.isEditable, binding)
@@ -43,7 +43,7 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter
43 43
44 override fun onLongClick(clicked: View): Boolean { 44 override fun onLongClick(clicked: View): Boolean {
45 if (setting.isEditable) { 45 if (setting.isEditable) {
46 return adapter.onLongClick(setting.setting!!, bindingAdapterPosition) 46 return adapter.onLongClick(setting.setting, bindingAdapterPosition)
47 } 47 }
48 return false 48 return false
49 } 49 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt
index 1763341e2..6f2276293 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/SettingsViewModel.kt
@@ -24,6 +24,9 @@ class SettingsViewModel : ViewModel() {
24 private val _shouldShowResetSettingsDialog = MutableLiveData(false) 24 private val _shouldShowResetSettingsDialog = MutableLiveData(false)
25 val shouldShowResetSettingsDialog: LiveData<Boolean> get() = _shouldShowResetSettingsDialog 25 val shouldShowResetSettingsDialog: LiveData<Boolean> get() = _shouldShowResetSettingsDialog
26 26
27 private val _shouldReloadSettingsList = MutableLiveData(false)
28 val shouldReloadSettingsList: LiveData<Boolean> get() = _shouldReloadSettingsList
29
27 fun setToolbarTitle(value: String) { 30 fun setToolbarTitle(value: String) {
28 _toolbarTitle.value = value 31 _toolbarTitle.value = value
29 } 32 }
@@ -40,6 +43,10 @@ class SettingsViewModel : ViewModel() {
40 _shouldShowResetSettingsDialog.value = value 43 _shouldShowResetSettingsDialog.value = value
41 } 44 }
42 45
46 fun setShouldReloadSettingsList(value: Boolean) {
47 _shouldReloadSettingsList.value = value
48 }
49
43 fun clear() { 50 fun clear() {
44 game = null 51 game = null
45 shouldSave = false 52 shouldSave = false
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
index d4d981f9e..9425f8b99 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
@@ -28,4 +28,6 @@ object NativeConfig {
28 external fun getIsRuntimeModifiable(key: String): Boolean 28 external fun getIsRuntimeModifiable(key: String): Boolean
29 29
30 external fun getConfigHeader(category: Int): String 30 external fun getConfigHeader(category: Int): String
31
32 external fun getPairedSettingKey(key: String): String
31} 33}
diff --git a/src/android/app/src/main/jni/native_config.cpp b/src/android/app/src/main/jni/native_config.cpp
index 6123b3d08..8a704960c 100644
--- a/src/android/app/src/main/jni/native_config.cpp
+++ b/src/android/app/src/main/jni/native_config.cpp
@@ -216,9 +216,22 @@ jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsRuntimeModifiable(JNIEn
216} 216}
217 217
218jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getConfigHeader(JNIEnv* env, jobject obj, 218jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getConfigHeader(JNIEnv* env, jobject obj,
219 jint jcategory) { 219 jint jcategory) {
220 auto category = static_cast<Settings::Category>(jcategory); 220 auto category = static_cast<Settings::Category>(jcategory);
221 return ToJString(env, Settings::TranslateCategory(category)); 221 return ToJString(env, Settings::TranslateCategory(category));
222} 222}
223 223
224jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getPairedSettingKey(JNIEnv* env, jobject obj,
225 jstring jkey) {
226 auto setting = getSetting<std::string>(env, jkey);
227 if (setting == nullptr) {
228 return ToJString(env, "");
229 }
230 if (setting->PairedSetting() == nullptr) {
231 return ToJString(env, "");
232 }
233
234 return ToJString(env, setting->PairedSetting()->GetLabel());
235}
236
224} // extern "C" 237} // extern "C"