summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/android/app/build.gradle.kts5
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/activities/EmulationActivity.kt67
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/LicenseAdapter.kt54
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/ui/KeyboardDialogFragment.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt7
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/view/SubmenuSetting.kt3
-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/utils/SettingsFile.kt9
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/AboutFragment.kt10
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt34
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicenseBottomSheetDialogFragment.kt59
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicensesFragment.kt137
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/model/License.kt16
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt4
-rw-r--r--src/android/app/src/main/res/layout/dialog_license.xml64
-rw-r--r--src/android/app/src/main/res/layout/fragment_about.xml33
-rw-r--r--src/android/app/src/main/res/layout/fragment_emulation.xml9
-rw-r--r--src/android/app/src/main/res/layout/fragment_licenses.xml30
-rw-r--r--src/android/app/src/main/res/navigation/home_navigation.xml11
-rw-r--r--src/android/app/src/main/res/values/arrays.xml52
-rw-r--r--src/android/app/src/main/res/values/strings.xml608
21 files changed, 1132 insertions, 143 deletions
diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts
index ec5f78746..06f22fabe 100644
--- a/src/android/app/build.gradle.kts
+++ b/src/android/app/build.gradle.kts
@@ -1,6 +1,8 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-3.0-or-later 2// SPDX-License-Identifier: GPL-3.0-or-later
3 3
4import android.annotation.SuppressLint
5
4plugins { 6plugins {
5 id("com.android.application") 7 id("com.android.application")
6 id("org.jetbrains.kotlin.android") 8 id("org.jetbrains.kotlin.android")
@@ -35,7 +37,7 @@ android {
35 jvmTarget = "17" 37 jvmTarget = "17"
36 } 38 }
37 39
38 packagingOptions { 40 packaging {
39 // This is necessary for libadrenotools custom driver loading 41 // This is necessary for libadrenotools custom driver loading
40 jniLibs.useLegacyPackaging = true 42 jniLibs.useLegacyPackaging = true
41 } 43 }
@@ -58,6 +60,7 @@ android {
58 versionName = getGitVersion() 60 versionName = getGitVersion()
59 61
60 ndk { 62 ndk {
63 @SuppressLint("ChromeOsAbiSupport")
61 abiFilters += listOf("arm64-v8a") 64 abiFilters += listOf("arm64-v8a")
62 } 65 }
63 66
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 81474b824..94d5156cf 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
@@ -5,7 +5,6 @@ package org.yuzu.yuzu_emu.activities
5 5
6import android.app.Activity 6import android.app.Activity
7import android.content.Context 7import android.content.Context
8import android.content.DialogInterface
9import android.content.Intent 8import android.content.Intent
10import android.content.res.Configuration 9import android.content.res.Configuration
11import android.graphics.Rect 10import android.graphics.Rect
@@ -13,22 +12,30 @@ import android.hardware.Sensor
13import android.hardware.SensorEvent 12import android.hardware.SensorEvent
14import android.hardware.SensorEventListener 13import android.hardware.SensorEventListener
15import android.hardware.SensorManager 14import android.hardware.SensorManager
15import android.hardware.display.DisplayManager
16import android.os.Bundle 16import android.os.Bundle
17import android.view.Display
17import android.view.InputDevice 18import android.view.InputDevice
18import android.view.KeyEvent 19import android.view.KeyEvent
19import android.view.MotionEvent 20import android.view.MotionEvent
20import android.view.Surface 21import android.view.Surface
21import android.view.View 22import android.view.View
22import android.view.WindowManager
23import android.view.inputmethod.InputMethodManager 23import android.view.inputmethod.InputMethodManager
24import androidx.activity.viewModels
24import androidx.appcompat.app.AppCompatActivity 25import androidx.appcompat.app.AppCompatActivity
25import androidx.preference.PreferenceManager 26import androidx.core.content.getSystemService
26import com.google.android.material.dialog.MaterialAlertDialogBuilder 27import androidx.core.view.WindowCompat
27import com.google.android.material.slider.Slider.OnChangeListener 28import androidx.core.view.WindowInsetsCompat
29import androidx.core.view.WindowInsetsControllerCompat
30import androidx.lifecycle.Lifecycle
31import androidx.lifecycle.lifecycleScope
32import androidx.lifecycle.repeatOnLifecycle
33import androidx.window.layout.WindowInfoTracker
34import kotlinx.coroutines.Dispatchers
35import kotlinx.coroutines.launch
28import org.yuzu.yuzu_emu.NativeLibrary 36import org.yuzu.yuzu_emu.NativeLibrary
29import org.yuzu.yuzu_emu.R 37import org.yuzu.yuzu_emu.R
30import org.yuzu.yuzu_emu.databinding.DialogSliderBinding 38import org.yuzu.yuzu_emu.features.settings.model.SettingsViewModel
31import org.yuzu.yuzu_emu.features.settings.model.Settings
32import org.yuzu.yuzu_emu.fragments.EmulationFragment 39import org.yuzu.yuzu_emu.fragments.EmulationFragment
33import org.yuzu.yuzu_emu.model.Game 40import org.yuzu.yuzu_emu.model.Game
34import org.yuzu.yuzu_emu.utils.ControllerMappingHelper 41import org.yuzu.yuzu_emu.utils.ControllerMappingHelper
@@ -44,7 +51,6 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
44 private var controllerMappingHelper: ControllerMappingHelper? = null 51 private var controllerMappingHelper: ControllerMappingHelper? = null
45 52
46 var isActivityRecreated = false 53 var isActivityRecreated = false
47 private var menuVisible = false
48 private var emulationFragment: EmulationFragment? = null 54 private var emulationFragment: EmulationFragment? = null
49 private lateinit var nfcReader: NfcReader 55 private lateinit var nfcReader: NfcReader
50 private lateinit var inputHandler: InputHandler 56 private lateinit var inputHandler: InputHandler
@@ -56,6 +62,8 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
56 62
57 private lateinit var game: Game 63 private lateinit var game: Game
58 64
65 private val settingsViewModel: SettingsViewModel by viewModels()
66
59 override fun onDestroy() { 67 override fun onDestroy() {
60 stopForegroundService(this) 68 stopForegroundService(this)
61 super.onDestroy() 69 super.onDestroy()
@@ -64,6 +72,8 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
64 override fun onCreate(savedInstanceState: Bundle?) { 72 override fun onCreate(savedInstanceState: Bundle?) {
65 ThemeHelper.setTheme(this) 73 ThemeHelper.setTheme(this)
66 74
75 settingsViewModel.settings.loadSettings()
76
67 super.onCreate(savedInstanceState) 77 super.onCreate(savedInstanceState)
68 if (savedInstanceState == null) { 78 if (savedInstanceState == null) {
69 // Get params we were passed 79 // Get params we were passed
@@ -98,6 +108,14 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
98 inputHandler = InputHandler() 108 inputHandler = InputHandler()
99 inputHandler.initialize() 109 inputHandler.initialize()
100 110
111 lifecycleScope.launch(Dispatchers.Main) {
112 lifecycle.repeatOnLifecycle(Lifecycle.State.STARTED) {
113 WindowInfoTracker.getOrCreate(this@EmulationActivity)
114 .windowLayoutInfo(this@EmulationActivity)
115 .collect { emulationFragment?.updateCurrentLayout(this@EmulationActivity, it) }
116 }
117 }
118
101 // Start a foreground service to prevent the app from getting killed in the background 119 // Start a foreground service to prevent the app from getting killed in the background
102 val startIntent = Intent(this, ForegroundService::class.java) 120 val startIntent = Intent(this, ForegroundService::class.java)
103 startForegroundService(startIntent) 121 startForegroundService(startIntent)
@@ -241,20 +259,20 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
241 override fun onAccuracyChanged(sensor: Sensor, i: Int) {} 259 override fun onAccuracyChanged(sensor: Sensor, i: Int) {}
242 260
243 private fun getAdjustedRotation():Int { 261 private fun getAdjustedRotation():Int {
244 val rotation = windowManager.defaultDisplay.rotation; 262 val rotation = getSystemService<DisplayManager>()!!.getDisplay(Display.DEFAULT_DISPLAY).rotation
245 val config: Configuration = resources.configuration 263 val config: Configuration = resources.configuration
246 264
247 if ((config.screenLayout and Configuration.SCREENLAYOUT_LONG_YES) != 0 || 265 if ((config.screenLayout and Configuration.SCREENLAYOUT_LONG_YES) != 0 ||
248 (config.screenLayout and Configuration.SCREENLAYOUT_LONG_NO) == 0) { 266 (config.screenLayout and Configuration.SCREENLAYOUT_LONG_NO) == 0) {
249 return rotation; 267 return rotation
250 } 268 }
251 when (rotation) { 269 when (rotation) {
252 Surface.ROTATION_0 -> return Surface.ROTATION_90; 270 Surface.ROTATION_0 -> return Surface.ROTATION_90
253 Surface.ROTATION_90 -> return Surface.ROTATION_0; 271 Surface.ROTATION_90 -> return Surface.ROTATION_0
254 Surface.ROTATION_180 -> return Surface.ROTATION_270; 272 Surface.ROTATION_180 -> return Surface.ROTATION_270
255 Surface.ROTATION_270 -> return Surface.ROTATION_180; 273 Surface.ROTATION_270 -> return Surface.ROTATION_180
256 } 274 }
257 return rotation; 275 return rotation
258 } 276 }
259 277
260 private fun restoreState(savedInstanceState: Bundle) { 278 private fun restoreState(savedInstanceState: Bundle) {
@@ -262,18 +280,13 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
262 } 280 }
263 281
264 private fun enableFullscreenImmersive() { 282 private fun enableFullscreenImmersive() {
265 window.attributes.layoutInDisplayCutoutMode = 283 WindowCompat.setDecorFitsSystemWindows(window, false)
266 WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES 284
267 285 WindowInsetsControllerCompat(window, window.decorView).let { controller ->
268 window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) 286 controller.hide(WindowInsetsCompat.Type.systemBars())
269 287 controller.systemBarsBehavior =
270 // It would be nice to use IMMERSIVE_STICKY, but that doesn't show the toolbar. 288 WindowInsetsControllerCompat.BEHAVIOR_SHOW_TRANSIENT_BARS_BY_SWIPE
271 window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_LAYOUT_STABLE or 289 }
272 View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION or
273 View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN or
274 View.SYSTEM_UI_FLAG_HIDE_NAVIGATION or
275 View.SYSTEM_UI_FLAG_FULLSCREEN or
276 View.SYSTEM_UI_FLAG_IMMERSIVE
277 } 290 }
278 291
279 private fun startMotionSensorListener() { 292 private fun startMotionSensorListener() {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/LicenseAdapter.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/LicenseAdapter.kt
new file mode 100644
index 000000000..7006651d0
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/adapters/LicenseAdapter.kt
@@ -0,0 +1,54 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.adapters
5
6import android.view.LayoutInflater
7import android.view.View
8import android.view.ViewGroup
9import androidx.appcompat.app.AppCompatActivity
10import androidx.recyclerview.widget.RecyclerView
11import androidx.recyclerview.widget.RecyclerView.ViewHolder
12import org.yuzu.yuzu_emu.YuzuApplication
13import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding
14import org.yuzu.yuzu_emu.fragments.LicenseBottomSheetDialogFragment
15import org.yuzu.yuzu_emu.model.License
16
17class LicenseAdapter(private val activity: AppCompatActivity, var licenses: List<License>) :
18 RecyclerView.Adapter<LicenseAdapter.LicenseViewHolder>(),
19 View.OnClickListener {
20 override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): LicenseViewHolder {
21 val binding =
22 ListItemSettingBinding.inflate(LayoutInflater.from(parent.context), parent, false)
23 binding.root.setOnClickListener(this)
24 return LicenseViewHolder(binding)
25 }
26
27 override fun getItemCount(): Int = licenses.size
28
29 override fun onBindViewHolder(holder: LicenseViewHolder, position: Int) {
30 holder.bind(licenses[position])
31 }
32
33 override fun onClick(view: View) {
34 val license = (view.tag as LicenseViewHolder).license
35 LicenseBottomSheetDialogFragment.newInstance(license)
36 .show(activity.supportFragmentManager, LicenseBottomSheetDialogFragment.TAG)
37 }
38
39 inner class LicenseViewHolder(val binding: ListItemSettingBinding) : ViewHolder(binding.root) {
40 lateinit var license: License
41
42 init {
43 itemView.tag = this
44 }
45
46 fun bind(license: License) {
47 this.license = license
48
49 val context = YuzuApplication.appContext
50 binding.textSettingName.text = context.getString(license.titleId)
51 binding.textSettingDescription.text = context.getString(license.descriptionId)
52 }
53 }
54}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/ui/KeyboardDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/ui/KeyboardDialogFragment.kt
index 4b12809bc..607a3d506 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/ui/KeyboardDialogFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/applets/keyboard/ui/KeyboardDialogFragment.kt
@@ -63,7 +63,7 @@ class KeyboardDialogFragment : DialogFragment() {
63 val headerText = 63 val headerText =
64 config.header_text!!.ifEmpty { resources.getString(R.string.software_keyboard) } 64 config.header_text!!.ifEmpty { resources.getString(R.string.software_keyboard) }
65 val okText = 65 val okText =
66 config.ok_text!!.ifEmpty { resources.getString(android.R.string.ok) } 66 config.ok_text!!.ifEmpty { resources.getString(R.string.submit) }
67 67
68 return MaterialAlertDialogBuilder(requireContext()) 68 return MaterialAlertDialogBuilder(requireContext())
69 .setTitle(headerText) 69 .setTitle(headerText)
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 23c31e13a..8df20b928 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
@@ -39,7 +39,7 @@ class Settings {
39 val isEmpty: Boolean 39 val isEmpty: Boolean
40 get() = sections.isEmpty() 40 get() = sections.isEmpty()
41 41
42 fun loadSettings(view: SettingsActivityView) { 42 fun loadSettings(view: SettingsActivityView? = null) {
43 sections = SettingsSectionMap() 43 sections = SettingsSectionMap()
44 loadYuzuSettings(view) 44 loadYuzuSettings(view)
45 if (!TextUtils.isEmpty(gameId)) { 45 if (!TextUtils.isEmpty(gameId)) {
@@ -48,13 +48,13 @@ class Settings {
48 isLoaded = true 48 isLoaded = true
49 } 49 }
50 50
51 private fun loadYuzuSettings(view: SettingsActivityView) { 51 private fun loadYuzuSettings(view: SettingsActivityView?) {
52 for ((fileName) in configFileSectionsMap) { 52 for ((fileName) in configFileSectionsMap) {
53 sections.putAll(SettingsFile.readFile(fileName, view)) 53 sections.putAll(SettingsFile.readFile(fileName, view))
54 } 54 }
55 } 55 }
56 56
57 private fun loadCustomGameSettings(gameId: String, view: SettingsActivityView) { 57 private fun loadCustomGameSettings(gameId: String, view: SettingsActivityView?) {
58 // Custom game settings 58 // Custom game settings
59 mergeSections(SettingsFile.readCustomGameSettings(gameId, view)) 59 mergeSections(SettingsFile.readCustomGameSettings(gameId, view))
60 } 60 }
@@ -108,6 +108,7 @@ class Settings {
108 const val SECTION_AUDIO = "Audio" 108 const val SECTION_AUDIO = "Audio"
109 const val SECTION_CPU = "Cpu" 109 const val SECTION_CPU = "Cpu"
110 const val SECTION_THEME = "Theme" 110 const val SECTION_THEME = "Theme"
111 const val SECTION_DEBUG = "Debug"
111 112
112 const val PREF_OVERLAY_INIT = "OverlayInit" 113 const val PREF_OVERLAY_INIT = "OverlayInit"
113 const val PREF_CONTROL_SCALE = "controlScale" 114 const val PREF_CONTROL_SCALE = "controlScale"
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 8c1af6396..a3ef59c2f 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
@@ -6,10 +6,9 @@ package org.yuzu.yuzu_emu.features.settings.model.view
6import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting 6import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
7 7
8class SubmenuSetting( 8class SubmenuSetting(
9 setting: AbstractSetting?,
10 titleId: Int, 9 titleId: Int,
11 descriptionId: Int, 10 descriptionId: Int,
12 val menuKey: String 11 val menuKey: String
13) : SettingsItem(setting, titleId, descriptionId) { 12) : SettingsItem(null, titleId, descriptionId) {
14 override val type = TYPE_SUBMENU 13 override val type = TYPE_SUBMENU
15} 14}
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 7d55c5b2f..061046b2e 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
@@ -68,6 +68,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
68 Settings.SECTION_RENDERER -> addGraphicsSettings(sl) 68 Settings.SECTION_RENDERER -> addGraphicsSettings(sl)
69 Settings.SECTION_AUDIO -> addAudioSettings(sl) 69 Settings.SECTION_AUDIO -> addAudioSettings(sl)
70 Settings.SECTION_THEME -> addThemeSettings(sl) 70 Settings.SECTION_THEME -> addThemeSettings(sl)
71 Settings.SECTION_DEBUG -> addDebugSettings(sl)
71 else -> { 72 else -> {
72 fragmentView.showToastMessage("Unimplemented menu", false) 73 fragmentView.showToastMessage("Unimplemented menu", false)
73 return 74 return
@@ -78,11 +79,10 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
78 } 79 }
79 80
80 private fun addConfigSettings(sl: ArrayList<SettingsItem>) { 81 private fun addConfigSettings(sl: ArrayList<SettingsItem>) {
81 settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_advanced_settings)) 82 settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.advanced_settings))
82 sl.apply { 83 sl.apply {
83 add( 84 add(
84 SubmenuSetting( 85 SubmenuSetting(
85 null,
86 R.string.preferences_general, 86 R.string.preferences_general,
87 0, 87 0,
88 Settings.SECTION_GENERAL 88 Settings.SECTION_GENERAL
@@ -90,7 +90,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
90 ) 90 )
91 add( 91 add(
92 SubmenuSetting( 92 SubmenuSetting(
93 null,
94 R.string.preferences_system, 93 R.string.preferences_system,
95 0, 94 0,
96 Settings.SECTION_SYSTEM 95 Settings.SECTION_SYSTEM
@@ -98,7 +97,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
98 ) 97 )
99 add( 98 add(
100 SubmenuSetting( 99 SubmenuSetting(
101 null,
102 R.string.preferences_graphics, 100 R.string.preferences_graphics,
103 0, 101 0,
104 Settings.SECTION_RENDERER 102 Settings.SECTION_RENDERER
@@ -106,13 +104,19 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
106 ) 104 )
107 add( 105 add(
108 SubmenuSetting( 106 SubmenuSetting(
109 null,
110 R.string.preferences_audio, 107 R.string.preferences_audio,
111 0, 108 0,
112 Settings.SECTION_AUDIO 109 Settings.SECTION_AUDIO
113 ) 110 )
114 ) 111 )
115 add( 112 add(
113 SubmenuSetting(
114 R.string.preferences_debug,
115 0,
116 Settings.SECTION_DEBUG
117 )
118 )
119 add(
116 RunnableSetting( 120 RunnableSetting(
117 R.string.reset_to_default, 121 R.string.reset_to_default,
118 0, 122 0,
@@ -223,17 +227,7 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
223 private fun addGraphicsSettings(sl: ArrayList<SettingsItem>) { 227 private fun addGraphicsSettings(sl: ArrayList<SettingsItem>) {
224 settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_graphics)) 228 settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_graphics))
225 sl.apply { 229 sl.apply {
226 add( 230
227 SingleChoiceSetting(
228 IntSetting.RENDERER_BACKEND,
229 R.string.renderer_api,
230 0,
231 R.array.rendererApiNames,
232 R.array.rendererApiValues,
233 IntSetting.RENDERER_BACKEND.key,
234 IntSetting.RENDERER_BACKEND.defaultValue
235 )
236 )
237 add( 231 add(
238 SingleChoiceSetting( 232 SingleChoiceSetting(
239 IntSetting.RENDERER_ACCURACY, 233 IntSetting.RENDERER_ACCURACY,
@@ -327,15 +321,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
327 IntSetting.RENDERER_ASYNCHRONOUS_SHADERS.defaultValue 321 IntSetting.RENDERER_ASYNCHRONOUS_SHADERS.defaultValue
328 ) 322 )
329 ) 323 )
330 add(
331 SwitchSetting(
332 IntSetting.RENDERER_DEBUG,
333 R.string.renderer_debug,
334 R.string.renderer_debug_description,
335 IntSetting.RENDERER_DEBUG.key,
336 IntSetting.RENDERER_DEBUG.defaultValue
337 )
338 )
339 } 324 }
340 } 325 }
341 326
@@ -451,4 +436,30 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
451 ) 436 )
452 } 437 }
453 } 438 }
439
440 private fun addDebugSettings(sl: ArrayList<SettingsItem>) {
441 settingsActivity.setToolbarTitle(settingsActivity.getString(R.string.preferences_debug))
442 sl.apply {
443 add(
444 SingleChoiceSetting(
445 IntSetting.RENDERER_BACKEND,
446 R.string.renderer_api,
447 0,
448 R.array.rendererApiNames,
449 R.array.rendererApiValues,
450 IntSetting.RENDERER_BACKEND.key,
451 IntSetting.RENDERER_BACKEND.defaultValue
452 )
453 )
454 add(
455 SwitchSetting(
456 IntSetting.RENDERER_DEBUG,
457 R.string.renderer_debug,
458 R.string.renderer_debug_description,
459 IntSetting.RENDERER_DEBUG.key,
460 IntSetting.RENDERER_DEBUG.defaultValue
461 )
462 )
463 }
464 }
454} 465}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
index c502fdca0..e29bca11d 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
@@ -37,7 +37,7 @@ object SettingsFile {
37 private fun readFile( 37 private fun readFile(
38 ini: File?, 38 ini: File?,
39 isCustomGame: Boolean, 39 isCustomGame: Boolean,
40 view: SettingsActivityView? 40 view: SettingsActivityView? = null
41 ): HashMap<String, SettingSection?> { 41 ): HashMap<String, SettingSection?> {
42 val sections: HashMap<String, SettingSection?> = SettingsSectionMap() 42 val sections: HashMap<String, SettingSection?> = SettingsSectionMap()
43 var reader: BufferedReader? = null 43 var reader: BufferedReader? = null
@@ -74,10 +74,13 @@ object SettingsFile {
74 return sections 74 return sections
75 } 75 }
76 76
77 fun readFile(fileName: String, view: SettingsActivityView): HashMap<String, SettingSection?> { 77 fun readFile(fileName: String, view: SettingsActivityView?): HashMap<String, SettingSection?> {
78 return readFile(getSettingsFile(fileName), false, view) 78 return readFile(getSettingsFile(fileName), false, view)
79 } 79 }
80 80
81 fun readFile(fileName: String): HashMap<String, SettingSection?> =
82 readFile(getSettingsFile(fileName), false)
83
81 /** 84 /**
82 * Reads a given .ini file from disk and returns it as a HashMap of SettingSections, themselves 85 * Reads a given .ini file from disk and returns it as a HashMap of SettingSections, themselves
83 * effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it 86 * effectively a HashMap of key/value settings. If unsuccessful, outputs an error telling why it
@@ -88,7 +91,7 @@ object SettingsFile {
88 */ 91 */
89 fun readCustomGameSettings( 92 fun readCustomGameSettings(
90 gameId: String, 93 gameId: String,
91 view: SettingsActivityView 94 view: SettingsActivityView?
92 ): HashMap<String, SettingSection?> { 95 ): HashMap<String, SettingSection?> {
93 return readFile(getCustomGameSettingsFile(gameId), true, view) 96 return readFile(getCustomGameSettingsFile(gameId), true, view)
94 } 97 }
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 0314feff6..c92e2755c 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
@@ -15,13 +15,12 @@ import android.view.View
15import android.view.ViewGroup 15import android.view.ViewGroup
16import android.view.ViewGroup.MarginLayoutParams 16import android.view.ViewGroup.MarginLayoutParams
17import android.widget.Toast 17import android.widget.Toast
18import androidx.core.content.ContextCompat
19import androidx.core.view.ViewCompat 18import androidx.core.view.ViewCompat
20import androidx.core.view.WindowInsetsCompat 19import androidx.core.view.WindowInsetsCompat
21import androidx.core.view.updatePadding 20import androidx.core.view.updatePadding
22import androidx.fragment.app.Fragment 21import androidx.fragment.app.Fragment
23import androidx.fragment.app.activityViewModels 22import androidx.fragment.app.activityViewModels
24import androidx.navigation.fragment.findNavController 23import androidx.navigation.findNavController
25import com.google.android.material.transition.MaterialSharedAxis 24import com.google.android.material.transition.MaterialSharedAxis
26import org.yuzu.yuzu_emu.BuildConfig 25import org.yuzu.yuzu_emu.BuildConfig
27import org.yuzu.yuzu_emu.R 26import org.yuzu.yuzu_emu.R
@@ -38,6 +37,7 @@ class AboutFragment : Fragment() {
38 super.onCreate(savedInstanceState) 37 super.onCreate(savedInstanceState)
39 enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true) 38 enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
40 returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false) 39 returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
40 reenterTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
41 } 41 }
42 42
43 override fun onCreateView( 43 override fun onCreateView(
@@ -54,7 +54,7 @@ class AboutFragment : Fragment() {
54 homeViewModel.setStatusBarShadeVisibility(visible = false) 54 homeViewModel.setStatusBarShadeVisibility(visible = false)
55 55
56 binding.toolbarAbout.setNavigationOnClickListener { 56 binding.toolbarAbout.setNavigationOnClickListener {
57 parentFragmentManager.primaryNavigationFragment?.findNavController()?.popBackStack() 57 binding.root.findNavController().popBackStack()
58 } 58 }
59 59
60 binding.imageLogo.setOnLongClickListener { 60 binding.imageLogo.setOnLongClickListener {
@@ -67,6 +67,10 @@ class AboutFragment : Fragment() {
67 } 67 }
68 68
69 binding.buttonContributors.setOnClickListener { openLink(getString(R.string.contributors_link)) } 69 binding.buttonContributors.setOnClickListener { openLink(getString(R.string.contributors_link)) }
70 binding.buttonLicenses.setOnClickListener {
71 exitTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
72 binding.root.findNavController().navigate(R.id.action_aboutFragment_to_licensesFragment)
73 }
70 74
71 binding.textBuildHash.text = BuildConfig.GIT_HASH 75 binding.textBuildHash.text = BuildConfig.GIT_HASH
72 binding.buttonBuildHash.setOnClickListener { 76 binding.buttonBuildHash.setOnClickListener {
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
index e00f02f86..41b1a6e23 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/EmulationFragment.kt
@@ -8,10 +8,13 @@ import android.app.AlertDialog
8import android.content.Context 8import android.content.Context
9import android.content.DialogInterface 9import android.content.DialogInterface
10import android.content.SharedPreferences 10import android.content.SharedPreferences
11import android.content.pm.ActivityInfo
12import android.content.res.Resources
11import android.graphics.Color 13import android.graphics.Color
12import android.os.Bundle 14import android.os.Bundle
13import android.os.Handler 15import android.os.Handler
14import android.os.Looper 16import android.os.Looper
17import android.util.TypedValue
15import android.view.* 18import android.view.*
16import android.widget.TextView 19import android.widget.TextView
17import androidx.activity.OnBackPressedCallback 20import androidx.activity.OnBackPressedCallback
@@ -20,8 +23,11 @@ import androidx.core.content.res.ResourcesCompat
20import androidx.core.graphics.Insets 23import androidx.core.graphics.Insets
21import androidx.core.view.ViewCompat 24import androidx.core.view.ViewCompat
22import androidx.core.view.WindowInsetsCompat 25import androidx.core.view.WindowInsetsCompat
26import androidx.core.view.updatePadding
23import androidx.fragment.app.Fragment 27import androidx.fragment.app.Fragment
24import androidx.preference.PreferenceManager 28import androidx.preference.PreferenceManager
29import androidx.window.layout.FoldingFeature
30import androidx.window.layout.WindowLayoutInfo
25import com.google.android.material.dialog.MaterialAlertDialogBuilder 31import com.google.android.material.dialog.MaterialAlertDialogBuilder
26import com.google.android.material.slider.Slider 32import com.google.android.material.slider.Slider
27import org.yuzu.yuzu_emu.NativeLibrary 33import org.yuzu.yuzu_emu.NativeLibrary
@@ -211,6 +217,33 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
211 } 217 }
212 } 218 }
213 219
220 private val Number.toPx get() = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, this.toFloat(), Resources.getSystem().displayMetrics).toInt()
221
222 fun updateCurrentLayout(emulationActivity: EmulationActivity, newLayoutInfo: WindowLayoutInfo) {
223 val isFolding = (newLayoutInfo.displayFeatures.find { it is FoldingFeature } as? FoldingFeature)?.let {
224 if (it.isSeparating) {
225 emulationActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
226 if (it.orientation == FoldingFeature.Orientation.HORIZONTAL) {
227 binding.surfaceEmulation.layoutParams.height = it.bounds.top
228 binding.inGameMenu.layoutParams.height = it.bounds.bottom
229 binding.overlayContainer.layoutParams.height = it.bounds.bottom - 48.toPx
230 binding.overlayContainer.updatePadding(0, 0, 0, 24.toPx)
231 }
232 }
233 it.isSeparating
234 } ?: false
235 if (!isFolding) {
236 binding.surfaceEmulation.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
237 binding.inGameMenu.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
238 binding.overlayContainer.layoutParams.height = ViewGroup.LayoutParams.MATCH_PARENT
239 binding.overlayContainer.updatePadding(0, 0, 0, 0)
240 emulationActivity.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
241 }
242 binding.surfaceInputOverlay.requestLayout()
243 binding.inGameMenu.requestLayout()
244 binding.overlayContainer.requestLayout()
245 }
246
214 override fun surfaceCreated(holder: SurfaceHolder) { 247 override fun surfaceCreated(holder: SurfaceHolder) {
215 // We purposely don't do anything here. 248 // We purposely don't do anything here.
216 // All work is done in surfaceChanged, which we are guaranteed to get even for surface creation. 249 // All work is done in surfaceChanged, which we are guaranteed to get even for surface creation.
@@ -281,6 +314,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
281 .setPositiveButton(android.R.string.ok) { _, _ -> 314 .setPositiveButton(android.R.string.ok) { _, _ ->
282 refreshInputOverlay() 315 refreshInputOverlay()
283 } 316 }
317 .setNegativeButton(android.R.string.cancel, null)
284 .setNeutralButton(R.string.emulation_toggle_all) { _, _ -> } 318 .setNeutralButton(R.string.emulation_toggle_all) { _, _ -> }
285 .show() 319 .show()
286 320
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicenseBottomSheetDialogFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicenseBottomSheetDialogFragment.kt
new file mode 100644
index 000000000..78419191c
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicenseBottomSheetDialogFragment.kt
@@ -0,0 +1,59 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.fragments
5
6import android.os.Bundle
7import android.view.LayoutInflater
8import android.view.View
9import android.view.ViewGroup
10import com.google.android.material.bottomsheet.BottomSheetBehavior
11import com.google.android.material.bottomsheet.BottomSheetDialogFragment
12import org.yuzu.yuzu_emu.databinding.DialogLicenseBinding
13import org.yuzu.yuzu_emu.model.License
14import org.yuzu.yuzu_emu.utils.SerializableHelper.parcelable
15
16class LicenseBottomSheetDialogFragment : BottomSheetDialogFragment() {
17 private var _binding: DialogLicenseBinding? = null
18 private val binding get() = _binding!!
19
20 override fun onCreateView(
21 inflater: LayoutInflater,
22 container: ViewGroup?,
23 savedInstanceState: Bundle?
24 ): View {
25 _binding = DialogLicenseBinding.inflate(layoutInflater)
26 return binding.root
27 }
28
29 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
30 super.onViewCreated(view, savedInstanceState)
31 BottomSheetBehavior.from<View>(view.parent as View).state =
32 BottomSheetBehavior.STATE_HALF_EXPANDED
33
34 val license = requireArguments().parcelable<License>(LICENSE)!!
35
36 binding.apply {
37 textTitle.setText(license.titleId)
38 textLink.setText(license.linkId)
39 textCopyright.setText(license.copyrightId)
40 textLicense.setText(license.licenseId)
41 }
42 }
43
44 companion object {
45 const val TAG = "LicenseBottomSheetDialogFragment"
46
47 const val LICENSE = "License"
48
49 fun newInstance(
50 license: License
51 ): LicenseBottomSheetDialogFragment {
52 val dialog = LicenseBottomSheetDialogFragment()
53 val bundle = Bundle()
54 bundle.putParcelable(LICENSE, license)
55 dialog.arguments = bundle
56 return dialog
57 }
58 }
59}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicensesFragment.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicensesFragment.kt
new file mode 100644
index 000000000..59141e823
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/fragments/LicensesFragment.kt
@@ -0,0 +1,137 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.fragments
5
6import android.os.Bundle
7import android.view.LayoutInflater
8import android.view.View
9import android.view.ViewGroup
10import android.view.ViewGroup.MarginLayoutParams
11import androidx.appcompat.app.AppCompatActivity
12import androidx.core.view.ViewCompat
13import androidx.core.view.WindowInsetsCompat
14import androidx.core.view.updatePadding
15import androidx.fragment.app.Fragment
16import androidx.fragment.app.activityViewModels
17import androidx.navigation.findNavController
18import androidx.recyclerview.widget.LinearLayoutManager
19import com.google.android.material.transition.MaterialSharedAxis
20import org.yuzu.yuzu_emu.R
21import org.yuzu.yuzu_emu.adapters.LicenseAdapter
22import org.yuzu.yuzu_emu.databinding.FragmentLicensesBinding
23import org.yuzu.yuzu_emu.model.HomeViewModel
24import org.yuzu.yuzu_emu.model.License
25
26class LicensesFragment : Fragment() {
27 private var _binding: FragmentLicensesBinding? = null
28 private val binding get() = _binding!!
29
30 private val homeViewModel: HomeViewModel by activityViewModels()
31
32 override fun onCreate(savedInstanceState: Bundle?) {
33 super.onCreate(savedInstanceState)
34 enterTransition = MaterialSharedAxis(MaterialSharedAxis.X, true)
35 returnTransition = MaterialSharedAxis(MaterialSharedAxis.X, false)
36 }
37
38 override fun onCreateView(
39 inflater: LayoutInflater,
40 container: ViewGroup?,
41 savedInstanceState: Bundle?
42 ): View {
43 _binding = FragmentLicensesBinding.inflate(layoutInflater)
44 return binding.root
45 }
46
47 override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
48 homeViewModel.setNavigationVisibility(visible = false, animated = true)
49 homeViewModel.setStatusBarShadeVisibility(visible = false)
50
51 binding.toolbarLicenses.setNavigationOnClickListener {
52 binding.root.findNavController().popBackStack()
53 }
54
55 val licenses = listOf(
56 License(
57 R.string.license_fidelityfx_fsr,
58 R.string.license_fidelityfx_fsr_description,
59 R.string.license_fidelityfx_fsr_link,
60 R.string.license_fidelityfx_fsr_copyright,
61 R.string.license_fidelityfx_fsr_text
62 ),
63 License(
64 R.string.license_cubeb,
65 R.string.license_cubeb_description,
66 R.string.license_cubeb_link,
67 R.string.license_cubeb_copyright,
68 R.string.license_cubeb_text
69 ),
70 License(
71 R.string.license_dynarmic,
72 R.string.license_dynarmic_description,
73 R.string.license_dynarmic_link,
74 R.string.license_dynarmic_copyright,
75 R.string.license_dynarmic_text
76 ),
77 License(
78 R.string.license_ffmpeg,
79 R.string.license_ffmpeg_description,
80 R.string.license_ffmpeg_link,
81 R.string.license_ffmpeg_copyright,
82 R.string.license_ffmpeg_text
83 ),
84 License(
85 R.string.license_opus,
86 R.string.license_opus_description,
87 R.string.license_opus_link,
88 R.string.license_opus_copyright,
89 R.string.license_opus_text
90 ),
91 License(
92 R.string.license_sirit,
93 R.string.license_sirit_description,
94 R.string.license_sirit_link,
95 R.string.license_sirit_copyright,
96 R.string.license_sirit_text
97 ),
98 License(
99 R.string.license_adreno_tools,
100 R.string.license_adreno_tools_description,
101 R.string.license_adreno_tools_link,
102 R.string.license_adreno_tools_copyright,
103 R.string.license_adreno_tools_text
104 )
105 )
106
107 binding.listLicenses.apply {
108 layoutManager = LinearLayoutManager(requireContext())
109 adapter = LicenseAdapter(requireActivity() as AppCompatActivity, licenses)
110 }
111
112 setInsets()
113 }
114
115 private fun setInsets() =
116 ViewCompat.setOnApplyWindowInsetsListener(binding.root) { _: View, windowInsets: WindowInsetsCompat ->
117 val barInsets = windowInsets.getInsets(WindowInsetsCompat.Type.systemBars())
118 val cutoutInsets = windowInsets.getInsets(WindowInsetsCompat.Type.displayCutout())
119
120 val leftInsets = barInsets.left + cutoutInsets.left
121 val rightInsets = barInsets.right + cutoutInsets.right
122
123 val mlpAppBar = binding.appbarLicenses.layoutParams as MarginLayoutParams
124 mlpAppBar.leftMargin = leftInsets
125 mlpAppBar.rightMargin = rightInsets
126 binding.appbarLicenses.layoutParams = mlpAppBar
127
128 val mlpScrollAbout = binding.listLicenses.layoutParams as MarginLayoutParams
129 mlpScrollAbout.leftMargin = leftInsets
130 mlpScrollAbout.rightMargin = rightInsets
131 binding.listLicenses.layoutParams = mlpScrollAbout
132
133 binding.listLicenses.updatePadding(bottom = barInsets.bottom)
134
135 windowInsets
136 }
137}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/License.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/License.kt
new file mode 100644
index 000000000..f24d5cf34
--- /dev/null
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/model/License.kt
@@ -0,0 +1,16 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4package org.yuzu.yuzu_emu.model
5
6import android.os.Parcelable
7import kotlinx.parcelize.Parcelize
8
9@Parcelize
10data class License(
11 val titleId: Int,
12 val descriptionId: Int,
13 val linkId: Int,
14 val copyrightId: Int,
15 val licenseId: Int
16) : Parcelable
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
index 6805efb55..124f62f08 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
@@ -35,6 +35,7 @@ import org.yuzu.yuzu_emu.activities.EmulationActivity
35import org.yuzu.yuzu_emu.databinding.ActivityMainBinding 35import org.yuzu.yuzu_emu.databinding.ActivityMainBinding
36import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding 36import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding
37import org.yuzu.yuzu_emu.features.settings.model.Settings 37import org.yuzu.yuzu_emu.features.settings.model.Settings
38import org.yuzu.yuzu_emu.features.settings.model.SettingsViewModel
38import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity 39import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity
39import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile 40import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
40import org.yuzu.yuzu_emu.fragments.IndeterminateProgressDialogFragment 41import org.yuzu.yuzu_emu.fragments.IndeterminateProgressDialogFragment
@@ -51,6 +52,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
51 52
52 private val homeViewModel: HomeViewModel by viewModels() 53 private val homeViewModel: HomeViewModel by viewModels()
53 private val gamesViewModel: GamesViewModel by viewModels() 54 private val gamesViewModel: GamesViewModel by viewModels()
55 private val settingsViewModel: SettingsViewModel by viewModels()
54 56
55 override var themeId: Int = 0 57 override var themeId: Int = 0
56 58
@@ -58,6 +60,8 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
58 val splashScreen = installSplashScreen() 60 val splashScreen = installSplashScreen()
59 splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady } 61 splashScreen.setKeepOnScreenCondition { !DirectoryInitialization.areDirectoriesReady }
60 62
63 settingsViewModel.settings.loadSettings()
64
61 ThemeHelper.setTheme(this) 65 ThemeHelper.setTheme(this)
62 66
63 super.onCreate(savedInstanceState) 67 super.onCreate(savedInstanceState)
diff --git a/src/android/app/src/main/res/layout/dialog_license.xml b/src/android/app/src/main/res/layout/dialog_license.xml
new file mode 100644
index 000000000..866857562
--- /dev/null
+++ b/src/android/app/src/main/res/layout/dialog_license.xml
@@ -0,0 +1,64 @@
1<?xml version="1.0" encoding="utf-8"?>
2<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
3 android:layout_width="match_parent"
4 android:layout_height="match_parent"
5 xmlns:tools="http://schemas.android.com/tools">
6
7 <androidx.core.widget.NestedScrollView
8 android:layout_width="match_parent"
9 android:layout_height="wrap_content">
10
11 <LinearLayout
12 android:layout_width="match_parent"
13 android:layout_height="wrap_content"
14 android:orientation="vertical"
15 android:layout_marginHorizontal="16dp">
16
17 <com.google.android.material.bottomsheet.BottomSheetDragHandleView
18 android:layout_width="wrap_content"
19 android:layout_height="wrap_content"
20 android:layout_gravity="center_horizontal"/>
21
22 <com.google.android.material.textview.MaterialTextView
23 style="@style/TextAppearance.Material3.HeadlineLarge"
24 android:id="@+id/text_title"
25 android:layout_width="match_parent"
26 android:layout_height="wrap_content"
27 android:gravity="center"
28 tools:text="@string/license_adreno_tools" />
29
30 <com.google.android.material.textview.MaterialTextView
31 style="@style/TextAppearance.Material3.BodyLarge"
32 android:id="@+id/text_link"
33 android:layout_width="match_parent"
34 android:layout_height="wrap_content"
35 android:gravity="center"
36 android:layout_marginTop="16dp"
37 android:autoLink="all"
38 tools:text="@string/license_adreno_tools_link" />
39
40 <com.google.android.material.textview.MaterialTextView
41 style="@style/TextAppearance.Material3.BodyLarge"
42 android:id="@+id/text_copyright"
43 android:layout_width="match_parent"
44 android:layout_height="wrap_content"
45 android:gravity="center"
46 android:layout_marginTop="16dp"
47 android:textStyle="bold"
48 tools:text="@string/license_adreno_tools_copyright" />
49
50 <com.google.android.material.textview.MaterialTextView
51 style="@style/TextAppearance.Material3.BodyMedium"
52 android:id="@+id/text_license"
53 android:layout_width="match_parent"
54 android:layout_height="wrap_content"
55 android:layout_gravity="center"
56 android:layout_marginVertical="16dp"
57 android:autoLink="all"
58 tools:text="@string/license_adreno_tools_text" />
59
60 </LinearLayout>
61
62 </androidx.core.widget.NestedScrollView>
63
64</androidx.coordinatorlayout.widget.CoordinatorLayout>
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 549f00aa5..3e1d98451 100644
--- a/src/android/app/src/main/res/layout/fragment_about.xml
+++ b/src/android/app/src/main/res/layout/fragment_about.xml
@@ -115,6 +115,39 @@
115 android:layout_marginHorizontal="20dp" /> 115 android:layout_marginHorizontal="20dp" />
116 116
117 <LinearLayout 117 <LinearLayout
118 android:id="@+id/button_licenses"
119 android:layout_width="match_parent"
120 android:layout_height="wrap_content"
121 android:paddingVertical="16dp"
122 android:paddingHorizontal="16dp"
123 android:background="?attr/selectableItemBackground"
124 android:orientation="vertical">
125
126 <com.google.android.material.textview.MaterialTextView
127 style="@style/TextAppearance.Material3.TitleMedium"
128 android:layout_width="match_parent"
129 android:layout_height="wrap_content"
130 android:layout_marginHorizontal="24dp"
131 android:textAlignment="viewStart"
132 android:text="@string/licenses" />
133
134 <com.google.android.material.textview.MaterialTextView
135 style="@style/TextAppearance.Material3.BodyMedium"
136 android:layout_width="match_parent"
137 android:layout_height="wrap_content"
138 android:layout_marginHorizontal="24dp"
139 android:layout_marginTop="6dp"
140 android:textAlignment="viewStart"
141 android:text="@string/licenses_description" />
142
143 </LinearLayout>
144
145 <com.google.android.material.divider.MaterialDivider
146 android:layout_width="match_parent"
147 android:layout_height="wrap_content"
148 android:layout_marginHorizontal="20dp" />
149
150 <LinearLayout
118 android:id="@+id/button_build_hash" 151 android:id="@+id/button_build_hash"
119 android:layout_width="match_parent" 152 android:layout_width="match_parent"
120 android:layout_height="wrap_content" 153 android:layout_height="wrap_content"
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 74ec512af..940dbd4bf 100644
--- a/src/android/app/src/main/res/layout/fragment_emulation.xml
+++ b/src/android/app/src/main/res/layout/fragment_emulation.xml
@@ -20,6 +20,12 @@
20 android:focusable="false" 20 android:focusable="false"
21 android:focusableInTouchMode="false" /> 21 android:focusableInTouchMode="false" />
22 22
23 <FrameLayout
24 android:id="@+id/overlay_container"
25 android:layout_width="match_parent"
26 android:layout_height="match_parent"
27 android:layout_gravity="bottom">
28
23 <!-- This is the onscreen input overlay --> 29 <!-- This is the onscreen input overlay -->
24 <org.yuzu.yuzu_emu.overlay.InputOverlay 30 <org.yuzu.yuzu_emu.overlay.InputOverlay
25 android:id="@+id/surface_input_overlay" 31 android:id="@+id/surface_input_overlay"
@@ -48,6 +54,7 @@
48 android:layout_gravity="center" 54 android:layout_gravity="center"
49 android:text="@string/emulation_done" 55 android:text="@string/emulation_done"
50 android:visibility="gone" /> 56 android:visibility="gone" />
57 </FrameLayout>
51 58
52 </androidx.coordinatorlayout.widget.CoordinatorLayout> 59 </androidx.coordinatorlayout.widget.CoordinatorLayout>
53 60
@@ -55,7 +62,7 @@
55 android:id="@+id/in_game_menu" 62 android:id="@+id/in_game_menu"
56 android:layout_width="wrap_content" 63 android:layout_width="wrap_content"
57 android:layout_height="match_parent" 64 android:layout_height="match_parent"
58 android:layout_gravity="start" 65 android:layout_gravity="start|bottom"
59 app:headerLayout="@layout/header_in_game" 66 app:headerLayout="@layout/header_in_game"
60 app:menu="@menu/menu_in_game" /> 67 app:menu="@menu/menu_in_game" />
61 68
diff --git a/src/android/app/src/main/res/layout/fragment_licenses.xml b/src/android/app/src/main/res/layout/fragment_licenses.xml
new file mode 100644
index 000000000..6b31ff5b4
--- /dev/null
+++ b/src/android/app/src/main/res/layout/fragment_licenses.xml
@@ -0,0 +1,30 @@
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 android:id="@+id/coordinator_licenses"
5 android:layout_width="match_parent"
6 android:layout_height="match_parent"
7 android:background="?attr/colorSurface">
8
9 <com.google.android.material.appbar.AppBarLayout
10 android:id="@+id/appbar_licenses"
11 android:layout_width="match_parent"
12 android:layout_height="wrap_content"
13 android:fitsSystemWindows="true">
14
15 <com.google.android.material.appbar.MaterialToolbar
16 android:id="@+id/toolbar_licenses"
17 android:layout_width="match_parent"
18 android:layout_height="?attr/actionBarSize"
19 app:title="@string/licenses"
20 app:navigationIcon="@drawable/ic_back" />
21
22 </com.google.android.material.appbar.AppBarLayout>
23
24 <androidx.recyclerview.widget.RecyclerView
25 android:id="@+id/list_licenses"
26 android:layout_width="match_parent"
27 android:layout_height="match_parent"
28 app:layout_behavior="@string/appbar_scrolling_view_behavior" />
29
30</androidx.coordinatorlayout.widget.CoordinatorLayout>
diff --git a/src/android/app/src/main/res/navigation/home_navigation.xml b/src/android/app/src/main/res/navigation/home_navigation.xml
index 2275ddc32..48072683e 100644
--- a/src/android/app/src/main/res/navigation/home_navigation.xml
+++ b/src/android/app/src/main/res/navigation/home_navigation.xml
@@ -40,11 +40,20 @@
40 <fragment 40 <fragment
41 android:id="@+id/aboutFragment" 41 android:id="@+id/aboutFragment"
42 android:name="org.yuzu.yuzu_emu.fragments.AboutFragment" 42 android:name="org.yuzu.yuzu_emu.fragments.AboutFragment"
43 android:label="AboutFragment" /> 43 android:label="AboutFragment" >
44 <action
45 android:id="@+id/action_aboutFragment_to_licensesFragment"
46 app:destination="@id/licensesFragment" />
47 </fragment>
44 48
45 <fragment 49 <fragment
46 android:id="@+id/earlyAccessFragment" 50 android:id="@+id/earlyAccessFragment"
47 android:name="org.yuzu.yuzu_emu.fragments.EarlyAccessFragment" 51 android:name="org.yuzu.yuzu_emu.fragments.EarlyAccessFragment"
48 android:label="EarlyAccessFragment" /> 52 android:label="EarlyAccessFragment" />
49 53
54 <fragment
55 android:id="@+id/licensesFragment"
56 android:name="org.yuzu.yuzu_emu.fragments.LicensesFragment"
57 android:label="LicensesFragment" />
58
50</navigation> 59</navigation>
diff --git a/src/android/app/src/main/res/values/arrays.xml b/src/android/app/src/main/res/values/arrays.xml
index fa88770c8..ea20cb17c 100644
--- a/src/android/app/src/main/res/values/arrays.xml
+++ b/src/android/app/src/main/res/values/arrays.xml
@@ -2,67 +2,67 @@
2<resources> 2<resources>
3 3
4 <string-array name="regionNames"> 4 <string-array name="regionNames">
5 <item>@string/region_auto</item> 5 <item>@string/auto</item>
6 <item>@string/region_japan</item>
7 <item>@string/region_usa</item>
8 <item>@string/region_europe</item>
9 <item>@string/region_australia</item> 6 <item>@string/region_australia</item>
10 <item>@string/region_china</item> 7 <item>@string/region_china</item>
8 <item>@string/region_europe</item>
9 <item>@string/region_japan</item>
11 <item>@string/region_korea</item> 10 <item>@string/region_korea</item>
12 <item>@string/region_taiwan</item> 11 <item>@string/region_taiwan</item>
12 <item>@string/region_usa</item>
13 </string-array> 13 </string-array>
14 14
15 <integer-array name="regionValues"> 15 <integer-array name="regionValues">
16 <item>-1</item> 16 <item>-1</item>
17 <item>0</item>
18 <item>1</item>
19 <item>2</item>
20 <item>3</item> 17 <item>3</item>
21 <item>4</item> 18 <item>4</item>
19 <item>2</item>
20 <item>0</item>
22 <item>5</item> 21 <item>5</item>
23 <item>6</item> 22 <item>6</item>
23 <item>1</item>
24 </integer-array> 24 </integer-array>
25 25
26 <string-array name="languageNames"> 26 <string-array name="languageNames">
27 <item>@string/language_japanese</item> 27 <item>@string/language_brazilian_portuguese</item>
28 <item>@string/language_british_english</item>
29 <item>@string/language_canadian_french</item>
30 <item>@string/language_chinese</item>
31 <item>@string/language_dutch</item>
28 <item>@string/language_english</item> 32 <item>@string/language_english</item>
29 <item>@string/language_french</item> 33 <item>@string/language_french</item>
30 <item>@string/langauge_german</item> 34 <item>@string/langauge_german</item>
31 <item>@string/language_italian</item> 35 <item>@string/language_italian</item>
32 <item>@string/language_spanish</item> 36 <item>@string/language_japanese</item>
33 <item>@string/language_chinese</item>
34 <item>@string/language_korean</item> 37 <item>@string/language_korean</item>
35 <item>@string/language_dutch</item> 38 <item>@string/language_latin_american_spanish</item>
36 <item>@string/language_portuguese</item> 39 <item>@string/language_portuguese</item>
37 <item>@string/language_russian</item> 40 <item>@string/language_russian</item>
38 <item>@string/language_taiwanese</item>
39 <item>@string/language_british_english</item>
40 <item>@string/language_canadian_french</item>
41 <item>@string/language_latin_american_spanish</item>
42 <item>@string/language_simplified_chinese</item> 41 <item>@string/language_simplified_chinese</item>
42 <item>@string/language_spanish</item>
43 <item>@string/language_taiwanese</item>
43 <item>@string/language_traditional_chinese</item> 44 <item>@string/language_traditional_chinese</item>
44 <item>@string/language_brazilian_portuguese</item>
45 </string-array> 45 </string-array>
46 46
47 <integer-array name="languageValues"> 47 <integer-array name="languageValues">
48 <item>0</item> 48 <item>17</item>
49 <item>12</item>
50 <item>13</item>
51 <item>6</item>
52 <item>8</item>
49 <item>1</item> 53 <item>1</item>
50 <item>2</item> 54 <item>2</item>
51 <item>3</item> 55 <item>3</item>
52 <item>4</item> 56 <item>4</item>
53 <item>5</item> 57 <item>0</item>
54 <item>6</item>
55 <item>7</item> 58 <item>7</item>
56 <item>8</item> 59 <item>14</item>
57 <item>9</item> 60 <item>9</item>
58 <item>10</item> 61 <item>10</item>
59 <item>11</item>
60 <item>12</item>
61 <item>13</item>
62 <item>14</item>
63 <item>15</item> 62 <item>15</item>
63 <item>5</item>
64 <item>11</item>
64 <item>16</item> 65 <item>16</item>
65 <item>17</item>
66 </integer-array> 66 </integer-array>
67 67
68 <string-array name="rendererApiNames"> 68 <string-array name="rendererApiNames">
@@ -166,7 +166,7 @@
166 </integer-array> 166 </integer-array>
167 167
168 <string-array name="cpuAccuracyNames"> 168 <string-array name="cpuAccuracyNames">
169 <item>@string/cpu_accuracy_auto</item> 169 <item>@string/auto</item>
170 <item>@string/cpu_accuracy_accurate</item> 170 <item>@string/cpu_accuracy_accurate</item>
171 <item>@string/cpu_accuracy_unsafe</item> 171 <item>@string/cpu_accuracy_unsafe</item>
172 <item>@string/cpu_accuracy_paranoid</item> 172 <item>@string/cpu_accuracy_paranoid</item>
diff --git a/src/android/app/src/main/res/values/strings.xml b/src/android/app/src/main/res/values/strings.xml
index 1646b90eb..0ae69afb4 100644
--- a/src/android/app/src/main/res/values/strings.xml
+++ b/src/android/app/src/main/res/values/strings.xml
@@ -41,7 +41,7 @@
41 <string name="add_games_warning">Skip selecting games folder?</string> 41 <string name="add_games_warning">Skip selecting games folder?</string>
42 <string name="add_games_warning_description">Games won\'t be displayed in the Games list if a folder isn\'t selected.</string> 42 <string name="add_games_warning_description">Games won\'t be displayed in the Games list if a folder isn\'t selected.</string>
43 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string> 43 <string name="add_games_warning_help">https://yuzu-emu.org/help/quickstart/#dumping-games</string>
44 <string name="home_search_games">Search Games</string> 44 <string name="home_search_games">Search games</string>
45 <string name="games_dir_selected">Games directory selected</string> 45 <string name="games_dir_selected">Games directory selected</string>
46 <string name="install_prod_keys">Install prod.keys</string> 46 <string name="install_prod_keys">Install prod.keys</string>
47 <string name="install_prod_keys_description">Required to decrypt retail games</string> 47 <string name="install_prod_keys_description">Required to decrypt retail games</string>
@@ -77,8 +77,8 @@
77 <string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string> 77 <string name="install_gpu_driver_description">Install alternative drivers for potentially better performance or accuracy</string>
78 <string name="advanced_settings">Advanced settings</string> 78 <string name="advanced_settings">Advanced settings</string>
79 <string name="settings_description">Configure emulator settings</string> 79 <string name="settings_description">Configure emulator settings</string>
80 <string name="search_recently_played">Recently Played</string> 80 <string name="search_recently_played">Recently played</string>
81 <string name="search_recently_added">Recently Added</string> 81 <string name="search_recently_added">Recently added</string>
82 <string name="search_retail">Retail</string> 82 <string name="search_retail">Retail</string>
83 <string name="search_homebrew">Homebrew</string> 83 <string name="search_homebrew">Homebrew</string>
84 <string name="open_user_folder">Open yuzu folder</string> 84 <string name="open_user_folder">Open yuzu folder</string>
@@ -113,6 +113,7 @@
113 <string name="contributors">Contributors</string> 113 <string name="contributors">Contributors</string>
114 <string name="contributors_description">Made with \u2764 from the yuzu team</string> 114 <string name="contributors_description">Made with \u2764 from the yuzu team</string>
115 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string> 115 <string name="contributors_link">https://github.com/yuzu-emu/yuzu/graphs/contributors</string>
116 <string name="licenses_description">Projects that make yuzu for Android possible</string>
116 <string name="build">Build</string> 117 <string name="build">Build</string>
117 <string name="support_link">https://discord.gg/u77vRWY</string> 118 <string name="support_link">https://discord.gg/u77vRWY</string>
118 <string name="website_link">https://yuzu-emu.org/</string> 119 <string name="website_link">https://yuzu-emu.org/</string>
@@ -133,39 +134,39 @@
133 <string name="are_you_interested">Are you interested?</string> 134 <string name="are_you_interested">Are you interested?</string>
134 135
135 <!-- General settings strings --> 136 <!-- General settings strings -->
136 <string name="frame_limit_enable">Enable limit speed</string> 137 <string name="frame_limit_enable">Limit speed</string>
137 <string name="frame_limit_enable_description">When enabled, emulation speed will be limited to a specified percentage of normal speed.</string> 138 <string name="frame_limit_enable_description">Limits emulation speed to a specified percentage of normal speed.</string>
138 <string name="frame_limit_slider">Limit speed percent</string> 139 <string name="frame_limit_slider">Limit speed percent</string>
139 <string name="frame_limit_slider_description">Specifies the percentage to limit emulation speed. With the default of 100% emulation will be limited to normal speed. Values higher or lower will increase or decrease the speed limit.</string> 140 <string name="frame_limit_slider_description">Specifies the percentage to limit emulation speed. 100% is the normal speed. Values higher or lower will increase or decrease the speed limit.</string>
140 <string name="cpu_accuracy">CPU accuracy</string> 141 <string name="cpu_accuracy">CPU accuracy</string>
141 142
142 <!-- System settings strings --> 143 <!-- System settings strings -->
143 <string name="use_docked_mode">Docked mode</string> 144 <string name="use_docked_mode">Docked Mode</string>
144 <string name="use_docked_mode_description">Emulates in docked mode, which increases the resolution at the expense of performance.</string> 145 <string name="use_docked_mode_description">Increases resolution, decreasing performance. Handheld Mode is used when disabled, lowering resolution and increasing performance.</string>
145 <string name="emulated_region">Emulated region</string> 146 <string name="emulated_region">Emulated region</string>
146 <string name="emulated_language">Emulated language</string> 147 <string name="emulated_language">Emulated language</string>
147 <string name="select_rtc_date">Select RTC Date</string> 148 <string name="select_rtc_date">Select RTC date</string>
148 <string name="select_rtc_time">Select RTC Time</string> 149 <string name="select_rtc_time">Select RTC time</string>
149 <string name="use_custom_rtc">Enable Custom RTC</string> 150 <string name="use_custom_rtc">Custom RTC</string>
150 <string name="use_custom_rtc_description">This setting allows you to set a custom real time clock separate from your current system time</string> 151 <string name="use_custom_rtc_description">Allows you to set a custom real-time clock separate from your current system time.</string>
151 <string name="set_custom_rtc">Set Custom RTC</string> 152 <string name="set_custom_rtc">Set custom RTC</string>
152 153
153 <!-- Graphics settings strings --> 154 <!-- Graphics settings strings -->
154 <string name="renderer_api">API</string> 155 <string name="renderer_api">API</string>
155 <string name="renderer_accuracy">Accuracy level</string> 156 <string name="renderer_accuracy">Accuracy level</string>
156 <string name="renderer_resolution">Resolution</string> 157 <string name="renderer_resolution">Resolution (Handheld/Docked)</string>
157 <string name="renderer_vsync">VSync mode</string> 158 <string name="renderer_vsync">VSync mode</string>
158 <string name="renderer_aspect_ratio">Aspect Ratio</string> 159 <string name="renderer_aspect_ratio">Aspect ratio</string>
159 <string name="renderer_scaling_filter">Window Adapting Filter</string> 160 <string name="renderer_scaling_filter">Window adapting filter</string>
160 <string name="renderer_anti_aliasing">Anti-Aliasing Method</string> 161 <string name="renderer_anti_aliasing">Anti-aliasing method</string>
161 <string name="renderer_force_max_clock">Force maximum clocks (Adreno only)</string> 162 <string name="renderer_force_max_clock">Force maximum clocks (Adreno only)</string>
162 <string name="renderer_force_max_clock_description">Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied).</string> 163 <string name="renderer_force_max_clock_description">Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied).</string>
163 <string name="renderer_asynchronous_shaders">Use asynchronous shaders</string> 164 <string name="renderer_asynchronous_shaders">Use asynchronous shaders</string>
164 <string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously, which will reduce stutter but may introduce glitches.</string> 165 <string name="renderer_asynchronous_shaders_description">Compiles shaders asynchronously, reducing stutter but may introduce glitches.</string>
165 <string name="renderer_debug">Enable graphics debugging</string> 166 <string name="renderer_debug">Graphics debugging</string>
166 <string name="renderer_debug_description">When checked, the graphics API enters a slower debugging mode.</string> 167 <string name="renderer_debug_description">Sets the graphics API to a slow debugging mode.</string>
167 <string name="use_disk_shader_cache">Use disk shader cache</string> 168 <string name="use_disk_shader_cache">Disk shader cache</string>
168 <string name="use_disk_shader_cache_description">Reduce stuttering by storing and loading generated shaders to disk.</string> 169 <string name="use_disk_shader_cache_description">Reduces stuttering by locally storing and loading generated shaders.</string>
169 170
170 <!-- Audio settings strings --> 171 <!-- Audio settings strings -->
171 <string name="audio_volume">Volume</string> 172 <string name="audio_volume">Volume</string>
@@ -180,10 +181,12 @@
180 <string name="reset_setting_confirmation">Do you want to reset this setting back to its default value?</string> 181 <string name="reset_setting_confirmation">Do you want to reset this setting back to its default value?</string>
181 <string name="reset_to_default">Reset to default</string> 182 <string name="reset_to_default">Reset to default</string>
182 <string name="reset_all_settings">Reset all settings?</string> 183 <string name="reset_all_settings">Reset all settings?</string>
183 <string name="reset_all_settings_description">All Advanced Settings will be reset to their default configuration. This can not be undone.</string> 184 <string name="reset_all_settings_description">All advanced settings will be reset to their default configuration. This can not be undone.</string>
184 <string name="settings_reset">Settings reset</string> 185 <string name="settings_reset">Settings reset</string>
185 <string name="close">Close</string> 186 <string name="close">Close</string>
186 <string name="learn_more">Learn More</string> 187 <string name="learn_more">Learn more</string>
188 <string name="auto">Auto</string>
189 <string name="submit">Submit</string>
187 190
188 <!-- GPU driver installation --> 191 <!-- GPU driver installation -->
189 <string name="select_gpu_driver">Select GPU driver</string> 192 <string name="select_gpu_driver">Select GPU driver</string>
@@ -197,13 +200,13 @@
197 <string name="installing_driver">Installing driver…</string> 200 <string name="installing_driver">Installing driver…</string>
198 201
199 <!-- Preferences Screen --> 202 <!-- Preferences Screen -->
200 <string name="preferences_advanced_settings">Advanced Settings</string>
201 <string name="preferences_settings">Settings</string> 203 <string name="preferences_settings">Settings</string>
202 <string name="preferences_general">General</string> 204 <string name="preferences_general">General</string>
203 <string name="preferences_system">System</string> 205 <string name="preferences_system">System</string>
204 <string name="preferences_graphics">Graphics</string> 206 <string name="preferences_graphics">Graphics</string>
205 <string name="preferences_audio">Audio</string> 207 <string name="preferences_audio">Audio</string>
206 <string name="preferences_theme">Theme and color</string> 208 <string name="preferences_theme">Theme and color</string>
209 <string name="preferences_debug">Debug</string>
207 210
208 <!-- ROM loading errors --> 211 <!-- ROM loading errors -->
209 <string name="loader_error_encrypted">Your ROM is encrypted</string> 212 <string name="loader_error_encrypted">Your ROM is encrypted</string>
@@ -215,29 +218,29 @@
215 <string name="loader_error_file_not_found">ROM file does not exist</string> 218 <string name="loader_error_file_not_found">ROM file does not exist</string>
216 219
217 <!-- Emulation Menu --> 220 <!-- Emulation Menu -->
218 <string name="emulation_exit">Exit Emulation</string> 221 <string name="emulation_exit">Exit emulation</string>
219 <string name="emulation_done">Done</string> 222 <string name="emulation_done">Done</string>
220 <string name="emulation_fps_counter">FPS Counter</string> 223 <string name="emulation_fps_counter">FPS counter</string>
221 <string name="emulation_toggle_controls">Toggle Controls</string> 224 <string name="emulation_toggle_controls">Toggle controls</string>
222 <string name="emulation_rel_stick_center">Relative Stick Center</string> 225 <string name="emulation_rel_stick_center">Relative stick center</string>
223 <string name="emulation_dpad_slide">DPad Slide</string> 226 <string name="emulation_dpad_slide">D-pad slide</string>
224 <string name="emulation_haptics">Haptics</string> 227 <string name="emulation_haptics">Touch haptics</string>
225 <string name="emulation_show_overlay">Show Overlay</string> 228 <string name="emulation_show_overlay">Show overlay</string>
226 <string name="emulation_toggle_all">Toggle All</string> 229 <string name="emulation_toggle_all">Toggle all</string>
227 <string name="emulation_control_adjust">Adjust Overlay</string> 230 <string name="emulation_control_adjust">Adjust overlay</string>
228 <string name="emulation_control_scale">Scale</string> 231 <string name="emulation_control_scale">Scale</string>
229 <string name="emulation_control_opacity">Opacity</string> 232 <string name="emulation_control_opacity">Opacity</string>
230 <string name="emulation_touch_overlay_reset">Reset Overlay</string> 233 <string name="emulation_touch_overlay_reset">Reset overlay</string>
231 <string name="emulation_touch_overlay_edit">Edit Overlay</string> 234 <string name="emulation_touch_overlay_edit">Edit overlay</string>
232 <string name="emulation_pause">Pause Emulation</string> 235 <string name="emulation_pause">Pause emulation</string>
233 <string name="emulation_unpause">Unpause Emulation</string> 236 <string name="emulation_unpause">Unpause emulation</string>
234 <string name="emulation_input_overlay">Overlay Options</string> 237 <string name="emulation_input_overlay">Overlay options</string>
235 <string name="emulation_game_loading">Game loading…</string> 238 <string name="emulation_game_loading">Game loading…</string>
236 239
237 <string name="load_settings">Loading Settings…</string> 240 <string name="load_settings">Loading settings…</string>
238 241
239 <!-- Software keyboard --> 242 <!-- Software keyboard -->
240 <string name="software_keyboard">Software Keyboard</string> 243 <string name="software_keyboard">Software keyboard</string>
241 244
242 <!-- Errors and warnings --> 245 <!-- Errors and warnings -->
243 <string name="abort_button">Abort</string> 246 <string name="abort_button">Abort</string>
@@ -251,7 +254,6 @@
251 <string name="performance_warning">Turning off this setting will significantly reduce emulation performance! For the best experience, it is recommended that you leave this setting enabled.</string> 254 <string name="performance_warning">Turning off this setting will significantly reduce emulation performance! For the best experience, it is recommended that you leave this setting enabled.</string>
252 255
253 <!-- Region Names --> 256 <!-- Region Names -->
254 <string name="region_auto">Auto-select</string>
255 <string name="region_japan">Japan</string> 257 <string name="region_japan">Japan</string>
256 <string name="region_usa">USA</string> 258 <string name="region_usa">USA</string>
257 <string name="region_europe">Europe</string> 259 <string name="region_europe">Europe</string>
@@ -321,18 +323,17 @@
321 <string name="ratio_force_four_three">Force 4:3</string> 323 <string name="ratio_force_four_three">Force 4:3</string>
322 <string name="ratio_force_twenty_one_nine">Force 21:9</string> 324 <string name="ratio_force_twenty_one_nine">Force 21:9</string>
323 <string name="ratio_force_sixteen_ten">Force 16:10</string> 325 <string name="ratio_force_sixteen_ten">Force 16:10</string>
324 <string name="ratio_stretch">Stretch to Window</string> 326 <string name="ratio_stretch">Stretch to window</string>
325 327
326 <!-- CPU Accuracy --> 328 <!-- CPU Accuracy -->
327 <string name="cpu_accuracy_auto">Auto</string>
328 <string name="cpu_accuracy_accurate">Accurate</string> 329 <string name="cpu_accuracy_accurate">Accurate</string>
329 <string name="cpu_accuracy_unsafe">Unsafe</string> 330 <string name="cpu_accuracy_unsafe">Unsafe</string>
330 <string name="cpu_accuracy_paranoid">Paranoid (Slow)</string> 331 <string name="cpu_accuracy_paranoid">Paranoid (Slow)</string>
331 332
332 <!-- Gamepad Buttons --> 333 <!-- Gamepad Buttons -->
333 <string name="gamepad_d_pad">D-Pad</string> 334 <string name="gamepad_d_pad">D-pad</string>
334 <string name="gamepad_left_stick">Left Stick</string> 335 <string name="gamepad_left_stick">Left stick</string>
335 <string name="gamepad_right_stick">Right Stick</string> 336 <string name="gamepad_right_stick">Right stick</string>
336 <string name="gamepad_home">Home</string> 337 <string name="gamepad_home">Home</string>
337 <string name="gamepad_screenshot">Screenshot</string> 338 <string name="gamepad_screenshot">Screenshot</string>
338 339
@@ -341,18 +342,525 @@
341 <string name="building_shaders">Building shaders</string> 342 <string name="building_shaders">Building shaders</string>
342 343
343 <!-- Theme options --> 344 <!-- Theme options -->
344 <string name="change_app_theme">Change App Theme</string> 345 <string name="change_app_theme">Change app theme</string>
345 <string name="theme_default">Default</string> 346 <string name="theme_default">Default</string>
346 <string name="theme_material_you">Material You</string> 347 <string name="theme_material_you">Material You</string>
347 348
348 <!-- Theme Modes --> 349 <!-- Theme Modes -->
349 <string name="change_theme_mode">Change Theme Mode</string> 350 <string name="change_theme_mode">Change theme mode</string>
350 <string name="theme_mode_follow_system">Follow System</string> 351 <string name="theme_mode_follow_system">Follow System</string>
351 <string name="theme_mode_light">Light</string> 352 <string name="theme_mode_light">Light</string>
352 <string name="theme_mode_dark">Dark</string> 353 <string name="theme_mode_dark">Dark</string>
353 354
354 <!-- Black backgrounds theme --> 355 <!-- Black backgrounds theme -->
355 <string name="use_black_backgrounds">Use Black Backgrounds</string> 356 <string name="use_black_backgrounds">Black backgrounds</string>
356 <string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string> 357 <string name="use_black_backgrounds_description">When using the dark theme, apply black backgrounds.</string>
357 358
359 <!-- Licenses screen strings -->
360 <string name="licenses">Licenses</string>
361 <string name="license_fidelityfx_fsr" translatable="false">FidelityFX-FSR</string>
362 <string name="license_fidelityfx_fsr_description">High-quality upscaling from AMD</string>
363 <string name="license_fidelityfx_fsr_link" translatable="false">https://github.com/GPUOpen-Effects/FidelityFX-FSR</string>
364 <string name="license_fidelityfx_fsr_copyright" translatable="false">Copyright © 2021 Advanced Micro Devices, Inc.</string>
365 <string name="license_fidelityfx_fsr_text" translatable="false">
366Permission is hereby granted, free of charge, to any person obtaining a copy
367of this software and associated documentation files (the \"Software"), to deal
368in the Software without restriction, including without limitation the rights
369to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
370copies of the Software, and to permit persons to whom the Software is
371furnished to do so, subject to the following conditions:\n\n
372
373The above copyright notice and this permission notice shall be included in
374all copies or substantial portions of the Software.\n\n
375
376THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
377IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
378FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
379AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
380LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
381OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
382THE SOFTWARE.
383 </string>
384 <string name="license_cubeb" translatable="false">cubeb</string>
385 <string name="license_cubeb_description" translatable="false">Cross platform audio library</string>
386 <string name="license_cubeb_link" translatable="false">https://github.com/mozilla/cubeb</string>
387 <string name="license_cubeb_copyright" translatable="false">Copyright © 2011 Mozilla Foundation</string>
388 <string name="license_cubeb_text" translatable="false">
389Permission to use, copy, modify, and distribute this software for any
390purpose with or without fee is hereby granted, provided that the above
391copyright notice and this permission notice appear in all copies.\n\n
392
393THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
394WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
395MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
396ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
397WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
398ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
399OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
400 </string>
401 <string name="license_dynarmic" translatable="false">Dynarmic</string>
402 <string name="license_dynarmic_description" translatable="false">An ARM dynamic recompiler</string>
403 <string name="license_dynarmic_link" translatable="false">https://github.com/merryhime/dynarmic</string>
404 <string name="license_dynarmic_copyright" translatable="false">Copyright © 2017 merryhime</string>
405 <string name="license_dynarmic_text" translatable="false">
406Permission to use, copy, modify, and/or distribute this software for
407any purpose with or without fee is hereby granted.\n\n
408
409THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
410WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
411MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
412ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
413WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
414AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
415OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
416 </string>
417 <string name="license_ffmpeg" translatable="false">FFmpeg</string>
418 <string name="license_ffmpeg_description" translatable="false">FFmpeg is a collection of libraries and tools to process multimedia content such as audio, video, subtitles and related metadata.</string>
419 <string name="license_ffmpeg_link" translatable="false">https://github.com/FFmpeg/FFmpeg</string>
420 <string name="license_ffmpeg_copyright" translatable="false">Copyright © 1991, 1999 Free Software Foundation, Inc.</string>
421 <string name="license_ffmpeg_text" translatable="false">
422GNU LESSER GENERAL PUBLIC LICENSE\n
423TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n
424
425 0. This License Agreement applies to any software library or other
426program which contains a notice placed by the copyright holder or
427other authorized party saying it may be distributed under the terms of
428this Lesser General Public License (also called \"this License\").
429Each licensee is addressed as \"you\".\n\n
430
431 A \"library\" means a collection of software functions and/or data
432prepared so as to be conveniently linked with application programs
433(which use some of those functions and data) to form executables.\n\n
434
435 The \"Library\", below, refers to any such software library or work
436which has been distributed under these terms. A \"work based on the
437Library\" means either the Library or any derivative work under
438copyright law: that is to say, a work containing the Library or a
439portion of it, either verbatim or with modifications and/or translated
440straightforwardly into another language. (Hereinafter, translation is
441included without limitation in the term \"modification\".)\n\n
442
443 \"Source code\" for a work means the preferred form of the work for
444making modifications to it. For a library, complete source code means
445all the source code for all modules it contains, plus any associated
446interface definition files, plus the scripts used to control compilation
447and installation of the library.\n\n
448
449 Activities other than copying, distribution and modification are not
450covered by this License; they are outside its scope. The act of
451running a program using the Library is not restricted, and output from
452such a program is covered only if its contents constitute a work based
453on the Library (independent of the use of the Library in a tool for
454writing it). Whether that is true depends on what the Library does
455and what the program that uses the Library does.\n\n
456
457 1. You may copy and distribute verbatim copies of the Library\'s
458complete source code as you receive it, in any medium, provided that
459you conspicuously and appropriately publish on each copy an
460appropriate copyright notice and disclaimer of warranty; keep intact
461all the notices that refer to this License and to the absence of any
462warranty; and distribute a copy of this License along with the
463Library.\n\n
464
465 You may charge a fee for the physical act of transferring a copy,
466and you may at your option offer warranty protection in exchange for a
467fee.\n\n
468
469 2. You may modify your copy or copies of the Library or any portion
470of it, thus forming a work based on the Library, and copy and
471distribute such modifications or work under the terms of Section 1
472above, provided that you also meet all of these conditions:\n\n
473
474a) The modified work must itself be a software library.\n\n
475
476b) You must cause the files modified to carry prominent notices
477stating that you changed the files and the date of any change.\n\n
478
479c) You must cause the whole of the work to be licensed at no
480charge to all third parties under the terms of this License.\n\n
481
482d) If a facility in the modified Library refers to a function or a
483table of data to be supplied by an application program that uses
484the facility, other than as an argument passed when the facility
485is invoked, then you must make a good faith effort to ensure that,
486in the event an application does not supply such function or
487table, the facility still operates, and performs whatever part of
488its purpose remains meaningful.\n\n
489
490(For example, a function in a library to compute square roots has
491a purpose that is entirely well-defined independent of the
492application. Therefore, Subsection 2d requires that any
493application-supplied function or table used by this function must
494be optional: if the application does not supply it, the square
495root function must still compute square roots.)\n\n
496
497These requirements apply to the modified work as a whole. If
498identifiable sections of that work are not derived from the Library,
499and can be reasonably considered independent and separate works in
500themselves, then this License, and its terms, do not apply to those
501sections when you distribute them as separate works. But when you
502distribute the same sections as part of a whole which is a work based
503on the Library, the distribution of the whole must be on the terms of
504this License, whose permissions for other licensees extend to the
505entire whole, and thus to each and every part regardless of who wrote
506it.\n\n
507
508Thus, it is not the intent of this section to claim rights or contest
509your rights to work written entirely by you; rather, the intent is to
510exercise the right to control the distribution of derivative or
511collective works based on the Library.\n\n
512
513In addition, mere aggregation of another work not based on the Library
514with the Library (or with a work based on the Library) on a volume of
515a storage or distribution medium does not bring the other work under
516the scope of this License.\n\n
517
518 3. You may opt to apply the terms of the ordinary GNU General Public
519License instead of this License to a given copy of the Library. To do
520this, you must alter all the notices that refer to this License, so
521that they refer to the ordinary GNU General Public License, version 2,
522instead of to this License. (If a newer version than version 2 of the
523ordinary GNU General Public License has appeared, then you can specify
524that version instead if you wish.) Do not make any other change in
525these notices.\n\n
526
527 Once this change is made in a given copy, it is irreversible for
528that copy, so the ordinary GNU General Public License applies to all
529subsequent copies and derivative works made from that copy.\n\n
530
531 This option is useful when you wish to copy part of the code of
532the Library into a program that is not a library.\n\n
533
534 4. You may copy and distribute the Library (or a portion or
535derivative of it, under Section 2) in object code or executable form
536under the terms of Sections 1 and 2 above provided that you accompany
537it with the complete corresponding machine-readable source code, which
538must be distributed under the terms of Sections 1 and 2 above on a
539medium customarily used for software interchange.\n\n
540
541 If distribution of object code is made by offering access to copy
542from a designated place, then offering equivalent access to copy the
543source code from the same place satisfies the requirement to
544distribute the source code, even though third parties are not
545compelled to copy the source along with the object code.\n\n
546
547 5. A program that contains no derivative of any portion of the
548Library, but is designed to work with the Library by being compiled or
549linked with it, is called a \"work that uses the Library\". Such a
550work, in isolation, is not a derivative work of the Library, and
551therefore falls outside the scope of this License.\n\n
552
553 However, linking a \"work that uses the Library\" with the Library
554creates an executable that is a derivative of the Library (because it
555contains portions of the Library), rather than a \"work that uses the
556library\". The executable is therefore covered by this License.
557Section 6 states terms for distribution of such executables.\n\n
558
559 When a \"work that uses the Library\" uses material from a header file
560that is part of the Library, the object code for the work may be a
561derivative work of the Library even though the source code is not.
562Whether this is true is especially significant if the work can be
563linked without the Library, or if the work is itself a library. The
564threshold for this to be true is not precisely defined by law.\n\n
565
566 If such an object file uses only numerical parameters, data
567structure layouts and accessors, and small macros and small inline
568functions (ten lines or less in length), then the use of the object
569file is unrestricted, regardless of whether it is legally a derivative
570work. (Executables containing this object code plus portions of the
571Library will still fall under Section 6.)\n\n
572
573 Otherwise, if the work is a derivative of the Library, you may
574distribute the object code for the work under the terms of Section 6.
575Any executables containing that work also fall under Section 6,
576whether or not they are linked directly with the Library itself.\n\n
577
578 6. As an exception to the Sections above, you may also combine or
579link a \"work that uses the Library\" with the Library to produce a
580work containing portions of the Library, and distribute that work
581under terms of your choice, provided that the terms permit
582modification of the work for the customer\'s own use and reverse
583engineering for debugging such modifications.\n\n
584
585 You must give prominent notice with each copy of the work that the
586Library is used in it and that the Library and its use are covered by
587this License. You must supply a copy of this License. If the work
588during execution displays copyright notices, you must include the
589copyright notice for the Library among them, as well as a reference
590directing the user to the copy of this License. Also, you must do one
591of these things:\n\n
592
593a) Accompany the work with the complete corresponding
594machine-readable source code for the Library including whatever
595changes were used in the work (which must be distributed under
596Sections 1 and 2 above); and, if the work is an executable linked
597with the Library, with the complete machine-readable \"work that
598uses the Library\", as object code and/or source code, so that the
599user can modify the Library and then relink to produce a modified
600executable containing the modified Library. (It is understood
601that the user who changes the contents of definitions files in the
602Library will not necessarily be able to recompile the application
603to use the modified definitions.)\n\n
604
605b) Use a suitable shared library mechanism for linking with the
606Library. A suitable mechanism is one that (1) uses at run time a
607copy of the library already present on the user\'s computer system,
608rather than copying library functions into the executable, and (2)
609will operate properly with a modified version of the library, if
610the user installs one, as long as the modified version is
611interface-compatible with the version that the work was made with.\n\n
612
613c) Accompany the work with a written offer, valid for at
614least three years, to give the same user the materials
615specified in Subsection 6a, above, for a charge no more
616than the cost of performing this distribution.\n\n
617
618d) If distribution of the work is made by offering access to copy
619from a designated place, offer equivalent access to copy the above
620specified materials from the same place.\n\n
621
622e) Verify that the user has already received a copy of these
623materials or that you have already sent this user a copy.\n\n
624
625 For an executable, the required form of the \"work that uses the
626Library\" must include any data and utility programs needed for
627reproducing the executable from it. However, as a special exception,
628the materials to be distributed need not include anything that is
629normally distributed (in either source or binary form) with the major
630components (compiler, kernel, and so on) of the operating system on
631which the executable runs, unless that component itself accompanies
632the executable.\n\n
633
634 It may happen that this requirement contradicts the license
635restrictions of other proprietary libraries that do not normally
636accompany the operating system. Such a contradiction means you cannot
637use both them and the Library together in an executable that you
638distribute.\n\n
639
640 7. You may place library facilities that are a work based on the
641Library side-by-side in a single library together with other library
642facilities not covered by this License, and distribute such a combined
643library, provided that the separate distribution of the work based on
644the Library and of the other library facilities is otherwise
645permitted, and provided that you do these two things:\n\n
646
647a) Accompany the combined library with a copy of the same work
648based on the Library, uncombined with any other library
649facilities. This must be distributed under the terms of the
650Sections above.\n\n
651
652b) Give prominent notice with the combined library of the fact
653that part of it is a work based on the Library, and explaining
654where to find the accompanying uncombined form of the same work.\n\n
655
656 8. You may not copy, modify, sublicense, link with, or distribute
657the Library except as expressly provided under this License. Any
658attempt otherwise to copy, modify, sublicense, link with, or
659distribute the Library is void, and will automatically terminate your
660rights under this License. However, parties who have received copies,
661or rights, from you under this License will not have their licenses
662terminated so long as such parties remain in full compliance.\n\n
663
664 9. You are not required to accept this License, since you have not
665signed it. However, nothing else grants you permission to modify or
666distribute the Library or its derivative works. These actions are
667prohibited by law if you do not accept this License. Therefore, by
668modifying or distributing the Library (or any work based on the
669Library), you indicate your acceptance of this License to do so, and
670all its terms and conditions for copying, distributing or modifying
671the Library or works based on it.\n\n
672
673 10. Each time you redistribute the Library (or any work based on the
674Library), the recipient automatically receives a license from the
675original licensor to copy, distribute, link with or modify the Library
676subject to these terms and conditions. You may not impose any further
677restrictions on the recipients\' exercise of the rights granted herein.
678You are not responsible for enforcing compliance by third parties with
679this License.\n\n
680
681 11. If, as a consequence of a court judgment or allegation of patent
682infringement or for any other reason (not limited to patent issues),
683conditions are imposed on you (whether by court order, agreement or
684otherwise) that contradict the conditions of this License, they do not
685excuse you from the conditions of this License. If you cannot
686distribute so as to satisfy simultaneously your obligations under this
687License and any other pertinent obligations, then as a consequence you
688may not distribute the Library at all. For example, if a patent
689license would not permit royalty-free redistribution of the Library by
690all those who receive copies directly or indirectly through you, then
691the only way you could satisfy both it and this License would be to
692refrain entirely from distribution of the Library.\n\n
693
694If any portion of this section is held invalid or unenforceable under any
695particular circumstance, the balance of the section is intended to apply,
696and the section as a whole is intended to apply in other circumstances.\n\n
697
698It is not the purpose of this section to induce you to infringe any
699patents or other property right claims or to contest validity of any
700such claims; this section has the sole purpose of protecting the
701integrity of the free software distribution system which is
702implemented by public license practices. Many people have made
703generous contributions to the wide range of software distributed
704through that system in reliance on consistent application of that
705system; it is up to the author/donor to decide if he or she is willing
706to distribute software through any other system and a licensee cannot
707impose that choice.\n\n
708
709This section is intended to make thoroughly clear what is believed to
710be a consequence of the rest of this License.\n\n
711
712 12. If the distribution and/or use of the Library is restricted in
713certain countries either by patents or by copyrighted interfaces, the
714original copyright holder who places the Library under this License may add
715an explicit geographical distribution limitation excluding those countries,
716so that distribution is permitted only in or among countries not thus
717excluded. In such case, this License incorporates the limitation as if
718written in the body of this License.\n\n
719
720 13. The Free Software Foundation may publish revised and/or new
721versions of the Lesser General Public License from time to time.
722Such new versions will be similar in spirit to the present version,
723but may differ in detail to address new problems or concerns.\n\n
724
725Each version is given a distinguishing version number. If the Library
726specifies a version number of this License which applies to it and
727"any later version\", you have the option of following the terms and
728conditions either of that version or of any later version published by
729the Free Software Foundation. If the Library does not specify a
730license version number, you may choose any version ever published by
731the Free Software Foundation.\n\n
732
733 14. If you wish to incorporate parts of the Library into other free
734programs whose distribution conditions are incompatible with these,
735write to the author to ask for permission. For software which is
736copyrighted by the Free Software Foundation, write to the Free
737Software Foundation; we sometimes make exceptions for this. Our
738decision will be guided by the two goals of preserving the free status
739of all derivatives of our free software and of promoting the sharing
740and reuse of software generally.\n\n
741
742NO WARRANTY\n\n
743
744 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
745WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
746EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
747OTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY
748KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
749IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
750PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
751LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
752THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\n\n
753
754 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
755WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
756AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
757FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
758CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
759LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
760RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
761FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
762SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
763DAMAGES.
764 </string>
765 <string name="license_opus" translatable="false">Opus</string>
766 <string name="license_opus_description" translatable="false">Modern audio compression for the internet</string>
767 <string name="license_opus_link" translatable="false">https://github.com/xiph/opus</string>
768 <string name="license_opus_copyright" translatable="false">Copyright 2001–2011 Xiph.Org, Skype Limited, Octasic, Jean-Marc Valin, Timothy B. Terriberry, CSIRO, Gregory Maxwell, Mark Borgerding, Erik de Castro Lopo</string>
769 <string name="license_opus_text" translatable="false">
770Redistribution and use in source and binary forms, with or without
771modification, are permitted provided that the following conditions
772are met:\n\n
773
774- Redistributions of source code must retain the above copyright
775notice, this list of conditions and the following disclaimer.\n\n
776
777- Redistributions in binary form must reproduce the above copyright
778notice, this list of conditions and the following disclaimer in the
779documentation and/or other materials provided with the distribution.\n\n
780
781- Neither the name of Internet Society, IETF or IETF Trust, nor the
782names of specific contributors, may be used to endorse or promote
783products derived from this software without specific prior written
784permission.\n\n
785
786THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
787``AS IS\'\' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
788LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
789A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
790OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
791EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
792PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
793PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
794LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
795NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
796SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n
797
798Opus is subject to the royalty-free patent licenses which are
799specified at:\n\n
800
801Xiph.Org Foundation:
802https://datatracker.ietf.org/ipr/1524/ \n\n
803
804Microsoft Corporation:
805https://datatracker.ietf.org/ipr/1914/ \n\n
806
807Broadcom Corporation:
808https://datatracker.ietf.org/ipr/1526/
809 </string>
810 <string name="license_sirit" translatable="false">Sirit</string>
811 <string name="license_sirit_description" translatable="false">A runtime SPIR-V assembler</string>
812 <string name="license_sirit_link" translatable="false">https://github.com/ReinUsesLisp/sirit</string>
813 <string name="license_sirit_copyright" translatable="false">Copyright © 2019, sirit All rights reserved.</string>
814 <string name="license_sirit_text" translatable="false">
815Redistribution and use in source and binary forms, with or without
816modification, are permitted provided that the following conditions are met:\n
817* Redistributions of source code must retain the above copyright
818 notice, this list of conditions and the following disclaimer.\n
819* Redistributions in binary form must reproduce the above copyright
820 notice, this list of conditions and the following disclaimer in the
821 documentation and/or other materials provided with the distribution.\n
822* Neither the name of the organization nor the
823 names of its contributors may be used to endorse or promote products
824 derived from this software without specific prior written permission.\n\n
825
826THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND
827ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
828WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
829DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY
830DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
831(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
832LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
833ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
834(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
835SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
836 </string>
837 <string name="license_adreno_tools" translatable="false">Adreno Tools</string>
838 <string name="license_adreno_tools_description" translatable="false">A library for applying rootless Adreno GPU driver modifications/replacements</string>
839 <string name="license_adreno_tools_link" translatable="false">https://github.com/bylaws/libadrenotools</string>
840 <string name="license_adreno_tools_copyright" translatable="false">Copyright © 2021, Billy Laws</string>
841 <string name="license_adreno_tools_text" translatable="false">
842BSD 2-Clause License\n\n
843
844Redistribution and use in source and binary forms, with or without
845modification, are permitted provided that the following conditions are met:\n\n
846
8471. Redistributions of source code must retain the above copyright notice, this
848 list of conditions and the following disclaimer.\n\n
849
8502. Redistributions in binary form must reproduce the above copyright notice,
851 this list of conditions and the following disclaimer in the documentation
852 and/or other materials provided with the distribution.\n\n
853
854THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\"
855AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
856IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
857DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
858FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
859DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
860SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
861CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
862OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
863OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
864 </string>
865
358</resources> 866</resources>