diff options
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 | ||
| 4 | import android.annotation.SuppressLint | ||
| 5 | |||
| 4 | plugins { | 6 | plugins { |
| 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 | ||
| 6 | import android.app.Activity | 6 | import android.app.Activity |
| 7 | import android.content.Context | 7 | import android.content.Context |
| 8 | import android.content.DialogInterface | ||
| 9 | import android.content.Intent | 8 | import android.content.Intent |
| 10 | import android.content.res.Configuration | 9 | import android.content.res.Configuration |
| 11 | import android.graphics.Rect | 10 | import android.graphics.Rect |
| @@ -13,22 +12,30 @@ import android.hardware.Sensor | |||
| 13 | import android.hardware.SensorEvent | 12 | import android.hardware.SensorEvent |
| 14 | import android.hardware.SensorEventListener | 13 | import android.hardware.SensorEventListener |
| 15 | import android.hardware.SensorManager | 14 | import android.hardware.SensorManager |
| 15 | import android.hardware.display.DisplayManager | ||
| 16 | import android.os.Bundle | 16 | import android.os.Bundle |
| 17 | import android.view.Display | ||
| 17 | import android.view.InputDevice | 18 | import android.view.InputDevice |
| 18 | import android.view.KeyEvent | 19 | import android.view.KeyEvent |
| 19 | import android.view.MotionEvent | 20 | import android.view.MotionEvent |
| 20 | import android.view.Surface | 21 | import android.view.Surface |
| 21 | import android.view.View | 22 | import android.view.View |
| 22 | import android.view.WindowManager | ||
| 23 | import android.view.inputmethod.InputMethodManager | 23 | import android.view.inputmethod.InputMethodManager |
| 24 | import androidx.activity.viewModels | ||
| 24 | import androidx.appcompat.app.AppCompatActivity | 25 | import androidx.appcompat.app.AppCompatActivity |
| 25 | import androidx.preference.PreferenceManager | 26 | import androidx.core.content.getSystemService |
| 26 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 27 | import androidx.core.view.WindowCompat |
| 27 | import com.google.android.material.slider.Slider.OnChangeListener | 28 | import androidx.core.view.WindowInsetsCompat |
| 29 | import androidx.core.view.WindowInsetsControllerCompat | ||
| 30 | import androidx.lifecycle.Lifecycle | ||
| 31 | import androidx.lifecycle.lifecycleScope | ||
| 32 | import androidx.lifecycle.repeatOnLifecycle | ||
| 33 | import androidx.window.layout.WindowInfoTracker | ||
| 34 | import kotlinx.coroutines.Dispatchers | ||
| 35 | import kotlinx.coroutines.launch | ||
| 28 | import org.yuzu.yuzu_emu.NativeLibrary | 36 | import org.yuzu.yuzu_emu.NativeLibrary |
| 29 | import org.yuzu.yuzu_emu.R | 37 | import org.yuzu.yuzu_emu.R |
| 30 | import org.yuzu.yuzu_emu.databinding.DialogSliderBinding | 38 | import org.yuzu.yuzu_emu.features.settings.model.SettingsViewModel |
| 31 | import org.yuzu.yuzu_emu.features.settings.model.Settings | ||
| 32 | import org.yuzu.yuzu_emu.fragments.EmulationFragment | 39 | import org.yuzu.yuzu_emu.fragments.EmulationFragment |
| 33 | import org.yuzu.yuzu_emu.model.Game | 40 | import org.yuzu.yuzu_emu.model.Game |
| 34 | import org.yuzu.yuzu_emu.utils.ControllerMappingHelper | 41 | import 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 | |||
| 4 | package org.yuzu.yuzu_emu.adapters | ||
| 5 | |||
| 6 | import android.view.LayoutInflater | ||
| 7 | import android.view.View | ||
| 8 | import android.view.ViewGroup | ||
| 9 | import androidx.appcompat.app.AppCompatActivity | ||
| 10 | import androidx.recyclerview.widget.RecyclerView | ||
| 11 | import androidx.recyclerview.widget.RecyclerView.ViewHolder | ||
| 12 | import org.yuzu.yuzu_emu.YuzuApplication | ||
| 13 | import org.yuzu.yuzu_emu.databinding.ListItemSettingBinding | ||
| 14 | import org.yuzu.yuzu_emu.fragments.LicenseBottomSheetDialogFragment | ||
| 15 | import org.yuzu.yuzu_emu.model.License | ||
| 16 | |||
| 17 | class 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 | |||
| 6 | import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting | 6 | import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting |
| 7 | 7 | ||
| 8 | class SubmenuSetting( | 8 | class 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 | |||
| 15 | import android.view.ViewGroup | 15 | import android.view.ViewGroup |
| 16 | import android.view.ViewGroup.MarginLayoutParams | 16 | import android.view.ViewGroup.MarginLayoutParams |
| 17 | import android.widget.Toast | 17 | import android.widget.Toast |
| 18 | import androidx.core.content.ContextCompat | ||
| 19 | import androidx.core.view.ViewCompat | 18 | import androidx.core.view.ViewCompat |
| 20 | import androidx.core.view.WindowInsetsCompat | 19 | import androidx.core.view.WindowInsetsCompat |
| 21 | import androidx.core.view.updatePadding | 20 | import androidx.core.view.updatePadding |
| 22 | import androidx.fragment.app.Fragment | 21 | import androidx.fragment.app.Fragment |
| 23 | import androidx.fragment.app.activityViewModels | 22 | import androidx.fragment.app.activityViewModels |
| 24 | import androidx.navigation.fragment.findNavController | 23 | import androidx.navigation.findNavController |
| 25 | import com.google.android.material.transition.MaterialSharedAxis | 24 | import com.google.android.material.transition.MaterialSharedAxis |
| 26 | import org.yuzu.yuzu_emu.BuildConfig | 25 | import org.yuzu.yuzu_emu.BuildConfig |
| 27 | import org.yuzu.yuzu_emu.R | 26 | import 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 | |||
| 8 | import android.content.Context | 8 | import android.content.Context |
| 9 | import android.content.DialogInterface | 9 | import android.content.DialogInterface |
| 10 | import android.content.SharedPreferences | 10 | import android.content.SharedPreferences |
| 11 | import android.content.pm.ActivityInfo | ||
| 12 | import android.content.res.Resources | ||
| 11 | import android.graphics.Color | 13 | import android.graphics.Color |
| 12 | import android.os.Bundle | 14 | import android.os.Bundle |
| 13 | import android.os.Handler | 15 | import android.os.Handler |
| 14 | import android.os.Looper | 16 | import android.os.Looper |
| 17 | import android.util.TypedValue | ||
| 15 | import android.view.* | 18 | import android.view.* |
| 16 | import android.widget.TextView | 19 | import android.widget.TextView |
| 17 | import androidx.activity.OnBackPressedCallback | 20 | import androidx.activity.OnBackPressedCallback |
| @@ -20,8 +23,11 @@ import androidx.core.content.res.ResourcesCompat | |||
| 20 | import androidx.core.graphics.Insets | 23 | import androidx.core.graphics.Insets |
| 21 | import androidx.core.view.ViewCompat | 24 | import androidx.core.view.ViewCompat |
| 22 | import androidx.core.view.WindowInsetsCompat | 25 | import androidx.core.view.WindowInsetsCompat |
| 26 | import androidx.core.view.updatePadding | ||
| 23 | import androidx.fragment.app.Fragment | 27 | import androidx.fragment.app.Fragment |
| 24 | import androidx.preference.PreferenceManager | 28 | import androidx.preference.PreferenceManager |
| 29 | import androidx.window.layout.FoldingFeature | ||
| 30 | import androidx.window.layout.WindowLayoutInfo | ||
| 25 | import com.google.android.material.dialog.MaterialAlertDialogBuilder | 31 | import com.google.android.material.dialog.MaterialAlertDialogBuilder |
| 26 | import com.google.android.material.slider.Slider | 32 | import com.google.android.material.slider.Slider |
| 27 | import org.yuzu.yuzu_emu.NativeLibrary | 33 | import 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 | |||
| 4 | package org.yuzu.yuzu_emu.fragments | ||
| 5 | |||
| 6 | import android.os.Bundle | ||
| 7 | import android.view.LayoutInflater | ||
| 8 | import android.view.View | ||
| 9 | import android.view.ViewGroup | ||
| 10 | import com.google.android.material.bottomsheet.BottomSheetBehavior | ||
| 11 | import com.google.android.material.bottomsheet.BottomSheetDialogFragment | ||
| 12 | import org.yuzu.yuzu_emu.databinding.DialogLicenseBinding | ||
| 13 | import org.yuzu.yuzu_emu.model.License | ||
| 14 | import org.yuzu.yuzu_emu.utils.SerializableHelper.parcelable | ||
| 15 | |||
| 16 | class 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 | |||
| 4 | package org.yuzu.yuzu_emu.fragments | ||
| 5 | |||
| 6 | import android.os.Bundle | ||
| 7 | import android.view.LayoutInflater | ||
| 8 | import android.view.View | ||
| 9 | import android.view.ViewGroup | ||
| 10 | import android.view.ViewGroup.MarginLayoutParams | ||
| 11 | import androidx.appcompat.app.AppCompatActivity | ||
| 12 | import androidx.core.view.ViewCompat | ||
| 13 | import androidx.core.view.WindowInsetsCompat | ||
| 14 | import androidx.core.view.updatePadding | ||
| 15 | import androidx.fragment.app.Fragment | ||
| 16 | import androidx.fragment.app.activityViewModels | ||
| 17 | import androidx.navigation.findNavController | ||
| 18 | import androidx.recyclerview.widget.LinearLayoutManager | ||
| 19 | import com.google.android.material.transition.MaterialSharedAxis | ||
| 20 | import org.yuzu.yuzu_emu.R | ||
| 21 | import org.yuzu.yuzu_emu.adapters.LicenseAdapter | ||
| 22 | import org.yuzu.yuzu_emu.databinding.FragmentLicensesBinding | ||
| 23 | import org.yuzu.yuzu_emu.model.HomeViewModel | ||
| 24 | import org.yuzu.yuzu_emu.model.License | ||
| 25 | |||
| 26 | class 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 | |||
| 4 | package org.yuzu.yuzu_emu.model | ||
| 5 | |||
| 6 | import android.os.Parcelable | ||
| 7 | import kotlinx.parcelize.Parcelize | ||
| 8 | |||
| 9 | @Parcelize | ||
| 10 | data 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 | |||
| 35 | import org.yuzu.yuzu_emu.databinding.ActivityMainBinding | 35 | import org.yuzu.yuzu_emu.databinding.ActivityMainBinding |
| 36 | import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding | 36 | import org.yuzu.yuzu_emu.databinding.DialogProgressBarBinding |
| 37 | import org.yuzu.yuzu_emu.features.settings.model.Settings | 37 | import org.yuzu.yuzu_emu.features.settings.model.Settings |
| 38 | import org.yuzu.yuzu_emu.features.settings.model.SettingsViewModel | ||
| 38 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity | 39 | import org.yuzu.yuzu_emu.features.settings.ui.SettingsActivity |
| 39 | import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile | 40 | import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile |
| 40 | import org.yuzu.yuzu_emu.fragments.IndeterminateProgressDialogFragment | 41 | import 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"> | ||
| 366 | Permission is hereby granted, free of charge, to any person obtaining a copy | ||
| 367 | of this software and associated documentation files (the \"Software"), to deal | ||
| 368 | in the Software without restriction, including without limitation the rights | ||
| 369 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
| 370 | copies of the Software, and to permit persons to whom the Software is | ||
| 371 | furnished to do so, subject to the following conditions:\n\n | ||
| 372 | |||
| 373 | The above copyright notice and this permission notice shall be included in | ||
| 374 | all copies or substantial portions of the Software.\n\n | ||
| 375 | |||
| 376 | THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
| 377 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
| 378 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
| 379 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
| 380 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
| 381 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | ||
| 382 | THE 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"> | ||
| 389 | Permission to use, copy, modify, and distribute this software for any | ||
| 390 | purpose with or without fee is hereby granted, provided that the above | ||
| 391 | copyright notice and this permission notice appear in all copies.\n\n | ||
| 392 | |||
| 393 | THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 394 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 395 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 396 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 397 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
| 398 | ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
| 399 | OR 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"> | ||
| 406 | Permission to use, copy, modify, and/or distribute this software for | ||
| 407 | any purpose with or without fee is hereby granted.\n\n | ||
| 408 | |||
| 409 | THE SOFTWARE IS PROVIDED \"AS IS\" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
| 410 | WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
| 411 | MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
| 412 | ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
| 413 | WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN | ||
| 414 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT | ||
| 415 | OF 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"> | ||
| 422 | GNU LESSER GENERAL PUBLIC LICENSE\n | ||
| 423 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\n\n | ||
| 424 | |||
| 425 | 0. This License Agreement applies to any software library or other | ||
| 426 | program which contains a notice placed by the copyright holder or | ||
| 427 | other authorized party saying it may be distributed under the terms of | ||
| 428 | this Lesser General Public License (also called \"this License\"). | ||
| 429 | Each licensee is addressed as \"you\".\n\n | ||
| 430 | |||
| 431 | A \"library\" means a collection of software functions and/or data | ||
| 432 | prepared 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 | ||
| 436 | which has been distributed under these terms. A \"work based on the | ||
| 437 | Library\" means either the Library or any derivative work under | ||
| 438 | copyright law: that is to say, a work containing the Library or a | ||
| 439 | portion of it, either verbatim or with modifications and/or translated | ||
| 440 | straightforwardly into another language. (Hereinafter, translation is | ||
| 441 | included without limitation in the term \"modification\".)\n\n | ||
| 442 | |||
| 443 | \"Source code\" for a work means the preferred form of the work for | ||
| 444 | making modifications to it. For a library, complete source code means | ||
| 445 | all the source code for all modules it contains, plus any associated | ||
| 446 | interface definition files, plus the scripts used to control compilation | ||
| 447 | and installation of the library.\n\n | ||
| 448 | |||
| 449 | Activities other than copying, distribution and modification are not | ||
| 450 | covered by this License; they are outside its scope. The act of | ||
| 451 | running a program using the Library is not restricted, and output from | ||
| 452 | such a program is covered only if its contents constitute a work based | ||
| 453 | on the Library (independent of the use of the Library in a tool for | ||
| 454 | writing it). Whether that is true depends on what the Library does | ||
| 455 | and what the program that uses the Library does.\n\n | ||
| 456 | |||
| 457 | 1. You may copy and distribute verbatim copies of the Library\'s | ||
| 458 | complete source code as you receive it, in any medium, provided that | ||
| 459 | you conspicuously and appropriately publish on each copy an | ||
| 460 | appropriate copyright notice and disclaimer of warranty; keep intact | ||
| 461 | all the notices that refer to this License and to the absence of any | ||
| 462 | warranty; and distribute a copy of this License along with the | ||
| 463 | Library.\n\n | ||
| 464 | |||
| 465 | You may charge a fee for the physical act of transferring a copy, | ||
| 466 | and you may at your option offer warranty protection in exchange for a | ||
| 467 | fee.\n\n | ||
| 468 | |||
| 469 | 2. You may modify your copy or copies of the Library or any portion | ||
| 470 | of it, thus forming a work based on the Library, and copy and | ||
| 471 | distribute such modifications or work under the terms of Section 1 | ||
| 472 | above, provided that you also meet all of these conditions:\n\n | ||
| 473 | |||
| 474 | a) The modified work must itself be a software library.\n\n | ||
| 475 | |||
| 476 | b) You must cause the files modified to carry prominent notices | ||
| 477 | stating that you changed the files and the date of any change.\n\n | ||
| 478 | |||
| 479 | c) You must cause the whole of the work to be licensed at no | ||
| 480 | charge to all third parties under the terms of this License.\n\n | ||
| 481 | |||
| 482 | d) If a facility in the modified Library refers to a function or a | ||
| 483 | table of data to be supplied by an application program that uses | ||
| 484 | the facility, other than as an argument passed when the facility | ||
| 485 | is invoked, then you must make a good faith effort to ensure that, | ||
| 486 | in the event an application does not supply such function or | ||
| 487 | table, the facility still operates, and performs whatever part of | ||
| 488 | its purpose remains meaningful.\n\n | ||
| 489 | |||
| 490 | (For example, a function in a library to compute square roots has | ||
| 491 | a purpose that is entirely well-defined independent of the | ||
| 492 | application. Therefore, Subsection 2d requires that any | ||
| 493 | application-supplied function or table used by this function must | ||
| 494 | be optional: if the application does not supply it, the square | ||
| 495 | root function must still compute square roots.)\n\n | ||
| 496 | |||
| 497 | These requirements apply to the modified work as a whole. If | ||
| 498 | identifiable sections of that work are not derived from the Library, | ||
| 499 | and can be reasonably considered independent and separate works in | ||
| 500 | themselves, then this License, and its terms, do not apply to those | ||
| 501 | sections when you distribute them as separate works. But when you | ||
| 502 | distribute the same sections as part of a whole which is a work based | ||
| 503 | on the Library, the distribution of the whole must be on the terms of | ||
| 504 | this License, whose permissions for other licensees extend to the | ||
| 505 | entire whole, and thus to each and every part regardless of who wrote | ||
| 506 | it.\n\n | ||
| 507 | |||
| 508 | Thus, it is not the intent of this section to claim rights or contest | ||
| 509 | your rights to work written entirely by you; rather, the intent is to | ||
| 510 | exercise the right to control the distribution of derivative or | ||
| 511 | collective works based on the Library.\n\n | ||
| 512 | |||
| 513 | In addition, mere aggregation of another work not based on the Library | ||
| 514 | with the Library (or with a work based on the Library) on a volume of | ||
| 515 | a storage or distribution medium does not bring the other work under | ||
| 516 | the scope of this License.\n\n | ||
| 517 | |||
| 518 | 3. You may opt to apply the terms of the ordinary GNU General Public | ||
| 519 | License instead of this License to a given copy of the Library. To do | ||
| 520 | this, you must alter all the notices that refer to this License, so | ||
| 521 | that they refer to the ordinary GNU General Public License, version 2, | ||
| 522 | instead of to this License. (If a newer version than version 2 of the | ||
| 523 | ordinary GNU General Public License has appeared, then you can specify | ||
| 524 | that version instead if you wish.) Do not make any other change in | ||
| 525 | these notices.\n\n | ||
| 526 | |||
| 527 | Once this change is made in a given copy, it is irreversible for | ||
| 528 | that copy, so the ordinary GNU General Public License applies to all | ||
| 529 | subsequent 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 | ||
| 532 | the 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 | ||
| 535 | derivative of it, under Section 2) in object code or executable form | ||
| 536 | under the terms of Sections 1 and 2 above provided that you accompany | ||
| 537 | it with the complete corresponding machine-readable source code, which | ||
| 538 | must be distributed under the terms of Sections 1 and 2 above on a | ||
| 539 | medium customarily used for software interchange.\n\n | ||
| 540 | |||
| 541 | If distribution of object code is made by offering access to copy | ||
| 542 | from a designated place, then offering equivalent access to copy the | ||
| 543 | source code from the same place satisfies the requirement to | ||
| 544 | distribute the source code, even though third parties are not | ||
| 545 | compelled 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 | ||
| 548 | Library, but is designed to work with the Library by being compiled or | ||
| 549 | linked with it, is called a \"work that uses the Library\". Such a | ||
| 550 | work, in isolation, is not a derivative work of the Library, and | ||
| 551 | therefore falls outside the scope of this License.\n\n | ||
| 552 | |||
| 553 | However, linking a \"work that uses the Library\" with the Library | ||
| 554 | creates an executable that is a derivative of the Library (because it | ||
| 555 | contains portions of the Library), rather than a \"work that uses the | ||
| 556 | library\". The executable is therefore covered by this License. | ||
| 557 | Section 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 | ||
| 560 | that is part of the Library, the object code for the work may be a | ||
| 561 | derivative work of the Library even though the source code is not. | ||
| 562 | Whether this is true is especially significant if the work can be | ||
| 563 | linked without the Library, or if the work is itself a library. The | ||
| 564 | threshold 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 | ||
| 567 | structure layouts and accessors, and small macros and small inline | ||
| 568 | functions (ten lines or less in length), then the use of the object | ||
| 569 | file is unrestricted, regardless of whether it is legally a derivative | ||
| 570 | work. (Executables containing this object code plus portions of the | ||
| 571 | Library will still fall under Section 6.)\n\n | ||
| 572 | |||
| 573 | Otherwise, if the work is a derivative of the Library, you may | ||
| 574 | distribute the object code for the work under the terms of Section 6. | ||
| 575 | Any executables containing that work also fall under Section 6, | ||
| 576 | whether 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 | ||
| 579 | link a \"work that uses the Library\" with the Library to produce a | ||
| 580 | work containing portions of the Library, and distribute that work | ||
| 581 | under terms of your choice, provided that the terms permit | ||
| 582 | modification of the work for the customer\'s own use and reverse | ||
| 583 | engineering for debugging such modifications.\n\n | ||
| 584 | |||
| 585 | You must give prominent notice with each copy of the work that the | ||
| 586 | Library is used in it and that the Library and its use are covered by | ||
| 587 | this License. You must supply a copy of this License. If the work | ||
| 588 | during execution displays copyright notices, you must include the | ||
| 589 | copyright notice for the Library among them, as well as a reference | ||
| 590 | directing the user to the copy of this License. Also, you must do one | ||
| 591 | of these things:\n\n | ||
| 592 | |||
| 593 | a) Accompany the work with the complete corresponding | ||
| 594 | machine-readable source code for the Library including whatever | ||
| 595 | changes were used in the work (which must be distributed under | ||
| 596 | Sections 1 and 2 above); and, if the work is an executable linked | ||
| 597 | with the Library, with the complete machine-readable \"work that | ||
| 598 | uses the Library\", as object code and/or source code, so that the | ||
| 599 | user can modify the Library and then relink to produce a modified | ||
| 600 | executable containing the modified Library. (It is understood | ||
| 601 | that the user who changes the contents of definitions files in the | ||
| 602 | Library will not necessarily be able to recompile the application | ||
| 603 | to use the modified definitions.)\n\n | ||
| 604 | |||
| 605 | b) Use a suitable shared library mechanism for linking with the | ||
| 606 | Library. A suitable mechanism is one that (1) uses at run time a | ||
| 607 | copy of the library already present on the user\'s computer system, | ||
| 608 | rather than copying library functions into the executable, and (2) | ||
| 609 | will operate properly with a modified version of the library, if | ||
| 610 | the user installs one, as long as the modified version is | ||
| 611 | interface-compatible with the version that the work was made with.\n\n | ||
| 612 | |||
| 613 | c) Accompany the work with a written offer, valid for at | ||
| 614 | least three years, to give the same user the materials | ||
| 615 | specified in Subsection 6a, above, for a charge no more | ||
| 616 | than the cost of performing this distribution.\n\n | ||
| 617 | |||
| 618 | d) If distribution of the work is made by offering access to copy | ||
| 619 | from a designated place, offer equivalent access to copy the above | ||
| 620 | specified materials from the same place.\n\n | ||
| 621 | |||
| 622 | e) Verify that the user has already received a copy of these | ||
| 623 | materials 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 | ||
| 626 | Library\" must include any data and utility programs needed for | ||
| 627 | reproducing the executable from it. However, as a special exception, | ||
| 628 | the materials to be distributed need not include anything that is | ||
| 629 | normally distributed (in either source or binary form) with the major | ||
| 630 | components (compiler, kernel, and so on) of the operating system on | ||
| 631 | which the executable runs, unless that component itself accompanies | ||
| 632 | the executable.\n\n | ||
| 633 | |||
| 634 | It may happen that this requirement contradicts the license | ||
| 635 | restrictions of other proprietary libraries that do not normally | ||
| 636 | accompany the operating system. Such a contradiction means you cannot | ||
| 637 | use both them and the Library together in an executable that you | ||
| 638 | distribute.\n\n | ||
| 639 | |||
| 640 | 7. You may place library facilities that are a work based on the | ||
| 641 | Library side-by-side in a single library together with other library | ||
| 642 | facilities not covered by this License, and distribute such a combined | ||
| 643 | library, provided that the separate distribution of the work based on | ||
| 644 | the Library and of the other library facilities is otherwise | ||
| 645 | permitted, and provided that you do these two things:\n\n | ||
| 646 | |||
| 647 | a) Accompany the combined library with a copy of the same work | ||
| 648 | based on the Library, uncombined with any other library | ||
| 649 | facilities. This must be distributed under the terms of the | ||
| 650 | Sections above.\n\n | ||
| 651 | |||
| 652 | b) Give prominent notice with the combined library of the fact | ||
| 653 | that part of it is a work based on the Library, and explaining | ||
| 654 | where 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 | ||
| 657 | the Library except as expressly provided under this License. Any | ||
| 658 | attempt otherwise to copy, modify, sublicense, link with, or | ||
| 659 | distribute the Library is void, and will automatically terminate your | ||
| 660 | rights under this License. However, parties who have received copies, | ||
| 661 | or rights, from you under this License will not have their licenses | ||
| 662 | terminated 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 | ||
| 665 | signed it. However, nothing else grants you permission to modify or | ||
| 666 | distribute the Library or its derivative works. These actions are | ||
| 667 | prohibited by law if you do not accept this License. Therefore, by | ||
| 668 | modifying or distributing the Library (or any work based on the | ||
| 669 | Library), you indicate your acceptance of this License to do so, and | ||
| 670 | all its terms and conditions for copying, distributing or modifying | ||
| 671 | the Library or works based on it.\n\n | ||
| 672 | |||
| 673 | 10. Each time you redistribute the Library (or any work based on the | ||
| 674 | Library), the recipient automatically receives a license from the | ||
| 675 | original licensor to copy, distribute, link with or modify the Library | ||
| 676 | subject to these terms and conditions. You may not impose any further | ||
| 677 | restrictions on the recipients\' exercise of the rights granted herein. | ||
| 678 | You are not responsible for enforcing compliance by third parties with | ||
| 679 | this License.\n\n | ||
| 680 | |||
| 681 | 11. If, as a consequence of a court judgment or allegation of patent | ||
| 682 | infringement or for any other reason (not limited to patent issues), | ||
| 683 | conditions are imposed on you (whether by court order, agreement or | ||
| 684 | otherwise) that contradict the conditions of this License, they do not | ||
| 685 | excuse you from the conditions of this License. If you cannot | ||
| 686 | distribute so as to satisfy simultaneously your obligations under this | ||
| 687 | License and any other pertinent obligations, then as a consequence you | ||
| 688 | may not distribute the Library at all. For example, if a patent | ||
| 689 | license would not permit royalty-free redistribution of the Library by | ||
| 690 | all those who receive copies directly or indirectly through you, then | ||
| 691 | the only way you could satisfy both it and this License would be to | ||
| 692 | refrain entirely from distribution of the Library.\n\n | ||
| 693 | |||
| 694 | If any portion of this section is held invalid or unenforceable under any | ||
| 695 | particular circumstance, the balance of the section is intended to apply, | ||
| 696 | and the section as a whole is intended to apply in other circumstances.\n\n | ||
| 697 | |||
| 698 | It is not the purpose of this section to induce you to infringe any | ||
| 699 | patents or other property right claims or to contest validity of any | ||
| 700 | such claims; this section has the sole purpose of protecting the | ||
| 701 | integrity of the free software distribution system which is | ||
| 702 | implemented by public license practices. Many people have made | ||
| 703 | generous contributions to the wide range of software distributed | ||
| 704 | through that system in reliance on consistent application of that | ||
| 705 | system; it is up to the author/donor to decide if he or she is willing | ||
| 706 | to distribute software through any other system and a licensee cannot | ||
| 707 | impose that choice.\n\n | ||
| 708 | |||
| 709 | This section is intended to make thoroughly clear what is believed to | ||
| 710 | be 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 | ||
| 713 | certain countries either by patents or by copyrighted interfaces, the | ||
| 714 | original copyright holder who places the Library under this License may add | ||
| 715 | an explicit geographical distribution limitation excluding those countries, | ||
| 716 | so that distribution is permitted only in or among countries not thus | ||
| 717 | excluded. In such case, this License incorporates the limitation as if | ||
| 718 | written in the body of this License.\n\n | ||
| 719 | |||
| 720 | 13. The Free Software Foundation may publish revised and/or new | ||
| 721 | versions of the Lesser General Public License from time to time. | ||
| 722 | Such new versions will be similar in spirit to the present version, | ||
| 723 | but may differ in detail to address new problems or concerns.\n\n | ||
| 724 | |||
| 725 | Each version is given a distinguishing version number. If the Library | ||
| 726 | specifies a version number of this License which applies to it and | ||
| 727 | "any later version\", you have the option of following the terms and | ||
| 728 | conditions either of that version or of any later version published by | ||
| 729 | the Free Software Foundation. If the Library does not specify a | ||
| 730 | license version number, you may choose any version ever published by | ||
| 731 | the Free Software Foundation.\n\n | ||
| 732 | |||
| 733 | 14. If you wish to incorporate parts of the Library into other free | ||
| 734 | programs whose distribution conditions are incompatible with these, | ||
| 735 | write to the author to ask for permission. For software which is | ||
| 736 | copyrighted by the Free Software Foundation, write to the Free | ||
| 737 | Software Foundation; we sometimes make exceptions for this. Our | ||
| 738 | decision will be guided by the two goals of preserving the free status | ||
| 739 | of all derivatives of our free software and of promoting the sharing | ||
| 740 | and reuse of software generally.\n\n | ||
| 741 | |||
| 742 | NO WARRANTY\n\n | ||
| 743 | |||
| 744 | 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO | ||
| 745 | WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. | ||
| 746 | EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR | ||
| 747 | OTHER PARTIES PROVIDE THE LIBRARY \"AS IS\" WITHOUT WARRANTY OF ANY | ||
| 748 | KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 749 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR | ||
| 750 | PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE | ||
| 751 | LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME | ||
| 752 | THE 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 | ||
| 755 | WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY | ||
| 756 | AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU | ||
| 757 | FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR | ||
| 758 | CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE | ||
| 759 | LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING | ||
| 760 | RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A | ||
| 761 | FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF | ||
| 762 | SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH | ||
| 763 | DAMAGES. | ||
| 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"> | ||
| 770 | Redistribution and use in source and binary forms, with or without | ||
| 771 | modification, are permitted provided that the following conditions | ||
| 772 | are met:\n\n | ||
| 773 | |||
| 774 | - Redistributions of source code must retain the above copyright | ||
| 775 | notice, this list of conditions and the following disclaimer.\n\n | ||
| 776 | |||
| 777 | - Redistributions in binary form must reproduce the above copyright | ||
| 778 | notice, this list of conditions and the following disclaimer in the | ||
| 779 | documentation and/or other materials provided with the distribution.\n\n | ||
| 780 | |||
| 781 | - Neither the name of Internet Society, IETF or IETF Trust, nor the | ||
| 782 | names of specific contributors, may be used to endorse or promote | ||
| 783 | products derived from this software without specific prior written | ||
| 784 | permission.\n\n | ||
| 785 | |||
| 786 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| 787 | ``AS IS\'\' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| 788 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| 789 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER | ||
| 790 | OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | ||
| 791 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | ||
| 792 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | ||
| 793 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | ||
| 794 | LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | ||
| 795 | NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
| 796 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n\n | ||
| 797 | |||
| 798 | Opus is subject to the royalty-free patent licenses which are | ||
| 799 | specified at:\n\n | ||
| 800 | |||
| 801 | Xiph.Org Foundation: | ||
| 802 | https://datatracker.ietf.org/ipr/1524/ \n\n | ||
| 803 | |||
| 804 | Microsoft Corporation: | ||
| 805 | https://datatracker.ietf.org/ipr/1914/ \n\n | ||
| 806 | |||
| 807 | Broadcom Corporation: | ||
| 808 | https://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"> | ||
| 815 | Redistribution and use in source and binary forms, with or without | ||
| 816 | modification, 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 | |||
| 826 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND | ||
| 827 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
| 828 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| 829 | DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER BE LIABLE FOR ANY | ||
| 830 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
| 831 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
| 832 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
| 833 | ON 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 | ||
| 835 | SOFTWARE, 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"> | ||
| 842 | BSD 2-Clause License\n\n | ||
| 843 | |||
| 844 | Redistribution and use in source and binary forms, with or without | ||
| 845 | modification, are permitted provided that the following conditions are met:\n\n | ||
| 846 | |||
| 847 | 1. Redistributions of source code must retain the above copyright notice, this | ||
| 848 | list of conditions and the following disclaimer.\n\n | ||
| 849 | |||
| 850 | 2. 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 | |||
| 854 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" | ||
| 855 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | ||
| 856 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
| 857 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE | ||
| 858 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | ||
| 859 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | ||
| 860 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER | ||
| 861 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | ||
| 862 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| 863 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| 864 | </string> | ||
| 865 | |||
| 358 | </resources> | 866 | </resources> |