mirror of
https://github.com/skyline-emu/skyline.git
synced 2024-11-16 18:59:18 +01:00
Add per-game settings configuration functionality
This commit is contained in:
parent
0467614dc0
commit
1a11aaa651
@ -23,6 +23,7 @@ import com.google.android.material.snackbar.Snackbar
|
|||||||
import emu.skyline.data.AppItem
|
import emu.skyline.data.AppItem
|
||||||
import emu.skyline.databinding.AppDialogBinding
|
import emu.skyline.databinding.AppDialogBinding
|
||||||
import emu.skyline.loader.LoaderResult
|
import emu.skyline.loader.LoaderResult
|
||||||
|
import emu.skyline.settings.SettingsActivity
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This dialog is used to show extra game metadata and provide extra options such as pinning the game to the home screen
|
* This dialog is used to show extra game metadata and provide extra options such as pinning the game to the home screen
|
||||||
@ -75,6 +76,13 @@ class AppDialog : BottomSheetDialogFragment() {
|
|||||||
startActivity(Intent(activity, EmulationActivity::class.java).apply { data = item.uri })
|
startActivity(Intent(activity, EmulationActivity::class.java).apply { data = item.uri })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding.gameSettings.isEnabled = item.loaderResult == LoaderResult.Success
|
||||||
|
binding.gameSettings.setOnClickListener {
|
||||||
|
startActivity(Intent(activity, SettingsActivity::class.java).apply {
|
||||||
|
putExtras(requireArguments())
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
val shortcutManager = requireActivity().getSystemService(ShortcutManager::class.java)
|
val shortcutManager = requireActivity().getSystemService(ShortcutManager::class.java)
|
||||||
binding.gamePin.isEnabled = shortcutManager.isRequestPinShortcutSupported
|
binding.gamePin.isEnabled = shortcutManager.isRequestPinShortcutSupported
|
||||||
|
|
||||||
|
@ -333,7 +333,6 @@ class MainActivity : AppCompatActivity() {
|
|||||||
super.onResume()
|
super.onResume()
|
||||||
|
|
||||||
// Try to return to normal GPU clocks upon resuming back to main activity, to avoid GPU being stuck at max clocks after a crash
|
// Try to return to normal GPU clocks upon resuming back to main activity, to avoid GPU being stuck at max clocks after a crash
|
||||||
if (EmulationSettings.global.forceMaxGpuClocks)
|
|
||||||
GpuDriverHelper.forceMaxGpuClocks(false)
|
GpuDriverHelper.forceMaxGpuClocks(false)
|
||||||
|
|
||||||
var layoutTypeChanged = false
|
var layoutTypeChanged = false
|
||||||
|
@ -22,6 +22,7 @@ import emu.skyline.adapter.GenericListItem
|
|||||||
import emu.skyline.adapter.GpuDriverViewItem
|
import emu.skyline.adapter.GpuDriverViewItem
|
||||||
import emu.skyline.adapter.SelectableGenericAdapter
|
import emu.skyline.adapter.SelectableGenericAdapter
|
||||||
import emu.skyline.adapter.SpacingItemDecoration
|
import emu.skyline.adapter.SpacingItemDecoration
|
||||||
|
import emu.skyline.data.AppItem
|
||||||
import emu.skyline.databinding.GpuDriverActivityBinding
|
import emu.skyline.databinding.GpuDriverActivityBinding
|
||||||
import emu.skyline.settings.EmulationSettings
|
import emu.skyline.settings.EmulationSettings
|
||||||
import emu.skyline.utils.GpuDriverHelper
|
import emu.skyline.utils.GpuDriverHelper
|
||||||
@ -38,6 +39,8 @@ import kotlinx.coroutines.launch
|
|||||||
class GpuDriverActivity : AppCompatActivity() {
|
class GpuDriverActivity : AppCompatActivity() {
|
||||||
private val binding by lazy { GpuDriverActivityBinding.inflate(layoutInflater) }
|
private val binding by lazy { GpuDriverActivityBinding.inflate(layoutInflater) }
|
||||||
|
|
||||||
|
private val item by lazy { intent.extras?.getSerializable("item") as AppItem? }
|
||||||
|
|
||||||
private val adapter = SelectableGenericAdapter(0)
|
private val adapter = SelectableGenericAdapter(0)
|
||||||
|
|
||||||
lateinit var emulationSettings : EmulationSettings
|
lateinit var emulationSettings : EmulationSettings
|
||||||
@ -80,7 +83,8 @@ class GpuDriverActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
GpuDriverHelper.getInstalledDrivers(this).onEachIndexed { index, (file, metadata) ->
|
GpuDriverHelper.getInstalledDrivers(this).onEachIndexed { index, (file, metadata) ->
|
||||||
items.add(GpuDriverViewItem(metadata).apply {
|
items.add(GpuDriverViewItem(metadata).apply {
|
||||||
onDelete = { position, wasChecked ->
|
// Enable the delete button when configuring global settings only
|
||||||
|
onDelete = if (emulationSettings.isGlobal) { position, wasChecked ->
|
||||||
// If the driver was selected, select the system driver as the active one
|
// If the driver was selected, select the system driver as the active one
|
||||||
if (wasChecked)
|
if (wasChecked)
|
||||||
emulationSettings.gpuDriver = EmulationSettings.SYSTEM_GPU_DRIVER
|
emulationSettings.gpuDriver = EmulationSettings.SYSTEM_GPU_DRIVER
|
||||||
@ -103,7 +107,7 @@ class GpuDriverActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}).show()
|
}).show()
|
||||||
}
|
} else null
|
||||||
|
|
||||||
onClick = {
|
onClick = {
|
||||||
emulationSettings.gpuDriver = metadata.label
|
emulationSettings.gpuDriver = metadata.label
|
||||||
@ -127,8 +131,18 @@ class GpuDriverActivity : AppCompatActivity() {
|
|||||||
WindowInsetsHelper.addMargin(binding.addDriverButton, bottom = true)
|
WindowInsetsHelper.addMargin(binding.addDriverButton, bottom = true)
|
||||||
|
|
||||||
setSupportActionBar(binding.titlebar.toolbar)
|
setSupportActionBar(binding.titlebar.toolbar)
|
||||||
supportActionBar?.setDisplayHomeAsUpEnabled(true)
|
supportActionBar?.apply {
|
||||||
supportActionBar?.title = getString(R.string.gpu_driver_config)
|
setDisplayHomeAsUpEnabled(true)
|
||||||
|
title = getString(R.string.gpu_driver_config)
|
||||||
|
subtitle = item?.title
|
||||||
|
}
|
||||||
|
|
||||||
|
emulationSettings = if (item == null) {
|
||||||
|
EmulationSettings.global
|
||||||
|
} else {
|
||||||
|
val appItem = item as AppItem
|
||||||
|
EmulationSettings.forTitleId(appItem.titleId ?: appItem.key())
|
||||||
|
}
|
||||||
|
|
||||||
val layoutManager = LinearLayoutManager(this)
|
val layoutManager = LinearLayoutManager(this)
|
||||||
binding.driverList.layoutManager = layoutManager
|
binding.driverList.layoutManager = layoutManager
|
||||||
@ -173,7 +187,6 @@ class GpuDriverActivity : AppCompatActivity() {
|
|||||||
installCallback.launch(intent)
|
installCallback.launch(intent)
|
||||||
}
|
}
|
||||||
|
|
||||||
emulationSettings = EmulationSettings.global
|
|
||||||
populateAdapter()
|
populateAdapter()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,6 +13,7 @@ import androidx.activity.result.contract.ActivityResultContracts
|
|||||||
import androidx.preference.Preference
|
import androidx.preference.Preference
|
||||||
import androidx.preference.Preference.SummaryProvider
|
import androidx.preference.Preference.SummaryProvider
|
||||||
import androidx.preference.R
|
import androidx.preference.R
|
||||||
|
import emu.skyline.data.AppItem
|
||||||
import emu.skyline.settings.EmulationSettings
|
import emu.skyline.settings.EmulationSettings
|
||||||
import emu.skyline.utils.GpuDriverHelper
|
import emu.skyline.utils.GpuDriverHelper
|
||||||
import emu.skyline.R as SkylineR
|
import emu.skyline.R as SkylineR
|
||||||
@ -25,6 +26,12 @@ class GpuDriverPreference @JvmOverloads constructor(context : Context, attrs : A
|
|||||||
notifyChanged()
|
notifyChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The app item being configured, used to load the correct settings in [GpuDriverActivity]
|
||||||
|
* This is populated by [emu.skyline.settings.GameSettingsFragment]
|
||||||
|
*/
|
||||||
|
var item : AppItem? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val supportsCustomDriverLoading = GpuDriverHelper.supportsCustomDriverLoading()
|
val supportsCustomDriverLoading = GpuDriverHelper.supportsCustomDriverLoading()
|
||||||
if (supportsCustomDriverLoading) {
|
if (supportsCustomDriverLoading) {
|
||||||
@ -48,5 +55,7 @@ class GpuDriverPreference @JvmOverloads constructor(context : Context, attrs : A
|
|||||||
/**
|
/**
|
||||||
* This launches [GpuDriverActivity] on click to manage driver packages
|
* This launches [GpuDriverActivity] on click to manage driver packages
|
||||||
*/
|
*/
|
||||||
override fun onClick() = driverCallback.launch(Intent(context, GpuDriverActivity::class.java))
|
override fun onClick() = driverCallback.launch(Intent(context, GpuDriverActivity::class.java).apply {
|
||||||
|
putExtra("item", item)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
* Copyright © 2023 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
*/
|
||||||
|
|
||||||
|
package emu.skyline.preference
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.content.Context
|
||||||
|
import android.util.AttributeSet
|
||||||
|
import androidx.preference.Preference
|
||||||
|
import com.google.android.material.dialog.MaterialAlertDialogBuilder
|
||||||
|
import emu.skyline.R
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears all values in the current shared preferences, showing a dialog to confirm the action
|
||||||
|
* This preference recreates the activity to update the UI after modifying shared preferences
|
||||||
|
*/
|
||||||
|
class ResetSettingsPreference @JvmOverloads constructor(context : Context, attrs : AttributeSet? = null, defStyleAttr : Int = androidx.preference.R.attr.preferenceStyle) : Preference(context, attrs, defStyleAttr) {
|
||||||
|
init {
|
||||||
|
setOnPreferenceClickListener {
|
||||||
|
MaterialAlertDialogBuilder(context)
|
||||||
|
.setTitle(title)
|
||||||
|
.setMessage(R.string.reset_settings_warning)
|
||||||
|
.setPositiveButton(android.R.string.ok) { _, _ ->
|
||||||
|
// Clear all shared preferences
|
||||||
|
sharedPreferences?.apply { edit().clear().apply() }
|
||||||
|
// Recreate the activity to update the UI after modifying shared preferences
|
||||||
|
(context as? Activity)?.recreate()
|
||||||
|
}
|
||||||
|
.setNegativeButton(android.R.string.cancel, null)
|
||||||
|
.show()
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,93 @@
|
|||||||
|
/*
|
||||||
|
* SPDX-License-Identifier: MPL-2.0
|
||||||
|
* Copyright © 2023 Skyline Team and Contributors (https://github.com/skyline-emu/)
|
||||||
|
*/
|
||||||
|
|
||||||
|
package emu.skyline.settings
|
||||||
|
|
||||||
|
import android.os.Bundle
|
||||||
|
import android.view.View
|
||||||
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
|
import androidx.preference.*
|
||||||
|
import emu.skyline.BuildConfig
|
||||||
|
import emu.skyline.R
|
||||||
|
import emu.skyline.data.AppItem
|
||||||
|
import emu.skyline.preference.GpuDriverPreference
|
||||||
|
import emu.skyline.preference.IntegerListPreference
|
||||||
|
import emu.skyline.utils.GpuDriverHelper
|
||||||
|
import emu.skyline.utils.WindowInsetsHelper
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This fragment is used to display custom game preferences
|
||||||
|
*/
|
||||||
|
class GameSettingsFragment : PreferenceFragmentCompat() {
|
||||||
|
companion object {
|
||||||
|
private const val DIALOG_FRAGMENT_TAG = "androidx.preference.PreferenceFragment.DIALOG"
|
||||||
|
}
|
||||||
|
|
||||||
|
private val item by lazy { requireArguments().getSerializable("item")!! as AppItem }
|
||||||
|
|
||||||
|
override fun onViewCreated(view : View, savedInstanceState : Bundle?) {
|
||||||
|
super.onViewCreated(view, savedInstanceState)
|
||||||
|
val recyclerView = view.findViewById<View>(R.id.recycler_view)
|
||||||
|
WindowInsetsHelper.setPadding(recyclerView, bottom = true)
|
||||||
|
|
||||||
|
(activity as AppCompatActivity).supportActionBar?.subtitle = item.title
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This constructs the preferences from XML preference resources
|
||||||
|
*/
|
||||||
|
override fun onCreatePreferences(savedInstanceState : Bundle?, rootKey : String?) {
|
||||||
|
preferenceManager.sharedPreferencesName = EmulationSettings.prefNameForTitle(item.titleId ?: item.key())
|
||||||
|
addPreferencesFromResource(R.xml.custom_game_preferences)
|
||||||
|
addPreferencesFromResource(R.xml.emulation_preferences)
|
||||||
|
|
||||||
|
// Toggle emulation settings enabled state based on use_custom_settings state
|
||||||
|
listOf<Preference?>(
|
||||||
|
findPreference("category_system"),
|
||||||
|
findPreference("category_presentation"),
|
||||||
|
findPreference("category_gpu"),
|
||||||
|
findPreference("category_hacks"),
|
||||||
|
findPreference("category_audio"),
|
||||||
|
findPreference("category_debug")
|
||||||
|
).forEach { it?.dependency = "use_custom_settings" }
|
||||||
|
|
||||||
|
// Uncheck `disable_frame_throttling` if `force_triple_buffering` gets disabled
|
||||||
|
val disableFrameThrottlingPref = findPreference<CheckBoxPreference>("disable_frame_throttling")!!
|
||||||
|
findPreference<CheckBoxPreference>("force_triple_buffering")?.setOnPreferenceChangeListener { _, newValue ->
|
||||||
|
if (newValue == false)
|
||||||
|
disableFrameThrottlingPref.isChecked = false
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only show debug settings in debug builds
|
||||||
|
@Suppress("SENSELESS_COMPARISON")
|
||||||
|
if (BuildConfig.BUILD_TYPE != "release")
|
||||||
|
findPreference<Preference>("category_debug")?.isVisible = true
|
||||||
|
|
||||||
|
if (!GpuDriverHelper.supportsForceMaxGpuClocks()) {
|
||||||
|
val forceMaxGpuClocksPref = findPreference<CheckBoxPreference>("force_max_gpu_clocks")!!
|
||||||
|
forceMaxGpuClocksPref.isSelectable = false
|
||||||
|
forceMaxGpuClocksPref.isChecked = false
|
||||||
|
forceMaxGpuClocksPref.summary = context!!.getString(R.string.force_max_gpu_clocks_desc_unsupported)
|
||||||
|
}
|
||||||
|
|
||||||
|
findPreference<GpuDriverPreference>("gpu_driver")?.item = item
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onDisplayPreferenceDialog(preference : Preference) {
|
||||||
|
if (preference is IntegerListPreference) {
|
||||||
|
// Check if dialog is already showing
|
||||||
|
if (parentFragmentManager.findFragmentByTag(DIALOG_FRAGMENT_TAG) != null)
|
||||||
|
return
|
||||||
|
|
||||||
|
val dialogFragment = IntegerListPreference.IntegerListPreferenceDialogFragmentCompat.newInstance(preference.getKey())
|
||||||
|
@Suppress("DEPRECATION")
|
||||||
|
dialogFragment.setTargetFragment(this, 0) // androidx.preference.PreferenceDialogFragmentCompat depends on the target fragment being set correctly even though it's deprecated
|
||||||
|
dialogFragment.show(parentFragmentManager, DIALOG_FRAGMENT_TAG)
|
||||||
|
} else {
|
||||||
|
super.onDisplayPreferenceDialog(preference)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -25,8 +25,12 @@ class SettingsActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The instance of [PreferenceFragmentCompat] that is shown inside [R.id.settings]
|
* The instance of [PreferenceFragmentCompat] that is shown inside [R.id.settings]
|
||||||
|
* Retrieves extras from the intent if any and instantiates the appropriate fragment
|
||||||
*/
|
*/
|
||||||
private val preferenceFragment by lazy {
|
private val preferenceFragment by lazy {
|
||||||
|
if (intent.hasExtra("item"))
|
||||||
|
GameSettingsFragment().apply { arguments = intent.extras }
|
||||||
|
else
|
||||||
GlobalSettingsFragment()
|
GlobalSettingsFragment()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:nextFocusRight="@id/game_play"
|
android:nextFocusRight="@id/game_play"
|
||||||
android:paddingHorizontal="16dp"
|
android:paddingHorizontal="16dp"
|
||||||
android:paddingBottom="16dp">
|
android:paddingBottom="8dp">
|
||||||
|
|
||||||
<com.google.android.material.imageview.ShapeableImageView
|
<com.google.android.material.imageview.ShapeableImageView
|
||||||
android:id="@+id/game_icon"
|
android:id="@+id/game_icon"
|
||||||
@ -36,9 +36,8 @@
|
|||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="16dp"
|
android:layout_marginStart="16dp"
|
||||||
app:layout_constraintHeight_min="140dp"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintHeight_min="140dp"
|
||||||
app:layout_constraintStart_toEndOf="@id/game_icon"
|
app:layout_constraintStart_toEndOf="@id/game_icon"
|
||||||
app:layout_constraintTop_toTopOf="parent">
|
app:layout_constraintTop_toTopOf="parent">
|
||||||
|
|
||||||
@ -86,14 +85,17 @@
|
|||||||
app:layout_constraintTop_toBottomOf="@id/game_version"
|
app:layout_constraintTop_toBottomOf="@id/game_version"
|
||||||
tools:text="Nintendo" />
|
tools:text="Nintendo" />
|
||||||
|
|
||||||
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
|
|
||||||
<com.google.android.flexbox.FlexboxLayout
|
<com.google.android.flexbox.FlexboxLayout
|
||||||
android:layout_width="0dp"
|
android:layout_width="0dp"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginTop="8dp"
|
||||||
app:flexWrap="nowrap"
|
app:flexWrap="nowrap"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
app:layout_constraintBottom_toBottomOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toBottomOf="@+id/game_author"
|
app:layout_constraintTop_toBottomOf="@id/game_icon"
|
||||||
app:layout_constraintVertical_bias="1">
|
app:layout_constraintVertical_bias="1">
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@ -108,7 +110,20 @@
|
|||||||
app:icon="@drawable/ic_play"
|
app:icon="@drawable/ic_play"
|
||||||
app:iconTint="?attr/colorAccent"
|
app:iconTint="?attr/colorAccent"
|
||||||
app:layout_flexGrow="1"
|
app:layout_flexGrow="1"
|
||||||
app:layout_maxWidth="180dp" />
|
app:layout_maxWidth="140dp" />
|
||||||
|
|
||||||
|
<Button
|
||||||
|
android:id="@+id/game_settings"
|
||||||
|
style="@style/Widget.MaterialComponents.Button.OutlinedButton.Icon"
|
||||||
|
android:layout_width="48dp"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:layout_marginStart="8dp"
|
||||||
|
android:contentDescription="@string/settings"
|
||||||
|
android:padding="0dp"
|
||||||
|
android:textColor="?attr/colorAccent"
|
||||||
|
app:icon="@drawable/ic_settings"
|
||||||
|
app:iconGravity="textStart"
|
||||||
|
app:iconPadding="0dp" />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
android:id="@+id/game_pin"
|
android:id="@+id/game_pin"
|
||||||
@ -117,12 +132,12 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginStart="8dp"
|
android:layout_marginStart="8dp"
|
||||||
android:contentDescription="@string/pin"
|
android:contentDescription="@string/pin"
|
||||||
|
android:padding="0dp"
|
||||||
android:textColor="?attr/colorAccent"
|
android:textColor="?attr/colorAccent"
|
||||||
app:icon="@drawable/ic_add_home"
|
app:icon="@drawable/ic_add_home"
|
||||||
app:iconGravity="textStart"
|
app:iconGravity="textStart"
|
||||||
android:padding="0dp"
|
|
||||||
app:iconPadding="0dp" />
|
app:iconPadding="0dp" />
|
||||||
|
|
||||||
</com.google.android.flexbox.FlexboxLayout>
|
</com.google.android.flexbox.FlexboxLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
|
@ -43,6 +43,14 @@
|
|||||||
<string name="select_action">Always Show Game Information</string>
|
<string name="select_action">Always Show Game Information</string>
|
||||||
<string name="select_action_desc_on">Game information will be shown on clicking a game</string>
|
<string name="select_action_desc_on">Game information will be shown on clicking a game</string>
|
||||||
<string name="select_action_desc_off">Game information will only be shown on long-clicking a game</string>
|
<string name="select_action_desc_off">Game information will only be shown on long-clicking a game</string>
|
||||||
|
<!-- Settings - Game -->
|
||||||
|
<string name="game">Game</string>
|
||||||
|
<string name="use_custom_settings">Enable Custom Settings</string>
|
||||||
|
<string name="use_custom_settings_desc_on">Custom settings are enabled for this game</string>
|
||||||
|
<string name="use_custom_settings_desc_off">Custom settings are disabled for this game</string>
|
||||||
|
<string name="reset_custom_settings">Reset Custom Settings</string>
|
||||||
|
<string name="reset_custom_settings_desc">Reset custom settings to the default values</string>
|
||||||
|
<string name="reset_settings_warning">Are you sure you want to reset all settings to the default values? <b>Current settings will be lost</b></string>
|
||||||
<!-- Settings - System -->
|
<!-- Settings - System -->
|
||||||
<string name="system">System</string>
|
<string name="system">System</string>
|
||||||
<string name="use_docked">Use Docked Mode</string>
|
<string name="use_docked">Use Docked Mode</string>
|
||||||
|
17
app/src/main/res/xml/custom_game_preferences.xml
Normal file
17
app/src/main/res/xml/custom_game_preferences.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<androidx.preference.PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:app="http://schemas.android.com/apk/res-auto">
|
||||||
|
<PreferenceCategory
|
||||||
|
android:key="category_game"
|
||||||
|
android:title="@string/game">
|
||||||
|
<CheckBoxPreference
|
||||||
|
android:defaultValue="false"
|
||||||
|
android:summaryOff="@string/use_custom_settings_desc_off"
|
||||||
|
android:summaryOn="@string/use_custom_settings_desc_on"
|
||||||
|
app:key="use_custom_settings"
|
||||||
|
app:title="@string/use_custom_settings" />
|
||||||
|
<emu.skyline.preference.ResetSettingsPreference
|
||||||
|
android:summary="@string/reset_custom_settings_desc"
|
||||||
|
app:key="reset_custom_settings"
|
||||||
|
app:title="@string/reset_custom_settings" />
|
||||||
|
</PreferenceCategory>
|
||||||
|
</androidx.preference.PreferenceScreen>
|
Loading…
Reference in New Issue
Block a user