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/activities/EmulationActivity.kt4
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt52
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt1
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt3
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragment.kt30
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsFragmentPresenter.kt61
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt14
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt8
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt7
-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/GameIconUtils.kt7
-rw-r--r--src/android/app/src/main/jni/uisettings.h2
-rw-r--r--src/android/app/src/main/res/drawable/ic_audio.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_code.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_graphics.xml9
-rw-r--r--src/android/app/src/main/res/drawable/ic_system_settings.xml9
-rw-r--r--src/android/app/src/main/res/layout-w600dp/fragment_about.xml233
-rw-r--r--src/android/app/src/main/res/layout/card_home_option.xml4
-rw-r--r--src/android/app/src/main/res/layout/fragment_about.xml10
-rw-r--r--src/android/app/src/main/res/layout/fragment_emulation.xml5
-rw-r--r--src/android/app/src/main/res/layout/fragment_home_settings.xml9
-rw-r--r--src/android/app/src/main/res/layout/list_item_setting.xml72
-rw-r--r--src/android/app/src/main/res/layout/list_item_setting_switch.xml8
-rw-r--r--src/android/app/src/main/res/layout/list_item_settings_header.xml3
-rw-r--r--src/android/app/src/main/res/values/arrays.xml2
-rw-r--r--src/android/app/src/main/res/values/strings.xml5
-rw-r--r--src/audio_core/sink/cubeb_sink.cpp2
-rw-r--r--src/audio_core/sink/sdl2_sink.cpp2
-rw-r--r--src/audio_core/sink/sink_stream.cpp12
-rw-r--r--src/audio_core/sink/sink_stream.h6
-rw-r--r--src/common/settings.cpp2
-rw-r--r--src/common/settings.h2
-rw-r--r--src/common/settings_common.h1
-rw-r--r--src/core/arm/arm_interface.cpp16
-rw-r--r--src/core/core_timing.cpp2
-rw-r--r--src/core/core_timing.h2
-rw-r--r--src/core/hle/kernel/k_page_table_base.cpp4
-rw-r--r--src/yuzu/configuration/config.cpp2
-rw-r--r--src/yuzu/configuration/configure_audio.cpp10
-rw-r--r--src/yuzu/main.cpp12
-rw-r--r--src/yuzu/uisettings.h10
43 files changed, 522 insertions, 167 deletions
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
index 054e4b755..f41d7bdbf 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt
@@ -373,8 +373,10 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
373 val pictureInPictureParamsBuilder = PictureInPictureParams.Builder() 373 val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
374 .getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder() 374 .getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
375 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { 375 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
376 val isEmulationActive = emulationViewModel.emulationStarted.value &&
377 !emulationViewModel.isEmulationStopping.value
376 pictureInPictureParamsBuilder.setAutoEnterEnabled( 378 pictureInPictureParamsBuilder.setAutoEnterEnabled(
377 BooleanSetting.PICTURE_IN_PICTURE.boolean 379 BooleanSetting.PICTURE_IN_PICTURE.boolean && isEmulationActive
378 ) 380 )
379 } 381 }
380 setPictureInPictureParams(pictureInPictureParamsBuilder.build()) 382 setPictureInPictureParams(pictureInPictureParamsBuilder.build())
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
index 0c82cdba8..2ef638559 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/GameAdapter.kt
@@ -22,12 +22,16 @@ import androidx.core.graphics.drawable.toBitmap
22import androidx.core.graphics.drawable.toDrawable 22import androidx.core.graphics.drawable.toDrawable
23import androidx.documentfile.provider.DocumentFile 23import androidx.documentfile.provider.DocumentFile
24import androidx.lifecycle.ViewModelProvider 24import androidx.lifecycle.ViewModelProvider
25import androidx.lifecycle.lifecycleScope
25import androidx.navigation.findNavController 26import androidx.navigation.findNavController
26import androidx.preference.PreferenceManager 27import androidx.preference.PreferenceManager
27import androidx.recyclerview.widget.AsyncDifferConfig 28import androidx.recyclerview.widget.AsyncDifferConfig
28import androidx.recyclerview.widget.DiffUtil 29import androidx.recyclerview.widget.DiffUtil
29import androidx.recyclerview.widget.ListAdapter 30import androidx.recyclerview.widget.ListAdapter
30import androidx.recyclerview.widget.RecyclerView 31import androidx.recyclerview.widget.RecyclerView
32import kotlinx.coroutines.Dispatchers
33import kotlinx.coroutines.launch
34import kotlinx.coroutines.withContext
31import org.yuzu.yuzu_emu.HomeNavigationDirections 35import org.yuzu.yuzu_emu.HomeNavigationDirections
32import org.yuzu.yuzu_emu.R 36import org.yuzu.yuzu_emu.R
33import org.yuzu.yuzu_emu.YuzuApplication 37import org.yuzu.yuzu_emu.YuzuApplication
@@ -92,28 +96,34 @@ class GameAdapter(private val activity: AppCompatActivity) :
92 data = Uri.parse(holder.game.path) 96 data = Uri.parse(holder.game.path)
93 } 97 }
94 98
95 val layerDrawable = ResourcesCompat.getDrawable( 99 activity.lifecycleScope.launch {
96 YuzuApplication.appContext.resources, 100 withContext(Dispatchers.IO) {
97 R.drawable.shortcut, 101 val layerDrawable = ResourcesCompat.getDrawable(
98 null 102 YuzuApplication.appContext.resources,
99 ) as LayerDrawable 103 R.drawable.shortcut,
100 layerDrawable.setDrawableByLayerId( 104 null
101 R.id.shortcut_foreground, 105 ) as LayerDrawable
102 GameIconUtils.getGameIcon(holder.game).toDrawable(YuzuApplication.appContext.resources) 106 layerDrawable.setDrawableByLayerId(
103 ) 107 R.id.shortcut_foreground,
104 val inset = YuzuApplication.appContext.resources 108 GameIconUtils.getGameIcon(activity, holder.game)
105 .getDimensionPixelSize(R.dimen.icon_inset) 109 .toDrawable(YuzuApplication.appContext.resources)
106 layerDrawable.setLayerInset(1, inset, inset, inset, inset)
107 val shortcut = ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
108 .setShortLabel(holder.game.title)
109 .setIcon(
110 IconCompat.createWithAdaptiveBitmap(
111 layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
112 ) 110 )
113 ) 111 val inset = YuzuApplication.appContext.resources
114 .setIntent(openIntent) 112 .getDimensionPixelSize(R.dimen.icon_inset)
115 .build() 113 layerDrawable.setLayerInset(1, inset, inset, inset, inset)
116 ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut) 114 val shortcut =
115 ShortcutInfoCompat.Builder(YuzuApplication.appContext, holder.game.path)
116 .setShortLabel(holder.game.title)
117 .setIcon(
118 IconCompat.createWithAdaptiveBitmap(
119 layerDrawable.toBitmap(config = Bitmap.Config.ARGB_8888)
120 )
121 )
122 .setIntent(openIntent)
123 .build()
124 ShortcutManagerCompat.pushDynamicShortcut(YuzuApplication.appContext, shortcut)
125 }
126 }
117 127
118 val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game) 128 val action = HomeNavigationDirections.actionGlobalEmulationActivity(holder.game)
119 view.findNavController().navigate(action) 129 view.findNavController().navigate(action)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
index 08e2a973d..2bf0e1b0d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
@@ -82,7 +82,6 @@ object Settings {
82 82
83 enum class MenuTag(val titleId: Int) { 83 enum class MenuTag(val titleId: Int) {
84 SECTION_ROOT(R.string.advanced_settings), 84 SECTION_ROOT(R.string.advanced_settings),
85 SECTION_GENERAL(R.string.preferences_general),
86 SECTION_SYSTEM(R.string.preferences_system), 85 SECTION_SYSTEM(R.string.preferences_system),
87 SECTION_RENDERER(R.string.preferences_graphics), 86 SECTION_RENDERER(R.string.preferences_graphics),
88 SECTION_AUDIO(R.string.preferences_audio), 87 SECTION_AUDIO(R.string.preferences_audio),
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt
index 522cc49df..425160024 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/RunnableSetting.kt
@@ -3,10 +3,13 @@
3 3
4package org.yuzu.yuzu_emu.features.settings.model.view 4package org.yuzu.yuzu_emu.features.settings.model.view
5 5
6import androidx.annotation.DrawableRes
7
6class RunnableSetting( 8class RunnableSetting(
7 titleId: Int, 9 titleId: Int,
8 descriptionId: Int, 10 descriptionId: Int,
9 val isRuntimeRunnable: Boolean, 11 val isRuntimeRunnable: Boolean,
12 @DrawableRes val iconId: Int = 0,
10 val runnable: () -> Unit 13 val runnable: () -> Unit
11) : SettingsItem(emptySetting, titleId, descriptionId) { 14) : SettingsItem(emptySetting, titleId, descriptionId) {
12 override val type = TYPE_RUNNABLE 15 override val type = TYPE_RUNNABLE
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt
index b343e527e..94953b18a 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt
@@ -3,11 +3,14 @@
3 3
4package org.yuzu.yuzu_emu.features.settings.model.view 4package org.yuzu.yuzu_emu.features.settings.model.view
5 5
6import androidx.annotation.DrawableRes
7import androidx.annotation.StringRes
6import org.yuzu.yuzu_emu.features.settings.model.Settings 8import org.yuzu.yuzu_emu.features.settings.model.Settings
7 9
8class SubmenuSetting( 10class SubmenuSetting(
9 titleId: Int, 11 @StringRes titleId: Int,
10 descriptionId: Int, 12 @StringRes descriptionId: Int,
13 @DrawableRes val iconId: Int,
11 val menuKey: Settings.MenuTag 14 val menuKey: Settings.MenuTag
12) : SettingsItem(emptySetting, titleId, descriptionId) { 15) : SettingsItem(emptySetting, titleId, descriptionId) {
13 override val type = TYPE_SUBMENU 16 override val type = TYPE_SUBMENU
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 70d8ec14b..769baf744 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
@@ -20,7 +20,6 @@ import androidx.lifecycle.repeatOnLifecycle
20import androidx.navigation.findNavController 20import androidx.navigation.findNavController
21import androidx.navigation.fragment.navArgs 21import androidx.navigation.fragment.navArgs
22import androidx.recyclerview.widget.LinearLayoutManager 22import androidx.recyclerview.widget.LinearLayoutManager
23import com.google.android.material.divider.MaterialDividerItemDecoration
24import com.google.android.material.transition.MaterialSharedAxis 23import com.google.android.material.transition.MaterialSharedAxis
25import kotlinx.coroutines.flow.collectLatest 24import kotlinx.coroutines.flow.collectLatest
26import kotlinx.coroutines.launch 25import kotlinx.coroutines.launch
@@ -68,15 +67,9 @@ class SettingsFragment : Fragment() {
68 ) 67 )
69 68
70 binding.toolbarSettingsLayout.title = getString(args.menuTag.titleId) 69 binding.toolbarSettingsLayout.title = getString(args.menuTag.titleId)
71 val dividerDecoration = MaterialDividerItemDecoration(
72 requireContext(),
73 LinearLayoutManager.VERTICAL
74 )
75 dividerDecoration.isLastItemDecorated = false
76 binding.listSettings.apply { 70 binding.listSettings.apply {
77 adapter = settingsAdapter 71 adapter = settingsAdapter
78 layoutManager = LinearLayoutManager(requireContext()) 72 layoutManager = LinearLayoutManager(requireContext())
79 addItemDecoration(dividerDecoration)
80 } 73 }
81 74
82 binding.toolbarSettings.setNavigationOnClickListener { 75 binding.toolbarSettings.setNavigationOnClickListener {
@@ -94,17 +87,6 @@ class SettingsFragment : Fragment() {
94 } 87 }
95 } 88 }
96 } 89 }
97 launch {
98 settingsViewModel.isUsingSearch.collectLatest {
99 if (it) {
100 reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
101 exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
102 } else {
103 reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
104 exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
105 }
106 }
107 }
108 } 90 }
109 91
110 if (args.menuTag == Settings.MenuTag.SECTION_ROOT) { 92 if (args.menuTag == Settings.MenuTag.SECTION_ROOT) {
@@ -112,8 +94,6 @@ class SettingsFragment : Fragment() {
112 binding.toolbarSettings.setOnMenuItemClickListener { 94 binding.toolbarSettings.setOnMenuItemClickListener {
113 when (it.itemId) { 95 when (it.itemId) {
114 R.id.action_search -> { 96 R.id.action_search -> {
115 reenterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true)
116 exitTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false)
117 view.findNavController() 97 view.findNavController()
118 .navigate(R.id.action_settingsFragment_to_settingsSearchFragment) 98 .navigate(R.id.action_settingsFragment_to_settingsSearchFragment)
119 true 99 true
@@ -129,11 +109,6 @@ class SettingsFragment : Fragment() {
129 setInsets() 109 setInsets()
130 } 110 }
131 111
132 override fun onResume() {
133 super.onResume()
134 settingsViewModel.setIsUsingSearch(false)
135 }
136
137 private fun setInsets() { 112 private fun setInsets() {
138 ViewCompat.setOnApplyWindowInsetsListener( 113 ViewCompat.setOnApplyWindowInsetsListener(
139 binding.root 114 binding.root
@@ -144,10 +119,9 @@ class SettingsFragment : Fragment() {
144 val leftInsets = barInsets.left + cutoutInsets.left 119 val leftInsets = barInsets.left + cutoutInsets.left
145 val rightInsets = barInsets.right + cutoutInsets.right 120 val rightInsets = barInsets.right + cutoutInsets.right
146 121
147 val sideMargin = resources.getDimensionPixelSize(R.dimen.spacing_medlarge)
148 val mlpSettingsList = binding.listSettings.layoutParams as MarginLayoutParams 122 val mlpSettingsList = binding.listSettings.layoutParams as MarginLayoutParams
149 mlpSettingsList.leftMargin = sideMargin + leftInsets 123 mlpSettingsList.leftMargin = leftInsets
150 mlpSettingsList.rightMargin = sideMargin + rightInsets 124 mlpSettingsList.rightMargin = rightInsets
151 binding.listSettings.layoutParams = mlpSettingsList 125 binding.listSettings.layoutParams = mlpSettingsList
152 binding.listSettings.updatePadding( 126 binding.listSettings.updatePadding(
153 bottom = barInsets.bottom 127 bottom = barInsets.bottom
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 766414a6c..8b71e32f3 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
@@ -3,7 +3,6 @@
3 3
4package org.yuzu.yuzu_emu.features.settings.ui 4package org.yuzu.yuzu_emu.features.settings.ui
5 5
6import android.content.Context
7import android.content.SharedPreferences 6import android.content.SharedPreferences
8import android.os.Build 7import android.os.Build
9import android.widget.Toast 8import android.widget.Toast
@@ -32,8 +31,6 @@ class SettingsFragmentPresenter(
32 private val preferences: SharedPreferences 31 private val preferences: SharedPreferences
33 get() = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext) 32 get() = PreferenceManager.getDefaultSharedPreferences(YuzuApplication.appContext)
34 33
35 private val context: Context get() = YuzuApplication.appContext
36
37 // Extension for populating settings list based on paired settings 34 // Extension for populating settings list based on paired settings
38 fun ArrayList<SettingsItem>.add(key: String) { 35 fun ArrayList<SettingsItem>.add(key: String) {
39 val item = SettingsItem.settingsItems[key]!! 36 val item = SettingsItem.settingsItems[key]!!
@@ -53,7 +50,6 @@ class SettingsFragmentPresenter(
53 val sl = ArrayList<SettingsItem>() 50 val sl = ArrayList<SettingsItem>()
54 when (menuTag) { 51 when (menuTag) {
55 Settings.MenuTag.SECTION_ROOT -> addConfigSettings(sl) 52 Settings.MenuTag.SECTION_ROOT -> addConfigSettings(sl)
56 Settings.MenuTag.SECTION_GENERAL -> addGeneralSettings(sl)
57 Settings.MenuTag.SECTION_SYSTEM -> addSystemSettings(sl) 53 Settings.MenuTag.SECTION_SYSTEM -> addSystemSettings(sl)
58 Settings.MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl) 54 Settings.MenuTag.SECTION_RENDERER -> addGraphicsSettings(sl)
59 Settings.MenuTag.SECTION_AUDIO -> addAudioSettings(sl) 55 Settings.MenuTag.SECTION_AUDIO -> addAudioSettings(sl)
@@ -75,30 +71,53 @@ class SettingsFragmentPresenter(
75 71
76 private fun addConfigSettings(sl: ArrayList<SettingsItem>) { 72 private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
77 sl.apply { 73 sl.apply {
78 add(SubmenuSetting(R.string.preferences_general, 0, Settings.MenuTag.SECTION_GENERAL))
79 add(SubmenuSetting(R.string.preferences_system, 0, Settings.MenuTag.SECTION_SYSTEM))
80 add(SubmenuSetting(R.string.preferences_graphics, 0, Settings.MenuTag.SECTION_RENDERER))
81 add(SubmenuSetting(R.string.preferences_audio, 0, Settings.MenuTag.SECTION_AUDIO))
82 add(SubmenuSetting(R.string.preferences_debug, 0, Settings.MenuTag.SECTION_DEBUG))
83 add( 74 add(
84 RunnableSetting(R.string.reset_to_default, 0, false) { 75 SubmenuSetting(
85 settingsViewModel.setShouldShowResetSettingsDialog(true) 76 R.string.preferences_system,
86 } 77 R.string.preferences_system_description,
78 R.drawable.ic_system_settings,
79 Settings.MenuTag.SECTION_SYSTEM
80 )
81 )
82 add(
83 SubmenuSetting(
84 R.string.preferences_graphics,
85 R.string.preferences_graphics_description,
86 R.drawable.ic_graphics,
87 Settings.MenuTag.SECTION_RENDERER
88 )
89 )
90 add(
91 SubmenuSetting(
92 R.string.preferences_audio,
93 R.string.preferences_audio_description,
94 R.drawable.ic_audio,
95 Settings.MenuTag.SECTION_AUDIO
96 )
97 )
98 add(
99 SubmenuSetting(
100 R.string.preferences_debug,
101 R.string.preferences_debug_description,
102 R.drawable.ic_code,
103 Settings.MenuTag.SECTION_DEBUG
104 )
105 )
106 add(
107 RunnableSetting(
108 R.string.reset_to_default,
109 R.string.reset_to_default_description,
110 false,
111 R.drawable.ic_restore
112 ) { settingsViewModel.setShouldShowResetSettingsDialog(true) }
87 ) 113 )
88 } 114 }
89 } 115 }
90 116
91 private fun addGeneralSettings(sl: ArrayList<SettingsItem>) { 117 private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
92 sl.apply { 118 sl.apply {
93 add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key) 119 add(BooleanSetting.RENDERER_USE_SPEED_LIMIT.key)
94 add(ShortSetting.RENDERER_SPEED_LIMIT.key) 120 add(ShortSetting.RENDERER_SPEED_LIMIT.key)
95 add(IntSetting.CPU_ACCURACY.key)
96 add(BooleanSetting.PICTURE_IN_PICTURE.key)
97 }
98 }
99
100 private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
101 sl.apply {
102 add(BooleanSetting.USE_DOCKED_MODE.key) 121 add(BooleanSetting.USE_DOCKED_MODE.key)
103 add(IntSetting.REGION_INDEX.key) 122 add(IntSetting.REGION_INDEX.key)
104 add(IntSetting.LANGUAGE_INDEX.key) 123 add(IntSetting.LANGUAGE_INDEX.key)
@@ -116,6 +135,7 @@ class SettingsFragmentPresenter(
116 add(IntSetting.RENDERER_ANTI_ALIASING.key) 135 add(IntSetting.RENDERER_ANTI_ALIASING.key)
117 add(IntSetting.RENDERER_SCREEN_LAYOUT.key) 136 add(IntSetting.RENDERER_SCREEN_LAYOUT.key)
118 add(IntSetting.RENDERER_ASPECT_RATIO.key) 137 add(IntSetting.RENDERER_ASPECT_RATIO.key)
138 add(BooleanSetting.PICTURE_IN_PICTURE.key)
119 add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key) 139 add(BooleanSetting.RENDERER_USE_DISK_SHADER_CACHE.key)
120 add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key) 140 add(BooleanSetting.RENDERER_FORCE_MAX_CLOCK.key)
121 add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key) 141 add(BooleanSetting.RENDERER_ASYNCHRONOUS_SHADERS.key)
@@ -249,6 +269,7 @@ class SettingsFragmentPresenter(
249 add(BooleanSetting.RENDERER_DEBUG.key) 269 add(BooleanSetting.RENDERER_DEBUG.key)
250 270
251 add(HeaderSetting(R.string.cpu)) 271 add(HeaderSetting(R.string.cpu))
272 add(IntSetting.CPU_ACCURACY.key)
252 add(BooleanSetting.CPU_DEBUG_MODE.key) 273 add(BooleanSetting.CPU_DEBUG_MODE.key)
253 add(SettingsItem.FASTMEM_COMBINED) 274 add(SettingsItem.FASTMEM_COMBINED)
254 } 275 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt
index 83a2e94f1..036195624 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/RunnableViewHolder.kt
@@ -4,6 +4,7 @@
4package org.yuzu.yuzu_emu.features.settings.ui.viewholder 4package org.yuzu.yuzu_emu.features.settings.ui.viewholder
5 5
6import android.view.View 6import android.view.View
7import androidx.core.content.res.ResourcesCompat
7import org.yuzu.yuzu_emu.NativeLibrary 8import org.yuzu.yuzu_emu.NativeLibrary
8import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding 9import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
9import org.yuzu.yuzu_emu.features.settings.model.view.RunnableSetting 10import org.yuzu.yuzu_emu.features.settings.model.view.RunnableSetting
@@ -16,6 +17,19 @@ class RunnableViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
16 17
17 override fun bind(item: SettingsItem) { 18 override fun bind(item: SettingsItem) {
18 setting = item as RunnableSetting 19 setting = item as RunnableSetting
20 if (item.iconId != 0) {
21 binding.icon.visibility = View.VISIBLE
22 binding.icon.setImageDrawable(
23 ResourcesCompat.getDrawable(
24 binding.icon.resources,
25 item.iconId,
26 binding.icon.context.theme
27 )
28 )
29 } else {
30 binding.icon.visibility = View.GONE
31 }
32
19 binding.textSettingName.setText(item.nameId) 33 binding.textSettingName.setText(item.nameId)
20 if (item.descriptionId != 0) { 34 if (item.descriptionId != 0) {
21 binding.textSettingDescription.setText(item.descriptionId) 35 binding.textSettingDescription.setText(item.descriptionId)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt
index 1cf581a9d..8100c65dd 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/viewholder/SubmenuViewHolder.kt
@@ -4,6 +4,7 @@
4package org.yuzu.yuzu_emu.features.settings.ui.viewholder 4package org.yuzu.yuzu_emu.features.settings.ui.viewholder
5 5
6import android.view.View 6import android.view.View
7import androidx.core.content.res.ResourcesCompat
7import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding 8import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
8import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem 9import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
9import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting 10import org.yuzu.yuzu_emu.features.settings.model.view.SubmenuSetting
@@ -15,6 +16,19 @@ class SubmenuViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAd
15 16
16 override fun bind(item: SettingsItem) { 17 override fun bind(item: SettingsItem) {
17 this.item = item as SubmenuSetting 18 this.item = item as SubmenuSetting
19 if (item.iconId != 0) {
20 binding.icon.visibility = View.VISIBLE
21 binding.icon.setImageDrawable(
22 ResourcesCompat.getDrawable(
23 binding.icon.resources,
24 item.iconId,
25 binding.icon.context.theme
26 )
27 )
28 } else {
29 binding.icon.visibility = View.GONE
30 }
31
18 binding.textSettingName.setText(item.nameId) 32 binding.textSettingName.setText(item.nameId)
19 if (item.descriptionId != 0) { 33 if (item.descriptionId != 0) {
20 binding.textSettingDescription.setText(item.descriptionId) 34 binding.textSettingDescription.setText(item.descriptionId)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt
index 2ff827c6b..a1620fbb7 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt
@@ -114,10 +114,10 @@ class AboutFragment : Fragment() {
114 val leftInsets = barInsets.left + cutoutInsets.left 114 val leftInsets = barInsets.left + cutoutInsets.left
115 val rightInsets = barInsets.right + cutoutInsets.right 115 val rightInsets = barInsets.right + cutoutInsets.right
116 116
117 val mlpAppBar = binding.appbarAbout.layoutParams as MarginLayoutParams 117 val mlpToolbar = binding.toolbarAbout.layoutParams as MarginLayoutParams
118 mlpAppBar.leftMargin = leftInsets 118 mlpToolbar.leftMargin = leftInsets
119 mlpAppBar.rightMargin = rightInsets 119 mlpToolbar.rightMargin = rightInsets
120 binding.appbarAbout.layoutParams = mlpAppBar 120 binding.toolbarAbout.layoutParams = mlpToolbar
121 121
122 val mlpScrollAbout = binding.scrollAbout.layoutParams as MarginLayoutParams 122 val mlpScrollAbout = binding.scrollAbout.layoutParams as MarginLayoutParams
123 mlpScrollAbout.leftMargin = leftInsets 123 mlpScrollAbout.leftMargin = leftInsets
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt
index 9d0594c6e..f95d545bf 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/SettingsSearchFragment.kt
@@ -40,8 +40,10 @@ class SettingsSearchFragment : Fragment() {
40 40
41 override fun onCreate(savedInstanceState: Bundle?) { 41 override fun onCreate(savedInstanceState: Bundle?) {
42 super.onCreate(savedInstanceState) 42 super.onCreate(savedInstanceState)
43 enterTransition = MaterialSharedAxis(MaterialSharedAxis.Z, false) 43 enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
44 returnTransition = MaterialSharedAxis(MaterialSharedAxis.Z, true) 44 returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
45 reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
46 exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
45 } 47 }
46 48
47 override fun onCreateView( 49 override fun onCreateView(
@@ -55,7 +57,6 @@ class SettingsSearchFragment : Fragment() {
55 57
56 override fun onViewCreated(view: View, savedInstanceState: Bundle?) { 58 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
57 super.onViewCreated(view, savedInstanceState) 59 super.onViewCreated(view, savedInstanceState)
58 settingsViewModel.setIsUsingSearch(true)
59 60
60 if (savedInstanceState != null) { 61 if (savedInstanceState != null) {
61 binding.searchText.setText(savedInstanceState.getString(SEARCH_TEXT)) 62 binding.searchText.setText(savedInstanceState.getString(SEARCH_TEXT))
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 53fa7a8de..6f947674e 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
@@ -29,9 +29,6 @@ class SettingsViewModel : ViewModel() {
29 val shouldReloadSettingsList: StateFlow<Boolean> get() = _shouldReloadSettingsList 29 val shouldReloadSettingsList: StateFlow<Boolean> get() = _shouldReloadSettingsList
30 private val _shouldReloadSettingsList = MutableStateFlow(false) 30 private val _shouldReloadSettingsList = MutableStateFlow(false)
31 31
32 val isUsingSearch: StateFlow<Boolean> get() = _isUsingSearch
33 private val _isUsingSearch = MutableStateFlow(false)
34
35 val sliderProgress: StateFlow<Int> get() = _sliderProgress 32 val sliderProgress: StateFlow<Int> get() = _sliderProgress
36 private val _sliderProgress = MutableStateFlow(-1) 33 private val _sliderProgress = MutableStateFlow(-1)
37 34
@@ -57,10 +54,6 @@ class SettingsViewModel : ViewModel() {
57 _shouldReloadSettingsList.value = value 54 _shouldReloadSettingsList.value = value
58 } 55 }
59 56
60 fun setIsUsingSearch(value: Boolean) {
61 _isUsingSearch.value = value
62 }
63
64 fun setSliderTextValue(value: Float, units: String) { 57 fun setSliderTextValue(value: Float, units: String) {
65 _sliderProgress.value = value.toInt() 58 _sliderProgress.value = value.toInt()
66 _sliderTextValue.value = String.format( 59 _sliderTextValue.value = String.format(
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
index 654d62f52..2e9b0beb8 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/GameIconUtils.kt
@@ -8,9 +8,9 @@ import android.graphics.BitmapFactory
8import android.widget.ImageView 8import android.widget.ImageView
9import androidx.core.graphics.drawable.toBitmap 9import androidx.core.graphics.drawable.toBitmap
10import androidx.core.graphics.drawable.toDrawable 10import androidx.core.graphics.drawable.toDrawable
11import androidx.lifecycle.LifecycleOwner
11import coil.ImageLoader 12import coil.ImageLoader
12import coil.decode.DataSource 13import coil.decode.DataSource
13import coil.executeBlocking
14import coil.fetch.DrawableResult 14import coil.fetch.DrawableResult
15import coil.fetch.FetchResult 15import coil.fetch.FetchResult
16import coil.fetch.Fetcher 16import coil.fetch.Fetcher
@@ -76,12 +76,13 @@ object GameIconUtils {
76 imageLoader.enqueue(request) 76 imageLoader.enqueue(request)
77 } 77 }
78 78
79 fun getGameIcon(game: Game): Bitmap { 79 suspend fun getGameIcon(lifecycleOwner: LifecycleOwner, game: Game): Bitmap {
80 val request = ImageRequest.Builder(YuzuApplication.appContext) 80 val request = ImageRequest.Builder(YuzuApplication.appContext)
81 .data(game) 81 .data(game)
82 .lifecycle(lifecycleOwner)
82 .error(R.drawable.default_icon) 83 .error(R.drawable.default_icon)
83 .build() 84 .build()
84 return imageLoader.executeBlocking(request) 85 return imageLoader.execute(request)
85 .drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888) 86 .drawable!!.toBitmap(config = Bitmap.Config.ARGB_8888)
86 } 87 }
87} 88}
diff --git a/src/android/app/src/main/jni/uisettings.h b/src/android/app/src/main/jni/uisettings.h
index 494654af7..37bc33918 100644
--- a/src/android/app/src/main/jni/uisettings.h
+++ b/src/android/app/src/main/jni/uisettings.h
@@ -13,7 +13,7 @@ struct Values {
13 Settings::Linkage linkage; 13 Settings::Linkage linkage;
14 14
15 // Android 15 // Android
16 Settings::Setting<bool> picture_in_picture{linkage, true, "picture_in_picture", 16 Settings::Setting<bool> picture_in_picture{linkage, false, "picture_in_picture",
17 Settings::Category::Android}; 17 Settings::Category::Android};
18 Settings::Setting<s32> screen_layout{linkage, 18 Settings::Setting<s32> screen_layout{linkage,
19 5, 19 5,
diff --git a/src/android/app/src/main/res/drawable/ic_audio.xml b/src/android/app/src/main/res/drawable/ic_audio.xml
new file mode 100644
index 000000000..e306c3b0c
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_audio.xml
@@ -0,0 +1,9 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportHeight="24"
5 android:viewportWidth="24">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M3,9v6h4l5,5L12,4L7,9L3,9zM16.5,12c0,-1.77 -1.02,-3.29 -2.5,-4.03v8.05c1.48,-0.73 2.5,-2.25 2.5,-4.02zM14,3.23v2.06c2.89,0.86 5,3.54 5,6.71s-2.11,5.85 -5,6.71v2.06c4.01,-0.91 7,-4.49 7,-8.77s-2.99,-7.86 -7,-8.77z" />
9</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_code.xml b/src/android/app/src/main/res/drawable/ic_code.xml
new file mode 100644
index 000000000..26f83b39b
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_code.xml
@@ -0,0 +1,9 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportWidth="960"
5 android:viewportHeight="960">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M320,720 L80,480l240,-240 57,57 -184,184 183,183 -56,56ZM640,720 L583,663 767,479 584,296 640,240 880,480 640,720Z"/>
9</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_graphics.xml b/src/android/app/src/main/res/drawable/ic_graphics.xml
new file mode 100644
index 000000000..2fdb5a4d6
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_graphics.xml
@@ -0,0 +1,9 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportWidth="960"
5 android:viewportHeight="960">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M160,840q-33,0 -56.5,-23.5T80,760v-560q0,-33 23.5,-56.5T160,120h560q33,0 56.5,23.5T800,200v80h80v80h-80v80h80v80h-80v80h80v80h-80v80q0,33 -23.5,56.5T720,840L160,840ZM160,760h560v-560L160,200v560ZM240,680h200v-160L240,520v160ZM480,400h160v-120L480,280v120ZM240,480h200v-200L240,280v200ZM480,680h160v-240L480,440v240ZM160,200v560,-560Z"/>
9</vector>
diff --git a/src/android/app/src/main/res/drawable/ic_system_settings.xml b/src/android/app/src/main/res/drawable/ic_system_settings.xml
new file mode 100644
index 000000000..7701a2bab
--- /dev/null
+++ b/src/android/app/src/main/res/drawable/ic_system_settings.xml
@@ -0,0 +1,9 @@
1<vector xmlns:android="http://schemas.android.com/apk/res/android"
2 android:width="24dp"
3 android:height="24dp"
4 android:viewportWidth="960"
5 android:viewportHeight="960">
6 <path
7 android:fillColor="?attr/colorControlNormal"
8 android:pathData="M320,960q-17,0 -28.5,-11.5T280,920q0,-17 11.5,-28.5T320,880q17,0 28.5,11.5T360,920q0,17 -11.5,28.5T320,960ZM480,960q-17,0 -28.5,-11.5T440,920q0,-17 11.5,-28.5T480,880q17,0 28.5,11.5T520,920q0,17 -11.5,28.5T480,960ZM640,960q-17,0 -28.5,-11.5T600,920q0,-17 11.5,-28.5T640,880q17,0 28.5,11.5T680,920q0,17 -11.5,28.5T640,960ZM320,800q-33,0 -56.5,-23.5T240,720v-640q0,-33 23.5,-56.5T320,0h320q33,0 56.5,23.5T720,80v640q0,33 -23.5,56.5T640,800L320,800ZM320,720h320v-40L320,680v40ZM320,600h320v-400L320,200v400ZM320,120h320v-40L320,80v40ZM320,120v-40,40ZM320,720v-40,40Z"/>
9</vector>
diff --git a/src/android/app/src/main/res/layout-w600dp/fragment_about.xml b/src/android/app/src/main/res/layout-w600dp/fragment_about.xml
new file mode 100644
index 000000000..a26ffbc73
--- /dev/null
+++ b/src/android/app/src/main/res/layout-w600dp/fragment_about.xml
@@ -0,0 +1,233 @@
1<?xml version="1.0" encoding="utf-8"?>
2<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:app="http://schemas.android.com/apk/res-auto"
4 xmlns:tools="http://schemas.android.com/tools"
5 android:id="@+id/coordinator_about"
6 android:layout_width="match_parent"
7 android:layout_height="match_parent"
8 android:background="?attr/colorSurface">
9
10 <com.google.android.material.appbar.AppBarLayout
11 android:id="@+id/appbar_about"
12 android:layout_width="match_parent"
13 android:layout_height="wrap_content"
14 android:fitsSystemWindows="true">
15
16 <com.google.android.material.appbar.MaterialToolbar
17 android:id="@+id/toolbar_about"
18 android:layout_width="match_parent"
19 android:layout_height="?attr/actionBarSize"
20 app:navigationIcon="@drawable/ic_back"
21 app:title="@string/about" />
22
23 </com.google.android.material.appbar.AppBarLayout>
24
25 <androidx.core.widget.NestedScrollView
26 android:id="@+id/scroll_about"
27 android:layout_width="match_parent"
28 android:layout_height="match_parent"
29 android:fadeScrollbars="false"
30 android:scrollbars="vertical"
31 app:layout_behavior="@string/appbar_scrolling_view_behavior">
32
33 <LinearLayout
34 android:id="@+id/content_about"
35 android:layout_width="match_parent"
36 android:layout_height="match_parent"
37 android:orientation="horizontal">
38
39 <ImageView
40 android:id="@+id/image_logo"
41 android:layout_width="200dp"
42 android:layout_height="200dp"
43 android:layout_gravity="center_horizontal"
44 android:padding="20dp"
45 android:src="@drawable/ic_yuzu_title" />
46
47 <LinearLayout
48 android:layout_width="wrap_content"
49 android:layout_height="wrap_content"
50 android:orientation="vertical">
51
52 <LinearLayout
53 android:layout_width="match_parent"
54 android:layout_height="wrap_content"
55 android:orientation="vertical"
56 android:paddingHorizontal="16dp"
57 android:paddingVertical="16dp">
58
59 <com.google.android.material.textview.MaterialTextView
60 style="@style/TextAppearance.Material3.TitleMedium"
61 android:layout_width="match_parent"
62 android:layout_height="wrap_content"
63 android:layout_marginHorizontal="24dp"
64 android:text="@string/about"
65 android:textAlignment="viewStart" />
66
67 <com.google.android.material.textview.MaterialTextView
68 style="@style/TextAppearance.Material3.BodyMedium"
69 android:layout_width="match_parent"
70 android:layout_height="wrap_content"
71 android:layout_marginHorizontal="24dp"
72 android:layout_marginTop="6dp"
73 android:text="@string/about_app_description"
74 android:textAlignment="viewStart" />
75
76 </LinearLayout>
77
78 <com.google.android.material.divider.MaterialDivider
79 android:layout_width="match_parent"
80 android:layout_height="wrap_content"
81 android:layout_marginHorizontal="20dp" />
82
83 <LinearLayout
84 android:id="@+id/button_contributors"
85 android:layout_width="match_parent"
86 android:layout_height="wrap_content"
87 android:background="?attr/selectableItemBackground"
88 android:orientation="vertical"
89 android:paddingHorizontal="16dp"
90 android:paddingVertical="16dp">
91
92 <com.google.android.material.textview.MaterialTextView
93 style="@style/TextAppearance.Material3.TitleMedium"
94 android:layout_width="match_parent"
95 android:layout_height="wrap_content"
96 android:layout_marginHorizontal="24dp"
97 android:text="@string/contributors"
98 android:textAlignment="viewStart" />
99
100 <com.google.android.material.textview.MaterialTextView
101 style="@style/TextAppearance.Material3.BodyMedium"
102 android:layout_width="match_parent"
103 android:layout_height="wrap_content"
104 android:layout_marginHorizontal="24dp"
105 android:layout_marginTop="6dp"
106 android:text="@string/contributors_description"
107 android:textAlignment="viewStart" />
108
109 </LinearLayout>
110
111 <com.google.android.material.divider.MaterialDivider
112 android:layout_width="match_parent"
113 android:layout_height="wrap_content"
114 android:layout_marginHorizontal="20dp" />
115
116 <LinearLayout
117 android:id="@+id/button_licenses"
118 android:layout_width="match_parent"
119 android:layout_height="wrap_content"
120 android:background="?attr/selectableItemBackground"
121 android:orientation="vertical"
122 android:paddingHorizontal="16dp"
123 android:paddingVertical="16dp">
124
125 <com.google.android.material.textview.MaterialTextView
126 style="@style/TextAppearance.Material3.TitleMedium"
127 android:layout_width="match_parent"
128 android:layout_height="wrap_content"
129 android:layout_marginHorizontal="24dp"
130 android:text="@string/licenses"
131 android:textAlignment="viewStart" />
132
133 <com.google.android.material.textview.MaterialTextView
134 style="@style/TextAppearance.Material3.BodyMedium"
135 android:layout_width="match_parent"
136 android:layout_height="wrap_content"
137 android:layout_marginHorizontal="24dp"
138 android:layout_marginTop="6dp"
139 android:text="@string/licenses_description"
140 android:textAlignment="viewStart" />
141
142 </LinearLayout>
143
144 <com.google.android.material.divider.MaterialDivider
145 android:layout_width="match_parent"
146 android:layout_height="wrap_content"
147 android:layout_marginHorizontal="20dp" />
148
149 <LinearLayout
150 android:id="@+id/button_build_hash"
151 android:layout_width="match_parent"
152 android:layout_height="wrap_content"
153 android:background="?attr/selectableItemBackground"
154 android:orientation="vertical"
155 android:paddingHorizontal="16dp"
156 android:paddingVertical="16dp">
157
158 <com.google.android.material.textview.MaterialTextView
159 style="@style/TextAppearance.Material3.TitleMedium"
160 android:layout_width="match_parent"
161 android:layout_height="wrap_content"
162 android:layout_marginHorizontal="24dp"
163 android:text="@string/build"
164 android:textAlignment="viewStart" />
165
166 <com.google.android.material.textview.MaterialTextView
167 android:id="@+id/text_build_hash"
168 style="@style/TextAppearance.Material3.BodyMedium"
169 android:layout_width="match_parent"
170 android:layout_height="wrap_content"
171 android:layout_marginHorizontal="24dp"
172 android:layout_marginTop="6dp"
173 android:textAlignment="viewStart"
174 tools:text="abc123" />
175
176 </LinearLayout>
177
178 <com.google.android.material.divider.MaterialDivider
179 android:layout_width="match_parent"
180 android:layout_height="wrap_content"
181 android:layout_marginHorizontal="20dp" />
182
183 <LinearLayout
184 android:layout_width="match_parent"
185 android:layout_height="wrap_content"
186 android:layout_marginHorizontal="40dp"
187 android:layout_marginTop="12dp"
188 android:layout_marginBottom="16dp"
189 android:gravity="center_horizontal"
190 android:orientation="horizontal">
191
192 <Button
193 android:id="@+id/button_discord"
194 style="?attr/materialIconButtonStyle"
195 android:layout_width="0dp"
196 android:layout_height="wrap_content"
197 android:layout_weight="1"
198 app:icon="@drawable/ic_discord"
199 app:iconGravity="textEnd"
200 app:iconSize="24dp"
201 app:iconTint="?attr/colorOnSurface" />
202
203 <Button
204 android:id="@+id/button_website"
205 style="?attr/materialIconButtonStyle"
206 android:layout_width="0dp"
207 android:layout_height="wrap_content"
208 android:layout_weight="1"
209 app:icon="@drawable/ic_website"
210 app:iconGravity="textEnd"
211 app:iconSize="24dp"
212 app:iconTint="?attr/colorOnSurface" />
213
214 <Button
215 android:id="@+id/button_github"
216 style="?attr/materialIconButtonStyle"
217 android:layout_width="0dp"
218 android:layout_height="wrap_content"
219 android:layout_weight="1"
220 app:icon="@drawable/ic_github"
221 app:iconGravity="textEnd"
222 app:iconSize="24dp"
223 app:iconTint="?attr/colorOnSurface" />
224
225 </LinearLayout>
226
227 </LinearLayout>
228
229 </LinearLayout>
230
231 </androidx.core.widget.NestedScrollView>
232
233</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/src/android/app/src/main/res/layout/card_home_option.xml b/src/android/app/src/main/res/layout/card_home_option.xml
index 6e8a232f9..cb667c928 100644
--- a/src/android/app/src/main/res/layout/card_home_option.xml
+++ b/src/android/app/src/main/res/layout/card_home_option.xml
@@ -6,8 +6,8 @@
6 android:id="@+id/option_card" 6 android:id="@+id/option_card"
7 android:layout_width="match_parent" 7 android:layout_width="match_parent"
8 android:layout_height="wrap_content" 8 android:layout_height="wrap_content"
9 android:layout_marginVertical="12dp" 9 android:layout_marginBottom="24dp"
10 android:layout_marginHorizontal="16dp" 10 android:layout_marginHorizontal="12dp"
11 android:background="?attr/selectableItemBackground" 11 android:background="?attr/selectableItemBackground"
12 android:backgroundTint="?attr/colorSurfaceVariant" 12 android:backgroundTint="?attr/colorSurfaceVariant"
13 android:clickable="true" 13 android:clickable="true"
diff --git a/src/android/app/src/main/res/layout/fragment_about.xml b/src/android/app/src/main/res/layout/fragment_about.xml
index 3e1d98451..a24f5230e 100644
--- a/src/android/app/src/main/res/layout/fragment_about.xml
+++ b/src/android/app/src/main/res/layout/fragment_about.xml
@@ -38,17 +38,17 @@
38 38
39 <ImageView 39 <ImageView
40 android:id="@+id/image_logo" 40 android:id="@+id/image_logo"
41 android:layout_width="250dp" 41 android:layout_width="150dp"
42 android:layout_height="250dp" 42 android:layout_height="150dp"
43 android:layout_marginTop="20dp" 43 android:layout_marginTop="24dp"
44 android:layout_marginBottom="28dp"
44 android:layout_gravity="center_horizontal" 45 android:layout_gravity="center_horizontal"
45 android:src="@drawable/ic_yuzu_title" /> 46 android:src="@drawable/ic_yuzu_title" />
46 47
47 <com.google.android.material.divider.MaterialDivider 48 <com.google.android.material.divider.MaterialDivider
48 android:layout_width="match_parent" 49 android:layout_width="match_parent"
49 android:layout_height="wrap_content" 50 android:layout_height="wrap_content"
50 android:layout_marginHorizontal="20dp" 51 android:layout_marginHorizontal="20dp" />
51 android:layout_marginTop="28dp" />
52 52
53 <LinearLayout 53 <LinearLayout
54 android:layout_width="match_parent" 54 android:layout_width="match_parent"
diff --git a/src/android/app/src/main/res/layout/fragment_emulation.xml b/src/android/app/src/main/res/layout/fragment_emulation.xml
index cd6360b45..5252adf54 100644
--- a/src/android/app/src/main/res/layout/fragment_emulation.xml
+++ b/src/android/app/src/main/res/layout/fragment_emulation.xml
@@ -139,7 +139,7 @@
139 139
140 <com.google.android.material.textview.MaterialTextView 140 <com.google.android.material.textview.MaterialTextView
141 android:id="@+id/show_fps_text" 141 android:id="@+id/show_fps_text"
142 style="@style/TextAppearance.Material3.BodyMedium" 142 style="@style/TextAppearance.Material3.BodySmall"
143 android:layout_width="wrap_content" 143 android:layout_width="wrap_content"
144 android:layout_height="wrap_content" 144 android:layout_height="wrap_content"
145 android:layout_gravity="left" 145 android:layout_gravity="left"
@@ -147,7 +147,8 @@
147 android:focusable="false" 147 android:focusable="false"
148 android:paddingHorizontal="20dp" 148 android:paddingHorizontal="20dp"
149 android:textColor="@android:color/white" 149 android:textColor="@android:color/white"
150 android:textSize="12sp" 150 android:shadowColor="@android:color/black"
151 android:shadowRadius="3"
151 tools:ignore="RtlHardcoded" /> 152 tools:ignore="RtlHardcoded" />
152 153
153 </FrameLayout> 154 </FrameLayout>
diff --git a/src/android/app/src/main/res/layout/fragment_home_settings.xml b/src/android/app/src/main/res/layout/fragment_home_settings.xml
index 1cb421dcb..d84093ba3 100644
--- a/src/android/app/src/main/res/layout/fragment_home_settings.xml
+++ b/src/android/app/src/main/res/layout/fragment_home_settings.xml
@@ -14,13 +14,14 @@
14 android:layout_width="match_parent" 14 android:layout_width="match_parent"
15 android:layout_height="match_parent" 15 android:layout_height="match_parent"
16 android:orientation="vertical" 16 android:orientation="vertical"
17 android:background="?attr/colorSurface"> 17 android:background="?attr/colorSurface"
18 android:paddingHorizontal="8dp">
18 19
19 <ImageView 20 <ImageView
20 android:id="@+id/logo_image" 21 android:id="@+id/logo_image"
21 android:layout_width="128dp" 22 android:layout_width="96dp"
22 android:layout_height="128dp" 23 android:layout_height="96dp"
23 android:layout_margin="64dp" 24 android:layout_marginVertical="32dp"
24 android:layout_gravity="center_horizontal" 25 android:layout_gravity="center_horizontal"
25 android:src="@drawable/ic_yuzu_full" /> 26 android:src="@drawable/ic_yuzu_full" />
26 27
diff --git a/src/android/app/src/main/res/layout/list_item_setting.xml b/src/android/app/src/main/res/layout/list_item_setting.xml
index f1037a740..544280e75 100644
--- a/src/android/app/src/main/res/layout/list_item_setting.xml
+++ b/src/android/app/src/main/res/layout/list_item_setting.xml
@@ -10,41 +10,59 @@
10 android:focusable="true" 10 android:focusable="true"
11 android:gravity="center_vertical" 11 android:gravity="center_vertical"
12 android:minHeight="72dp" 12 android:minHeight="72dp"
13 android:padding="@dimen/spacing_large"> 13 android:padding="16dp">
14 14
15 <LinearLayout 15 <LinearLayout
16 android:layout_width="match_parent" 16 android:layout_width="match_parent"
17 android:layout_height="wrap_content" 17 android:layout_height="wrap_content"
18 android:orientation="vertical"> 18 android:orientation="horizontal">
19 19
20 <com.google.android.material.textview.MaterialTextView 20 <ImageView
21 android:id="@+id/text_setting_name" 21 android:id="@+id/icon"
22 style="@style/TextAppearance.Material3.HeadlineMedium" 22 android:layout_width="24dp"
23 android:layout_width="match_parent" 23 android:layout_height="24dp"
24 android:layout_height="wrap_content" 24 android:layout_marginStart="8dp"
25 android:textAlignment="viewStart" 25 android:layout_marginEnd="24dp"
26 android:textSize="16sp" 26 android:layout_gravity="center_vertical"
27 app:lineHeight="22dp" 27 android:visibility="gone"
28 tools:text="Setting Name" /> 28 app:tint="?attr/colorOnSurface" />
29
30 <com.google.android.material.textview.MaterialTextView
31 android:id="@+id/text_setting_description"
32 style="@style/TextAppearance.Material3.BodySmall"
33 android:layout_width="match_parent"
34 android:layout_height="wrap_content"
35 android:layout_marginTop="@dimen/spacing_small"
36 android:textAlignment="viewStart"
37 tools:text="@string/app_disclaimer" />
38 29
39 <com.google.android.material.textview.MaterialTextView 30 <LinearLayout
40 android:id="@+id/text_setting_value"
41 style="@style/TextAppearance.Material3.LabelMedium"
42 android:layout_width="match_parent" 31 android:layout_width="match_parent"
43 android:layout_height="wrap_content" 32 android:layout_height="wrap_content"
44 android:layout_marginTop="@dimen/spacing_small" 33 android:orientation="vertical">
45 android:textAlignment="viewStart" 34
46 android:textStyle="bold" 35 <com.google.android.material.textview.MaterialTextView
47 tools:text="1x" /> 36 android:id="@+id/text_setting_name"
37 style="@style/TextAppearance.Material3.HeadlineMedium"
38 android:layout_width="match_parent"
39 android:layout_height="wrap_content"
40 android:textAlignment="viewStart"
41 android:textSize="17sp"
42 app:lineHeight="22dp"
43 tools:text="Setting Name" />
44
45 <com.google.android.material.textview.MaterialTextView
46 android:id="@+id/text_setting_description"
47 style="@style/TextAppearance.Material3.BodySmall"
48 android:layout_width="match_parent"
49 android:layout_height="wrap_content"
50 android:layout_marginTop="@dimen/spacing_small"
51 android:textAlignment="viewStart"
52 tools:text="@string/app_disclaimer" />
53
54 <com.google.android.material.textview.MaterialTextView
55 android:id="@+id/text_setting_value"
56 style="@style/TextAppearance.Material3.LabelMedium"
57 android:layout_width="match_parent"
58 android:layout_height="wrap_content"
59 android:layout_marginTop="@dimen/spacing_small"
60 android:textAlignment="viewStart"
61 android:textStyle="bold"
62 android:textSize="13sp"
63 tools:text="1x" />
64
65 </LinearLayout>
48 66
49 </LinearLayout> 67 </LinearLayout>
50 68
diff --git a/src/android/app/src/main/res/layout/list_item_setting_switch.xml b/src/android/app/src/main/res/layout/list_item_setting_switch.xml
index a5767adee..a8f5aff78 100644
--- a/src/android/app/src/main/res/layout/list_item_setting_switch.xml
+++ b/src/android/app/src/main/res/layout/list_item_setting_switch.xml
@@ -8,9 +8,7 @@
8 android:clickable="true" 8 android:clickable="true"
9 android:focusable="true" 9 android:focusable="true"
10 android:minHeight="72dp" 10 android:minHeight="72dp"
11 android:paddingVertical="@dimen/spacing_large" 11 android:padding="16dp">
12 android:paddingStart="@dimen/spacing_large"
13 android:paddingEnd="24dp">
14 12
15 <com.google.android.material.materialswitch.MaterialSwitch 13 <com.google.android.material.materialswitch.MaterialSwitch
16 android:id="@+id/switch_widget" 14 android:id="@+id/switch_widget"
@@ -24,7 +22,7 @@
24 android:layout_height="wrap_content" 22 android:layout_height="wrap_content"
25 android:layout_alignParentTop="true" 23 android:layout_alignParentTop="true"
26 android:layout_centerVertical="true" 24 android:layout_centerVertical="true"
27 android:layout_marginEnd="@dimen/spacing_large" 25 android:layout_marginEnd="24dp"
28 android:layout_toStartOf="@+id/switch_widget" 26 android:layout_toStartOf="@+id/switch_widget"
29 android:gravity="center_vertical" 27 android:gravity="center_vertical"
30 android:orientation="vertical"> 28 android:orientation="vertical">
@@ -35,7 +33,7 @@
35 android:layout_width="wrap_content" 33 android:layout_width="wrap_content"
36 android:layout_height="wrap_content" 34 android:layout_height="wrap_content"
37 android:textAlignment="viewStart" 35 android:textAlignment="viewStart"
38 android:textSize="16sp" 36 android:textSize="17sp"
39 app:lineHeight="28dp" 37 app:lineHeight="28dp"
40 tools:text="@string/frame_limit_enable" /> 38 tools:text="@string/frame_limit_enable" />
41 39
diff --git a/src/android/app/src/main/res/layout/list_item_settings_header.xml b/src/android/app/src/main/res/layout/list_item_settings_header.xml
index cf85bc0da..21276b19e 100644
--- a/src/android/app/src/main/res/layout/list_item_settings_header.xml
+++ b/src/android/app/src/main/res/layout/list_item_settings_header.xml
@@ -7,7 +7,8 @@
7 android:layout_height="wrap_content" 7 android:layout_height="wrap_content"
8 android:layout_gravity="start|center_vertical" 8 android:layout_gravity="start|center_vertical"
9 android:paddingHorizontal="@dimen/spacing_large" 9 android:paddingHorizontal="@dimen/spacing_large"
10 android:paddingVertical="16dp" 10 android:paddingTop="16dp"
11 android:paddingBottom="8dp"
11 android:textAlignment="viewStart" 12 android:textAlignment="viewStart"
12 android:textColor="?attr/colorPrimary" 13 android:textColor="?attr/colorPrimary"
13 android:textStyle="bold" 14 android:textStyle="bold"
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml
index dc10159c9..51bcc49a3 100644
--- a/src/android/app/src/main/res/values/arrays.xml
+++ b/src/android/app/src/main/res/values/arrays.xml
@@ -2,7 +2,6 @@
2<resources> 2<resources>
3 3
4 <string-array name="regionNames"> 4 <string-array name="regionNames">
5 <item>@string/auto</item>
6 <item>@string/region_australia</item> 5 <item>@string/region_australia</item>
7 <item>@string/region_china</item> 6 <item>@string/region_china</item>
8 <item>@string/region_europe</item> 7 <item>@string/region_europe</item>
@@ -13,7 +12,6 @@
13 </string-array> 12 </string-array>
14 13
15 <integer-array name="regionValues"> 14 <integer-array name="regionValues">
16 <item>-1</item>
17 <item>3</item> 15 <item>3</item>
18 <item>4</item> 16 <item>4</item>
19 <item>2</item> 17 <item>2</item>
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index c551a6106..98c3f20f8 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -240,6 +240,7 @@
240 <string name="shutting_down">Shutting down…</string> 240 <string name="shutting_down">Shutting down…</string>
241 <string name="reset_setting_confirmation">Do you want to reset this setting back to its default value?</string> 241 <string name="reset_setting_confirmation">Do you want to reset this setting back to its default value?</string>
242 <string name="reset_to_default">Reset to default</string> 242 <string name="reset_to_default">Reset to default</string>
243 <string name="reset_to_default_description">Resets all advanced settings</string>
243 <string name="reset_all_settings">Reset all settings?</string> 244 <string name="reset_all_settings">Reset all settings?</string>
244 <string name="reset_all_settings_description">All advanced settings will be reset to their default configuration. This can not be undone.</string> 245 <string name="reset_all_settings_description">All advanced settings will be reset to their default configuration. This can not be undone.</string>
245 <string name="settings_reset">Settings reset</string> 246 <string name="settings_reset">Settings reset</string>
@@ -271,10 +272,14 @@
271 <string name="preferences_settings">Settings</string> 272 <string name="preferences_settings">Settings</string>
272 <string name="preferences_general">General</string> 273 <string name="preferences_general">General</string>
273 <string name="preferences_system">System</string> 274 <string name="preferences_system">System</string>
275 <string name="preferences_system_description">Docked mode, region, language</string>
274 <string name="preferences_graphics">Graphics</string> 276 <string name="preferences_graphics">Graphics</string>
277 <string name="preferences_graphics_description">Accuracy level, resolution, shader cache</string>
275 <string name="preferences_audio">Audio</string> 278 <string name="preferences_audio">Audio</string>
279 <string name="preferences_audio_description">Output engine, volume</string>
276 <string name="preferences_theme">Theme and color</string> 280 <string name="preferences_theme">Theme and color</string>
277 <string name="preferences_debug">Debug</string> 281 <string name="preferences_debug">Debug</string>
282 <string name="preferences_debug_description">CPU/GPU debugging, graphics API, fastmem</string>
278 283
279 <!-- ROM loading errors --> 284 <!-- ROM loading errors -->
280 <string name="loader_error_encrypted">Your ROM is encrypted</string> 285 <string name="loader_error_encrypted">Your ROM is encrypted</string>
diff --git a/src/audio_core/sink/cubeb_sink.cpp b/src/audio_core/sink/cubeb_sink.cpp
index bbb598bc5..51a23fe15 100644
--- a/src/audio_core/sink/cubeb_sink.cpp
+++ b/src/audio_core/sink/cubeb_sink.cpp
@@ -146,7 +146,7 @@ public:
146 return; 146 return;
147 } 147 }
148 148
149 paused = true; 149 SignalPause();
150 if (cubeb_stream_stop(stream_backend) != CUBEB_OK) { 150 if (cubeb_stream_stop(stream_backend) != CUBEB_OK) {
151 LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream"); 151 LOG_CRITICAL(Audio_Sink, "Error stopping cubeb stream");
152 } 152 }
diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp
index 7b89151de..96e0efce2 100644
--- a/src/audio_core/sink/sdl2_sink.cpp
+++ b/src/audio_core/sink/sdl2_sink.cpp
@@ -111,7 +111,7 @@ public:
111 if (device == 0 || paused) { 111 if (device == 0 || paused) {
112 return; 112 return;
113 } 113 }
114 paused = true; 114 SignalPause();
115 SDL_PauseAudioDevice(device, 1); 115 SDL_PauseAudioDevice(device, 1);
116 } 116 }
117 117
diff --git a/src/audio_core/sink/sink_stream.cpp b/src/audio_core/sink/sink_stream.cpp
index d66d04fae..2a09db599 100644
--- a/src/audio_core/sink/sink_stream.cpp
+++ b/src/audio_core/sink/sink_stream.cpp
@@ -282,11 +282,19 @@ u64 SinkStream::GetExpectedPlayedSampleCount() {
282void SinkStream::WaitFreeSpace(std::stop_token stop_token) { 282void SinkStream::WaitFreeSpace(std::stop_token stop_token) {
283 std::unique_lock lk{release_mutex}; 283 std::unique_lock lk{release_mutex};
284 release_cv.wait_for(lk, std::chrono::milliseconds(5), 284 release_cv.wait_for(lk, std::chrono::milliseconds(5),
285 [this]() { return queued_buffers < max_queue_size; }); 285 [this]() { return paused || queued_buffers < max_queue_size; });
286 if (queued_buffers > max_queue_size + 3) { 286 if (queued_buffers > max_queue_size + 3) {
287 Common::CondvarWait(release_cv, lk, stop_token, 287 Common::CondvarWait(release_cv, lk, stop_token,
288 [this] { return queued_buffers < max_queue_size; }); 288 [this] { return paused || queued_buffers < max_queue_size; });
289 } 289 }
290} 290}
291 291
292void SinkStream::SignalPause() {
293 {
294 std::scoped_lock lk{release_mutex};
295 paused = true;
296 }
297 release_cv.notify_one();
298}
299
292} // namespace AudioCore::Sink 300} // namespace AudioCore::Sink
diff --git a/src/audio_core/sink/sink_stream.h b/src/audio_core/sink/sink_stream.h
index 6a4996ca3..f2ccd19b8 100644
--- a/src/audio_core/sink/sink_stream.h
+++ b/src/audio_core/sink/sink_stream.h
@@ -214,6 +214,12 @@ public:
214 void WaitFreeSpace(std::stop_token stop_token); 214 void WaitFreeSpace(std::stop_token stop_token);
215 215
216protected: 216protected:
217 /**
218 * Unblocks the ADSP if the stream is paused.
219 */
220 void SignalPause();
221
222protected:
217 /// Core system 223 /// Core system
218 Core::System& system; 224 Core::System& system;
219 /// Type of this stream 225 /// Type of this stream
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index 98b43e49c..51717be06 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -203,6 +203,8 @@ const char* TranslateCategory(Category category) {
203 case Category::Ui: 203 case Category::Ui:
204 case Category::UiGeneral: 204 case Category::UiGeneral:
205 return "UI"; 205 return "UI";
206 case Category::UiAudio:
207 return "UiAudio";
206 case Category::UiLayout: 208 case Category::UiLayout:
207 return "UiLayout"; 209 return "UiLayout";
208 case Category::UiGameList: 210 case Category::UiGameList:
diff --git a/src/common/settings.h b/src/common/settings.h
index 9317075f7..e899f1ae6 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -153,7 +153,7 @@ struct Values {
153 true, 153 true,
154 true}; 154 true};
155 Setting<bool, false> audio_muted{ 155 Setting<bool, false> audio_muted{
156 linkage, false, "audio_muted", Category::Audio, Specialization::Default, false, true}; 156 linkage, false, "audio_muted", Category::Audio, Specialization::Default, true, true};
157 Setting<bool, false> dump_audio_commands{ 157 Setting<bool, false> dump_audio_commands{
158 linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false}; 158 linkage, false, "dump_audio_commands", Category::Audio, Specialization::Default, false};
159 159
diff --git a/src/common/settings_common.h b/src/common/settings_common.h
index 1800ab10d..7943223eb 100644
--- a/src/common/settings_common.h
+++ b/src/common/settings_common.h
@@ -32,6 +32,7 @@ enum class Category : u32 {
32 AddOns, 32 AddOns,
33 Controls, 33 Controls,
34 Ui, 34 Ui,
35 UiAudio,
35 UiGeneral, 36 UiGeneral,
36 UiLayout, 37 UiLayout,
37 UiGameList, 38 UiGameList,
diff --git a/src/core/arm/arm_interface.cpp b/src/core/arm/arm_interface.cpp
index 5e27dde58..558fba5bd 100644
--- a/src/core/arm/arm_interface.cpp
+++ b/src/core/arm/arm_interface.cpp
@@ -153,6 +153,14 @@ void ARM_Interface::Run() {
153 Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())}; 153 Kernel::KThread* current_thread{Kernel::GetCurrentThreadPointer(system.Kernel())};
154 HaltReason hr{}; 154 HaltReason hr{};
155 155
156 // If the thread is scheduled for termination, exit the thread.
157 if (current_thread->HasDpc()) {
158 if (current_thread->IsTerminationRequested()) {
159 current_thread->Exit();
160 UNREACHABLE();
161 }
162 }
163
156 // Notify the debugger and go to sleep if a step was performed 164 // Notify the debugger and go to sleep if a step was performed
157 // and this thread has been scheduled again. 165 // and this thread has been scheduled again.
158 if (current_thread->GetStepState() == StepState::StepPerformed) { 166 if (current_thread->GetStepState() == StepState::StepPerformed) {
@@ -174,14 +182,6 @@ void ARM_Interface::Run() {
174 } 182 }
175 system.ExitCPUProfile(); 183 system.ExitCPUProfile();
176 184
177 // If the thread is scheduled for termination, exit the thread.
178 if (current_thread->HasDpc()) {
179 if (current_thread->IsTerminationRequested()) {
180 current_thread->Exit();
181 UNREACHABLE();
182 }
183 }
184
185 // Notify the debugger and go to sleep if a breakpoint was hit, 185 // Notify the debugger and go to sleep if a breakpoint was hit,
186 // or if the thread is unable to continue for any reason. 186 // or if the thread is unable to continue for any reason.
187 if (True(hr & HaltReason::InstructionBreakpoint) || True(hr & HaltReason::PrefetchAbort)) { 187 if (True(hr & HaltReason::InstructionBreakpoint) || True(hr & HaltReason::PrefetchAbort)) {
diff --git a/src/core/core_timing.cpp b/src/core/core_timing.cpp
index e671b270f..d6b5abc68 100644
--- a/src/core/core_timing.cpp
+++ b/src/core/core_timing.cpp
@@ -76,6 +76,7 @@ void CoreTiming::Initialize(std::function<void()>&& on_thread_init_) {
76} 76}
77 77
78void CoreTiming::ClearPendingEvents() { 78void CoreTiming::ClearPendingEvents() {
79 std::scoped_lock lock{basic_lock};
79 event_queue.clear(); 80 event_queue.clear();
80} 81}
81 82
@@ -113,6 +114,7 @@ bool CoreTiming::IsRunning() const {
113} 114}
114 115
115bool CoreTiming::HasPendingEvents() const { 116bool CoreTiming::HasPendingEvents() const {
117 std::scoped_lock lock{basic_lock};
116 return !(wait_set && event_queue.empty()); 118 return !(wait_set && event_queue.empty());
117} 119}
118 120
diff --git a/src/core/core_timing.h b/src/core/core_timing.h
index 26a8b93a7..21548f0a9 100644
--- a/src/core/core_timing.h
+++ b/src/core/core_timing.h
@@ -161,7 +161,7 @@ private:
161 std::shared_ptr<EventType> ev_lost; 161 std::shared_ptr<EventType> ev_lost;
162 Common::Event event{}; 162 Common::Event event{};
163 Common::Event pause_event{}; 163 Common::Event pause_event{};
164 std::mutex basic_lock; 164 mutable std::mutex basic_lock;
165 std::mutex advance_lock; 165 std::mutex advance_lock;
166 std::unique_ptr<std::jthread> timer_thread; 166 std::unique_ptr<std::jthread> timer_thread;
167 std::atomic<bool> paused{}; 167 std::atomic<bool> paused{};
diff --git a/src/core/hle/kernel/k_page_table_base.cpp b/src/core/hle/kernel/k_page_table_base.cpp
index 6a57ad55c..47dc8fd35 100644
--- a/src/core/hle/kernel/k_page_table_base.cpp
+++ b/src/core/hle/kernel/k_page_table_base.cpp
@@ -1617,9 +1617,9 @@ void KPageTableBase::RemapPageGroup(PageLinkedList* page_list, KProcessAddress a
1617 const KMemoryInfo info = it->GetMemoryInfo(); 1617 const KMemoryInfo info = it->GetMemoryInfo();
1618 1618
1619 // Determine the range to map. 1619 // Determine the range to map.
1620 KProcessAddress map_address = std::max(info.GetAddress(), GetInteger(start_address)); 1620 KProcessAddress map_address = std::max<u64>(info.GetAddress(), GetInteger(start_address));
1621 const KProcessAddress map_end_address = 1621 const KProcessAddress map_end_address =
1622 std::min(info.GetEndAddress(), GetInteger(end_address)); 1622 std::min<u64>(info.GetEndAddress(), GetInteger(end_address));
1623 ASSERT(map_end_address != map_address); 1623 ASSERT(map_end_address != map_address);
1624 1624
1625 // Determine if we should disable head merge. 1625 // Determine if we should disable head merge.
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 09cd8d180..c0ae6468b 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -361,6 +361,7 @@ void Config::ReadAudioValues() {
361 qt_config->beginGroup(QStringLiteral("Audio")); 361 qt_config->beginGroup(QStringLiteral("Audio"));
362 362
363 ReadCategory(Settings::Category::Audio); 363 ReadCategory(Settings::Category::Audio);
364 ReadCategory(Settings::Category::UiAudio);
364 365
365 qt_config->endGroup(); 366 qt_config->endGroup();
366} 367}
@@ -901,6 +902,7 @@ void Config::SaveAudioValues() {
901 qt_config->beginGroup(QStringLiteral("Audio")); 902 qt_config->beginGroup(QStringLiteral("Audio"));
902 903
903 WriteCategory(Settings::Category::Audio); 904 WriteCategory(Settings::Category::Audio);
905 WriteCategory(Settings::Category::UiAudio);
904 906
905 qt_config->endGroup(); 907 qt_config->endGroup();
906} 908}
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index 81dd51ad3..9b6ef47a7 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -38,17 +38,21 @@ void ConfigureAudio::Setup(const ConfigurationShared::Builder& builder) {
38 38
39 std::map<u32, QWidget*> hold; 39 std::map<u32, QWidget*> hold;
40 40
41 auto push = [&](Settings::Category category) { 41 auto push_settings = [&](Settings::Category category) {
42 for (auto* setting : Settings::values.linkage.by_category[category]) { 42 for (auto* setting : Settings::values.linkage.by_category[category]) {
43 settings.push_back(setting); 43 settings.push_back(setting);
44 } 44 }
45 };
46
47 auto push_ui_settings = [&](Settings::Category category) {
45 for (auto* setting : UISettings::values.linkage.by_category[category]) { 48 for (auto* setting : UISettings::values.linkage.by_category[category]) {
46 settings.push_back(setting); 49 settings.push_back(setting);
47 } 50 }
48 }; 51 };
49 52
50 push(Settings::Category::Audio); 53 push_settings(Settings::Category::Audio);
51 push(Settings::Category::SystemAudio); 54 push_settings(Settings::Category::SystemAudio);
55 push_ui_settings(Settings::Category::UiAudio);
52 56
53 for (auto* setting : settings) { 57 for (auto* setting : settings) {
54 auto* widget = builder.BuildWidget(setting, apply_funcs); 58 auto* widget = builder.BuildWidget(setting, apply_funcs);
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index d2a054eaa..f077d7f9c 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -1064,12 +1064,6 @@ void GMainWindow::InitializeWidgets() {
1064 volume_slider->setObjectName(QStringLiteral("volume_slider")); 1064 volume_slider->setObjectName(QStringLiteral("volume_slider"));
1065 volume_slider->setMaximum(200); 1065 volume_slider->setMaximum(200);
1066 volume_slider->setPageStep(5); 1066 volume_slider->setPageStep(5);
1067 connect(volume_slider, &QSlider::valueChanged, this, [this](int percentage) {
1068 Settings::values.audio_muted = false;
1069 const auto volume = static_cast<u8>(percentage);
1070 Settings::values.volume.SetValue(volume);
1071 UpdateVolumeUI();
1072 });
1073 volume_popup->layout()->addWidget(volume_slider); 1067 volume_popup->layout()->addWidget(volume_slider);
1074 1068
1075 volume_button = new VolumeButton(); 1069 volume_button = new VolumeButton();
@@ -1077,6 +1071,12 @@ void GMainWindow::InitializeWidgets() {
1077 volume_button->setFocusPolicy(Qt::NoFocus); 1071 volume_button->setFocusPolicy(Qt::NoFocus);
1078 volume_button->setCheckable(true); 1072 volume_button->setCheckable(true);
1079 UpdateVolumeUI(); 1073 UpdateVolumeUI();
1074 connect(volume_slider, &QSlider::valueChanged, this, [this](int percentage) {
1075 Settings::values.audio_muted = false;
1076 const auto volume = static_cast<u8>(percentage);
1077 Settings::values.volume.SetValue(volume);
1078 UpdateVolumeUI();
1079 });
1080 connect(volume_button, &QPushButton::clicked, this, [&] { 1080 connect(volume_button, &QPushButton::clicked, this, [&] {
1081 UpdateVolumeUI(); 1081 UpdateVolumeUI();
1082 volume_popup->setVisible(!volume_popup->isVisible()); 1082 volume_popup->setVisible(!volume_popup->isVisible());
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index 77d992c54..3485a6347 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -109,9 +109,13 @@ struct Values {
109 Settings::Specialization::Default, 109 Settings::Specialization::Default,
110 true, 110 true,
111 true}; 111 true};
112 Setting<bool> mute_when_in_background{ 112 Setting<bool> mute_when_in_background{linkage,
113 linkage, false, "muteWhenInBackground", Category::Audio, Settings::Specialization::Default, 113 false,
114 true, true}; 114 "muteWhenInBackground",
115 Category::UiAudio,
116 Settings::Specialization::Default,
117 true,
118 true};
115 Setting<bool> hide_mouse{ 119 Setting<bool> hide_mouse{
116 linkage, true, "hideInactiveMouse", Category::UiGeneral, Settings::Specialization::Default, 120 linkage, true, "hideInactiveMouse", Category::UiGeneral, Settings::Specialization::Default,
117 true, true}; 121 true, true};