| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model | ||
|
|
||
| enum class FloatSetting( | ||
| private val file: String, | ||
| private val section: String, | ||
| private val key: String, | ||
| private val defaultValue: Float | ||
| ) : AbstractFloatSetting { | ||
| // These entries have the same names and order as in C++, just for consistency. | ||
| MAIN_EMULATION_SPEED(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "EmulationSpeed", 1.0f), | ||
| MAIN_OVERCLOCK(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "Overclock", 1.0f); | ||
|
|
||
| override val isOverridden: Boolean | ||
| get() = NativeConfig.isOverridden(file, section, key) | ||
|
|
||
| override val isRuntimeEditable: Boolean | ||
| get() = NativeConfig.isSettingSaveable(file, section, key) | ||
|
|
||
| override fun delete(settings: Settings): Boolean { | ||
| if (!NativeConfig.isSettingSaveable(file, section, key)) { | ||
| throw UnsupportedOperationException("Unsupported setting: $file, $section, $key") | ||
| } | ||
| return NativeConfig.deleteKey(settings.writeLayer, file, section, key) | ||
| } | ||
|
|
||
| override val float: Float | ||
| get() = NativeConfig.getFloat(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue) | ||
|
|
||
| override fun setFloat(settings: Settings, newValue: Float) { | ||
| if (!NativeConfig.isSettingSaveable(file, section, key)) { | ||
| throw UnsupportedOperationException("Unsupported setting: $file, $section, $key") | ||
| } | ||
| NativeConfig.setFloat(settings.writeLayer, file, section, key, newValue) | ||
| } | ||
|
|
||
| fun setFloat(layer: Int, newValue: Float) { | ||
| NativeConfig.setFloat(layer, file, section, key, newValue) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,219 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model | ||
|
|
||
| import android.content.pm.ActivityInfo | ||
| import org.dolphinemu.dolphinemu.NativeLibrary | ||
| import org.dolphinemu.dolphinemu.overlay.InputOverlayPointer | ||
| import java.util.* | ||
|
|
||
| enum class IntSetting( | ||
| private val file: String, | ||
| private val section: String, | ||
| private val key: String, | ||
| private val defaultValue: Int | ||
| ) : AbstractIntSetting { | ||
| // These entries have the same names and order as in C++, just for consistency. | ||
| MAIN_CPU_CORE( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_CORE, | ||
| "CPUCore", | ||
| NativeLibrary.DefaultCPUCore() | ||
| ), | ||
| MAIN_GC_LANGUAGE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SelectedLanguage", 0), | ||
| MAIN_MEM1_SIZE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MEM1Size", 0x01800000), | ||
| MAIN_MEM2_SIZE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "MEM2Size", 0x04000000), | ||
| MAIN_SLOT_A(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SlotA", 8), | ||
| MAIN_SLOT_B(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SlotB", 255), | ||
| MAIN_SERIAL_PORT_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SerialPort1", 255), | ||
| MAIN_FALLBACK_REGION(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "FallbackRegion", 2), | ||
| MAIN_SI_DEVICE_0(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice0", 6), | ||
| MAIN_SI_DEVICE_1(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice1", 0), | ||
| MAIN_SI_DEVICE_2(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice2", 0), | ||
| MAIN_SI_DEVICE_3(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "SIDevice3", 0), | ||
| MAIN_AUDIO_VOLUME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_DSP, "Volume", 100), | ||
| MAIN_OVERLAY_GC_CONTROLLER( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_ANDROID, | ||
| "OverlayGCController", | ||
| 0 | ||
| ), | ||
|
|
||
| // Defaults to GameCube controller 1 | ||
| MAIN_OVERLAY_WII_CONTROLLER( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_ANDROID, | ||
| "OverlayWiiController", | ||
| 4 | ||
| ), | ||
|
|
||
| // Defaults to Wii Remote 1 | ||
| MAIN_CONTROL_SCALE(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "ControlScale", 50), | ||
| MAIN_CONTROL_OPACITY(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "ControlOpacity", 65), | ||
| MAIN_EMULATION_ORIENTATION( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_ANDROID, | ||
| "EmulationOrientation", | ||
| ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE | ||
| ), | ||
| MAIN_INTERFACE_THEME(Settings.FILE_DOLPHIN, Settings.SECTION_INI_ANDROID, "InterfaceTheme", 0), | ||
| MAIN_INTERFACE_THEME_MODE( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_ANDROID, | ||
| "InterfaceThemeMode", | ||
| -1 | ||
| ), | ||
| MAIN_LAST_PLATFORM_TAB( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_ANDROID, | ||
| "LastPlatformTab", | ||
| 0 | ||
| ), | ||
| MAIN_IR_MODE( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_ANDROID, | ||
| "IRMode", | ||
| InputOverlayPointer.MODE_FOLLOW | ||
| ), | ||
| MAIN_DOUBLE_TAP_BUTTON( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_ANDROID_OVERLAY_BUTTONS, | ||
| "DoubleTapButton", | ||
| NativeLibrary.ButtonType.WIIMOTE_BUTTON_A | ||
| ), | ||
| SYSCONF_LANGUAGE(Settings.FILE_SYSCONF, "IPL", "LNG", 0x01), | ||
| SYSCONF_SOUND_MODE(Settings.FILE_SYSCONF, "IPL", "SND", 0x01), | ||
| SYSCONF_SENSOR_BAR_POSITION(Settings.FILE_SYSCONF, "BT", "BAR", 0x01), | ||
| SYSCONF_SENSOR_BAR_SENSITIVITY(Settings.FILE_SYSCONF, "BT", "SENS", 0x03), | ||
| SYSCONF_SPEAKER_VOLUME(Settings.FILE_SYSCONF, "BT", "SPKV", 0x58), | ||
| GFX_ASPECT_RATIO(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "AspectRatio", 0), | ||
| GFX_SAFE_TEXTURE_CACHE_COLOR_SAMPLES( | ||
| Settings.FILE_GFX, | ||
| Settings.SECTION_GFX_SETTINGS, | ||
| "SafeTextureCacheColorSamples", | ||
| 128 | ||
| ), | ||
| GFX_PNG_COMPRESSION_LEVEL( | ||
| Settings.FILE_GFX, | ||
| Settings.SECTION_GFX_SETTINGS, | ||
| "PNGCompressionLevel", | ||
| 6 | ||
| ), | ||
| GFX_MSAA(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "MSAA", 1), | ||
| GFX_EFB_SCALE(Settings.FILE_GFX, Settings.SECTION_GFX_SETTINGS, "InternalResolution", 1), | ||
| GFX_SHADER_COMPILATION_MODE( | ||
| Settings.FILE_GFX, | ||
| Settings.SECTION_GFX_SETTINGS, | ||
| "ShaderCompilationMode", | ||
| 0 | ||
| ), | ||
| GFX_ENHANCE_FORCE_TEXTURE_FILTERING( | ||
| Settings.FILE_GFX, | ||
| Settings.SECTION_GFX_ENHANCEMENTS, | ||
| "ForceTextureFiltering", | ||
| 0 | ||
| ), | ||
| GFX_ENHANCE_MAX_ANISOTROPY( | ||
| Settings.FILE_GFX, | ||
| Settings.SECTION_GFX_ENHANCEMENTS, | ||
| "MaxAnisotropy", | ||
| 0 | ||
| ), | ||
| GFX_STEREO_MODE(Settings.FILE_GFX, Settings.SECTION_STEREOSCOPY, "StereoMode", 0), | ||
| GFX_STEREO_DEPTH(Settings.FILE_GFX, Settings.SECTION_STEREOSCOPY, "StereoDepth", 20), | ||
| GFX_STEREO_CONVERGENCE_PERCENTAGE( | ||
| Settings.FILE_GFX, | ||
| Settings.SECTION_STEREOSCOPY, | ||
| "StereoConvergencePercentage", | ||
| 100 | ||
| ), | ||
| GFX_PERF_SAMP_WINDOW( | ||
| Settings.FILE_GFX, | ||
| Settings.SECTION_GFX_SETTINGS, | ||
| "PerfSampWindowMS", | ||
| 1000 | ||
| ), | ||
| LOGGER_VERBOSITY(Settings.FILE_LOGGER, Settings.SECTION_LOGGER_OPTIONS, "Verbosity", 1), | ||
| WIIMOTE_1_SOURCE(Settings.FILE_WIIMOTE, "Wiimote1", "Source", 1), | ||
| WIIMOTE_2_SOURCE(Settings.FILE_WIIMOTE, "Wiimote2", "Source", 0), | ||
| WIIMOTE_3_SOURCE(Settings.FILE_WIIMOTE, "Wiimote3", "Source", 0), | ||
| WIIMOTE_4_SOURCE(Settings.FILE_WIIMOTE, "Wiimote4", "Source", 0), | ||
| WIIMOTE_BB_SOURCE(Settings.FILE_WIIMOTE, "BalanceBoard", "Source", 0); | ||
|
|
||
| override val isOverridden: Boolean | ||
| get() = NativeConfig.isOverridden(file, section, key) | ||
|
|
||
| override val isRuntimeEditable: Boolean | ||
| get() { | ||
| if (file == Settings.FILE_SYSCONF) return false | ||
| for (setting in NOT_RUNTIME_EDITABLE) { | ||
| if (setting == this) return false | ||
| } | ||
| return NativeConfig.isSettingSaveable(file, section, key) | ||
| } | ||
|
|
||
| override fun delete(settings: Settings): Boolean { | ||
| if (!NativeConfig.isSettingSaveable(file, section, key)) { | ||
| throw UnsupportedOperationException("Unsupported setting: $file, $section, $key") | ||
| } | ||
| return NativeConfig.deleteKey(settings.writeLayer, file, section, key) | ||
| } | ||
|
|
||
| override val int: Int | ||
| get() = NativeConfig.getInt(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue) | ||
|
|
||
| override fun setInt(settings: Settings, newValue: Int) { | ||
| if (!NativeConfig.isSettingSaveable(file, section, key)) { | ||
| throw UnsupportedOperationException("Unsupported setting: $file, $section, $key") | ||
| } | ||
| NativeConfig.setInt(settings.writeLayer, file, section, key, newValue) | ||
| } | ||
|
|
||
| fun setInt(layer: Int, newValue: Int) { | ||
| if (!NativeConfig.isSettingSaveable(file, section, key)) { | ||
| throw UnsupportedOperationException("Unsupported setting: $file, $section, $key") | ||
| } | ||
| NativeConfig.setInt(layer, file, section, key, newValue) | ||
| } | ||
|
|
||
| companion object { | ||
| private val NOT_RUNTIME_EDITABLE_ARRAY = arrayOf( | ||
| MAIN_CPU_CORE, | ||
| MAIN_GC_LANGUAGE, | ||
| MAIN_MEM1_SIZE, | ||
| MAIN_MEM2_SIZE, | ||
| MAIN_SLOT_A, | ||
| MAIN_SLOT_B, | ||
| MAIN_SERIAL_PORT_1, | ||
| MAIN_FALLBACK_REGION, | ||
| MAIN_SI_DEVICE_0, | ||
| MAIN_SI_DEVICE_1, | ||
| MAIN_SI_DEVICE_2, | ||
| MAIN_SI_DEVICE_3 | ||
| ) | ||
|
|
||
| private val NOT_RUNTIME_EDITABLE: Set<IntSetting> = | ||
| HashSet(listOf(*NOT_RUNTIME_EDITABLE_ARRAY)) | ||
|
|
||
| @JvmStatic | ||
| fun getSettingForSIDevice(channel: Int): IntSetting { | ||
| return arrayOf( | ||
| MAIN_SI_DEVICE_0, | ||
| MAIN_SI_DEVICE_1, | ||
| MAIN_SI_DEVICE_2, | ||
| MAIN_SI_DEVICE_3 | ||
| )[channel] | ||
| } | ||
|
|
||
| @JvmStatic | ||
| fun getSettingForWiimoteSource(index: Int): IntSetting { | ||
| return arrayOf( | ||
| WIIMOTE_1_SOURCE, | ||
| WIIMOTE_2_SOURCE, | ||
| WIIMOTE_3_SOURCE, | ||
| WIIMOTE_4_SOURCE, | ||
| WIIMOTE_BB_SOURCE | ||
| )[index] | ||
| } | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,107 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model | ||
|
|
||
| object NativeConfig { | ||
| const val LAYER_BASE_OR_CURRENT = 0 | ||
| const val LAYER_BASE = 1 | ||
| const val LAYER_LOCAL_GAME = 2 | ||
| const val LAYER_ACTIVE = 3 | ||
| const val LAYER_CURRENT = 4 | ||
|
|
||
| @JvmStatic | ||
| external fun isSettingSaveable(file: String, section: String, key: String): Boolean | ||
|
|
||
| @JvmStatic | ||
| external fun loadGameInis(gameId: String, revision: Int) | ||
|
|
||
| @JvmStatic | ||
| external fun unloadGameInis() | ||
|
|
||
| @JvmStatic | ||
| external fun save(layer: Int) | ||
|
|
||
| @JvmStatic | ||
| external fun deleteAllKeys(layer: Int) | ||
|
|
||
| @JvmStatic | ||
| external fun isOverridden(file: String, section: String, key: String): Boolean | ||
|
|
||
| @JvmStatic | ||
| external fun deleteKey(layer: Int, file: String, section: String, key: String): Boolean | ||
|
|
||
| @JvmStatic | ||
| external fun exists(layer: Int, file: String, section: String, key: String): Boolean | ||
|
|
||
| @JvmStatic | ||
| external fun getString( | ||
| layer: Int, | ||
| file: String, | ||
| section: String, | ||
| key: String, | ||
| defaultValue: String | ||
| ): String | ||
|
|
||
| @JvmStatic | ||
| external fun getBoolean( | ||
| layer: Int, | ||
| file: String, | ||
| section: String, | ||
| key: String, | ||
| defaultValue: Boolean | ||
| ): Boolean | ||
|
|
||
| @JvmStatic | ||
| external fun getInt( | ||
| layer: Int, | ||
| file: String, | ||
| section: String, | ||
| key: String, | ||
| defaultValue: Int | ||
| ): Int | ||
|
|
||
| @JvmStatic | ||
| external fun getFloat( | ||
| layer: Int, | ||
| file: String, | ||
| section: String, | ||
| key: String, | ||
| defaultValue: Float | ||
| ): Float | ||
|
|
||
| @JvmStatic | ||
| external fun setString( | ||
| layer: Int, | ||
| file: String, | ||
| section: String, | ||
| key: String, | ||
| value: String? | ||
| ) | ||
|
|
||
| @JvmStatic | ||
| external fun setBoolean( | ||
| layer: Int, | ||
| file: String, | ||
| section: String, | ||
| key: String, | ||
| value: Boolean | ||
| ) | ||
|
|
||
| @JvmStatic | ||
| external fun setInt( | ||
| layer: Int, | ||
| file: String, | ||
| section: String, | ||
| key: String, | ||
| value: Int | ||
| ) | ||
|
|
||
| @JvmStatic | ||
| external fun setFloat( | ||
| layer: Int, | ||
| file: String, | ||
| section: String, | ||
| key: String, | ||
| value: Float | ||
| ) | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model | ||
|
|
||
| object PostProcessing { | ||
| @JvmStatic | ||
| val shaderList: Array<String?> | ||
| external get | ||
|
|
||
| @JvmStatic | ||
| val anaglyphShaderList: Array<String?> | ||
| external get | ||
|
|
||
| @JvmStatic | ||
| val passiveShaderList: Array<String?> | ||
| external get | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,144 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model | ||
|
|
||
| import android.content.Context | ||
| import android.text.TextUtils | ||
| import android.widget.Toast | ||
| import org.dolphinemu.dolphinemu.NativeLibrary | ||
| import org.dolphinemu.dolphinemu.R | ||
| import org.dolphinemu.dolphinemu.features.input.model.MappingCommon | ||
| import org.dolphinemu.dolphinemu.services.GameFileCacheManager | ||
| import java.io.Closeable | ||
|
|
||
| class Settings : Closeable { | ||
| private var gameId: String = "" | ||
| private var revision = 0 | ||
|
|
||
| var isWii = false | ||
| private set | ||
|
|
||
| private var settingsLoaded = false | ||
| private var loadedRecursiveIsoPathsValue = false | ||
|
|
||
| private val isGameSpecific: Boolean | ||
| get() = !TextUtils.isEmpty(gameId) | ||
|
|
||
| val writeLayer: Int | ||
| get() = if (isGameSpecific) NativeConfig.LAYER_LOCAL_GAME else NativeConfig.LAYER_BASE_OR_CURRENT | ||
|
|
||
| fun areSettingsLoaded(): Boolean { | ||
| return settingsLoaded | ||
| } | ||
|
|
||
| @JvmOverloads | ||
| fun loadSettings(isWii: Boolean = true) { | ||
| this.isWii = isWii | ||
| settingsLoaded = true | ||
|
|
||
| if (isGameSpecific) { | ||
| // Loading game INIs while the core is running will mess with the game INIs loaded by the core | ||
| check(!NativeLibrary.IsRunning()) { "Attempted to load game INI while emulating" } | ||
| NativeConfig.loadGameInis(gameId, revision) | ||
| } | ||
|
|
||
| loadedRecursiveIsoPathsValue = BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean | ||
| } | ||
|
|
||
| fun loadSettings(gameId: String, revision: Int, isWii: Boolean) { | ||
| this.gameId = gameId | ||
| this.revision = revision | ||
| loadSettings(isWii) | ||
| } | ||
|
|
||
| fun saveSettings(context: Context?) { | ||
| if (!isGameSpecific) { | ||
| if (context != null) Toast.makeText( | ||
| context, | ||
| R.string.settings_saved, | ||
| Toast.LENGTH_SHORT | ||
| ).show() | ||
|
|
||
| MappingCommon.save() | ||
|
|
||
| NativeConfig.save(NativeConfig.LAYER_BASE) | ||
|
|
||
| NativeLibrary.ReloadLoggerConfig() | ||
| NativeLibrary.UpdateGCAdapterScanThread() | ||
|
|
||
| if (loadedRecursiveIsoPathsValue != BooleanSetting.MAIN_RECURSIVE_ISO_PATHS.boolean) { | ||
| // Refresh game library | ||
| GameFileCacheManager.startRescan() | ||
| } | ||
| } else { | ||
| // custom game settings | ||
| if (context != null) { | ||
| Toast.makeText( | ||
| context, context.getString(R.string.settings_saved_game_specific, gameId), | ||
| Toast.LENGTH_SHORT | ||
| ).show() | ||
| } | ||
| NativeConfig.save(NativeConfig.LAYER_LOCAL_GAME) | ||
| } | ||
| } | ||
|
|
||
| fun clearGameSettings() { | ||
| NativeConfig.deleteAllKeys(NativeConfig.LAYER_LOCAL_GAME) | ||
| } | ||
|
|
||
| fun gameIniContainsJunk(): Boolean { | ||
| // Older versions of Android Dolphin would copy the entire contents of most of the global INIs | ||
| // into any game INI that got saved (with some of the sections renamed to match the game INI | ||
| // section names). The problems with this are twofold: | ||
| // | ||
| // 1. The user game INIs will contain entries that Dolphin doesn't support reading from | ||
| // game INIs. This is annoying when editing game INIs manually but shouldn't really be | ||
| // a problem for those who only use the GUI. | ||
| // | ||
| // 2. Global settings will stick around in user game INIs. For instance, if someone wants to | ||
| // change the texture cache accuracy to safe for all games, they have to edit not only the | ||
| // global settings but also every single game INI they have created, since the old value of | ||
| // the texture cache accuracy Setting has been copied into every user game INI. | ||
| // | ||
| // These problems are serious enough that we should detect and delete such INI files. | ||
| // Problem 1 is easy to detect, but due to the nature of problem 2, it's unfortunately not | ||
| // possible to know which lines were added intentionally by the user and which lines were added | ||
| // unintentionally, which is why we have to delete the whole file in order to fix everything. | ||
| return if (!isGameSpecific) false else NativeConfig.exists( | ||
| NativeConfig.LAYER_LOCAL_GAME, | ||
| FILE_DOLPHIN, | ||
| SECTION_INI_INTERFACE, | ||
| "ThemeName" | ||
| ) | ||
| } | ||
|
|
||
| override fun close() { | ||
| if (isGameSpecific) { | ||
| NativeConfig.unloadGameInis() | ||
| } | ||
| } | ||
|
|
||
| companion object { | ||
| const val FILE_DOLPHIN = "Dolphin" | ||
| const val FILE_SYSCONF = "SYSCONF" | ||
| const val FILE_GFX = "GFX" | ||
| const val FILE_LOGGER = "Logger" | ||
| const val FILE_WIIMOTE = "WiimoteNew" | ||
| const val FILE_GAME_SETTINGS_ONLY = "GameSettingsOnly" | ||
| const val SECTION_INI_ANDROID = "Android" | ||
| const val SECTION_INI_ANDROID_OVERLAY_BUTTONS = "AndroidOverlayButtons" | ||
| const val SECTION_INI_GENERAL = "General" | ||
| const val SECTION_INI_CORE = "Core" | ||
| const val SECTION_INI_INTERFACE = "Interface" | ||
| const val SECTION_INI_DSP = "DSP" | ||
| const val SECTION_LOGGER_LOGS = "Logs" | ||
| const val SECTION_LOGGER_OPTIONS = "Options" | ||
| const val SECTION_GFX_SETTINGS = "Settings" | ||
| const val SECTION_GFX_ENHANCEMENTS = "Enhancements" | ||
| const val SECTION_GFX_HACKS = "Hacks" | ||
| const val SECTION_DEBUG = "Debug" | ||
| const val SECTION_EMULATED_USB_DEVICES = "EmulatedUSBDevices" | ||
| const val SECTION_STEREOSCOPY = "Stereoscopy" | ||
| const val SECTION_ANALYTICS = "Analytics" | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model | ||
|
|
||
| import org.dolphinemu.dolphinemu.NativeLibrary | ||
| import java.util.* | ||
|
|
||
| enum class StringSetting( | ||
| private val file: String, | ||
| private val section: String, | ||
| private val key: String, | ||
| private val defaultValue: String | ||
| ) : AbstractStringSetting { | ||
| // These entries have the same names and order as in C++, just for consistency. | ||
| MAIN_DEFAULT_ISO(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "DefaultISO", ""), | ||
| MAIN_BBA_MAC(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "BBA_MAC", ""), | ||
| MAIN_BBA_XLINK_IP(Settings.FILE_DOLPHIN, Settings.SECTION_INI_CORE, "BBA_XLINK_IP", ""), | ||
|
|
||
| // Schthack PSO Server - https://schtserv.com/ | ||
| MAIN_BBA_BUILTIN_DNS( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_CORE, | ||
| "BBA_BUILTIN_DNS", | ||
| "149.56.167.128" | ||
| ), | ||
| MAIN_CUSTOM_RTC_VALUE( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_CORE, | ||
| "CustomRTCValue", | ||
| "0x386d4380" | ||
| ), | ||
| MAIN_GFX_BACKEND( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_CORE, | ||
| "GFXBackend", | ||
| NativeLibrary.GetDefaultGraphicsBackendName() | ||
| ), | ||
| MAIN_DUMP_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "DumpPath", ""), | ||
| MAIN_LOAD_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "LoadPath", ""), | ||
| MAIN_RESOURCEPACK_PATH( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_GENERAL, | ||
| "ResourcePackPath", | ||
| "" | ||
| ), | ||
| MAIN_FS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "NANDRootPath", ""), | ||
| MAIN_WII_SD_CARD_IMAGE_PATH( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_GENERAL, | ||
| "WiiSDCardPath", | ||
| "" | ||
| ), | ||
| MAIN_WII_SD_CARD_SYNC_FOLDER_PATH( | ||
| Settings.FILE_DOLPHIN, | ||
| Settings.SECTION_INI_GENERAL, | ||
| "WiiSDCardSyncFolder", | ||
| "" | ||
| ), | ||
| MAIN_WFS_PATH(Settings.FILE_DOLPHIN, Settings.SECTION_INI_GENERAL, "WFSPath", ""), | ||
| GFX_ENHANCE_POST_SHADER( | ||
| Settings.FILE_GFX, | ||
| Settings.SECTION_GFX_ENHANCEMENTS, | ||
| "PostProcessingShader", | ||
| "" | ||
| ); | ||
|
|
||
| override val isOverridden: Boolean | ||
| get() = NativeConfig.isOverridden(file, section, key) | ||
|
|
||
| override val isRuntimeEditable: Boolean | ||
| get() { | ||
| for (setting in NOT_RUNTIME_EDITABLE) { | ||
| if (setting == this) return false | ||
| } | ||
| return NativeConfig.isSettingSaveable(file, section, key) | ||
| } | ||
|
|
||
| override fun delete(settings: Settings): Boolean { | ||
| return NativeConfig.deleteKey(settings.writeLayer, file, section, key) | ||
| } | ||
|
|
||
| override val string: String | ||
| get() = if (!NativeConfig.isSettingSaveable(file, section, key)) { | ||
| throw UnsupportedOperationException("Unsupported setting: $file, $section, $key") | ||
| } else NativeConfig.getString(NativeConfig.LAYER_ACTIVE, file, section, key, defaultValue) | ||
|
|
||
| override fun setString(settings: Settings, newValue: String) { | ||
| NativeConfig.setString(settings.writeLayer, file, section, key, newValue) | ||
| } | ||
|
|
||
| fun setString(layer: Int, newValue: String?) { | ||
| NativeConfig.setString(layer, file, section, key, newValue) | ||
| } | ||
|
|
||
| companion object { | ||
| private val NOT_RUNTIME_EDITABLE_ARRAY = arrayOf( | ||
| MAIN_CUSTOM_RTC_VALUE, | ||
| MAIN_GFX_BACKEND | ||
| ) | ||
|
|
||
| private val NOT_RUNTIME_EDITABLE: Set<StringSetting> = | ||
| HashSet(listOf(*NOT_RUNTIME_EDITABLE_ARRAY)) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
|
|
||
| class FilePicker( | ||
| context: Context, | ||
| override var setting: AbstractStringSetting, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| val requestType: Int, | ||
| val defaultPathRelativeToUserDirectory: String? | ||
| ) : SettingsItem(context, titleId, descriptionId) { | ||
| override val type: Int = TYPE_FILE_PICKER | ||
|
|
||
| fun getSelectedValue() : String { | ||
| return setting.string | ||
| } | ||
|
|
||
| fun setSelectedValue(settings: Settings, selection: String) { | ||
| setting.setString(settings, selection) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractFloatSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
| import kotlin.math.roundToInt | ||
|
|
||
| open class FloatSliderSetting : SliderSetting { | ||
| var floatSetting: AbstractFloatSetting | ||
|
|
||
| override val setting: AbstractSetting | ||
| get() = floatSetting | ||
|
|
||
| constructor( | ||
| context: Context, | ||
| setting: AbstractFloatSetting, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| min: Int, | ||
| max: Int, | ||
| units: String?, | ||
| stepSize: Int | ||
| ) : super(context, titleId, descriptionId, min, max, units, stepSize) { | ||
| floatSetting = setting | ||
| } | ||
|
|
||
| constructor( | ||
| setting: AbstractFloatSetting, | ||
| name: CharSequence, | ||
| description: CharSequence?, | ||
| min: Int, | ||
| max: Int, | ||
| units: String? | ||
| ) : super(name, description, min, max, units) { | ||
| floatSetting = setting | ||
| } | ||
|
|
||
| override val selectedValue: Int | ||
| get() = floatSetting.float.roundToInt() | ||
|
|
||
| open fun setSelectedValue(settings: Settings?, selection: Float) { | ||
| floatSetting.setFloat(settings!!, selection) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
|
|
||
| open class HeaderSetting : SettingsItem { | ||
| override val setting: AbstractSetting? = null | ||
|
|
||
| constructor( | ||
| context: Context, | ||
| titleId: Int, | ||
| descriptionId: Int | ||
| ) : super(context, titleId, descriptionId) | ||
|
|
||
| constructor(title: CharSequence, description: CharSequence?) : super(title, description) | ||
|
|
||
| override val type: Int = TYPE_HEADER | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,11 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
|
|
||
| class HyperLinkHeaderSetting( | ||
| context: Context, | ||
| titleId: Int, | ||
| descriptionId: Int | ||
| ) : HeaderSetting(context, titleId, descriptionId) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
|
|
||
| class InputStringSetting( | ||
| context: Context, | ||
| setting: AbstractStringSetting, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| ) : SettingsItem(context, titleId, descriptionId) { | ||
| override val type: Int = TYPE_STRING | ||
|
|
||
| private var stringSetting: AbstractStringSetting = setting | ||
|
|
||
| override val setting: AbstractSetting | ||
| get() = stringSetting | ||
|
|
||
| val selectedValue: String | ||
| get() = stringSetting.string | ||
|
|
||
| fun setSelectedValue(settings: Settings, selection: String) { | ||
| stringSetting.setString(settings, selection) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
|
|
||
| class IntSliderSetting( | ||
| context: Context, | ||
| private val intSetting: AbstractIntSetting, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| min: Int, | ||
| max: Int, | ||
| units: String?, | ||
| stepSize: Int | ||
| ) : SliderSetting(context, titleId, descriptionId, min, max, units, stepSize) { | ||
| override val setting: AbstractSetting | ||
| get() = intSetting | ||
|
|
||
| override val selectedValue: Int | ||
| get() = intSetting.int | ||
|
|
||
| fun setSelectedValue(settings: Settings?, selection: Int) { | ||
| intSetting.setInt(settings!!, selection) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
|
|
||
| class InvertedSwitchSetting( | ||
| context: Context, | ||
| setting: AbstractBooleanSetting, | ||
| titleId: Int, | ||
| descriptionId: Int | ||
| ) : SwitchSetting(context, setting, titleId, descriptionId) { | ||
| override val setting: AbstractSetting | ||
| get() = booleanSetting | ||
|
|
||
| override val isChecked: Boolean | ||
| get() = !booleanSetting.boolean | ||
|
|
||
| override fun setChecked(settings: Settings?, checked: Boolean) { | ||
| booleanSetting.setBoolean(settings!!, !checked) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import org.dolphinemu.dolphinemu.features.settings.model.AdHocBooleanSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
|
|
||
| class LogSwitchSetting( | ||
| var key: String, | ||
| title: CharSequence?, | ||
| description: CharSequence? | ||
| ) : SwitchSetting( | ||
| AdHocBooleanSetting( | ||
| Settings.FILE_LOGGER, | ||
| Settings.SECTION_LOGGER_LOGS, | ||
| key, | ||
| false | ||
| ), | ||
| title, | ||
| description | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractFloatSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
| import kotlin.math.roundToInt | ||
|
|
||
| class PercentSliderSetting( | ||
| context: Context, | ||
| override val setting: AbstractFloatSetting, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| min: Int, | ||
| max: Int, | ||
| units: String?, | ||
| stepSize: Int | ||
| ) : FloatSliderSetting(context, setting, titleId, descriptionId, min, max, units, stepSize) { | ||
| override val selectedValue: Int | ||
| get() = (floatSetting.float * 100).roundToInt() | ||
|
|
||
| override fun setSelectedValue(settings: Settings?, selection: Float) { | ||
| floatSetting.setFloat(settings!!, selection / 100) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,24 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.NativeLibrary | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
|
|
||
| class RunRunnable( | ||
| context: Context, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| val alertText: Int, | ||
| val toastTextAfterRun: Int, | ||
| private val worksDuringEmulation: Boolean, | ||
| val runnable: Runnable | ||
| ) : SettingsItem(context, titleId, descriptionId) { | ||
| override val type: Int = TYPE_RUN_RUNNABLE | ||
|
|
||
| override val setting: AbstractSetting? = null | ||
|
|
||
| override val isEditable: Boolean | ||
| get() = worksDuringEmulation || !NativeLibrary.IsRunning() | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.NativeLibrary | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
|
|
||
| /** | ||
| * ViewModel abstraction for an Item in the RecyclerView powering SettingsFragments. | ||
| * Most of them correspond to a single line in an INI file, but there are a few with multiple | ||
| * analogues and a few with none (Headers, for example, do not correspond to anything on disk.) | ||
| */ | ||
| abstract class SettingsItem { | ||
| val name: CharSequence | ||
| val description: CharSequence? | ||
|
|
||
| /** | ||
| * Base constructor. | ||
| * | ||
| * @param name A text string to be displayed as this Setting's name. | ||
| * @param description A text string to be displayed as this Setting's description. | ||
| */ | ||
| constructor(name: CharSequence, description: CharSequence?) { | ||
| this.name = name | ||
| this.description = description | ||
| } | ||
|
|
||
| /** | ||
| * @param nameId Resource ID for a text string to be displayed as this Setting's name. | ||
| * @param descriptionId Resource ID for a text string to be displayed as this Setting's description. | ||
| */ | ||
| constructor(context: Context, nameId: Int, descriptionId: Int) { | ||
| name = if (nameId == 0) "" else context.getText(nameId) | ||
| description = if (descriptionId == 0) "" else context.getText(descriptionId) | ||
| } | ||
|
|
||
| /** | ||
| * Used by [SettingsAdapter]'s onCreateViewHolder() | ||
| * method to determine which type of ViewHolder should be created. | ||
| * | ||
| * @return An integer (ideally, one of the constants defined in this file) | ||
| */ | ||
| abstract val type: Int | ||
|
|
||
| abstract val setting: AbstractSetting? | ||
|
|
||
| val isOverridden: Boolean | ||
| get() { | ||
| val setting = setting | ||
| return setting != null && setting.isOverridden | ||
| } | ||
|
|
||
| open val isEditable: Boolean | ||
| get() { | ||
| if (!NativeLibrary.IsRunning()) return true | ||
| val setting = setting | ||
| return setting != null && setting.isRuntimeEditable | ||
| } | ||
|
|
||
| private fun hasSetting(): Boolean { | ||
| return setting != null | ||
| } | ||
|
|
||
| open fun canClear(): Boolean { | ||
| return hasSetting() | ||
| } | ||
|
|
||
| open fun clear(settings: Settings) { | ||
| setting!!.delete(settings) | ||
| } | ||
|
|
||
| companion object { | ||
| const val TYPE_HEADER = 0 | ||
| const val TYPE_SWITCH = 1 | ||
| const val TYPE_SINGLE_CHOICE = 2 | ||
| const val TYPE_SLIDER = 3 | ||
| const val TYPE_SUBMENU = 4 | ||
| const val TYPE_INPUT_MAPPING_CONTROL = 5 | ||
| const val TYPE_STRING_SINGLE_CHOICE = 6 | ||
| const val TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS = 8 | ||
| const val TYPE_FILE_PICKER = 9 | ||
| const val TYPE_RUN_RUNNABLE = 10 | ||
| const val TYPE_STRING = 11 | ||
| const val TYPE_HYPERLINK_HEADER = 12 | ||
| const val TYPE_DATETIME_CHOICE = 13 | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,30 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
| import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag | ||
|
|
||
| class SingleChoiceSetting( | ||
| context: Context, | ||
| private val intSetting: AbstractIntSetting, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| val choicesId: Int, | ||
| val valuesId: Int, | ||
| val menuTag: MenuTag? = null | ||
| ) : SettingsItem(context, titleId, descriptionId) { | ||
| override val type: Int = TYPE_SINGLE_CHOICE | ||
|
|
||
| override val setting: AbstractSetting | ||
| get() = intSetting | ||
|
|
||
| val selectedValue: Int | ||
| get() = intSetting.int | ||
|
|
||
| fun setSelectedValue(settings: Settings?, selection: Int) { | ||
| intSetting.setInt(settings!!, selection) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,27 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractIntSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
|
|
||
| class SingleChoiceSettingDynamicDescriptions( | ||
| context: Context, | ||
| override val setting: AbstractIntSetting, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| val choicesId: Int, | ||
| val valuesId: Int, | ||
| val descriptionChoicesId: Int, | ||
| val descriptionValuesId: Int, | ||
| ) : SettingsItem(context, titleId, descriptionId) { | ||
| override val type: Int = TYPE_SINGLE_CHOICE_DYNAMIC_DESCRIPTIONS | ||
|
|
||
| val selectedValue: Int | ||
| get() = setting.int | ||
|
|
||
| fun setSelectedValue(settings: Settings, selection: Int) { | ||
| setting.setInt(settings, selection) | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,47 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
|
|
||
| abstract class SliderSetting : SettingsItem { | ||
| override val type: Int = TYPE_SLIDER | ||
|
|
||
| var min: Int | ||
| private set | ||
| var max: Int | ||
| private set | ||
| var units: String? | ||
| private set | ||
| var stepSize = 0 | ||
| private set | ||
|
|
||
| constructor( | ||
| context: Context, | ||
| nameId: Int, | ||
| descriptionId: Int, | ||
| min: Int, | ||
| max: Int, | ||
| units: String?, | ||
| stepSize: Int | ||
| ) : super(context, nameId, descriptionId) { | ||
| this.min = min | ||
| this.max = max | ||
| this.units = units | ||
| this.stepSize = stepSize | ||
| } | ||
|
|
||
| constructor( | ||
| name: CharSequence, | ||
| description: CharSequence?, | ||
| min: Int, | ||
| max: Int, | ||
| units: String? | ||
| ) : super(name, description) { | ||
| this.min = min | ||
| this.max = max | ||
| this.units = units | ||
| } | ||
|
|
||
| abstract val selectedValue: Int | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,110 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.DolphinApplication | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractStringSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
| import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag | ||
|
|
||
| open class StringSingleChoiceSetting : SettingsItem { | ||
| override val type: Int = TYPE_SINGLE_CHOICE | ||
|
|
||
| private val stringSetting: AbstractStringSetting? | ||
|
|
||
| override val setting: AbstractSetting? | ||
| get() = stringSetting | ||
|
|
||
| var choices: Array<String?>? | ||
| protected set | ||
| var values: Array<String?>? | ||
| protected set | ||
| val menuTag: MenuTag? | ||
| var noChoicesAvailableString = 0 | ||
| private set | ||
|
|
||
| open val selectedChoice: String? | ||
| get() = getChoiceAt(selectedValueIndex) | ||
|
|
||
| open val selectedValue: String | ||
| get() = stringSetting!!.string | ||
|
|
||
| @JvmOverloads | ||
| constructor( | ||
| context: Context, | ||
| setting: AbstractStringSetting?, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| choices: Array<String?>?, | ||
| values: Array<String?>?, | ||
| menuTag: MenuTag? = null | ||
| ) : super(context, titleId, descriptionId) { | ||
| stringSetting = setting | ||
| this.choices = choices | ||
| this.values = values | ||
| this.menuTag = menuTag | ||
| } | ||
|
|
||
| constructor( | ||
| context: Context, | ||
| setting: AbstractStringSetting, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| choices: Array<String?>, | ||
| values: Array<String?>, | ||
| noChoicesAvailableString: Int | ||
| ) : this(context, setting, titleId, descriptionId, choices, values) { | ||
| this.noChoicesAvailableString = noChoicesAvailableString | ||
| } | ||
|
|
||
| @JvmOverloads | ||
| constructor( | ||
| context: Context, | ||
| setting: AbstractStringSetting, | ||
| titleId: Int, | ||
| descriptionId: Int, | ||
| choicesId: Int, | ||
| valuesId: Int, | ||
| menuTag: MenuTag? = null | ||
| ) : super(context, titleId, descriptionId) { | ||
| stringSetting = setting | ||
| choices = DolphinApplication.getAppContext().resources.getStringArray(choicesId) | ||
| values = DolphinApplication.getAppContext().resources.getStringArray(valuesId) | ||
| this.menuTag = menuTag | ||
| } | ||
|
|
||
| fun getChoiceAt(index: Int): String? { | ||
| if (choices == null) return null | ||
|
|
||
| return if (index >= 0 && index < choices!!.size) { | ||
| choices!![index] | ||
| } else "" | ||
| } | ||
|
|
||
| fun getValueAt(index: Int): String? { | ||
| if (values == null) return null | ||
|
|
||
| return if (index >= 0 && index < values!!.size) { | ||
| values!![index] | ||
| } else "" | ||
| } | ||
|
|
||
| val selectedValueIndex: Int | ||
| get() { | ||
| val selectedValue = selectedValue | ||
| for (i in values!!.indices) { | ||
| if (values!![i] == selectedValue) { | ||
| return i | ||
| } | ||
| } | ||
| return -1 | ||
| } | ||
|
|
||
| open fun setSelectedValue(settings: Settings?, selection: String?) { | ||
| stringSetting!!.setString(settings!!, selection!!) | ||
| } | ||
|
|
||
| open fun refreshChoicesAndValues() {} | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,17 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag | ||
|
|
||
| class SubmenuSetting( | ||
| context: Context, | ||
| titleId: Int, | ||
| val menuKey: MenuTag | ||
| ) : SettingsItem(context, titleId, 0) { | ||
| override val type: Int = TYPE_SUBMENU | ||
|
|
||
| override val setting: AbstractSetting? = null | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| // SPDX-License-Identifier: GPL-2.0-or-later | ||
|
|
||
| package org.dolphinemu.dolphinemu.features.settings.model.view | ||
|
|
||
| import android.content.Context | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractBooleanSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.AbstractSetting | ||
| import org.dolphinemu.dolphinemu.features.settings.model.Settings | ||
|
|
||
| open class SwitchSetting : SettingsItem { | ||
| override val type: Int = TYPE_SWITCH | ||
|
|
||
| protected var booleanSetting: AbstractBooleanSetting | ||
|
|
||
| override val setting: AbstractSetting | ||
| get() = booleanSetting | ||
|
|
||
| constructor( | ||
| context: Context, | ||
| setting: AbstractBooleanSetting, | ||
| titleId: Int, | ||
| descriptionId: Int | ||
| ) : super(context, titleId, descriptionId) { | ||
| booleanSetting = setting | ||
| } | ||
|
|
||
| constructor( | ||
| setting: AbstractBooleanSetting, | ||
| title: CharSequence?, | ||
| description: CharSequence? | ||
| ) : super(title!!, description) { | ||
| booleanSetting = setting | ||
| } | ||
|
|
||
| open val isChecked: Boolean | ||
| get() = booleanSetting.boolean | ||
|
|
||
| open fun setChecked(settings: Settings?, checked: Boolean) { | ||
| booleanSetting.setBoolean(settings!!, checked) | ||
| } | ||
| } |