android: Refactor settings to expose more options

In AbstractSetting, this removes the category, androidDefault, and valueAsString properties as they are no longer needed and have replacements. isSwitchable, global, and getValueAsString are all exposed and give better options for working with global/per-game settings.
This commit is contained in:
t895 2023-12-10 20:10:36 -05:00
parent d590cfb9d0
commit 70c3d36536
34 changed files with 320 additions and 349 deletions

View File

@ -172,7 +172,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
override fun onUserLeaveHint() { override fun onUserLeaveHint() {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) { if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
if (BooleanSetting.PICTURE_IN_PICTURE.boolean && !isInPictureInPictureMode) { if (BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && !isInPictureInPictureMode) {
val pictureInPictureParamsBuilder = PictureInPictureParams.Builder() val pictureInPictureParamsBuilder = PictureInPictureParams.Builder()
.getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder() .getPictureInPictureActionsBuilder().getPictureInPictureAspectBuilder()
enterPictureInPictureMode(pictureInPictureParamsBuilder.build()) enterPictureInPictureMode(pictureInPictureParamsBuilder.build())
@ -284,7 +284,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
private fun PictureInPictureParams.Builder.getPictureInPictureAspectBuilder(): private fun PictureInPictureParams.Builder.getPictureInPictureAspectBuilder():
PictureInPictureParams.Builder { PictureInPictureParams.Builder {
val aspectRatio = when (IntSetting.RENDERER_ASPECT_RATIO.int) { val aspectRatio = when (IntSetting.RENDERER_ASPECT_RATIO.getInt()) {
0 -> Rational(16, 9) 0 -> Rational(16, 9)
1 -> Rational(4, 3) 1 -> Rational(4, 3)
2 -> Rational(21, 9) 2 -> Rational(21, 9)
@ -331,7 +331,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
pictureInPictureActions.add(pauseRemoteAction) pictureInPictureActions.add(pauseRemoteAction)
} }
if (BooleanSetting.AUDIO_MUTED.boolean) { if (BooleanSetting.AUDIO_MUTED.getBoolean()) {
val unmuteIcon = Icon.createWithResource( val unmuteIcon = Icon.createWithResource(
this@EmulationActivity, this@EmulationActivity,
R.drawable.ic_pip_unmute R.drawable.ic_pip_unmute
@ -376,7 +376,7 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
val isEmulationActive = emulationViewModel.emulationStarted.value && val isEmulationActive = emulationViewModel.emulationStarted.value &&
!emulationViewModel.isEmulationStopping.value !emulationViewModel.isEmulationStopping.value
pictureInPictureParamsBuilder.setAutoEnterEnabled( pictureInPictureParamsBuilder.setAutoEnterEnabled(
BooleanSetting.PICTURE_IN_PICTURE.boolean && isEmulationActive BooleanSetting.PICTURE_IN_PICTURE.getBoolean() && isEmulationActive
) )
} }
setPictureInPictureParams(pictureInPictureParamsBuilder.build()) setPictureInPictureParams(pictureInPictureParamsBuilder.build())
@ -390,9 +390,13 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
if (!NativeLibrary.isPaused()) NativeLibrary.pauseEmulation() if (!NativeLibrary.isPaused()) NativeLibrary.pauseEmulation()
} }
if (intent.action == actionUnmute) { if (intent.action == actionUnmute) {
if (BooleanSetting.AUDIO_MUTED.boolean) BooleanSetting.AUDIO_MUTED.setBoolean(false) if (BooleanSetting.AUDIO_MUTED.getBoolean()) {
BooleanSetting.AUDIO_MUTED.setBoolean(false)
}
} else if (intent.action == actionMute) { } else if (intent.action == actionMute) {
if (!BooleanSetting.AUDIO_MUTED.boolean) BooleanSetting.AUDIO_MUTED.setBoolean(true) if (!BooleanSetting.AUDIO_MUTED.getBoolean()) {
BooleanSetting.AUDIO_MUTED.setBoolean(true)
}
} }
buildPictureInPictureParams() buildPictureInPictureParams()
} }
@ -423,7 +427,9 @@ class EmulationActivity : AppCompatActivity(), SensorEventListener {
} catch (ignored: Exception) { } catch (ignored: Exception) {
} }
// Always resume audio, since there is no UI button // Always resume audio, since there is no UI button
if (BooleanSetting.AUDIO_MUTED.boolean) BooleanSetting.AUDIO_MUTED.setBoolean(false) if (BooleanSetting.AUDIO_MUTED.getBoolean()) {
BooleanSetting.AUDIO_MUTED.setBoolean(false)
}
} }
} }

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.features.settings.model package org.yuzu.yuzu_emu.features.settings.model
interface AbstractBooleanSetting : AbstractSetting { interface AbstractBooleanSetting : AbstractSetting {
val boolean: Boolean fun getBoolean(needsGlobal: Boolean = false): Boolean
fun setBoolean(value: Boolean) fun setBoolean(value: Boolean)
} }

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.features.settings.model package org.yuzu.yuzu_emu.features.settings.model
interface AbstractByteSetting : AbstractSetting { interface AbstractByteSetting : AbstractSetting {
val byte: Byte fun getByte(needsGlobal: Boolean = false): Byte
fun setByte(value: Byte) fun setByte(value: Byte)
} }

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.features.settings.model package org.yuzu.yuzu_emu.features.settings.model
interface AbstractFloatSetting : AbstractSetting { interface AbstractFloatSetting : AbstractSetting {
val float: Float fun getFloat(needsGlobal: Boolean = false): Float
fun setFloat(value: Float) fun setFloat(value: Float)
} }

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.features.settings.model package org.yuzu.yuzu_emu.features.settings.model
interface AbstractIntSetting : AbstractSetting { interface AbstractIntSetting : AbstractSetting {
val int: Int fun getInt(needsGlobal: Boolean = false): Int
fun setInt(value: Int) fun setInt(value: Int)
} }

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.features.settings.model package org.yuzu.yuzu_emu.features.settings.model
interface AbstractLongSetting : AbstractSetting { interface AbstractLongSetting : AbstractSetting {
val long: Long fun getLong(needsGlobal: Boolean = false): Long
fun setLong(value: Long) fun setLong(value: Long)
} }

View File

@ -7,12 +7,7 @@ import org.yuzu.yuzu_emu.utils.NativeConfig
interface AbstractSetting { interface AbstractSetting {
val key: String val key: String
val category: Settings.Category
val defaultValue: Any val defaultValue: Any
val androidDefault: Any?
get() = null
val valueAsString: String
get() = ""
val isRuntimeModifiable: Boolean val isRuntimeModifiable: Boolean
get() = NativeConfig.getIsRuntimeModifiable(key) get() = NativeConfig.getIsRuntimeModifiable(key)
@ -20,5 +15,14 @@ interface AbstractSetting {
val pairedSettingKey: String val pairedSettingKey: String
get() = NativeConfig.getPairedSettingKey(key) get() = NativeConfig.getPairedSettingKey(key)
val isSwitchable: Boolean
get() = NativeConfig.getIsSwitchable(key)
var global: Boolean
get() = NativeConfig.usingGlobal(key)
set(value) = NativeConfig.setGlobal(key, value)
fun getValueAsString(needsGlobal: Boolean = false): String
fun reset() fun reset()
} }

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.features.settings.model package org.yuzu.yuzu_emu.features.settings.model
interface AbstractShortSetting : AbstractSetting { interface AbstractShortSetting : AbstractSetting {
val short: Short fun getShort(needsGlobal: Boolean = false): Short
fun setShort(value: Short) fun setShort(value: Short)
} }

View File

@ -4,7 +4,6 @@
package org.yuzu.yuzu_emu.features.settings.model package org.yuzu.yuzu_emu.features.settings.model
interface AbstractStringSetting : AbstractSetting { interface AbstractStringSetting : AbstractSetting {
val string: String fun getString(needsGlobal: Boolean = false): String
fun setString(value: String) fun setString(value: String)
} }

View File

@ -5,36 +5,34 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
enum class BooleanSetting( enum class BooleanSetting(override val key: String) : AbstractBooleanSetting {
override val key: String, AUDIO_MUTED("audio_muted"),
override val category: Settings.Category, CPU_DEBUG_MODE("cpu_debug_mode"),
override val androidDefault: Boolean? = null FASTMEM("cpuopt_fastmem"),
) : AbstractBooleanSetting { FASTMEM_EXCLUSIVES("cpuopt_fastmem_exclusives"),
AUDIO_MUTED("audio_muted", Settings.Category.Audio), RENDERER_USE_SPEED_LIMIT("use_speed_limit"),
CPU_DEBUG_MODE("cpu_debug_mode", Settings.Category.Cpu), USE_DOCKED_MODE("use_docked_mode"),
FASTMEM("cpuopt_fastmem", Settings.Category.Cpu), RENDERER_USE_DISK_SHADER_CACHE("use_disk_shader_cache"),
FASTMEM_EXCLUSIVES("cpuopt_fastmem_exclusives", Settings.Category.Cpu), RENDERER_FORCE_MAX_CLOCK("force_max_clock"),
RENDERER_USE_SPEED_LIMIT("use_speed_limit", Settings.Category.Core), RENDERER_ASYNCHRONOUS_SHADERS("use_asynchronous_shaders"),
USE_DOCKED_MODE("use_docked_mode", Settings.Category.System, false), RENDERER_REACTIVE_FLUSHING("use_reactive_flushing"),
RENDERER_USE_DISK_SHADER_CACHE("use_disk_shader_cache", Settings.Category.Renderer), RENDERER_DEBUG("debug"),
RENDERER_FORCE_MAX_CLOCK("force_max_clock", Settings.Category.Renderer), PICTURE_IN_PICTURE("picture_in_picture"),
RENDERER_ASYNCHRONOUS_SHADERS("use_asynchronous_shaders", Settings.Category.Renderer), USE_CUSTOM_RTC("custom_rtc_enabled");
RENDERER_REACTIVE_FLUSHING("use_reactive_flushing", Settings.Category.Renderer, false),
RENDERER_DEBUG("debug", Settings.Category.Renderer),
PICTURE_IN_PICTURE("picture_in_picture", Settings.Category.Android),
USE_CUSTOM_RTC("custom_rtc_enabled", Settings.Category.System);
override val boolean: Boolean override fun getBoolean(needsGlobal: Boolean): Boolean =
get() = NativeConfig.getBoolean(key, false) NativeConfig.getBoolean(key, needsGlobal)
override fun setBoolean(value: Boolean) = NativeConfig.setBoolean(key, value) override fun setBoolean(value: Boolean) {
if (NativeConfig.isPerGameConfigLoaded()) {
override val defaultValue: Boolean by lazy { global = false
androidDefault ?: NativeConfig.getBoolean(key, true) }
NativeConfig.setBoolean(key, value)
} }
override val valueAsString: String override val defaultValue: Boolean by lazy { NativeConfig.getDefaultToString(key).toBoolean() }
get() = if (boolean) "1" else "0"
override fun getValueAsString(needsGlobal: Boolean): String = getBoolean(needsGlobal).toString()
override fun reset() = NativeConfig.setBoolean(key, defaultValue) override fun reset() = NativeConfig.setBoolean(key, defaultValue)
} }

View File

@ -5,21 +5,21 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
enum class ByteSetting( enum class ByteSetting(override val key: String) : AbstractByteSetting {
override val key: String, AUDIO_VOLUME("volume");
override val category: Settings.Category
) : AbstractByteSetting {
AUDIO_VOLUME("volume", Settings.Category.Audio);
override val byte: Byte override fun getByte(needsGlobal: Boolean): Byte = NativeConfig.getByte(key, needsGlobal)
get() = NativeConfig.getByte(key, false)
override fun setByte(value: Byte) = NativeConfig.setByte(key, value) override fun setByte(value: Byte) {
if (NativeConfig.isPerGameConfigLoaded()) {
global = false
}
NativeConfig.setByte(key, value)
}
override val defaultValue: Byte by lazy { NativeConfig.getByte(key, true) } override val defaultValue: Byte by lazy { NativeConfig.getDefaultToString(key).toByte() }
override val valueAsString: String override fun getValueAsString(needsGlobal: Boolean): String = getByte(needsGlobal).toString()
get() = byte.toString()
override fun reset() = NativeConfig.setByte(key, defaultValue) override fun reset() = NativeConfig.setByte(key, defaultValue)
} }

View File

@ -5,22 +5,22 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
enum class FloatSetting( enum class FloatSetting(override val key: String) : AbstractFloatSetting {
override val key: String,
override val category: Settings.Category
) : AbstractFloatSetting {
// No float settings currently exist // No float settings currently exist
EMPTY_SETTING("", Settings.Category.UiGeneral); EMPTY_SETTING("");
override val float: Float override fun getFloat(needsGlobal: Boolean): Float = NativeConfig.getFloat(key, false)
get() = NativeConfig.getFloat(key, false)
override fun setFloat(value: Float) = NativeConfig.setFloat(key, value) override fun setFloat(value: Float) {
if (NativeConfig.isPerGameConfigLoaded()) {
global = false
}
NativeConfig.setFloat(key, value)
}
override val defaultValue: Float by lazy { NativeConfig.getFloat(key, true) } override val defaultValue: Float by lazy { NativeConfig.getDefaultToString(key).toFloat() }
override val valueAsString: String override fun getValueAsString(needsGlobal: Boolean): String = getFloat(needsGlobal).toString()
get() = float.toString()
override fun reset() = NativeConfig.setFloat(key, defaultValue) override fun reset() = NativeConfig.setFloat(key, defaultValue)
} }

View File

@ -5,36 +5,33 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
enum class IntSetting( enum class IntSetting(override val key: String) : AbstractIntSetting {
override val key: String, CPU_BACKEND("cpu_backend"),
override val category: Settings.Category, CPU_ACCURACY("cpu_accuracy"),
override val androidDefault: Int? = null REGION_INDEX("region_index"),
) : AbstractIntSetting { LANGUAGE_INDEX("language_index"),
CPU_BACKEND("cpu_backend", Settings.Category.Cpu), RENDERER_BACKEND("backend"),
CPU_ACCURACY("cpu_accuracy", Settings.Category.Cpu), RENDERER_ACCURACY("gpu_accuracy"),
REGION_INDEX("region_index", Settings.Category.System), RENDERER_RESOLUTION("resolution_setup"),
LANGUAGE_INDEX("language_index", Settings.Category.System), RENDERER_VSYNC("use_vsync"),
RENDERER_BACKEND("backend", Settings.Category.Renderer), RENDERER_SCALING_FILTER("scaling_filter"),
RENDERER_ACCURACY("gpu_accuracy", Settings.Category.Renderer, 0), RENDERER_ANTI_ALIASING("anti_aliasing"),
RENDERER_RESOLUTION("resolution_setup", Settings.Category.Renderer), RENDERER_SCREEN_LAYOUT("screen_layout"),
RENDERER_VSYNC("use_vsync", Settings.Category.Renderer), RENDERER_ASPECT_RATIO("aspect_ratio"),
RENDERER_SCALING_FILTER("scaling_filter", Settings.Category.Renderer), AUDIO_OUTPUT_ENGINE("output_engine");
RENDERER_ANTI_ALIASING("anti_aliasing", Settings.Category.Renderer),
RENDERER_SCREEN_LAYOUT("screen_layout", Settings.Category.Android),
RENDERER_ASPECT_RATIO("aspect_ratio", Settings.Category.Renderer),
AUDIO_OUTPUT_ENGINE("output_engine", Settings.Category.Audio);
override val int: Int override fun getInt(needsGlobal: Boolean): Int = NativeConfig.getInt(key, needsGlobal)
get() = NativeConfig.getInt(key, false)
override fun setInt(value: Int) = NativeConfig.setInt(key, value) override fun setInt(value: Int) {
if (NativeConfig.isPerGameConfigLoaded()) {
override val defaultValue: Int by lazy { global = false
androidDefault ?: NativeConfig.getInt(key, true) }
NativeConfig.setInt(key, value)
} }
override val valueAsString: String override val defaultValue: Int by lazy { NativeConfig.getDefaultToString(key).toInt() }
get() = int.toString()
override fun getValueAsString(needsGlobal: Boolean): String = getInt(needsGlobal).toString()
override fun reset() = NativeConfig.setInt(key, defaultValue) override fun reset() = NativeConfig.setInt(key, defaultValue)
} }

View File

@ -5,21 +5,21 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
enum class LongSetting( enum class LongSetting(override val key: String) : AbstractLongSetting {
override val key: String, CUSTOM_RTC("custom_rtc");
override val category: Settings.Category
) : AbstractLongSetting {
CUSTOM_RTC("custom_rtc", Settings.Category.System);
override val long: Long override fun getLong(needsGlobal: Boolean): Long = NativeConfig.getLong(key, needsGlobal)
get() = NativeConfig.getLong(key, false)
override fun setLong(value: Long) = NativeConfig.setLong(key, value) override fun setLong(value: Long) {
if (NativeConfig.isPerGameConfigLoaded()) {
global = false
}
NativeConfig.setLong(key, value)
}
override val defaultValue: Long by lazy { NativeConfig.getLong(key, true) } override val defaultValue: Long by lazy { NativeConfig.getDefaultToString(key).toLong() }
override val valueAsString: String override fun getValueAsString(needsGlobal: Boolean): String = getLong(needsGlobal).toString()
get() = long.toString()
override fun reset() = NativeConfig.setLong(key, defaultValue) override fun reset() = NativeConfig.setLong(key, defaultValue)
} }

View File

@ -6,62 +6,11 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.R import org.yuzu.yuzu_emu.R
object Settings { object Settings {
enum class Category {
Android,
Audio,
Core,
Cpu,
CpuDebug,
CpuUnsafe,
Renderer,
RendererAdvanced,
RendererDebug,
System,
SystemAudio,
DataStorage,
Debugging,
DebuggingGraphics,
Miscellaneous,
Network,
WebService,
AddOns,
Controls,
Ui,
UiGeneral,
UiLayout,
UiGameList,
Screenshots,
Shortcuts,
Multiplayer,
Services,
Paths,
MaxEnum
}
val settingsList = listOf<AbstractSetting>(
*BooleanSetting.values(),
*ByteSetting.values(),
*ShortSetting.values(),
*IntSetting.values(),
*FloatSetting.values(),
*LongSetting.values(),
*StringSetting.values()
)
const val SECTION_GENERAL = "General"
const val SECTION_SYSTEM = "System"
const val SECTION_RENDERER = "Renderer"
const val SECTION_AUDIO = "Audio"
const val SECTION_CPU = "Cpu"
const val SECTION_THEME = "Theme"
const val SECTION_DEBUG = "Debug"
enum class MenuTag(val titleId: Int) { enum class MenuTag(val titleId: Int) {
SECTION_ROOT(R.string.advanced_settings), SECTION_ROOT(R.string.advanced_settings),
SECTION_SYSTEM(R.string.preferences_system), SECTION_SYSTEM(R.string.preferences_system),
SECTION_RENDERER(R.string.preferences_graphics), SECTION_RENDERER(R.string.preferences_graphics),
SECTION_AUDIO(R.string.preferences_audio), SECTION_AUDIO(R.string.preferences_audio),
SECTION_CPU(R.string.cpu),
SECTION_THEME(R.string.preferences_theme), SECTION_THEME(R.string.preferences_theme),
SECTION_DEBUG(R.string.preferences_debug); SECTION_DEBUG(R.string.preferences_debug);
} }

View File

@ -5,21 +5,21 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
enum class ShortSetting( enum class ShortSetting(override val key: String) : AbstractShortSetting {
override val key: String, RENDERER_SPEED_LIMIT("speed_limit");
override val category: Settings.Category
) : AbstractShortSetting {
RENDERER_SPEED_LIMIT("speed_limit", Settings.Category.Core);
override val short: Short override fun getShort(needsGlobal: Boolean): Short = NativeConfig.getShort(key, needsGlobal)
get() = NativeConfig.getShort(key, false)
override fun setShort(value: Short) = NativeConfig.setShort(key, value) override fun setShort(value: Short) {
if (NativeConfig.isPerGameConfigLoaded()) {
global = false
}
NativeConfig.setShort(key, value)
}
override val defaultValue: Short by lazy { NativeConfig.getShort(key, true) } override val defaultValue: Short by lazy { NativeConfig.getDefaultToString(key).toShort() }
override val valueAsString: String override fun getValueAsString(needsGlobal: Boolean): String = getShort(needsGlobal).toString()
get() = short.toString()
override fun reset() = NativeConfig.setShort(key, defaultValue) override fun reset() = NativeConfig.setShort(key, defaultValue)
} }

View File

@ -5,22 +5,21 @@ package org.yuzu.yuzu_emu.features.settings.model
import org.yuzu.yuzu_emu.utils.NativeConfig import org.yuzu.yuzu_emu.utils.NativeConfig
enum class StringSetting( enum class StringSetting(override val key: String) : AbstractStringSetting {
override val key: String, DRIVER_PATH("driver_path");
override val category: Settings.Category
) : AbstractStringSetting {
// No string settings currently exist
EMPTY_SETTING("", Settings.Category.UiGeneral);
override val string: String override fun getString(needsGlobal: Boolean): String = NativeConfig.getString(key, needsGlobal)
get() = NativeConfig.getString(key, false)
override fun setString(value: String) = NativeConfig.setString(key, value) override fun setString(value: String) {
if (NativeConfig.isPerGameConfigLoaded()) {
global = false
}
NativeConfig.setString(key, value)
}
override val defaultValue: String by lazy { NativeConfig.getString(key, true) } override val defaultValue: String by lazy { NativeConfig.getDefaultToString(key) }
override val valueAsString: String override fun getValueAsString(needsGlobal: Boolean): String = getString(needsGlobal)
get() = string
override fun reset() = NativeConfig.setString(key, defaultValue) override fun reset() = NativeConfig.setString(key, defaultValue)
} }

View File

@ -12,7 +12,6 @@ class DateTimeSetting(
) : SettingsItem(longSetting, titleId, descriptionId) { ) : SettingsItem(longSetting, titleId, descriptionId) {
override val type = TYPE_DATETIME_SETTING override val type = TYPE_DATETIME_SETTING
var value: Long fun getValue(needsGlobal: Boolean = false): Long = longSetting.getLong(needsGlobal)
get() = longSetting.long fun setValue(value: Long) = (setting as AbstractLongSetting).setLong(value)
set(value) = (setting as AbstractLongSetting).setLong(value)
} }

View File

@ -11,7 +11,6 @@ import org.yuzu.yuzu_emu.features.settings.model.BooleanSetting
import org.yuzu.yuzu_emu.features.settings.model.ByteSetting import org.yuzu.yuzu_emu.features.settings.model.ByteSetting
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.LongSetting import org.yuzu.yuzu_emu.features.settings.model.LongSetting
import org.yuzu.yuzu_emu.features.settings.model.Settings
import org.yuzu.yuzu_emu.features.settings.model.ShortSetting import org.yuzu.yuzu_emu.features.settings.model.ShortSetting
/** /**
@ -48,8 +47,8 @@ abstract class SettingsItem(
val emptySetting = object : AbstractSetting { val emptySetting = object : AbstractSetting {
override val key: String = "" override val key: String = ""
override val category: Settings.Category = Settings.Category.Ui
override val defaultValue: Any = false override val defaultValue: Any = false
override fun getValueAsString(needsGlobal: Boolean): String = ""
override fun reset() {} override fun reset() {}
} }
@ -270,9 +269,9 @@ abstract class SettingsItem(
) )
val fastmem = object : AbstractBooleanSetting { val fastmem = object : AbstractBooleanSetting {
override val boolean: Boolean override fun getBoolean(needsGlobal: Boolean): Boolean =
get() = BooleanSetting.FASTMEM.getBoolean() &&
BooleanSetting.FASTMEM.boolean && BooleanSetting.FASTMEM_EXCLUSIVES.boolean BooleanSetting.FASTMEM_EXCLUSIVES.getBoolean()
override fun setBoolean(value: Boolean) { override fun setBoolean(value: Boolean) {
BooleanSetting.FASTMEM.setBoolean(value) BooleanSetting.FASTMEM.setBoolean(value)
@ -280,9 +279,22 @@ abstract class SettingsItem(
} }
override val key: String = FASTMEM_COMBINED override val key: String = FASTMEM_COMBINED
override val category = Settings.Category.Cpu
override val isRuntimeModifiable: Boolean = false override val isRuntimeModifiable: Boolean = false
override val defaultValue: Boolean = true override val defaultValue: Boolean = true
override val isSwitchable: Boolean = true
override var global: Boolean
get() {
return BooleanSetting.FASTMEM.global &&
BooleanSetting.FASTMEM_EXCLUSIVES.global
}
set(value) {
BooleanSetting.FASTMEM.global = value
BooleanSetting.FASTMEM_EXCLUSIVES.global = value
}
override fun getValueAsString(needsGlobal: Boolean): String =
getBoolean().toString()
override fun reset() = setBoolean(defaultValue) override fun reset() = setBoolean(defaultValue)
} }
put(SwitchSetting(fastmem, R.string.fastmem, 0)) put(SwitchSetting(fastmem, R.string.fastmem, 0))

View File

@ -15,16 +15,11 @@ class SingleChoiceSetting(
) : SettingsItem(setting, titleId, descriptionId) { ) : SettingsItem(setting, titleId, descriptionId) {
override val type = TYPE_SINGLE_CHOICE override val type = TYPE_SINGLE_CHOICE
var selectedValue: Int fun getSelectedValue(needsGlobal: Boolean = false) =
get() { when (setting) {
return when (setting) { is AbstractIntSetting -> setting.getInt(needsGlobal)
is AbstractIntSetting -> setting.int
else -> -1 else -> -1
} }
}
set(value) { fun setSelectedValue(value: Int) = (setting as AbstractIntSetting).setInt(value)
when (setting) {
is AbstractIntSetting -> setting.setInt(value)
}
}
} }

View File

@ -20,22 +20,20 @@ class SliderSetting(
) : SettingsItem(setting, titleId, descriptionId) { ) : SettingsItem(setting, titleId, descriptionId) {
override val type = TYPE_SLIDER override val type = TYPE_SLIDER
var selectedValue: Int fun getSelectedValue(needsGlobal: Boolean = false) =
get() { when (setting) {
return when (setting) { is AbstractByteSetting -> setting.getByte(needsGlobal).toInt()
is AbstractByteSetting -> setting.byte.toInt() is AbstractShortSetting -> setting.getShort(needsGlobal).toInt()
is AbstractShortSetting -> setting.short.toInt() is AbstractIntSetting -> setting.getInt(needsGlobal)
is AbstractIntSetting -> setting.int is AbstractFloatSetting -> setting.getFloat(needsGlobal).roundToInt()
is AbstractFloatSetting -> setting.float.roundToInt()
else -> -1 else -> -1
} }
}
set(value) { fun setSelectedValue(value: Int) =
when (setting) { when (setting) {
is AbstractByteSetting -> setting.setByte(value.toByte()) is AbstractByteSetting -> setting.setByte(value.toByte())
is AbstractShortSetting -> setting.setShort(value.toShort()) is AbstractShortSetting -> setting.setShort(value.toShort())
is AbstractIntSetting -> setting.setInt(value)
is AbstractFloatSetting -> setting.setFloat(value.toFloat()) is AbstractFloatSetting -> setting.setFloat(value.toFloat())
} else -> (setting as AbstractIntSetting).setInt(value)
} }
} }

View File

@ -17,14 +17,13 @@ class StringSingleChoiceSetting(
fun getValueAt(index: Int): String = fun getValueAt(index: Int): String =
if (index >= 0 && index < values.size) values[index] else "" if (index >= 0 && index < values.size) values[index] else ""
var selectedValue: String fun getSelectedValue(needsGlobal: Boolean = false) = stringSetting.getString(needsGlobal)
get() = stringSetting.string fun setSelectedValue(value: String) = stringSetting.setString(value)
set(value) = stringSetting.setString(value)
val selectValueIndex: Int val selectValueIndex: Int
get() { get() {
for (i in values.indices) { for (i in values.indices) {
if (values[i] == selectedValue) { if (values[i] == getSelectedValue()) {
return i return i
} }
} }

View File

@ -14,15 +14,15 @@ class SwitchSetting(
) : SettingsItem(setting, titleId, descriptionId) { ) : SettingsItem(setting, titleId, descriptionId) {
override val type = TYPE_SWITCH override val type = TYPE_SWITCH
var checked: Boolean fun getIsChecked(needsGlobal: Boolean = false): Boolean {
get() {
return when (setting) { return when (setting) {
is AbstractIntSetting -> setting.int == 1 is AbstractIntSetting -> setting.getInt(needsGlobal) == 1
is AbstractBooleanSetting -> setting.boolean is AbstractBooleanSetting -> setting.getBoolean(needsGlobal)
else -> false else -> false
} }
} }
set(value) {
fun setChecked(value: Boolean) {
when (setting) { when (setting) {
is AbstractIntSetting -> setting.setInt(if (value) 1 else 0) is AbstractIntSetting -> setting.setInt(if (value) 1 else 0)
is AbstractBooleanSetting -> setting.setBoolean(value) is AbstractBooleanSetting -> setting.setBoolean(value)

View File

@ -102,8 +102,9 @@ class SettingsAdapter(
return currentList[position].type return currentList[position].type
} }
fun onBooleanClick(item: SwitchSetting, checked: Boolean) { fun onBooleanClick(item: SwitchSetting, checked: Boolean, position: Int) {
item.checked = checked item.setChecked(checked)
notifyItemChanged(position)
settingsViewModel.setShouldReloadSettingsList(true) settingsViewModel.setShouldReloadSettingsList(true)
} }
@ -126,7 +127,7 @@ class SettingsAdapter(
} }
fun onDateTimeClick(item: DateTimeSetting, position: Int) { fun onDateTimeClick(item: DateTimeSetting, position: Int) {
val storedTime = item.value * 1000 val storedTime = item.getValue() * 1000
// Helper to extract hour and minute from epoch time // Helper to extract hour and minute from epoch time
val calendar: Calendar = Calendar.getInstance() val calendar: Calendar = Calendar.getInstance()
@ -159,9 +160,9 @@ class SettingsAdapter(
var epochTime: Long = datePicker.selection!! / 1000 var epochTime: Long = datePicker.selection!! / 1000
epochTime += timePicker.hour.toLong() * 60 * 60 epochTime += timePicker.hour.toLong() * 60 * 60
epochTime += timePicker.minute.toLong() * 60 epochTime += timePicker.minute.toLong() * 60
if (item.value != epochTime) { if (item.getValue() != epochTime) {
notifyItemChanged(position) notifyItemChanged(position)
item.value = epochTime item.setValue(epochTime)
} }
} }
datePicker.show( datePicker.show(

View File

@ -36,7 +36,14 @@ class SettingsFragmentPresenter(
val item = SettingsItem.settingsItems[key]!! val item = SettingsItem.settingsItems[key]!!
val pairedSettingKey = item.setting.pairedSettingKey val pairedSettingKey = item.setting.pairedSettingKey
if (pairedSettingKey.isNotEmpty()) { if (pairedSettingKey.isNotEmpty()) {
val pairedSettingValue = NativeConfig.getBoolean(pairedSettingKey, false) val pairedSettingValue = NativeConfig.getBoolean(
pairedSettingKey,
if (NativeLibrary.isRunning() && !NativeConfig.isPerGameConfigLoaded()) {
!NativeConfig.usingGlobal(pairedSettingKey)
} else {
NativeConfig.usingGlobal(pairedSettingKey)
}
)
if (!pairedSettingValue) return if (!pairedSettingValue) return
} }
add(item) add(item)
@ -153,8 +160,8 @@ class SettingsFragmentPresenter(
private fun addThemeSettings(sl: ArrayList<SettingsItem>) { private fun addThemeSettings(sl: ArrayList<SettingsItem>) {
sl.apply { sl.apply {
val theme: AbstractIntSetting = object : AbstractIntSetting { val theme: AbstractIntSetting = object : AbstractIntSetting {
override val int: Int override fun getInt(needsGlobal: Boolean): Int =
get() = preferences.getInt(Settings.PREF_THEME, 0) preferences.getInt(Settings.PREF_THEME, 0)
override fun setInt(value: Int) { override fun setInt(value: Int) {
preferences.edit() preferences.edit()
@ -164,8 +171,8 @@ class SettingsFragmentPresenter(
} }
override val key: String = Settings.PREF_THEME override val key: String = Settings.PREF_THEME
override val category = Settings.Category.UiGeneral
override val isRuntimeModifiable: Boolean = false override val isRuntimeModifiable: Boolean = false
override fun getValueAsString(needsGlobal: Boolean): String = getInt().toString()
override val defaultValue: Int = 0 override val defaultValue: Int = 0
override fun reset() { override fun reset() {
preferences.edit() preferences.edit()
@ -197,8 +204,8 @@ class SettingsFragmentPresenter(
} }
val themeMode: AbstractIntSetting = object : AbstractIntSetting { val themeMode: AbstractIntSetting = object : AbstractIntSetting {
override val int: Int override fun getInt(needsGlobal: Boolean): Int =
get() = preferences.getInt(Settings.PREF_THEME_MODE, -1) preferences.getInt(Settings.PREF_THEME_MODE, -1)
override fun setInt(value: Int) { override fun setInt(value: Int) {
preferences.edit() preferences.edit()
@ -208,8 +215,8 @@ class SettingsFragmentPresenter(
} }
override val key: String = Settings.PREF_THEME_MODE override val key: String = Settings.PREF_THEME_MODE
override val category = Settings.Category.UiGeneral
override val isRuntimeModifiable: Boolean = false override val isRuntimeModifiable: Boolean = false
override fun getValueAsString(needsGlobal: Boolean): String = getInt().toString()
override val defaultValue: Int = -1 override val defaultValue: Int = -1
override fun reset() { override fun reset() {
preferences.edit() preferences.edit()
@ -230,8 +237,8 @@ class SettingsFragmentPresenter(
) )
val blackBackgrounds: AbstractBooleanSetting = object : AbstractBooleanSetting { val blackBackgrounds: AbstractBooleanSetting = object : AbstractBooleanSetting {
override val boolean: Boolean override fun getBoolean(needsGlobal: Boolean): Boolean =
get() = preferences.getBoolean(Settings.PREF_BLACK_BACKGROUNDS, false) preferences.getBoolean(Settings.PREF_BLACK_BACKGROUNDS, false)
override fun setBoolean(value: Boolean) { override fun setBoolean(value: Boolean) {
preferences.edit() preferences.edit()
@ -241,8 +248,10 @@ class SettingsFragmentPresenter(
} }
override val key: String = Settings.PREF_BLACK_BACKGROUNDS override val key: String = Settings.PREF_BLACK_BACKGROUNDS
override val category = Settings.Category.UiGeneral
override val isRuntimeModifiable: Boolean = false override val isRuntimeModifiable: Boolean = false
override fun getValueAsString(needsGlobal: Boolean): String =
getBoolean().toString()
override val defaultValue: Boolean = false override val defaultValue: Boolean = false
override fun reset() { override fun reset() {
preferences.edit() preferences.edit()

View File

@ -29,7 +29,7 @@ class DateTimeViewHolder(val binding: ListItemSettingBinding, adapter: SettingsA
} }
binding.textSettingValue.visibility = View.VISIBLE binding.textSettingValue.visibility = View.VISIBLE
val epochTime = setting.value val epochTime = setting.getValue()
val instant = Instant.ofEpochMilli(epochTime * 1000) val instant = Instant.ofEpochMilli(epochTime * 1000)
val zonedTime = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC")) val zonedTime = ZonedDateTime.ofInstant(instant, ZoneId.of("UTC"))
val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM) val dateFormatter = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)

View File

@ -29,14 +29,14 @@ class SingleChoiceViewHolder(val binding: ListItemSettingBinding, adapter: Setti
val resMgr = binding.textSettingValue.context.resources val resMgr = binding.textSettingValue.context.resources
val values = resMgr.getIntArray(item.valuesId) val values = resMgr.getIntArray(item.valuesId)
for (i in values.indices) { for (i in values.indices) {
if (values[i] == item.selectedValue) { if (values[i] == item.getSelectedValue()) {
binding.textSettingValue.text = resMgr.getStringArray(item.choicesId)[i] binding.textSettingValue.text = resMgr.getStringArray(item.choicesId)[i]
break break
} }
} }
} else if (item is StringSingleChoiceSetting) { } else if (item is StringSingleChoiceSetting) {
for (i in item.values.indices) { for (i in item.values.indices) {
if (item.values[i] == item.selectedValue) { if (item.values[i] == item.getSelectedValue()) {
binding.textSettingValue.text = item.choices[i] binding.textSettingValue.text = item.choices[i]
break break
} }

View File

@ -26,7 +26,7 @@ class SliderViewHolder(val binding: ListItemSettingBinding, adapter: SettingsAda
binding.textSettingValue.visibility = View.VISIBLE binding.textSettingValue.visibility = View.VISIBLE
binding.textSettingValue.text = String.format( binding.textSettingValue.text = String.format(
binding.textSettingValue.context.getString(R.string.value_with_units), binding.textSettingValue.context.getString(R.string.value_with_units),
setting.selectedValue, setting.getSelectedValue(),
setting.units setting.units
) )

View File

@ -27,7 +27,7 @@ class SwitchSettingViewHolder(val binding: ListItemSettingSwitchBinding, adapter
} }
binding.switchWidget.setOnCheckedChangeListener(null) binding.switchWidget.setOnCheckedChangeListener(null)
binding.switchWidget.isChecked = setting.checked binding.switchWidget.isChecked = setting.getIsChecked(setting.needsRuntimeGlobal)
binding.switchWidget.setOnCheckedChangeListener { _: CompoundButton, _: Boolean -> binding.switchWidget.setOnCheckedChangeListener { _: CompoundButton, _: Boolean ->
adapter.onBooleanClick(item, binding.switchWidget.isChecked) adapter.onBooleanClick(item, binding.switchWidget.isChecked)
} }

View File

@ -435,7 +435,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
@SuppressLint("SourceLockedOrientationActivity") @SuppressLint("SourceLockedOrientationActivity")
private fun updateOrientation() { private fun updateOrientation() {
emulationActivity?.let { emulationActivity?.let {
it.requestedOrientation = when (IntSetting.RENDERER_SCREEN_LAYOUT.int) { it.requestedOrientation = when (IntSetting.RENDERER_SCREEN_LAYOUT.getInt()) {
Settings.LayoutOption_MobileLandscape -> Settings.LayoutOption_MobileLandscape ->
ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE
Settings.LayoutOption_MobilePortrait -> Settings.LayoutOption_MobilePortrait ->
@ -617,7 +617,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
@SuppressLint("SourceLockedOrientationActivity") @SuppressLint("SourceLockedOrientationActivity")
private fun startConfiguringControls() { private fun startConfiguringControls() {
// Lock the current orientation to prevent editing inconsistencies // Lock the current orientation to prevent editing inconsistencies
if (IntSetting.RENDERER_SCREEN_LAYOUT.int == Settings.LayoutOption_Unspecified) { if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == Settings.LayoutOption_Unspecified) {
emulationActivity?.let { emulationActivity?.let {
it.requestedOrientation = it.requestedOrientation =
if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) { if (resources.configuration.orientation == Configuration.ORIENTATION_PORTRAIT) {
@ -635,7 +635,7 @@ class EmulationFragment : Fragment(), SurfaceHolder.Callback {
binding.doneControlConfig.visibility = View.GONE binding.doneControlConfig.visibility = View.GONE
binding.surfaceInputOverlay.setIsInEditMode(false) binding.surfaceInputOverlay.setIsInEditMode(false)
// Unlock the orientation if it was locked for editing // Unlock the orientation if it was locked for editing
if (IntSetting.RENDERER_SCREEN_LAYOUT.int == Settings.LayoutOption_Unspecified) { if (IntSetting.RENDERER_SCREEN_LAYOUT.getInt() == Settings.LayoutOption_Unspecified) {
emulationActivity?.let { emulationActivity?.let {
it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED it.requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED
} }

View File

@ -70,7 +70,7 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
sliderBinding = DialogSliderBinding.inflate(layoutInflater) sliderBinding = DialogSliderBinding.inflate(layoutInflater)
val item = settingsViewModel.clickedItem as SliderSetting val item = settingsViewModel.clickedItem as SliderSetting
settingsViewModel.setSliderTextValue(item.selectedValue.toFloat(), item.units) settingsViewModel.setSliderTextValue(item.getSelectedValue().toFloat(), item.units)
sliderBinding.slider.apply { sliderBinding.slider.apply {
valueFrom = item.min.toFloat() valueFrom = item.min.toFloat()
valueTo = item.max.toFloat() valueTo = item.max.toFloat()
@ -136,18 +136,18 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
is SingleChoiceSetting -> { is SingleChoiceSetting -> {
val scSetting = settingsViewModel.clickedItem as SingleChoiceSetting val scSetting = settingsViewModel.clickedItem as SingleChoiceSetting
val value = getValueForSingleChoiceSelection(scSetting, which) val value = getValueForSingleChoiceSelection(scSetting, which)
scSetting.selectedValue = value scSetting.setSelectedValue(value)
} }
is StringSingleChoiceSetting -> { is StringSingleChoiceSetting -> {
val scSetting = settingsViewModel.clickedItem as StringSingleChoiceSetting val scSetting = settingsViewModel.clickedItem as StringSingleChoiceSetting
val value = scSetting.getValueAt(which) val value = scSetting.getValueAt(which)
scSetting.selectedValue = value scSetting.setSelectedValue(value)
} }
is SliderSetting -> { is SliderSetting -> {
val sliderSetting = settingsViewModel.clickedItem as SliderSetting val sliderSetting = settingsViewModel.clickedItem as SliderSetting
sliderSetting.selectedValue = settingsViewModel.sliderProgress.value sliderSetting.setSelectedValue(settingsViewModel.sliderProgress.value)
} }
} }
closeDialog() closeDialog()
@ -171,7 +171,7 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
} }
private fun getSelectionForSingleChoiceValue(item: SingleChoiceSetting): Int { private fun getSelectionForSingleChoiceValue(item: SingleChoiceSetting): Int {
val value = item.selectedValue val value = item.getSelectedValue()
val valuesId = item.valuesId val valuesId = item.valuesId
if (valuesId > 0) { if (valuesId > 0) {
val valuesArray = requireContext().resources.getIntArray(valuesId) val valuesArray = requireContext().resources.getIntArray(valuesId)
@ -211,7 +211,7 @@ class SettingsDialogFragment : DialogFragment(), DialogInterface.OnClickListener
throw IllegalArgumentException("[SettingsDialogFragment] Incompatible type!") throw IllegalArgumentException("[SettingsDialogFragment] Incompatible type!")
SettingsItem.TYPE_SLIDER -> settingsViewModel.setSliderProgress( SettingsItem.TYPE_SLIDER -> settingsViewModel.setSliderProgress(
(clickedItem as SliderSetting).selectedValue.toFloat() (clickedItem as SliderSetting).getSelectedValue().toFloat()
) )
} }
settingsViewModel.clickedItem = clickedItem settingsViewModel.clickedItem = clickedItem

View File

@ -31,32 +31,63 @@ object NativeConfig {
external fun saveSettings() external fun saveSettings()
external fun getBoolean(key: String, getDefault: Boolean): Boolean external fun getBoolean(key: String, getDefault: Boolean): Boolean
@Synchronized
external fun getBoolean(key: String, needsGlobal: Boolean): Boolean
@Synchronized
external fun setBoolean(key: String, value: Boolean) external fun setBoolean(key: String, value: Boolean)
external fun getByte(key: String, getDefault: Boolean): Byte @Synchronized
external fun getByte(key: String, needsGlobal: Boolean): Byte
@Synchronized
external fun setByte(key: String, value: Byte) external fun setByte(key: String, value: Byte)
external fun getShort(key: String, getDefault: Boolean): Short @Synchronized
external fun getShort(key: String, needsGlobal: Boolean): Short
@Synchronized
external fun setShort(key: String, value: Short) external fun setShort(key: String, value: Short)
external fun getInt(key: String, getDefault: Boolean): Int @Synchronized
external fun getInt(key: String, needsGlobal: Boolean): Int
@Synchronized
external fun setInt(key: String, value: Int) external fun setInt(key: String, value: Int)
external fun getFloat(key: String, getDefault: Boolean): Float @Synchronized
external fun getFloat(key: String, needsGlobal: Boolean): Float
@Synchronized
external fun setFloat(key: String, value: Float) external fun setFloat(key: String, value: Float)
external fun getLong(key: String, getDefault: Boolean): Long @Synchronized
external fun getLong(key: String, needsGlobal: Boolean): Long
@Synchronized
external fun setLong(key: String, value: Long) external fun setLong(key: String, value: Long)
external fun getString(key: String, getDefault: Boolean): String @Synchronized
external fun getString(key: String, needsGlobal: Boolean): String
@Synchronized
external fun setString(key: String, value: String) external fun setString(key: String, value: String)
external fun getIsRuntimeModifiable(key: String): Boolean external fun getIsRuntimeModifiable(key: String): Boolean
external fun getConfigHeader(category: Int): String
external fun getPairedSettingKey(key: String): String external fun getPairedSettingKey(key: String): String
external fun getIsSwitchable(key: String): Boolean
@Synchronized
external fun usingGlobal(key: String): Boolean
@Synchronized
external fun setGlobal(key: String, global: Boolean)
external fun getDefaultToString(key: String): String
/** /**
* Gets every [GameDir] in AndroidSettings::values.game_dirs * Gets every [GameDir] in AndroidSettings::values.game_dirs
*/ */

View File

@ -49,18 +49,12 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_saveSettings(JNIEnv* env, jobjec
} }
jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getBoolean(JNIEnv* env, jobject obj, jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getBoolean(JNIEnv* env, jobject obj,
jstring jkey, jboolean getDefault) { jstring jkey, jboolean needGlobal) {
auto setting = getSetting<bool>(env, jkey); auto setting = getSetting<bool>(env, jkey);
if (setting == nullptr) { if (setting == nullptr) {
return false; return false;
} }
setting->SetGlobal(true); return setting->GetValue(static_cast<bool>(needGlobal));
if (static_cast<bool>(getDefault)) {
return setting->GetDefault();
}
return setting->GetValue();
} }
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setBoolean(JNIEnv* env, jobject obj, jstring jkey, void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setBoolean(JNIEnv* env, jobject obj, jstring jkey,
@ -69,23 +63,16 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setBoolean(JNIEnv* env, jobject
if (setting == nullptr) { if (setting == nullptr) {
return; return;
} }
setting->SetGlobal(true);
setting->SetValue(static_cast<bool>(value)); setting->SetValue(static_cast<bool>(value));
} }
jbyte Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getByte(JNIEnv* env, jobject obj, jstring jkey, jbyte Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getByte(JNIEnv* env, jobject obj, jstring jkey,
jboolean getDefault) { jboolean needGlobal) {
auto setting = getSetting<u8>(env, jkey); auto setting = getSetting<u8>(env, jkey);
if (setting == nullptr) { if (setting == nullptr) {
return -1; return -1;
} }
setting->SetGlobal(true); return setting->GetValue(static_cast<bool>(needGlobal));
if (static_cast<bool>(getDefault)) {
return setting->GetDefault();
}
return setting->GetValue();
} }
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setByte(JNIEnv* env, jobject obj, jstring jkey, void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setByte(JNIEnv* env, jobject obj, jstring jkey,
@ -94,23 +81,16 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setByte(JNIEnv* env, jobject obj
if (setting == nullptr) { if (setting == nullptr) {
return; return;
} }
setting->SetGlobal(true);
setting->SetValue(value); setting->SetValue(value);
} }
jshort Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getShort(JNIEnv* env, jobject obj, jstring jkey, jshort Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getShort(JNIEnv* env, jobject obj, jstring jkey,
jboolean getDefault) { jboolean needGlobal) {
auto setting = getSetting<u16>(env, jkey); auto setting = getSetting<u16>(env, jkey);
if (setting == nullptr) { if (setting == nullptr) {
return -1; return -1;
} }
setting->SetGlobal(true); return setting->GetValue(static_cast<bool>(needGlobal));
if (static_cast<bool>(getDefault)) {
return setting->GetDefault();
}
return setting->GetValue();
} }
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setShort(JNIEnv* env, jobject obj, jstring jkey, void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setShort(JNIEnv* env, jobject obj, jstring jkey,
@ -119,23 +99,16 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setShort(JNIEnv* env, jobject ob
if (setting == nullptr) { if (setting == nullptr) {
return; return;
} }
setting->SetGlobal(true);
setting->SetValue(value); setting->SetValue(value);
} }
jint Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getInt(JNIEnv* env, jobject obj, jstring jkey, jint Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getInt(JNIEnv* env, jobject obj, jstring jkey,
jboolean getDefault) { jboolean needGlobal) {
auto setting = getSetting<int>(env, jkey); auto setting = getSetting<int>(env, jkey);
if (setting == nullptr) { if (setting == nullptr) {
return -1; return -1;
} }
setting->SetGlobal(true); return setting->GetValue(needGlobal);
if (static_cast<bool>(getDefault)) {
return setting->GetDefault();
}
return setting->GetValue();
} }
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setInt(JNIEnv* env, jobject obj, jstring jkey, void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setInt(JNIEnv* env, jobject obj, jstring jkey,
@ -144,23 +117,16 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setInt(JNIEnv* env, jobject obj,
if (setting == nullptr) { if (setting == nullptr) {
return; return;
} }
setting->SetGlobal(true);
setting->SetValue(value); setting->SetValue(value);
} }
jfloat Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getFloat(JNIEnv* env, jobject obj, jstring jkey, jfloat Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getFloat(JNIEnv* env, jobject obj, jstring jkey,
jboolean getDefault) { jboolean needGlobal) {
auto setting = getSetting<float>(env, jkey); auto setting = getSetting<float>(env, jkey);
if (setting == nullptr) { if (setting == nullptr) {
return -1; return -1;
} }
setting->SetGlobal(true); return setting->GetValue(static_cast<bool>(needGlobal));
if (static_cast<bool>(getDefault)) {
return setting->GetDefault();
}
return setting->GetValue();
} }
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setFloat(JNIEnv* env, jobject obj, jstring jkey, void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setFloat(JNIEnv* env, jobject obj, jstring jkey,
@ -169,23 +135,16 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setFloat(JNIEnv* env, jobject ob
if (setting == nullptr) { if (setting == nullptr) {
return; return;
} }
setting->SetGlobal(true);
setting->SetValue(value); setting->SetValue(value);
} }
jlong Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getLong(JNIEnv* env, jobject obj, jstring jkey, jlong Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getLong(JNIEnv* env, jobject obj, jstring jkey,
jboolean getDefault) { jboolean needGlobal) {
auto setting = getSetting<long>(env, jkey); auto setting = getSetting<s64>(env, jkey);
if (setting == nullptr) { if (setting == nullptr) {
return -1; return -1;
} }
setting->SetGlobal(true); return setting->GetValue(static_cast<bool>(needGlobal));
if (static_cast<bool>(getDefault)) {
return setting->GetDefault();
}
return setting->GetValue();
} }
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setLong(JNIEnv* env, jobject obj, jstring jkey, void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setLong(JNIEnv* env, jobject obj, jstring jkey,
@ -194,23 +153,16 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setLong(JNIEnv* env, jobject obj
if (setting == nullptr) { if (setting == nullptr) {
return; return;
} }
setting->SetGlobal(true);
setting->SetValue(value); setting->SetValue(value);
} }
jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getString(JNIEnv* env, jobject obj, jstring jkey, jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getString(JNIEnv* env, jobject obj, jstring jkey,
jboolean getDefault) { jboolean needGlobal) {
auto setting = getSetting<std::string>(env, jkey); auto setting = getSetting<std::string>(env, jkey);
if (setting == nullptr) { if (setting == nullptr) {
return ToJString(env, ""); return ToJString(env, "");
} }
setting->SetGlobal(true); return ToJString(env, setting->GetValue(static_cast<bool>(needGlobal)));
if (static_cast<bool>(getDefault)) {
return ToJString(env, setting->GetDefault());
}
return ToJString(env, setting->GetValue());
} }
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setString(JNIEnv* env, jobject obj, jstring jkey, void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setString(JNIEnv* env, jobject obj, jstring jkey,
@ -220,27 +172,18 @@ void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setString(JNIEnv* env, jobject o
return; return;
} }
setting->SetGlobal(true);
setting->SetValue(GetJString(env, value)); setting->SetValue(GetJString(env, value));
} }
jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsRuntimeModifiable(JNIEnv* env, jobject obj, jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsRuntimeModifiable(JNIEnv* env, jobject obj,
jstring jkey) { jstring jkey) {
auto key = GetJString(env, jkey); auto setting = getSetting<std::string>(env, jkey);
auto setting = Settings::values.linkage.by_key[key]; if (setting != nullptr) {
if (setting != 0) {
return setting->RuntimeModfiable(); return setting->RuntimeModfiable();
} }
LOG_ERROR(Frontend, "[Android Native] Could not find setting - {}", key);
return true; return true;
} }
jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getConfigHeader(JNIEnv* env, jobject obj,
jint jcategory) {
auto category = static_cast<Settings::Category>(jcategory);
return ToJString(env, Settings::TranslateCategory(category));
}
jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getPairedSettingKey(JNIEnv* env, jobject obj, jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getPairedSettingKey(JNIEnv* env, jobject obj,
jstring jkey) { jstring jkey) {
auto setting = getSetting<std::string>(env, jkey); auto setting = getSetting<std::string>(env, jkey);
@ -254,6 +197,41 @@ jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getPairedSettingKey(JNIEnv* e
return ToJString(env, setting->PairedSetting()->GetLabel()); return ToJString(env, setting->PairedSetting()->GetLabel());
} }
jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getIsSwitchable(JNIEnv* env, jobject obj,
jstring jkey) {
auto setting = getSetting<std::string>(env, jkey);
if (setting != nullptr) {
return setting->Switchable();
}
return false;
}
jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_usingGlobal(JNIEnv* env, jobject obj,
jstring jkey) {
auto setting = getSetting<std::string>(env, jkey);
if (setting != nullptr) {
return setting->UsingGlobal();
}
return true;
}
void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_setGlobal(JNIEnv* env, jobject obj, jstring jkey,
jboolean global) {
auto setting = getSetting<std::string>(env, jkey);
if (setting != nullptr) {
setting->SetGlobal(static_cast<bool>(global));
}
}
jstring Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getDefaultToString(JNIEnv* env, jobject obj,
jstring jkey) {
auto setting = getSetting<std::string>(env, jkey);
if (setting != nullptr) {
return ToJString(env, setting->DefaultToString());
}
return ToJString(env, "");
}
jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getGameDirs(JNIEnv* env, jobject obj) { jobjectArray Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getGameDirs(JNIEnv* env, jobject obj) {
jclass gameDirClass = IDCache::GetGameDirClass(); jclass gameDirClass = IDCache::GetGameDirClass();
jmethodID gameDirConstructor = IDCache::GetGameDirConstructor(); jmethodID gameDirConstructor = IDCache::GetGameDirConstructor();

View File

@ -81,6 +81,9 @@ public:
[[nodiscard]] virtual const Type& GetValue() const { [[nodiscard]] virtual const Type& GetValue() const {
return value; return value;
} }
[[nodiscard]] virtual const Type& GetValue(bool need_global) const {
return value;
}
/** /**
* Sets the setting to the given value. * Sets the setting to the given value.
@ -353,7 +356,7 @@ public:
} }
return custom; return custom;
} }
[[nodiscard]] const Type& GetValue(bool need_global) const { [[nodiscard]] const Type& GetValue(bool need_global) const override final {
if (use_global || need_global) { if (use_global || need_global) {
return this->value; return this->value;
} }