android: Abstract settings
Previously we could only add settings that would change our ini file. Now we can create abstract settings in our presenter to alter things like shared preferences for theme support!
This commit is contained in:
parent
6dfe4240ac
commit
c609847e49
24 changed files with 417 additions and 362 deletions
|
@ -0,0 +1,8 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.features.settings.model
|
||||||
|
|
||||||
|
interface AbstractBooleanSetting : AbstractSetting {
|
||||||
|
var boolean: Boolean
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.features.settings.model
|
||||||
|
|
||||||
|
interface AbstractFloatSetting : AbstractSetting {
|
||||||
|
var float: Float
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.features.settings.model
|
||||||
|
|
||||||
|
interface AbstractIntSetting : AbstractSetting {
|
||||||
|
var int: Int
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.features.settings.model
|
||||||
|
|
||||||
|
interface AbstractSetting {
|
||||||
|
val key: String?
|
||||||
|
val section: String?
|
||||||
|
val isRuntimeEditable: Boolean
|
||||||
|
val valueAsString: String
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
package org.yuzu.yuzu_emu.features.settings.model
|
||||||
|
|
||||||
|
interface AbstractStringSetting : AbstractSetting {
|
||||||
|
var string: String
|
||||||
|
}
|
|
@ -3,10 +3,33 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model
|
package org.yuzu.yuzu_emu.features.settings.model
|
||||||
|
|
||||||
class BooleanSetting(
|
enum class BooleanSetting(
|
||||||
key: String,
|
override val key: String,
|
||||||
section: String,
|
override val section: String,
|
||||||
var value: Boolean
|
val defaultValue: Boolean
|
||||||
) : Setting(key, section) {
|
) : AbstractBooleanSetting {
|
||||||
override val valueAsString get() = if (value) "True" else "False"
|
// No boolean settings currently exist
|
||||||
|
EMPTY_SETTING("", "", false);
|
||||||
|
|
||||||
|
override var boolean: Boolean = defaultValue
|
||||||
|
|
||||||
|
override val valueAsString: String
|
||||||
|
get() = boolean.toString()
|
||||||
|
|
||||||
|
override val isRuntimeEditable: Boolean
|
||||||
|
get() {
|
||||||
|
for (setting in NOT_RUNTIME_EDITABLE) {
|
||||||
|
if (setting == this) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val NOT_RUNTIME_EDITABLE = emptyList<BooleanSetting>()
|
||||||
|
|
||||||
|
fun from(key: String): BooleanSetting? =
|
||||||
|
BooleanSetting.values().firstOrNull { it.key == key }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,32 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model
|
package org.yuzu.yuzu_emu.features.settings.model
|
||||||
|
|
||||||
class FloatSetting(
|
enum class FloatSetting(
|
||||||
key: String,
|
override val key: String,
|
||||||
section: String,
|
override val section: String,
|
||||||
var value: Float
|
val defaultValue: Float
|
||||||
) : Setting(key, section) {
|
) : AbstractFloatSetting {
|
||||||
override val valueAsString get() = value.toString()
|
// No float settings currently exist
|
||||||
|
EMPTY_SETTING("", "", 0f);
|
||||||
|
|
||||||
|
override var float: Float = defaultValue
|
||||||
|
|
||||||
|
override val valueAsString: String
|
||||||
|
get() = float.toString()
|
||||||
|
|
||||||
|
override val isRuntimeEditable: Boolean
|
||||||
|
get() {
|
||||||
|
for (setting in NOT_RUNTIME_EDITABLE) {
|
||||||
|
if (setting == this) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val NOT_RUNTIME_EDITABLE = emptyList<FloatSetting>()
|
||||||
|
|
||||||
|
fun from(key: String): FloatSetting? = FloatSetting.values().firstOrNull { it.key == key }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,121 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model
|
package org.yuzu.yuzu_emu.features.settings.model
|
||||||
|
|
||||||
class IntSetting(
|
enum class IntSetting(
|
||||||
key: String,
|
override val key: String,
|
||||||
section: String,
|
override val section: String,
|
||||||
var value: Int
|
val defaultValue: Int
|
||||||
) : Setting(key, section) {
|
) : AbstractIntSetting {
|
||||||
override val valueAsString get() = value.toString()
|
RENDERER_USE_SPEED_LIMIT(
|
||||||
|
"use_speed_limit",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
1
|
||||||
|
),
|
||||||
|
USE_DOCKED_MODE(
|
||||||
|
"use_docked_mode",
|
||||||
|
Settings.SECTION_SYSTEM,
|
||||||
|
0
|
||||||
|
),
|
||||||
|
RENDERER_USE_DISK_SHADER_CACHE(
|
||||||
|
"use_disk_shader_cache",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
1
|
||||||
|
),
|
||||||
|
RENDERER_FORCE_MAX_CLOCK(
|
||||||
|
"force_max_clock",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
1
|
||||||
|
),
|
||||||
|
RENDERER_ASYNCHRONOUS_SHADERS(
|
||||||
|
"use_asynchronous_shaders",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
0
|
||||||
|
),
|
||||||
|
RENDERER_DEBUG(
|
||||||
|
"debug",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
0
|
||||||
|
),
|
||||||
|
RENDERER_SPEED_LIMIT(
|
||||||
|
"speed_limit",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
100
|
||||||
|
),
|
||||||
|
CPU_ACCURACY(
|
||||||
|
"cpu_accuracy",
|
||||||
|
Settings.SECTION_CPU,
|
||||||
|
0
|
||||||
|
),
|
||||||
|
REGION_INDEX(
|
||||||
|
"region_index",
|
||||||
|
Settings.SECTION_SYSTEM,
|
||||||
|
-1
|
||||||
|
),
|
||||||
|
LANGUAGE_INDEX(
|
||||||
|
"language_index",
|
||||||
|
Settings.SECTION_SYSTEM,
|
||||||
|
1
|
||||||
|
),
|
||||||
|
RENDERER_BACKEND(
|
||||||
|
"backend",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
1
|
||||||
|
),
|
||||||
|
RENDERER_ACCURACY(
|
||||||
|
"gpu_accuracy",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
0
|
||||||
|
),
|
||||||
|
RENDERER_RESOLUTION(
|
||||||
|
"resolution_setup",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
2
|
||||||
|
),
|
||||||
|
RENDERER_SCALING_FILTER(
|
||||||
|
"scaling_filter",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
1
|
||||||
|
),
|
||||||
|
RENDERER_ANTI_ALIASING(
|
||||||
|
"anti_aliasing",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
0
|
||||||
|
),
|
||||||
|
RENDERER_ASPECT_RATIO(
|
||||||
|
"aspect_ratio",
|
||||||
|
Settings.SECTION_RENDERER,
|
||||||
|
0
|
||||||
|
),
|
||||||
|
AUDIO_VOLUME(
|
||||||
|
"volume",
|
||||||
|
Settings.SECTION_AUDIO,
|
||||||
|
100
|
||||||
|
);
|
||||||
|
|
||||||
|
override var int: Int = defaultValue
|
||||||
|
|
||||||
|
override val valueAsString: String
|
||||||
|
get() = int.toString()
|
||||||
|
|
||||||
|
override val isRuntimeEditable: Boolean
|
||||||
|
get() {
|
||||||
|
for (setting in NOT_RUNTIME_EDITABLE) {
|
||||||
|
if (setting == this) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val NOT_RUNTIME_EDITABLE = listOf(
|
||||||
|
RENDERER_USE_DISK_SHADER_CACHE,
|
||||||
|
RENDERER_ASYNCHRONOUS_SHADERS,
|
||||||
|
RENDERER_DEBUG,
|
||||||
|
RENDERER_BACKEND,
|
||||||
|
RENDERER_RESOLUTION
|
||||||
|
)
|
||||||
|
|
||||||
|
fun from(key: String): IntSetting? = IntSetting.values().firstOrNull { it.key == key }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Abstraction for a setting item as read from / written to yuzu's configuration ini files.
|
|
||||||
* These files generally consist of a key/value pair, though the type of value is ambiguous and
|
|
||||||
* must be inferred at read-time. The type of value determines which child of this class is used
|
|
||||||
* to represent the Setting.
|
|
||||||
*/
|
|
||||||
abstract class Setting(
|
|
||||||
/**
|
|
||||||
* @return The identifier used to write this setting to the ini file.
|
|
||||||
*/
|
|
||||||
val key: String,
|
|
||||||
/**
|
|
||||||
* @return The name of the header under which this Setting should be written in the ini file.
|
|
||||||
*/
|
|
||||||
val section: String
|
|
||||||
) {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @return A representation of this Setting's backing value converted to a String (e.g. for serialization).
|
|
||||||
*/
|
|
||||||
abstract val valueAsString: String
|
|
||||||
}
|
|
|
@ -8,15 +8,15 @@ package org.yuzu.yuzu_emu.features.settings.model
|
||||||
* internally stored as a HashMap.
|
* internally stored as a HashMap.
|
||||||
*/
|
*/
|
||||||
class SettingSection(val name: String) {
|
class SettingSection(val name: String) {
|
||||||
val settings = HashMap<String, Setting>()
|
val settings = HashMap<String, AbstractSetting>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience method; inserts a value directly into the backing HashMap.
|
* Convenience method; inserts a value directly into the backing HashMap.
|
||||||
*
|
*
|
||||||
* @param setting The Setting to be inserted.
|
* @param setting The Setting to be inserted.
|
||||||
*/
|
*/
|
||||||
fun putSetting(setting: Setting) {
|
fun putSetting(setting: AbstractSetting) {
|
||||||
settings[setting.key] = setting
|
settings[setting.key!!] = setting
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -25,7 +25,7 @@ class SettingSection(val name: String) {
|
||||||
* @param key Used to retrieve the Setting.
|
* @param key Used to retrieve the Setting.
|
||||||
* @return A Setting object (you should probably cast this before using)
|
* @return A Setting object (you should probably cast this before using)
|
||||||
*/
|
*/
|
||||||
fun getSetting(key: String): Setting? {
|
fun getSetting(key: String): AbstractSetting? {
|
||||||
return settings[key]
|
return settings[key]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,32 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model
|
package org.yuzu.yuzu_emu.features.settings.model
|
||||||
|
|
||||||
class StringSetting(
|
enum class StringSetting(
|
||||||
key: String,
|
override val key: String,
|
||||||
section: String,
|
override val section: String,
|
||||||
var value: String
|
defaultValue: String
|
||||||
) : Setting(key, section) {
|
) : AbstractStringSetting {
|
||||||
override val valueAsString get() = value
|
// No string settings currently exist
|
||||||
|
EMPTY_SETTING("", "", "");
|
||||||
|
|
||||||
|
override var string: String = defaultValue
|
||||||
|
|
||||||
|
override val valueAsString: String
|
||||||
|
get() = string
|
||||||
|
|
||||||
|
override val isRuntimeEditable: Boolean
|
||||||
|
get() {
|
||||||
|
for (setting in NOT_RUNTIME_EDITABLE) {
|
||||||
|
if (setting == this) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private val NOT_RUNTIME_EDITABLE = emptyList<StringSetting>()
|
||||||
|
|
||||||
|
fun from(key: String): StringSetting? = StringSetting.values().firstOrNull { it.key == key }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,36 +3,30 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractStringSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||||
|
|
||||||
class DateTimeSetting(
|
class DateTimeSetting(
|
||||||
key: String,
|
val key: String? = null,
|
||||||
section: String,
|
setting: AbstractSetting?,
|
||||||
titleId: Int,
|
titleId: Int,
|
||||||
descriptionId: Int,
|
descriptionId: Int,
|
||||||
private val defaultValue: String,
|
private val defaultValue: String? = null
|
||||||
setting: Setting
|
) : SettingsItem(setting, titleId, descriptionId) {
|
||||||
) : SettingsItem(key, section, setting, titleId, descriptionId) {
|
|
||||||
override val type = TYPE_DATETIME_SETTING
|
override val type = TYPE_DATETIME_SETTING
|
||||||
|
|
||||||
val value: String
|
val value: String
|
||||||
get() = if (setting != null) {
|
get() = if (setting != null) {
|
||||||
val setting = setting as StringSetting
|
val setting = setting as StringSetting
|
||||||
setting.value
|
setting.string
|
||||||
} else {
|
} else {
|
||||||
defaultValue
|
defaultValue!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSelectedValue(datetime: String): StringSetting? {
|
fun setSelectedValue(datetime: String): AbstractStringSetting {
|
||||||
return if (setting == null) {
|
val stringSetting = setting as AbstractStringSetting
|
||||||
val newSetting = StringSetting(key!!, section!!, datetime)
|
stringSetting.string = datetime
|
||||||
setting = newSetting
|
return stringSetting
|
||||||
newSetting
|
|
||||||
} else {
|
|
||||||
val newSetting = setting as StringSetting
|
|
||||||
newSetting.value = datetime
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,13 +3,12 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
|
|
||||||
class HeaderSetting(
|
class HeaderSetting(
|
||||||
key: String?,
|
setting: AbstractSetting?,
|
||||||
setting: Setting?,
|
|
||||||
titleId: Int,
|
titleId: Int,
|
||||||
descriptionId: Int?
|
descriptionId: Int?
|
||||||
) : SettingsItem(key, null, setting, titleId, descriptionId) {
|
) : SettingsItem(setting, titleId, descriptionId) {
|
||||||
override val type = TYPE_HEADER
|
override val type = TYPE_HEADER
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,19 +3,17 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments.
|
* ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments.
|
||||||
* Each one corresponds to a [Setting] object, so this class's subclasses
|
* Each one corresponds to a [AbstractSetting] object, so this class's subclasses
|
||||||
* should vaguely correspond to those subclasses. There are a few with multiple analogues
|
* should vaguely correspond to those subclasses. There are a few with multiple analogues
|
||||||
* and a few with none (Headers, for example, do not correspond to anything in the ini
|
* and a few with none (Headers, for example, do not correspond to anything in the ini
|
||||||
* file.)
|
* file.)
|
||||||
*/
|
*/
|
||||||
abstract class SettingsItem(
|
abstract class SettingsItem(
|
||||||
val key: String?,
|
var setting: AbstractSetting?,
|
||||||
val section: String?,
|
|
||||||
var setting: Setting?,
|
|
||||||
val nameId: Int,
|
val nameId: Int,
|
||||||
val descriptionId: Int?
|
val descriptionId: Int?
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -3,27 +3,26 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||||
|
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
|
||||||
|
|
||||||
class SingleChoiceSetting(
|
class SingleChoiceSetting(
|
||||||
key: String,
|
setting: AbstractIntSetting?,
|
||||||
section: String,
|
|
||||||
setting: Setting?,
|
|
||||||
titleId: Int,
|
titleId: Int,
|
||||||
descriptionId: Int,
|
descriptionId: Int,
|
||||||
val choicesId: Int,
|
val choicesId: Int,
|
||||||
val valuesId: Int,
|
val valuesId: Int,
|
||||||
private val defaultValue: Int,
|
val key: String? = null,
|
||||||
) : SettingsItem(key, section, setting, titleId, descriptionId) {
|
val defaultValue: Int? = null
|
||||||
|
) : SettingsItem(setting, titleId, descriptionId) {
|
||||||
override val type = TYPE_SINGLE_CHOICE
|
override val type = TYPE_SINGLE_CHOICE
|
||||||
|
|
||||||
val selectedValue: Int
|
val selectedValue: Int
|
||||||
get() = if (setting != null) {
|
get() = if (setting != null) {
|
||||||
val setting = setting as IntSetting
|
val setting = setting as IntSetting
|
||||||
setting.value
|
setting.int
|
||||||
} else {
|
} else {
|
||||||
defaultValue
|
defaultValue!!
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -31,17 +30,11 @@ class SingleChoiceSetting(
|
||||||
* initializes a new one and returns it, so it can be added to the Hashmap.
|
* initializes a new one and returns it, so it can be added to the Hashmap.
|
||||||
*
|
*
|
||||||
* @param selection New value of the int.
|
* @param selection New value of the int.
|
||||||
* @return null if overwritten successfully otherwise; a newly created IntSetting.
|
* @return the existing setting with the new value applied.
|
||||||
*/
|
*/
|
||||||
fun setSelectedValue(selection: Int): IntSetting? {
|
fun setSelectedValue(selection: Int): AbstractIntSetting {
|
||||||
return if (setting == null) {
|
val intSetting = setting as AbstractIntSetting
|
||||||
val newSetting = IntSetting(key!!, section!!, selection)
|
intSetting.int = selection
|
||||||
setting = newSetting
|
return intSetting
|
||||||
newSetting
|
|
||||||
} else {
|
|
||||||
val newSetting = setting as IntSetting
|
|
||||||
newSetting.value = selection
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,31 +3,32 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||||
|
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractFloatSetting
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.FloatSetting
|
import org.yuzu.yuzu_emu.features.settings.model.FloatSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
|
||||||
import org.yuzu.yuzu_emu.utils.Log
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
class SliderSetting(
|
class SliderSetting(
|
||||||
key: String,
|
setting: AbstractSetting?,
|
||||||
section: String,
|
|
||||||
setting: Setting?,
|
|
||||||
titleId: Int,
|
titleId: Int,
|
||||||
descriptionId: Int,
|
descriptionId: Int,
|
||||||
val min: Int,
|
val min: Int,
|
||||||
val max: Int,
|
val max: Int,
|
||||||
val units: String,
|
val units: String,
|
||||||
val defaultValue: Int,
|
val key: String? = null,
|
||||||
) : SettingsItem(key, section, setting, titleId, descriptionId) {
|
val defaultValue: Int? = null,
|
||||||
|
) : SettingsItem(setting, titleId, descriptionId) {
|
||||||
override val type = TYPE_SLIDER
|
override val type = TYPE_SLIDER
|
||||||
|
|
||||||
val selectedValue: Int
|
val selectedValue: Int
|
||||||
get() {
|
get() {
|
||||||
val setting = setting ?: return defaultValue
|
val setting = setting ?: return defaultValue!!
|
||||||
return when (setting) {
|
return when (setting) {
|
||||||
is IntSetting -> setting.value
|
is IntSetting -> setting.int
|
||||||
is FloatSetting -> setting.value.roundToInt()
|
is FloatSetting -> setting.float.roundToInt()
|
||||||
else -> {
|
else -> {
|
||||||
Log.error("[SliderSetting] Error casting setting type.")
|
Log.error("[SliderSetting] Error casting setting type.")
|
||||||
-1
|
-1
|
||||||
|
@ -40,18 +41,12 @@ class SliderSetting(
|
||||||
* initializes a new one and returns it, so it can be added to the Hashmap.
|
* initializes a new one and returns it, so it can be added to the Hashmap.
|
||||||
*
|
*
|
||||||
* @param selection New value of the int.
|
* @param selection New value of the int.
|
||||||
* @return null if overwritten successfully otherwise; a newly created IntSetting.
|
* @return the existing setting with the new value applied.
|
||||||
*/
|
*/
|
||||||
fun setSelectedValue(selection: Int): IntSetting? {
|
fun setSelectedValue(selection: Int): AbstractIntSetting {
|
||||||
return if (setting == null) {
|
val intSetting = setting as AbstractIntSetting
|
||||||
val newSetting = IntSetting(key!!, section!!, selection)
|
intSetting.int = selection
|
||||||
setting = newSetting
|
return intSetting
|
||||||
newSetting
|
|
||||||
} else {
|
|
||||||
val newSetting = setting as IntSetting
|
|
||||||
newSetting.value = selection
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -59,17 +54,11 @@ class SliderSetting(
|
||||||
* initializes a new one and returns it, so it can be added to the Hashmap.
|
* initializes a new one and returns it, so it can be added to the Hashmap.
|
||||||
*
|
*
|
||||||
* @param selection New value of the float.
|
* @param selection New value of the float.
|
||||||
* @return null if overwritten successfully otherwise; a newly created FloatSetting.
|
* @return the existing setting with the new value applied.
|
||||||
*/
|
*/
|
||||||
fun setSelectedValue(selection: Float): FloatSetting? {
|
fun setSelectedValue(selection: Float): AbstractFloatSetting {
|
||||||
return if (setting == null) {
|
val floatSetting = setting as AbstractFloatSetting
|
||||||
val newSetting = FloatSetting(key!!, section!!, selection)
|
floatSetting.float = selection
|
||||||
setting = newSetting
|
return floatSetting
|
||||||
newSetting
|
|
||||||
} else {
|
|
||||||
val newSetting = setting as FloatSetting
|
|
||||||
newSetting.value = selection
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,19 +3,19 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractStringSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
import org.yuzu.yuzu_emu.features.settings.model.StringSetting
|
||||||
|
|
||||||
class StringSingleChoiceSetting(
|
class StringSingleChoiceSetting(
|
||||||
key: String,
|
val key: String? = null,
|
||||||
section: String,
|
setting: AbstractSetting?,
|
||||||
setting: Setting?,
|
|
||||||
titleId: Int,
|
titleId: Int,
|
||||||
descriptionId: Int,
|
descriptionId: Int,
|
||||||
val choicesId: Array<String>,
|
val choicesId: Array<String>,
|
||||||
private val valuesId: Array<String>?,
|
private val valuesId: Array<String>?,
|
||||||
private val defaultValue: String
|
private val defaultValue: String? = null
|
||||||
) : SettingsItem(key, section, setting, titleId, descriptionId) {
|
) : SettingsItem(setting, titleId, descriptionId) {
|
||||||
override val type = TYPE_STRING_SINGLE_CHOICE
|
override val type = TYPE_STRING_SINGLE_CHOICE
|
||||||
|
|
||||||
fun getValueAt(index: Int): String? {
|
fun getValueAt(index: Int): String? {
|
||||||
|
@ -28,9 +28,9 @@ class StringSingleChoiceSetting(
|
||||||
val selectedValue: String
|
val selectedValue: String
|
||||||
get() = if (setting != null) {
|
get() = if (setting != null) {
|
||||||
val setting = setting as StringSetting
|
val setting = setting as StringSetting
|
||||||
setting.value
|
setting.string
|
||||||
} else {
|
} else {
|
||||||
defaultValue
|
defaultValue!!
|
||||||
}
|
}
|
||||||
val selectValueIndex: Int
|
val selectValueIndex: Int
|
||||||
get() {
|
get() {
|
||||||
|
@ -48,17 +48,11 @@ class StringSingleChoiceSetting(
|
||||||
* initializes a new one and returns it, so it can be added to the Hashmap.
|
* initializes a new one and returns it, so it can be added to the Hashmap.
|
||||||
*
|
*
|
||||||
* @param selection New value of the int.
|
* @param selection New value of the int.
|
||||||
* @return null if overwritten successfully otherwise; a newly created IntSetting.
|
* @return the existing setting with the new value applied.
|
||||||
*/
|
*/
|
||||||
fun setSelectedValue(selection: String?): StringSetting? {
|
fun setSelectedValue(selection: String): AbstractStringSetting {
|
||||||
return if (setting == null) {
|
val stringSetting = setting as AbstractStringSetting
|
||||||
val newSetting = StringSetting(key!!, section!!, selection!!)
|
stringSetting.string = selection
|
||||||
setting = newSetting
|
return stringSetting
|
||||||
newSetting
|
|
||||||
} else {
|
|
||||||
val newSetting = setting as StringSetting
|
|
||||||
newSetting.value = selection!!
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,16 +3,13 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
|
|
||||||
class SubmenuSetting(
|
class SubmenuSetting(
|
||||||
key: String?,
|
setting: AbstractSetting?,
|
||||||
setting: Setting?,
|
|
||||||
titleId: Int,
|
titleId: Int,
|
||||||
descriptionId: Int,
|
descriptionId: Int,
|
||||||
val menuKey: String
|
val menuKey: String
|
||||||
) : SettingsItem(
|
) : SettingsItem(setting, titleId, descriptionId) {
|
||||||
key, null, setting, titleId, descriptionId
|
|
||||||
) {
|
|
||||||
override val type = TYPE_SUBMENU
|
override val type = TYPE_SUBMENU
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,67 +3,42 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.model.view
|
package org.yuzu.yuzu_emu.features.settings.model.view
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractBooleanSetting
|
||||||
import org.yuzu.yuzu_emu.YuzuApplication
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractIntSetting
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
import org.yuzu.yuzu_emu.utils.Log
|
||||||
import org.yuzu.yuzu_emu.features.settings.ui.SettingsFragmentView
|
|
||||||
|
|
||||||
class SwitchSetting : SettingsItem {
|
class SwitchSetting(
|
||||||
|
setting: AbstractSetting,
|
||||||
|
titleId: Int,
|
||||||
|
descriptionId: Int,
|
||||||
|
val key: String? = null,
|
||||||
|
val defaultValue: Boolean? = null
|
||||||
|
) : SettingsItem(setting, titleId, descriptionId) {
|
||||||
override val type = TYPE_SWITCH
|
override val type = TYPE_SWITCH
|
||||||
|
|
||||||
private var defaultValue: Boolean
|
|
||||||
private var showPerformanceWarning: Boolean
|
|
||||||
private var fragmentView: SettingsFragmentView? = null
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
key: String,
|
|
||||||
section: String,
|
|
||||||
setting: Setting?,
|
|
||||||
titleId: Int,
|
|
||||||
descriptionId: Int,
|
|
||||||
defaultValue: Boolean
|
|
||||||
) : super(key, section, setting, titleId, descriptionId) {
|
|
||||||
this.defaultValue = defaultValue
|
|
||||||
showPerformanceWarning = false
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor(
|
|
||||||
key: String,
|
|
||||||
section: String,
|
|
||||||
titleId: Int,
|
|
||||||
descriptionId: Int,
|
|
||||||
defaultValue: Boolean,
|
|
||||||
setting: Setting,
|
|
||||||
show_performance_warning: Boolean,
|
|
||||||
view: SettingsFragmentView
|
|
||||||
) : super(key, section, setting, titleId, descriptionId) {
|
|
||||||
this.defaultValue = defaultValue
|
|
||||||
fragmentView = view
|
|
||||||
showPerformanceWarning = show_performance_warning
|
|
||||||
}
|
|
||||||
|
|
||||||
val isChecked: Boolean
|
val isChecked: Boolean
|
||||||
get() {
|
get() {
|
||||||
if (setting == null) {
|
if (setting == null) {
|
||||||
return defaultValue
|
return defaultValue!!
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try integer setting
|
// Try integer setting
|
||||||
try {
|
try {
|
||||||
val setting = setting as IntSetting
|
val setting = setting as AbstractIntSetting
|
||||||
return setting.value == 1
|
return setting.int == 1
|
||||||
} catch (_: ClassCastException) {
|
} catch (_: ClassCastException) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try boolean setting
|
// Try boolean setting
|
||||||
try {
|
try {
|
||||||
val setting = setting as BooleanSetting
|
val setting = setting as AbstractBooleanSetting
|
||||||
return setting.value
|
return setting.boolean
|
||||||
} catch (_: ClassCastException) {
|
} catch (_: ClassCastException) {
|
||||||
}
|
}
|
||||||
return defaultValue
|
return defaultValue!!
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -71,24 +46,20 @@ class SwitchSetting : SettingsItem {
|
||||||
* initializes a new one and returns it, so it can be added to the Hashmap.
|
* initializes a new one and returns it, so it can be added to the Hashmap.
|
||||||
*
|
*
|
||||||
* @param checked Pretty self explanatory.
|
* @param checked Pretty self explanatory.
|
||||||
* @return null if overwritten successfully; otherwise, a newly created BooleanSetting.
|
* @return the existing setting with the new value applied.
|
||||||
*/
|
*/
|
||||||
fun setChecked(checked: Boolean): IntSetting? {
|
fun setChecked(checked: Boolean): AbstractSetting {
|
||||||
// Show a performance warning if the setting has been disabled
|
// Try integer setting
|
||||||
if (showPerformanceWarning && !checked) {
|
try {
|
||||||
fragmentView!!.showToastMessage(
|
val setting = setting as AbstractIntSetting
|
||||||
YuzuApplication.appContext.getString(R.string.performance_warning), true
|
setting.int = if (checked) 1 else 0
|
||||||
)
|
return setting
|
||||||
|
} catch (_: ClassCastException) {
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (setting == null) {
|
// Try boolean setting
|
||||||
val newSetting = IntSetting(key!!, section!!, if (checked) 1 else 0)
|
val setting = setting as AbstractBooleanSetting
|
||||||
setting = newSetting
|
setting.boolean = checked
|
||||||
newSetting
|
return setting
|
||||||
} else {
|
|
||||||
val newSetting = setting as IntSetting
|
|
||||||
newSetting.value = if (checked) 1 else 0
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -101,9 +101,7 @@ class SettingsAdapter(
|
||||||
|
|
||||||
fun onBooleanClick(item: SwitchSetting, position: Int, checked: Boolean) {
|
fun onBooleanClick(item: SwitchSetting, position: Int, checked: Boolean) {
|
||||||
val setting = item.setChecked(checked)
|
val setting = item.setChecked(checked)
|
||||||
if (setting != null) {
|
fragmentView.putSetting(setting)
|
||||||
fragmentView.putSetting(setting)
|
|
||||||
}
|
|
||||||
fragmentView.onSettingChanged()
|
fragmentView.onSettingChanged()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -209,7 +207,7 @@ class SettingsAdapter(
|
||||||
.setPositiveButton(android.R.string.ok, this)
|
.setPositiveButton(android.R.string.ok, this)
|
||||||
.setNegativeButton(android.R.string.cancel, defaultCancelListener)
|
.setNegativeButton(android.R.string.cancel, defaultCancelListener)
|
||||||
.setNeutralButton(R.string.slider_default) { dialog: DialogInterface, which: Int ->
|
.setNeutralButton(R.string.slider_default) { dialog: DialogInterface, which: Int ->
|
||||||
sliderBinding.slider.value = item.defaultValue.toFloat()
|
sliderBinding.slider.value = item.defaultValue!!.toFloat()
|
||||||
onClick(dialog, which)
|
onClick(dialog, which)
|
||||||
}
|
}
|
||||||
.show()
|
.show()
|
||||||
|
@ -230,19 +228,15 @@ class SettingsAdapter(
|
||||||
|
|
||||||
// Get the backing Setting, which may be null (if for example it was missing from the file)
|
// Get the backing Setting, which may be null (if for example it was missing from the file)
|
||||||
val setting = scSetting.setSelectedValue(value)
|
val setting = scSetting.setSelectedValue(value)
|
||||||
if (setting != null) {
|
fragmentView.putSetting(setting)
|
||||||
fragmentView.putSetting(setting)
|
|
||||||
}
|
|
||||||
closeDialog()
|
closeDialog()
|
||||||
}
|
}
|
||||||
is StringSingleChoiceSetting -> {
|
is StringSingleChoiceSetting -> {
|
||||||
val scSetting = clickedItem as StringSingleChoiceSetting
|
val scSetting = clickedItem as StringSingleChoiceSetting
|
||||||
val value = scSetting.getValueAt(which)
|
val value = scSetting.getValueAt(which)
|
||||||
if (scSetting.selectedValue != value) fragmentView.onSettingChanged()
|
if (scSetting.selectedValue != value) fragmentView.onSettingChanged()
|
||||||
val setting = scSetting.setSelectedValue(value)
|
val setting = scSetting.setSelectedValue(value!!)
|
||||||
if (setting != null) {
|
fragmentView.putSetting(setting)
|
||||||
fragmentView.putSetting(setting)
|
|
||||||
}
|
|
||||||
closeDialog()
|
closeDialog()
|
||||||
}
|
}
|
||||||
is SliderSetting -> {
|
is SliderSetting -> {
|
||||||
|
@ -253,14 +247,10 @@ class SettingsAdapter(
|
||||||
if (sliderSetting.setting is FloatSetting) {
|
if (sliderSetting.setting is FloatSetting) {
|
||||||
val value = sliderProgress.toFloat()
|
val value = sliderProgress.toFloat()
|
||||||
val setting = sliderSetting.setSelectedValue(value)
|
val setting = sliderSetting.setSelectedValue(value)
|
||||||
if (setting != null) {
|
fragmentView.putSetting(setting)
|
||||||
fragmentView.putSetting(setting)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
val setting = sliderSetting.setSelectedValue(sliderProgress)
|
val setting = sliderSetting.setSelectedValue(sliderProgress)
|
||||||
if (setting != null) {
|
fragmentView.putSetting(setting)
|
||||||
fragmentView.putSetting(setting)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
closeDialog()
|
closeDialog()
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@ import androidx.fragment.app.Fragment
|
||||||
import androidx.recyclerview.widget.LinearLayoutManager
|
import androidx.recyclerview.widget.LinearLayoutManager
|
||||||
import com.google.android.material.divider.MaterialDividerItemDecoration
|
import com.google.android.material.divider.MaterialDividerItemDecoration
|
||||||
import org.yuzu.yuzu_emu.databinding.FragmentSettingsBinding
|
import org.yuzu.yuzu_emu.databinding.FragmentSettingsBinding
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
||||||
|
|
||||||
class SettingsFragment : Fragment(), SettingsFragmentView {
|
class SettingsFragment : Fragment(), SettingsFragmentView {
|
||||||
|
@ -91,7 +90,7 @@ class SettingsFragment : Fragment(), SettingsFragmentView {
|
||||||
activityView!!.showToastMessage(message!!, is_long)
|
activityView!!.showToastMessage(message!!, is_long)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun putSetting(setting: Setting) {
|
override fun putSetting(setting: AbstractSetting) {
|
||||||
fragmentPresenter.putSetting(setting)
|
fragmentPresenter.putSetting(setting)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,9 @@ package org.yuzu.yuzu_emu.features.settings.ui
|
||||||
import android.text.TextUtils
|
import android.text.TextUtils
|
||||||
import androidx.appcompat.app.AppCompatActivity
|
import androidx.appcompat.app.AppCompatActivity
|
||||||
import org.yuzu.yuzu_emu.R
|
import org.yuzu.yuzu_emu.R
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
|
||||||
|
import org.yuzu.yuzu_emu.features.settings.model.IntSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
import org.yuzu.yuzu_emu.features.settings.model.Settings
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.*
|
import org.yuzu.yuzu_emu.features.settings.model.view.*
|
||||||
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile
|
||||||
|
@ -28,8 +30,11 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||||
loadSettingsList()
|
loadSettingsList()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun putSetting(setting: Setting) {
|
fun putSetting(setting: AbstractSetting) {
|
||||||
settings.getSection(setting.section)!!.putSetting(setting)
|
val section = settings.getSection(setting.section!!)!!
|
||||||
|
if (section.getSetting(setting.key!!) == null) {
|
||||||
|
section.putSetting(setting)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadSettingsList() {
|
fun loadSettingsList() {
|
||||||
|
@ -60,7 +65,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||||
sl.apply {
|
sl.apply {
|
||||||
add(
|
add(
|
||||||
SubmenuSetting(
|
SubmenuSetting(
|
||||||
null,
|
|
||||||
null,
|
null,
|
||||||
R.string.preferences_general,
|
R.string.preferences_general,
|
||||||
0,
|
0,
|
||||||
|
@ -69,7 +73,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SubmenuSetting(
|
SubmenuSetting(
|
||||||
null,
|
|
||||||
null,
|
null,
|
||||||
R.string.preferences_system,
|
R.string.preferences_system,
|
||||||
0,
|
0,
|
||||||
|
@ -78,7 +81,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SubmenuSetting(
|
SubmenuSetting(
|
||||||
null,
|
|
||||||
null,
|
null,
|
||||||
R.string.preferences_graphics,
|
R.string.preferences_graphics,
|
||||||
0,
|
0,
|
||||||
|
@ -87,7 +89,6 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SubmenuSetting(
|
SubmenuSetting(
|
||||||
null,
|
|
||||||
null,
|
null,
|
||||||
R.string.preferences_audio,
|
R.string.preferences_audio,
|
||||||
0,
|
0,
|
||||||
|
@ -99,45 +100,36 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||||
|
|
||||||
private fun addGeneralSettings(sl: ArrayList<SettingsItem>) {
|
private fun addGeneralSettings(sl: ArrayList<SettingsItem>) {
|
||||||
settingsActivity.setTitle(R.string.preferences_general)
|
settingsActivity.setTitle(R.string.preferences_general)
|
||||||
val rendererSection = settings.getSection(Settings.SECTION_RENDERER)
|
|
||||||
val frameLimitEnable =
|
|
||||||
rendererSection!!.getSetting(SettingsFile.KEY_RENDERER_USE_SPEED_LIMIT)
|
|
||||||
val frameLimitValue = rendererSection.getSetting(SettingsFile.KEY_RENDERER_SPEED_LIMIT)
|
|
||||||
val cpuSection = settings.getSection(Settings.SECTION_CPU)
|
|
||||||
val cpuAccuracy = cpuSection!!.getSetting(SettingsFile.KEY_CPU_ACCURACY)
|
|
||||||
sl.apply {
|
sl.apply {
|
||||||
add(
|
add(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
SettingsFile.KEY_RENDERER_USE_SPEED_LIMIT,
|
IntSetting.RENDERER_USE_SPEED_LIMIT,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
frameLimitEnable,
|
|
||||||
R.string.frame_limit_enable,
|
R.string.frame_limit_enable,
|
||||||
R.string.frame_limit_enable_description,
|
R.string.frame_limit_enable_description,
|
||||||
|
IntSetting.RENDERER_USE_SPEED_LIMIT.key,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SliderSetting(
|
SliderSetting(
|
||||||
SettingsFile.KEY_RENDERER_SPEED_LIMIT,
|
IntSetting.RENDERER_SPEED_LIMIT,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
frameLimitValue,
|
|
||||||
R.string.frame_limit_slider,
|
R.string.frame_limit_slider,
|
||||||
R.string.frame_limit_slider_description,
|
R.string.frame_limit_slider_description,
|
||||||
1,
|
1,
|
||||||
200,
|
200,
|
||||||
"%",
|
"%",
|
||||||
|
IntSetting.RENDERER_SPEED_LIMIT.key,
|
||||||
100
|
100
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
SettingsFile.KEY_CPU_ACCURACY,
|
IntSetting.CPU_ACCURACY,
|
||||||
Settings.SECTION_CPU,
|
|
||||||
cpuAccuracy,
|
|
||||||
R.string.cpu_accuracy,
|
R.string.cpu_accuracy,
|
||||||
0,
|
0,
|
||||||
R.array.cpuAccuracyNames,
|
R.array.cpuAccuracyNames,
|
||||||
R.array.cpuAccuracyValues,
|
R.array.cpuAccuracyValues,
|
||||||
|
IntSetting.CPU_ACCURACY.key,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -146,42 +138,35 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||||
|
|
||||||
private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
|
private fun addSystemSettings(sl: ArrayList<SettingsItem>) {
|
||||||
settingsActivity.setTitle(R.string.preferences_system)
|
settingsActivity.setTitle(R.string.preferences_system)
|
||||||
val systemSection = settings.getSection(Settings.SECTION_SYSTEM)
|
|
||||||
val dockedMode = systemSection!!.getSetting(SettingsFile.KEY_USE_DOCKED_MODE)
|
|
||||||
val region = systemSection.getSetting(SettingsFile.KEY_REGION_INDEX)
|
|
||||||
val language = systemSection.getSetting(SettingsFile.KEY_LANGUAGE_INDEX)
|
|
||||||
sl.apply {
|
sl.apply {
|
||||||
add(
|
add(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
SettingsFile.KEY_USE_DOCKED_MODE,
|
IntSetting.USE_DOCKED_MODE,
|
||||||
Settings.SECTION_SYSTEM,
|
|
||||||
dockedMode,
|
|
||||||
R.string.use_docked_mode,
|
R.string.use_docked_mode,
|
||||||
R.string.use_docked_mode_description,
|
R.string.use_docked_mode_description,
|
||||||
false,
|
IntSetting.USE_DOCKED_MODE.key,
|
||||||
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
SettingsFile.KEY_REGION_INDEX,
|
IntSetting.REGION_INDEX,
|
||||||
Settings.SECTION_SYSTEM,
|
|
||||||
region,
|
|
||||||
R.string.emulated_region,
|
R.string.emulated_region,
|
||||||
0,
|
0,
|
||||||
R.array.regionNames,
|
R.array.regionNames,
|
||||||
R.array.regionValues,
|
R.array.regionValues,
|
||||||
|
IntSetting.REGION_INDEX.key,
|
||||||
-1
|
-1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
SettingsFile.KEY_LANGUAGE_INDEX,
|
IntSetting.LANGUAGE_INDEX,
|
||||||
Settings.SECTION_SYSTEM,
|
|
||||||
language,
|
|
||||||
R.string.emulated_language,
|
R.string.emulated_language,
|
||||||
0,
|
0,
|
||||||
R.array.languageNames,
|
R.array.languageNames,
|
||||||
R.array.languageValues,
|
R.array.languageValues,
|
||||||
|
IntSetting.LANGUAGE_INDEX.key,
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -190,133 +175,106 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||||
|
|
||||||
private fun addGraphicsSettings(sl: ArrayList<SettingsItem>) {
|
private fun addGraphicsSettings(sl: ArrayList<SettingsItem>) {
|
||||||
settingsActivity.setTitle(R.string.preferences_graphics)
|
settingsActivity.setTitle(R.string.preferences_graphics)
|
||||||
val rendererSection = settings.getSection(Settings.SECTION_RENDERER)
|
|
||||||
val rendererBackend = rendererSection!!.getSetting(SettingsFile.KEY_RENDERER_BACKEND)
|
|
||||||
val rendererAccuracy = rendererSection.getSetting(SettingsFile.KEY_RENDERER_ACCURACY)
|
|
||||||
val rendererResolution = rendererSection.getSetting(SettingsFile.KEY_RENDERER_RESOLUTION)
|
|
||||||
val rendererScalingFilter =
|
|
||||||
rendererSection.getSetting(SettingsFile.KEY_RENDERER_SCALING_FILTER)
|
|
||||||
val rendererAntiAliasing =
|
|
||||||
rendererSection.getSetting(SettingsFile.KEY_RENDERER_ANTI_ALIASING)
|
|
||||||
val rendererAspectRatio =
|
|
||||||
rendererSection.getSetting(SettingsFile.KEY_RENDERER_ASPECT_RATIO)
|
|
||||||
val rendererUseDiskShaderCache =
|
|
||||||
rendererSection.getSetting(SettingsFile.KEY_RENDERER_USE_DISK_SHADER_CACHE)
|
|
||||||
val rendererForceMaxClocks =
|
|
||||||
rendererSection.getSetting(SettingsFile.KEY_RENDERER_FORCE_MAX_CLOCK)
|
|
||||||
val rendererAsynchronousShaders =
|
|
||||||
rendererSection.getSetting(SettingsFile.KEY_RENDERER_ASYNCHRONOUS_SHADERS)
|
|
||||||
val rendererDebug = rendererSection.getSetting(SettingsFile.KEY_RENDERER_DEBUG)
|
|
||||||
sl.apply {
|
sl.apply {
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
SettingsFile.KEY_RENDERER_BACKEND,
|
IntSetting.RENDERER_BACKEND,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererBackend,
|
|
||||||
R.string.renderer_api,
|
R.string.renderer_api,
|
||||||
0,
|
0,
|
||||||
R.array.rendererApiNames,
|
R.array.rendererApiNames,
|
||||||
R.array.rendererApiValues,
|
R.array.rendererApiValues,
|
||||||
|
IntSetting.RENDERER_BACKEND.key,
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
SettingsFile.KEY_RENDERER_ACCURACY,
|
IntSetting.RENDERER_ACCURACY,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererAccuracy,
|
|
||||||
R.string.renderer_accuracy,
|
R.string.renderer_accuracy,
|
||||||
0,
|
0,
|
||||||
R.array.rendererAccuracyNames,
|
R.array.rendererAccuracyNames,
|
||||||
R.array.rendererAccuracyValues,
|
R.array.rendererAccuracyValues,
|
||||||
|
IntSetting.RENDERER_ACCURACY.key,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
SettingsFile.KEY_RENDERER_RESOLUTION,
|
IntSetting.RENDERER_RESOLUTION,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererResolution,
|
|
||||||
R.string.renderer_resolution,
|
R.string.renderer_resolution,
|
||||||
0,
|
0,
|
||||||
R.array.rendererResolutionNames,
|
R.array.rendererResolutionNames,
|
||||||
R.array.rendererResolutionValues,
|
R.array.rendererResolutionValues,
|
||||||
|
IntSetting.RENDERER_RESOLUTION.key,
|
||||||
2
|
2
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
SettingsFile.KEY_RENDERER_SCALING_FILTER,
|
IntSetting.RENDERER_SCALING_FILTER,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererScalingFilter,
|
|
||||||
R.string.renderer_scaling_filter,
|
R.string.renderer_scaling_filter,
|
||||||
0,
|
0,
|
||||||
R.array.rendererScalingFilterNames,
|
R.array.rendererScalingFilterNames,
|
||||||
R.array.rendererScalingFilterValues,
|
R.array.rendererScalingFilterValues,
|
||||||
|
IntSetting.RENDERER_SCALING_FILTER.key,
|
||||||
1
|
1
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
SettingsFile.KEY_RENDERER_ANTI_ALIASING,
|
IntSetting.RENDERER_ANTI_ALIASING,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererAntiAliasing,
|
|
||||||
R.string.renderer_anti_aliasing,
|
R.string.renderer_anti_aliasing,
|
||||||
0,
|
0,
|
||||||
R.array.rendererAntiAliasingNames,
|
R.array.rendererAntiAliasingNames,
|
||||||
R.array.rendererAntiAliasingValues,
|
R.array.rendererAntiAliasingValues,
|
||||||
|
IntSetting.RENDERER_ANTI_ALIASING.key,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SingleChoiceSetting(
|
SingleChoiceSetting(
|
||||||
SettingsFile.KEY_RENDERER_ASPECT_RATIO,
|
IntSetting.RENDERER_ASPECT_RATIO,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererAspectRatio,
|
|
||||||
R.string.renderer_aspect_ratio,
|
R.string.renderer_aspect_ratio,
|
||||||
0,
|
0,
|
||||||
R.array.rendererAspectRatioNames,
|
R.array.rendererAspectRatioNames,
|
||||||
R.array.rendererAspectRatioValues,
|
R.array.rendererAspectRatioValues,
|
||||||
|
IntSetting.RENDERER_ASPECT_RATIO.key,
|
||||||
0
|
0
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
SettingsFile.KEY_RENDERER_USE_DISK_SHADER_CACHE,
|
IntSetting.RENDERER_USE_DISK_SHADER_CACHE,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererUseDiskShaderCache,
|
|
||||||
R.string.use_disk_shader_cache,
|
R.string.use_disk_shader_cache,
|
||||||
R.string.use_disk_shader_cache_description,
|
R.string.use_disk_shader_cache_description,
|
||||||
|
IntSetting.RENDERER_USE_DISK_SHADER_CACHE.key,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
SettingsFile.KEY_RENDERER_FORCE_MAX_CLOCK,
|
IntSetting.RENDERER_FORCE_MAX_CLOCK,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererForceMaxClocks,
|
|
||||||
R.string.renderer_force_max_clock,
|
R.string.renderer_force_max_clock,
|
||||||
R.string.renderer_force_max_clock_description,
|
R.string.renderer_force_max_clock_description,
|
||||||
|
IntSetting.RENDERER_FORCE_MAX_CLOCK.key,
|
||||||
true
|
true
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
SettingsFile.KEY_RENDERER_ASYNCHRONOUS_SHADERS,
|
IntSetting.RENDERER_ASYNCHRONOUS_SHADERS,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererAsynchronousShaders,
|
|
||||||
R.string.renderer_asynchronous_shaders,
|
R.string.renderer_asynchronous_shaders,
|
||||||
R.string.renderer_asynchronous_shaders_description,
|
R.string.renderer_asynchronous_shaders_description,
|
||||||
|
IntSetting.RENDERER_ASYNCHRONOUS_SHADERS.key,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
add(
|
add(
|
||||||
SwitchSetting(
|
SwitchSetting(
|
||||||
SettingsFile.KEY_RENDERER_DEBUG,
|
IntSetting.RENDERER_DEBUG,
|
||||||
Settings.SECTION_RENDERER,
|
|
||||||
rendererDebug,
|
|
||||||
R.string.renderer_debug,
|
R.string.renderer_debug,
|
||||||
R.string.renderer_debug_description,
|
R.string.renderer_debug_description,
|
||||||
|
IntSetting.RENDERER_DEBUG.key,
|
||||||
false
|
false
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -325,18 +283,15 @@ class SettingsFragmentPresenter(private val fragmentView: SettingsFragmentView)
|
||||||
|
|
||||||
private fun addAudioSettings(sl: ArrayList<SettingsItem>) {
|
private fun addAudioSettings(sl: ArrayList<SettingsItem>) {
|
||||||
settingsActivity.setTitle(R.string.preferences_audio)
|
settingsActivity.setTitle(R.string.preferences_audio)
|
||||||
val audioSection = settings.getSection(Settings.SECTION_AUDIO)
|
|
||||||
val audioVolume = audioSection!!.getSetting(SettingsFile.KEY_AUDIO_VOLUME)
|
|
||||||
sl.add(
|
sl.add(
|
||||||
SliderSetting(
|
SliderSetting(
|
||||||
SettingsFile.KEY_AUDIO_VOLUME,
|
IntSetting.AUDIO_VOLUME,
|
||||||
Settings.SECTION_AUDIO,
|
|
||||||
audioVolume,
|
|
||||||
R.string.audio_volume,
|
R.string.audio_volume,
|
||||||
R.string.audio_volume_description,
|
R.string.audio_volume_description,
|
||||||
0,
|
0,
|
||||||
100,
|
100,
|
||||||
"%",
|
"%",
|
||||||
|
IntSetting.AUDIO_VOLUME.key,
|
||||||
100
|
100
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
package org.yuzu.yuzu_emu.features.settings.ui
|
package org.yuzu.yuzu_emu.features.settings.ui
|
||||||
|
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.Setting
|
import org.yuzu.yuzu_emu.features.settings.model.AbstractSetting
|
||||||
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
import org.yuzu.yuzu_emu.features.settings.model.view.SettingsItem
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -49,7 +49,7 @@ interface SettingsFragmentView {
|
||||||
*
|
*
|
||||||
* @param setting The (possibly previously missing) new setting.
|
* @param setting The (possibly previously missing) new setting.
|
||||||
*/
|
*/
|
||||||
fun putSetting(setting: Setting)
|
fun putSetting(setting: AbstractSetting)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Have the fragment tell the containing Activity that a setting was modified.
|
* Have the fragment tell the containing Activity that a setting was modified.
|
||||||
|
|
|
@ -21,32 +21,7 @@ import java.util.*
|
||||||
*/
|
*/
|
||||||
object SettingsFile {
|
object SettingsFile {
|
||||||
const val FILE_NAME_CONFIG = "config"
|
const val FILE_NAME_CONFIG = "config"
|
||||||
const val KEY_DESIGN = "design"
|
|
||||||
|
|
||||||
// CPU
|
|
||||||
const val KEY_CPU_ACCURACY = "cpu_accuracy"
|
|
||||||
|
|
||||||
// System
|
|
||||||
const val KEY_USE_DOCKED_MODE = "use_docked_mode"
|
|
||||||
const val KEY_REGION_INDEX = "region_index"
|
|
||||||
const val KEY_LANGUAGE_INDEX = "language_index"
|
|
||||||
const val KEY_RENDERER_BACKEND = "backend"
|
|
||||||
|
|
||||||
// Renderer
|
|
||||||
const val KEY_RENDERER_RESOLUTION = "resolution_setup"
|
|
||||||
const val KEY_RENDERER_SCALING_FILTER = "scaling_filter"
|
|
||||||
const val KEY_RENDERER_ANTI_ALIASING = "anti_aliasing"
|
|
||||||
const val KEY_RENDERER_ASPECT_RATIO = "aspect_ratio"
|
|
||||||
const val KEY_RENDERER_ACCURACY = "gpu_accuracy"
|
|
||||||
const val KEY_RENDERER_USE_DISK_SHADER_CACHE = "use_disk_shader_cache"
|
|
||||||
const val KEY_RENDERER_ASYNCHRONOUS_SHADERS = "use_asynchronous_shaders"
|
|
||||||
const val KEY_RENDERER_FORCE_MAX_CLOCK = "force_max_clock"
|
|
||||||
const val KEY_RENDERER_USE_SPEED_LIMIT = "use_speed_limit"
|
|
||||||
const val KEY_RENDERER_DEBUG = "debug"
|
|
||||||
const val KEY_RENDERER_SPEED_LIMIT = "speed_limit"
|
|
||||||
|
|
||||||
// Audio
|
|
||||||
const val KEY_AUDIO_VOLUME = "volume"
|
|
||||||
private val sectionsMap = BiMap<String?, String?>()
|
private val sectionsMap = BiMap<String?, String?>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,7 +50,7 @@ object SettingsFile {
|
||||||
current = sectionFromLine(line!!, isCustomGame)
|
current = sectionFromLine(line!!, isCustomGame)
|
||||||
sections[current.name] = current
|
sections[current.name] = current
|
||||||
} else if (current != null) {
|
} else if (current != null) {
|
||||||
val setting = settingFromLine(current, line!!)
|
val setting = settingFromLine(line!!)
|
||||||
if (setting != null) {
|
if (setting != null) {
|
||||||
current.putSetting(setting)
|
current.putSetting(setting)
|
||||||
}
|
}
|
||||||
|
@ -201,11 +176,10 @@ object SettingsFile {
|
||||||
* For a line of text, determines what type of data is being represented, and returns
|
* For a line of text, determines what type of data is being represented, and returns
|
||||||
* a Setting object containing this data.
|
* a Setting object containing this data.
|
||||||
*
|
*
|
||||||
* @param current The section currently being parsed by the consuming method.
|
|
||||||
* @param line The line of text being parsed.
|
* @param line The line of text being parsed.
|
||||||
* @return A typed Setting containing the key/value contained in the line.
|
* @return A typed Setting containing the key/value contained in the line.
|
||||||
*/
|
*/
|
||||||
private fun settingFromLine(current: SettingSection, line: String): Setting? {
|
private fun settingFromLine(line: String): AbstractSetting? {
|
||||||
val splitLine = line.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
val splitLine = line.split("=".toRegex()).dropLastWhile { it.isEmpty() }.toTypedArray()
|
||||||
if (splitLine.size != 2) {
|
if (splitLine.size != 2) {
|
||||||
Log.warning("Skipping invalid config line \"$line\"")
|
Log.warning("Skipping invalid config line \"$line\"")
|
||||||
|
@ -217,17 +191,25 @@ object SettingsFile {
|
||||||
Log.warning("Skipping null value in config line \"$line\"")
|
Log.warning("Skipping null value in config line \"$line\"")
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
val valueAsInt = value.toInt()
|
val booleanSetting = BooleanSetting.from(key)
|
||||||
return IntSetting(key, current.name, valueAsInt)
|
if (booleanSetting != null) {
|
||||||
} catch (_: NumberFormatException) {
|
booleanSetting.boolean = value.toBoolean()
|
||||||
|
return booleanSetting
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
val valueAsFloat = value.toFloat()
|
val intSetting = IntSetting.from(key)
|
||||||
return FloatSetting(key, current.name, valueAsFloat)
|
if (intSetting != null) {
|
||||||
} catch (_: NumberFormatException) {
|
intSetting.int = value.toInt()
|
||||||
|
return intSetting
|
||||||
}
|
}
|
||||||
return StringSetting(key, current.name, value)
|
|
||||||
|
val floatSetting = FloatSetting.from(key)
|
||||||
|
if (floatSetting != null) {
|
||||||
|
floatSetting.float = value.toFloat()
|
||||||
|
return floatSetting
|
||||||
|
}
|
||||||
|
return StringSetting.from(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Reference in a new issue