summaryrefslogtreecommitdiff
path: root/src/android
diff options
context:
space:
mode:
Diffstat (limited to 'src/android')
-rw-r--r--src/android/app/build.gradle.kts1
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt4
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt4
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt42
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt2
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt1
-rw-r--r--src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt24
-rw-r--r--src/android/app/src/main/jni/CMakeLists.txt11
-rw-r--r--src/android/app/src/main/jni/android_config.cpp70
-rw-r--r--src/android/app/src/main/jni/android_config.h41
-rw-r--r--src/android/app/src/main/jni/android_settings.cpp (renamed from src/android/app/src/main/jni/uisettings.cpp)2
-rw-r--r--src/android/app/src/main/jni/android_settings.h (renamed from src/android/app/src/main/jni/uisettings.h)0
-rw-r--r--src/android/app/src/main/jni/config.cpp330
-rw-r--r--src/android/app/src/main/jni/config.h47
-rw-r--r--src/android/app/src/main/jni/default_ini.h511
-rw-r--r--src/android/app/src/main/jni/native.cpp15
-rw-r--r--src/android/app/src/main/jni/native_config.cpp23
18 files changed, 170 insertions, 960 deletions
diff --git a/src/android/app/build.gradle.kts b/src/android/app/build.gradle.kts
index 021b070e0..5721327e7 100644
--- a/src/android/app/build.gradle.kts
+++ b/src/android/app/build.gradle.kts
@@ -219,7 +219,6 @@ dependencies {
219 implementation("io.coil-kt:coil:2.2.2") 219 implementation("io.coil-kt:coil:2.2.2")
220 implementation("androidx.core:core-splashscreen:1.0.1") 220 implementation("androidx.core:core-splashscreen:1.0.1")
221 implementation("androidx.window:window:1.2.0-beta03") 221 implementation("androidx.window:window:1.2.0-beta03")
222 implementation("org.ini4j:ini4j:0.5.4")
223 implementation("androidx.constraintlayout:constraintlayout:2.1.4") 222 implementation("androidx.constraintlayout:constraintlayout:2.1.4")
224 implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0") 223 implementation("androidx.swiperefreshlayout:swiperefreshlayout:1.1.0")
225 implementation("androidx.navigation:navigation-fragment-ktx:2.7.4") 224 implementation("androidx.navigation:navigation-fragment-ktx:2.7.4")
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
index 9ebd6c732..f2ba2504c 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
@@ -230,8 +230,6 @@ object NativeLibrary {
230 */ 230 */
231 external fun onTouchReleased(finger_id: Int) 231 external fun onTouchReleased(finger_id: Int)
232 232
233 external fun reloadSettings()
234
235 external fun initGameIni(gameID: String?) 233 external fun initGameIni(gameID: String?)
236 234
237 external fun setAppDirectory(directory: String) 235 external fun setAppDirectory(directory: String)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
index 2bf0e1b0d..d005c656e 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
@@ -7,7 +7,7 @@ import android.text.TextUtils
7import android.widget.Toast 7import android.widget.Toast
8import org.yuzu.yuzu_emu.R 8import org.yuzu.yuzu_emu.R
9import org.yuzu.yuzu_emu.YuzuApplication 9import org.yuzu.yuzu_emu.YuzuApplication
10import org.yuzu.yuzu_emu.features.settings.utils.SettingsFile 10import org.yuzu.yuzu_emu.utils.NativeConfig
11 11
12object Settings { 12object Settings {
13 private val context get() = YuzuApplication.appContext 13 private val context get() = YuzuApplication.appContext
@@ -19,7 +19,7 @@ object Settings {
19 context.getString(R.string.ini_saved), 19 context.getString(R.string.ini_saved),
20 Toast.LENGTH_SHORT 20 Toast.LENGTH_SHORT
21 ).show() 21 ).show()
22 SettingsFile.saveFile(SettingsFile.FILE_NAME_CONFIG) 22 NativeConfig.saveSettings()
23 } else { 23 } else {
24 // TODO: Save custom game settings 24 // TODO: Save custom game settings
25 Toast.makeText( 25 Toast.makeText(
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
index c73edd50e..48bdbdd75 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
@@ -21,7 +21,6 @@ import androidx.navigation.navArgs
21import com.google.android.material.color.MaterialColors 21import com.google.android.material.color.MaterialColors
22import kotlinx.coroutines.flow.collectLatest 22import kotlinx.coroutines.flow.collectLatest
23import kotlinx.coroutines.launch 23import kotlinx.coroutines.launch
24import org.yuzu.yuzu_emu.NativeLibrary
25import java.io.IOException 24import java.io.IOException
26import org.yuzu.yuzu_emu.R 25import org.yuzu.yuzu_emu.R
27import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding 26import org.yuzu.yuzu_emu.databinding.ActivitySettingsBinding
@@ -165,11 +164,12 @@ class SettingsActivity : AppCompatActivity() {
165 settingsViewModel.shouldSave = false 164 settingsViewModel.shouldSave = false
166 165
167 // Delete settings file because the user may have changed values that do not exist in the UI 166 // Delete settings file because the user may have changed values that do not exist in the UI
167 NativeConfig.unloadConfig()
168 val settingsFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_CONFIG) 168 val settingsFile = SettingsFile.getSettingsFile(SettingsFile.FILE_NAME_CONFIG)
169 if (!settingsFile.delete()) { 169 if (!settingsFile.delete()) {
170 throw IOException("Failed to delete $settingsFile") 170 throw IOException("Failed to delete $settingsFile")
171 } 171 }
172 NativeLibrary.reloadSettings() 172 NativeConfig.initializeConfig()
173 173
174 Toast.makeText( 174 Toast.makeText(
175 applicationContext, 175 applicationContext,
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
index 2b04d666a..3ae5b4653 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
@@ -3,15 +3,8 @@
3 3
4package org.yuzu.yuzu_emu.features.settings.utils 4package org.yuzu.yuzu_emu.features.settings.utils
5 5
6import android.widget.Toast
7import java.io.* 6import java.io.*
8import org.ini4j.Wini
9import org.yuzu.yuzu_emu.R
10import org.yuzu.yuzu_emu.YuzuApplication
11import org.yuzu.yuzu_emu.features.settings.model.*
12import org.yuzu.yuzu_emu.utils.DirectoryInitialization 7import org.yuzu.yuzu_emu.utils.DirectoryInitialization
13import org.yuzu.yuzu_emu.utils.Log
14import org.yuzu.yuzu_emu.utils.NativeConfig
15 8
16/** 9/**
17 * Contains static methods for interacting with .ini files in which settings are stored. 10 * Contains static methods for interacting with .ini files in which settings are stored.
@@ -19,41 +12,6 @@ import org.yuzu.yuzu_emu.utils.NativeConfig
19object SettingsFile { 12object SettingsFile {
20 const val FILE_NAME_CONFIG = "config" 13 const val FILE_NAME_CONFIG = "config"
21 14
22 /**
23 * Saves a Settings HashMap to a given .ini file on disk. If unsuccessful, outputs an error
24 * telling why it failed.
25 *
26 * @param fileName The target filename without a path or extension.
27 */
28 fun saveFile(fileName: String) {
29 val ini = getSettingsFile(fileName)
30 try {
31 val wini = Wini(ini)
32 for (specificCategory in Settings.Category.values()) {
33 val categoryHeader = NativeConfig.getConfigHeader(specificCategory.ordinal)
34 for (setting in Settings.settingsList) {
35 if (setting.key!!.isEmpty()) continue
36
37 val settingCategoryHeader =
38 NativeConfig.getConfigHeader(setting.category.ordinal)
39 val iniSetting: String? = wini.get(categoryHeader, setting.key)
40 if (iniSetting != null || settingCategoryHeader == categoryHeader) {
41 wini.put(settingCategoryHeader, setting.key, setting.valueAsString)
42 }
43 }
44 }
45 wini.store()
46 } catch (e: IOException) {
47 Log.error("[SettingsFile] File not found: " + fileName + ".ini: " + e.message)
48 val context = YuzuApplication.appContext
49 Toast.makeText(
50 context,
51 context.getString(R.string.error_saving, fileName, e.message),
52 Toast.LENGTH_SHORT
53 ).show()
54 }
55 }
56
57 fun getSettingsFile(fileName: String): File = 15 fun getSettingsFile(fileName: String): File =
58 File(DirectoryInitialization.userDirectory + "/config/" + fileName + ".ini") 16 File(DirectoryInitialization.userDirectory + "/config/" + fileName + ".ini")
59} 17}
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
index ace5dddea..bd2f4cd25 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
@@ -625,6 +625,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
625 } 625 }
626 626
627 // Clear existing user data 627 // Clear existing user data
628 NativeConfig.unloadConfig()
628 File(DirectoryInitialization.userDirectory!!).deleteRecursively() 629 File(DirectoryInitialization.userDirectory!!).deleteRecursively()
629 630
630 // Copy archive to internal storage 631 // Copy archive to internal storage
@@ -643,6 +644,7 @@ class MainActivity : AppCompatActivity(), ThemeProvider {
643 644
644 // Reinitialize relevant data 645 // Reinitialize relevant data
645 NativeLibrary.initializeSystem(true) 646 NativeLibrary.initializeSystem(true)
647 NativeConfig.initializeConfig()
646 gamesViewModel.reloadGames(false) 648 gamesViewModel.reloadGames(false)
647 649
648 return@newInstance getString(R.string.user_data_import_success) 650 return@newInstance getString(R.string.user_data_import_success)
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
index 5e9a1176a..21270fc84 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
@@ -16,6 +16,7 @@ object DirectoryInitialization {
16 if (!areDirectoriesReady) { 16 if (!areDirectoriesReady) {
17 initializeInternalStorage() 17 initializeInternalStorage()
18 NativeLibrary.initializeSystem(false) 18 NativeLibrary.initializeSystem(false)
19 NativeConfig.initializeConfig()
19 areDirectoriesReady = true 20 areDirectoriesReady = true
20 } 21 }
21 } 22 }
diff --git a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
index 9425f8b99..87e579fa7 100644
--- a/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
+++ b/src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
@@ -4,6 +4,30 @@
4package org.yuzu.yuzu_emu.utils 4package org.yuzu.yuzu_emu.utils
5 5
6object NativeConfig { 6object NativeConfig {
7 /**
8 * Creates a Config object and opens the emulation config.
9 */
10 @Synchronized
11 external fun initializeConfig()
12
13 /**
14 * Destroys the stored config object. This automatically saves the existing config.
15 */
16 @Synchronized
17 external fun unloadConfig()
18
19 /**
20 * Reads values saved to the config file and saves them.
21 */
22 @Synchronized
23 external fun reloadSettings()
24
25 /**
26 * Saves settings values in memory to disk.
27 */
28 @Synchronized
29 external fun saveSettings()
30
7 external fun getBoolean(key: String, getDefault: Boolean): Boolean 31 external fun getBoolean(key: String, getDefault: Boolean): Boolean
8 external fun setBoolean(key: String, value: Boolean) 32 external fun setBoolean(key: String, value: Boolean)
9 33
diff --git a/src/android/app/src/main/jni/CMakeLists.txt b/src/android/app/src/main/jni/CMakeLists.txt
index 88a570f68..2acc93da8 100644
--- a/src/android/app/src/main/jni/CMakeLists.txt
+++ b/src/android/app/src/main/jni/CMakeLists.txt
@@ -6,9 +6,6 @@ add_library(yuzu-android SHARED
6 android_common/android_common.h 6 android_common/android_common.h
7 applets/software_keyboard.cpp 7 applets/software_keyboard.cpp
8 applets/software_keyboard.h 8 applets/software_keyboard.h
9 config.cpp
10 config.h
11 default_ini.h
12 emu_window/emu_window.cpp 9 emu_window/emu_window.cpp
13 emu_window/emu_window.h 10 emu_window/emu_window.h
14 id_cache.cpp 11 id_cache.cpp
@@ -16,15 +13,17 @@ add_library(yuzu-android SHARED
16 native.cpp 13 native.cpp
17 native.h 14 native.h
18 native_config.cpp 15 native_config.cpp
19 uisettings.cpp 16 android_settings.cpp
20 game_metadata.cpp 17 game_metadata.cpp
21 native_log.cpp 18 native_log.cpp
19 android_config.cpp
20 android_config.h
22) 21)
23 22
24set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR}) 23set_property(TARGET yuzu-android PROPERTY IMPORTED_LOCATION ${FFmpeg_LIBRARY_DIR})
25 24
26target_link_libraries(yuzu-android PRIVATE audio_core common core input_common) 25target_link_libraries(yuzu-android PRIVATE audio_core common core input_common frontend_common)
27target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad inih jnigraphics log) 26target_link_libraries(yuzu-android PRIVATE android camera2ndk EGL glad jnigraphics log)
28if (ARCHITECTURE_arm64) 27if (ARCHITECTURE_arm64)
29 target_link_libraries(yuzu-android PRIVATE adrenotools) 28 target_link_libraries(yuzu-android PRIVATE adrenotools)
30endif() 29endif()
diff --git a/src/android/app/src/main/jni/android_config.cpp b/src/android/app/src/main/jni/android_config.cpp
new file mode 100644
index 000000000..3041c25c9
--- /dev/null
+++ b/src/android/app/src/main/jni/android_config.cpp
@@ -0,0 +1,70 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "android_config.h"
5#include "android_settings.h"
6#include "common/settings_setting.h"
7
8AndroidConfig::AndroidConfig(const std::string& config_name, ConfigType config_type)
9 : Config(config_type) {
10 Initialize(config_name);
11 if (config_type != ConfigType::InputProfile) {
12 ReadAndroidValues();
13 SaveAndroidValues();
14 }
15}
16
17AndroidConfig::~AndroidConfig() {
18 if (global) {
19 AndroidConfig::SaveAllValues();
20 }
21}
22
23void AndroidConfig::ReloadAllValues() {
24 Reload();
25 ReadAndroidValues();
26 SaveAndroidValues();
27}
28
29void AndroidConfig::SaveAllValues() {
30 Save();
31 SaveAndroidValues();
32}
33
34void AndroidConfig::ReadAndroidValues() {
35 if (global) {
36 ReadAndroidUIValues();
37 }
38}
39
40void AndroidConfig::ReadAndroidUIValues() {
41 BeginGroup(Settings::TranslateCategory(Settings::Category::Android));
42
43 ReadCategory(Settings::Category::Android);
44
45 EndGroup();
46}
47
48void AndroidConfig::SaveAndroidValues() {
49 if (global) {
50 SaveAndroidUIValues();
51 }
52
53 WriteToIni();
54}
55
56void AndroidConfig::SaveAndroidUIValues() {
57 BeginGroup(Settings::TranslateCategory(Settings::Category::Android));
58
59 WriteCategory(Settings::Category::Android);
60
61 EndGroup();
62}
63
64std::vector<Settings::BasicSetting*>& AndroidConfig::FindRelevantList(Settings::Category category) {
65 auto& map = Settings::values.linkage.by_category;
66 if (map.contains(category)) {
67 return Settings::values.linkage.by_category[category];
68 }
69 return AndroidSettings::values.linkage.by_category[category];
70}
diff --git a/src/android/app/src/main/jni/android_config.h b/src/android/app/src/main/jni/android_config.h
new file mode 100644
index 000000000..e679392fd
--- /dev/null
+++ b/src/android/app/src/main/jni/android_config.h
@@ -0,0 +1,41 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "frontend_common/config.h"
7
8class AndroidConfig final : public Config {
9public:
10 explicit AndroidConfig(const std::string& config_name = "config",
11 ConfigType config_type = ConfigType::GlobalConfig);
12 ~AndroidConfig() override;
13
14 void ReloadAllValues() override;
15 void SaveAllValues() override;
16
17protected:
18 void ReadAndroidValues();
19 void ReadAndroidUIValues();
20 void ReadHidbusValues() override {}
21 void ReadDebugControlValues() override {}
22 void ReadPathValues() override {}
23 void ReadShortcutValues() override {}
24 void ReadUIValues() override {}
25 void ReadUIGamelistValues() override {}
26 void ReadUILayoutValues() override {}
27 void ReadMultiplayerValues() override {}
28
29 void SaveAndroidValues();
30 void SaveAndroidUIValues();
31 void SaveHidbusValues() override {}
32 void SaveDebugControlValues() override {}
33 void SavePathValues() override {}
34 void SaveShortcutValues() override {}
35 void SaveUIValues() override {}
36 void SaveUIGamelistValues() override {}
37 void SaveUILayoutValues() override {}
38 void SaveMultiplayerValues() override {}
39
40 std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) override;
41};
diff --git a/src/android/app/src/main/jni/uisettings.cpp b/src/android/app/src/main/jni/android_settings.cpp
index f2f0bad50..16023a6b0 100644
--- a/src/android/app/src/main/jni/uisettings.cpp
+++ b/src/android/app/src/main/jni/android_settings.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project 1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "uisettings.h" 4#include "android_settings.h"
5 5
6namespace AndroidSettings { 6namespace AndroidSettings {
7 7
diff --git a/src/android/app/src/main/jni/uisettings.h b/src/android/app/src/main/jni/android_settings.h
index 37bc33918..37bc33918 100644
--- a/src/android/app/src/main/jni/uisettings.h
+++ b/src/android/app/src/main/jni/android_settings.h
diff --git a/src/android/app/src/main/jni/config.cpp b/src/android/app/src/main/jni/config.cpp
deleted file mode 100644
index 81120ab0f..000000000
--- a/src/android/app/src/main/jni/config.cpp
+++ /dev/null
@@ -1,330 +0,0 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include <memory>
5#include <optional>
6#include <sstream>
7
8#include <INIReader.h>
9#include "common/fs/file.h"
10#include "common/fs/fs.h"
11#include "common/fs/path_util.h"
12#include "common/logging/log.h"
13#include "common/settings.h"
14#include "common/settings_enums.h"
15#include "core/hle/service/acc/profile_manager.h"
16#include "input_common/main.h"
17#include "jni/config.h"
18#include "jni/default_ini.h"
19#include "uisettings.h"
20
21namespace FS = Common::FS;
22
23Config::Config(const std::string& config_name, ConfigType config_type)
24 : type(config_type), global{config_type == ConfigType::GlobalConfig} {
25 Initialize(config_name);
26}
27
28Config::~Config() = default;
29
30bool Config::LoadINI(const std::string& default_contents, bool retry) {
31 void(FS::CreateParentDir(config_loc));
32 config = std::make_unique<INIReader>(FS::PathToUTF8String(config_loc));
33 const auto config_loc_str = FS::PathToUTF8String(config_loc);
34 if (config->ParseError() < 0) {
35 if (retry) {
36 LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...",
37 config_loc_str);
38
39 void(FS::CreateParentDir(config_loc));
40 void(FS::WriteStringToFile(config_loc, FS::FileType::TextFile, default_contents));
41
42 config = std::make_unique<INIReader>(config_loc_str);
43
44 return LoadINI(default_contents, false);
45 }
46 LOG_ERROR(Config, "Failed.");
47 return false;
48 }
49 LOG_INFO(Config, "Successfully loaded {}", config_loc_str);
50 return true;
51}
52
53template <>
54void Config::ReadSetting(const std::string& group, Settings::Setting<std::string>& setting) {
55 std::string setting_value = config->Get(group, setting.GetLabel(), setting.GetDefault());
56 if (setting_value.empty()) {
57 setting_value = setting.GetDefault();
58 }
59 setting = std::move(setting_value);
60}
61
62template <>
63void Config::ReadSetting(const std::string& group, Settings::Setting<bool>& setting) {
64 setting = config->GetBoolean(group, setting.GetLabel(), setting.GetDefault());
65}
66
67template <typename Type, bool ranged>
68void Config::ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting) {
69 setting = static_cast<Type>(
70 config->GetInteger(group, setting.GetLabel(), static_cast<long>(setting.GetDefault())));
71}
72
73void Config::ReadValues() {
74 ReadSetting("ControlsGeneral", Settings::values.mouse_enabled);
75 ReadSetting("ControlsGeneral", Settings::values.touch_device);
76 ReadSetting("ControlsGeneral", Settings::values.keyboard_enabled);
77 ReadSetting("ControlsGeneral", Settings::values.debug_pad_enabled);
78 ReadSetting("ControlsGeneral", Settings::values.vibration_enabled);
79 ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations);
80 ReadSetting("ControlsGeneral", Settings::values.motion_enabled);
81 Settings::values.touchscreen.enabled =
82 config->GetBoolean("ControlsGeneral", "touch_enabled", true);
83 Settings::values.touchscreen.rotation_angle =
84 config->GetInteger("ControlsGeneral", "touch_angle", 0);
85 Settings::values.touchscreen.diameter_x =
86 config->GetInteger("ControlsGeneral", "touch_diameter_x", 15);
87 Settings::values.touchscreen.diameter_y =
88 config->GetInteger("ControlsGeneral", "touch_diameter_y", 15);
89
90 int num_touch_from_button_maps =
91 config->GetInteger("ControlsGeneral", "touch_from_button_map", 0);
92 if (num_touch_from_button_maps > 0) {
93 for (int i = 0; i < num_touch_from_button_maps; ++i) {
94 Settings::TouchFromButtonMap map;
95 map.name = config->Get("ControlsGeneral",
96 std::string("touch_from_button_maps_") + std::to_string(i) +
97 std::string("_name"),
98 "default");
99 const int num_touch_maps = config->GetInteger(
100 "ControlsGeneral",
101 std::string("touch_from_button_maps_") + std::to_string(i) + std::string("_count"),
102 0);
103 map.buttons.reserve(num_touch_maps);
104
105 for (int j = 0; j < num_touch_maps; ++j) {
106 std::string touch_mapping =
107 config->Get("ControlsGeneral",
108 std::string("touch_from_button_maps_") + std::to_string(i) +
109 std::string("_bind_") + std::to_string(j),
110 "");
111 map.buttons.emplace_back(std::move(touch_mapping));
112 }
113
114 Settings::values.touch_from_button_maps.emplace_back(std::move(map));
115 }
116 } else {
117 Settings::values.touch_from_button_maps.emplace_back(
118 Settings::TouchFromButtonMap{"default", {}});
119 num_touch_from_button_maps = 1;
120 }
121 Settings::values.touch_from_button_map_index = std::clamp(
122 Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
123
124 ReadSetting("ControlsGeneral", Settings::values.udp_input_servers);
125
126 // Data Storage
127 ReadSetting("Data Storage", Settings::values.use_virtual_sd);
128 FS::SetYuzuPath(FS::YuzuPath::NANDDir,
129 config->Get("Data Storage", "nand_directory",
130 FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
131 FS::SetYuzuPath(FS::YuzuPath::SDMCDir,
132 config->Get("Data Storage", "sdmc_directory",
133 FS::GetYuzuPathString(FS::YuzuPath::SDMCDir)));
134 FS::SetYuzuPath(FS::YuzuPath::LoadDir,
135 config->Get("Data Storage", "load_directory",
136 FS::GetYuzuPathString(FS::YuzuPath::LoadDir)));
137 FS::SetYuzuPath(FS::YuzuPath::DumpDir,
138 config->Get("Data Storage", "dump_directory",
139 FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
140 ReadSetting("Data Storage", Settings::values.gamecard_inserted);
141 ReadSetting("Data Storage", Settings::values.gamecard_current_game);
142 ReadSetting("Data Storage", Settings::values.gamecard_path);
143
144 // System
145 ReadSetting("System", Settings::values.current_user);
146 Settings::values.current_user = std::clamp<int>(Settings::values.current_user.GetValue(), 0,
147 Service::Account::MAX_USERS - 1);
148
149 // Disable docked mode by default on Android
150 Settings::values.use_docked_mode.SetValue(config->GetBoolean("System", "use_docked_mode", false)
151 ? Settings::ConsoleMode::Docked
152 : Settings::ConsoleMode::Handheld);
153
154 const auto rng_seed_enabled = config->GetBoolean("System", "rng_seed_enabled", false);
155 if (rng_seed_enabled) {
156 Settings::values.rng_seed.SetValue(config->GetInteger("System", "rng_seed", 0));
157 } else {
158 Settings::values.rng_seed.SetValue(0);
159 }
160 Settings::values.rng_seed_enabled.SetValue(rng_seed_enabled);
161
162 const auto custom_rtc_enabled = config->GetBoolean("System", "custom_rtc_enabled", false);
163 if (custom_rtc_enabled) {
164 Settings::values.custom_rtc = config->GetInteger("System", "custom_rtc", 0);
165 } else {
166 Settings::values.custom_rtc = 0;
167 }
168 Settings::values.custom_rtc_enabled = custom_rtc_enabled;
169
170 ReadSetting("System", Settings::values.language_index);
171 ReadSetting("System", Settings::values.region_index);
172 ReadSetting("System", Settings::values.time_zone_index);
173 ReadSetting("System", Settings::values.sound_index);
174
175 // Core
176 ReadSetting("Core", Settings::values.use_multi_core);
177 ReadSetting("Core", Settings::values.memory_layout_mode);
178
179 // Cpu
180 ReadSetting("Cpu", Settings::values.cpu_accuracy);
181 ReadSetting("Cpu", Settings::values.cpu_debug_mode);
182 ReadSetting("Cpu", Settings::values.cpuopt_page_tables);
183 ReadSetting("Cpu", Settings::values.cpuopt_block_linking);
184 ReadSetting("Cpu", Settings::values.cpuopt_return_stack_buffer);
185 ReadSetting("Cpu", Settings::values.cpuopt_fast_dispatcher);
186 ReadSetting("Cpu", Settings::values.cpuopt_context_elimination);
187 ReadSetting("Cpu", Settings::values.cpuopt_const_prop);
188 ReadSetting("Cpu", Settings::values.cpuopt_misc_ir);
189 ReadSetting("Cpu", Settings::values.cpuopt_reduce_misalign_checks);
190 ReadSetting("Cpu", Settings::values.cpuopt_fastmem);
191 ReadSetting("Cpu", Settings::values.cpuopt_fastmem_exclusives);
192 ReadSetting("Cpu", Settings::values.cpuopt_recompile_exclusives);
193 ReadSetting("Cpu", Settings::values.cpuopt_ignore_memory_aborts);
194 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma);
195 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error);
196 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
197 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_inaccurate_nan);
198 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_fastmem_check);
199 ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_global_monitor);
200
201 // Renderer
202 ReadSetting("Renderer", Settings::values.renderer_backend);
203 ReadSetting("Renderer", Settings::values.renderer_debug);
204 ReadSetting("Renderer", Settings::values.renderer_shader_feedback);
205 ReadSetting("Renderer", Settings::values.enable_nsight_aftermath);
206 ReadSetting("Renderer", Settings::values.disable_shader_loop_safety_checks);
207 ReadSetting("Renderer", Settings::values.vulkan_device);
208
209 ReadSetting("Renderer", Settings::values.resolution_setup);
210 ReadSetting("Renderer", Settings::values.scaling_filter);
211 ReadSetting("Renderer", Settings::values.fsr_sharpening_slider);
212 ReadSetting("Renderer", Settings::values.anti_aliasing);
213 ReadSetting("Renderer", Settings::values.fullscreen_mode);
214 ReadSetting("Renderer", Settings::values.aspect_ratio);
215 ReadSetting("Renderer", Settings::values.max_anisotropy);
216 ReadSetting("Renderer", Settings::values.use_speed_limit);
217 ReadSetting("Renderer", Settings::values.speed_limit);
218 ReadSetting("Renderer", Settings::values.use_disk_shader_cache);
219 ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation);
220 ReadSetting("Renderer", Settings::values.vsync_mode);
221 ReadSetting("Renderer", Settings::values.shader_backend);
222 ReadSetting("Renderer", Settings::values.use_asynchronous_shaders);
223 ReadSetting("Renderer", Settings::values.nvdec_emulation);
224 ReadSetting("Renderer", Settings::values.use_fast_gpu_time);
225 ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache);
226
227 ReadSetting("Renderer", Settings::values.bg_red);
228 ReadSetting("Renderer", Settings::values.bg_green);
229 ReadSetting("Renderer", Settings::values.bg_blue);
230
231 // Use GPU accuracy normal by default on Android
232 Settings::values.gpu_accuracy = static_cast<Settings::GpuAccuracy>(config->GetInteger(
233 "Renderer", "gpu_accuracy", static_cast<u32>(Settings::GpuAccuracy::Normal)));
234
235 // Use GPU default anisotropic filtering on Android
236 Settings::values.max_anisotropy =
237 static_cast<Settings::AnisotropyMode>(config->GetInteger("Renderer", "max_anisotropy", 1));
238
239 // Disable ASTC compute by default on Android
240 Settings::values.accelerate_astc.SetValue(
241 config->GetBoolean("Renderer", "accelerate_astc", false) ? Settings::AstcDecodeMode::Gpu
242 : Settings::AstcDecodeMode::Cpu);
243
244 // Enable asynchronous presentation by default on Android
245 Settings::values.async_presentation =
246 config->GetBoolean("Renderer", "async_presentation", true);
247
248 // Disable force_max_clock by default on Android
249 Settings::values.renderer_force_max_clock =
250 config->GetBoolean("Renderer", "force_max_clock", false);
251
252 // Disable use_reactive_flushing by default on Android
253 Settings::values.use_reactive_flushing =
254 config->GetBoolean("Renderer", "use_reactive_flushing", false);
255
256 // Audio
257 ReadSetting("Audio", Settings::values.sink_id);
258 ReadSetting("Audio", Settings::values.audio_output_device_id);
259 ReadSetting("Audio", Settings::values.volume);
260
261 // Miscellaneous
262 // log_filter has a different default here than from common
263 Settings::values.log_filter = "*:Info";
264 ReadSetting("Miscellaneous", Settings::values.use_dev_keys);
265
266 // Debugging
267 Settings::values.record_frame_times =
268 config->GetBoolean("Debugging", "record_frame_times", false);
269 ReadSetting("Debugging", Settings::values.dump_exefs);
270 ReadSetting("Debugging", Settings::values.dump_nso);
271 ReadSetting("Debugging", Settings::values.enable_fs_access_log);
272 ReadSetting("Debugging", Settings::values.reporting_services);
273 ReadSetting("Debugging", Settings::values.quest_flag);
274 ReadSetting("Debugging", Settings::values.use_debug_asserts);
275 ReadSetting("Debugging", Settings::values.use_auto_stub);
276 ReadSetting("Debugging", Settings::values.disable_macro_jit);
277 ReadSetting("Debugging", Settings::values.disable_macro_hle);
278 ReadSetting("Debugging", Settings::values.use_gdbstub);
279 ReadSetting("Debugging", Settings::values.gdbstub_port);
280
281 const auto title_list = config->Get("AddOns", "title_ids", "");
282 std::stringstream ss(title_list);
283 std::string line;
284 while (std::getline(ss, line, '|')) {
285 const auto title_id = std::strtoul(line.c_str(), nullptr, 16);
286 const auto disabled_list = config->Get("AddOns", "disabled_" + line, "");
287
288 std::stringstream inner_ss(disabled_list);
289 std::string inner_line;
290 std::vector<std::string> out;
291 while (std::getline(inner_ss, inner_line, '|')) {
292 out.push_back(inner_line);
293 }
294
295 Settings::values.disabled_addons.insert_or_assign(title_id, out);
296 }
297
298 // Web Service
299 ReadSetting("WebService", Settings::values.enable_telemetry);
300 ReadSetting("WebService", Settings::values.web_api_url);
301 ReadSetting("WebService", Settings::values.yuzu_username);
302 ReadSetting("WebService", Settings::values.yuzu_token);
303
304 // Network
305 ReadSetting("Network", Settings::values.network_interface);
306
307 // Android
308 ReadSetting("Android", AndroidSettings::values.picture_in_picture);
309 ReadSetting("Android", AndroidSettings::values.screen_layout);
310}
311
312void Config::Initialize(const std::string& config_name) {
313 const auto fs_config_loc = FS::GetYuzuPath(FS::YuzuPath::ConfigDir);
314 const auto config_file = fmt::format("{}.ini", config_name);
315
316 switch (type) {
317 case ConfigType::GlobalConfig:
318 config_loc = FS::PathToUTF8String(fs_config_loc / config_file);
319 break;
320 case ConfigType::PerGameConfig:
321 config_loc = FS::PathToUTF8String(fs_config_loc / "custom" / FS::ToU8String(config_file));
322 break;
323 case ConfigType::InputProfile:
324 config_loc = FS::PathToUTF8String(fs_config_loc / "input" / config_file);
325 LoadINI(DefaultINI::android_config_file);
326 return;
327 }
328 LoadINI(DefaultINI::android_config_file);
329 ReadValues();
330}
diff --git a/src/android/app/src/main/jni/config.h b/src/android/app/src/main/jni/config.h
deleted file mode 100644
index e1e8f47ed..000000000
--- a/src/android/app/src/main/jni/config.h
+++ /dev/null
@@ -1,47 +0,0 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include <filesystem>
7#include <memory>
8#include <optional>
9#include <string>
10
11#include "common/settings.h"
12
13class INIReader;
14
15class Config {
16 bool LoadINI(const std::string& default_contents = "", bool retry = true);
17
18public:
19 enum class ConfigType {
20 GlobalConfig,
21 PerGameConfig,
22 InputProfile,
23 };
24
25 explicit Config(const std::string& config_name = "config",
26 ConfigType config_type = ConfigType::GlobalConfig);
27 ~Config();
28
29 void Initialize(const std::string& config_name);
30
31private:
32 /**
33 * Applies a value read from the config to a Setting.
34 *
35 * @param group The name of the INI group
36 * @param setting The yuzu setting to modify
37 */
38 template <typename Type, bool ranged>
39 void ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting);
40
41 void ReadValues();
42
43 const ConfigType type;
44 std::unique_ptr<INIReader> config;
45 std::string config_loc;
46 const bool global;
47};
diff --git a/src/android/app/src/main/jni/default_ini.h b/src/android/app/src/main/jni/default_ini.h
deleted file mode 100644
index d81422a74..000000000
--- a/src/android/app/src/main/jni/default_ini.h
+++ /dev/null
@@ -1,511 +0,0 @@
1// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6namespace DefaultINI {
7
8const char* android_config_file = R"(
9
10[ControlsP0]
11# The input devices and parameters for each Switch native input
12# The config section determines the player number where the config will be applied on. For example "ControlsP0", "ControlsP1", ...
13# It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..."
14# Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values
15
16# Indicates if this player should be connected at boot
17connected=
18
19# for button input, the following devices are available:
20# - "keyboard" (default) for keyboard input. Required parameters:
21# - "code": the code of the key to bind
22# - "sdl" for joystick input using SDL. Required parameters:
23# - "guid": SDL identification GUID of the joystick
24# - "port": the index of the joystick to bind
25# - "button"(optional): the index of the button to bind
26# - "hat"(optional): the index of the hat to bind as direction buttons
27# - "axis"(optional): the index of the axis to bind
28# - "direction"(only used for hat): the direction name of the hat to bind. Can be "up", "down", "left" or "right"
29# - "threshold"(only used for axis): a float value in (-1.0, 1.0) which the button is
30# triggered if the axis value crosses
31# - "direction"(only used for axis): "+" means the button is triggered when the axis value
32# is greater than the threshold; "-" means the button is triggered when the axis value
33# is smaller than the threshold
34button_a=
35button_b=
36button_x=
37button_y=
38button_lstick=
39button_rstick=
40button_l=
41button_r=
42button_zl=
43button_zr=
44button_plus=
45button_minus=
46button_dleft=
47button_dup=
48button_dright=
49button_ddown=
50button_lstick_left=
51button_lstick_up=
52button_lstick_right=
53button_lstick_down=
54button_sl=
55button_sr=
56button_home=
57button_screenshot=
58
59# for analog input, the following devices are available:
60# - "analog_from_button" (default) for emulating analog input from direction buttons. Required parameters:
61# - "up", "down", "left", "right": sub-devices for each direction.
62# Should be in the format as a button input devices using escape characters, for example, "engine$0keyboard$1code$00"
63# - "modifier": sub-devices as a modifier.
64# - "modifier_scale": a float number representing the applied modifier scale to the analog input.
65# Must be in range of 0.0-1.0. Defaults to 0.5
66# - "sdl" for joystick input using SDL. Required parameters:
67# - "guid": SDL identification GUID of the joystick
68# - "port": the index of the joystick to bind
69# - "axis_x": the index of the axis to bind as x-axis (default to 0)
70# - "axis_y": the index of the axis to bind as y-axis (default to 1)
71lstick=
72rstick=
73
74# for motion input, the following devices are available:
75# - "keyboard" (default) for emulating random motion input from buttons. Required parameters:
76# - "code": the code of the key to bind
77# - "sdl" for motion input using SDL. Required parameters:
78# - "guid": SDL identification GUID of the joystick
79# - "port": the index of the joystick to bind
80# - "motion": the index of the motion sensor to bind
81# - "cemuhookudp" for motion input using Cemu Hook protocol. Required parameters:
82# - "guid": the IP address of the cemu hook server encoded to a hex string. for example 192.168.0.1 = "c0a80001"
83# - "port": the port of the cemu hook server
84# - "pad": the index of the joystick
85# - "motion": the index of the motion sensor of the joystick to bind
86motionleft=
87motionright=
88
89[ControlsGeneral]
90# To use the debug_pad, prepend `debug_pad_` before each button setting above.
91# i.e. debug_pad_button_a=
92
93# Enable debug pad inputs to the guest
94# 0 (default): Disabled, 1: Enabled
95debug_pad_enabled =
96
97# Whether to enable or disable vibration
98# 0: Disabled, 1 (default): Enabled
99vibration_enabled=
100
101# Whether to enable or disable accurate vibrations
102# 0 (default): Disabled, 1: Enabled
103enable_accurate_vibrations=
104
105# Enables controller motion inputs
106# 0: Disabled, 1 (default): Enabled
107motion_enabled =
108
109# Defines the udp device's touch screen coordinate system for cemuhookudp devices
110# - "min_x", "min_y", "max_x", "max_y"
111touch_device=
112
113# for mapping buttons to touch inputs.
114#touch_from_button_map=1
115#touch_from_button_maps_0_name=default
116#touch_from_button_maps_0_count=2
117#touch_from_button_maps_0_bind_0=foo
118#touch_from_button_maps_0_bind_1=bar
119# etc.
120
121# List of Cemuhook UDP servers, delimited by ','.
122# Default: 127.0.0.1:26760
123# Example: 127.0.0.1:26760,123.4.5.67:26761
124udp_input_servers =
125
126# Enable controlling an axis via a mouse input.
127# 0 (default): Off, 1: On
128mouse_panning =
129
130# Set mouse sensitivity.
131# Default: 1.0
132mouse_panning_sensitivity =
133
134# Emulate an analog control stick from keyboard inputs.
135# 0 (default): Disabled, 1: Enabled
136emulate_analog_keyboard =
137
138# Enable mouse inputs to the guest
139# 0 (default): Disabled, 1: Enabled
140mouse_enabled =
141
142# Enable keyboard inputs to the guest
143# 0 (default): Disabled, 1: Enabled
144keyboard_enabled =
145
146[Core]
147# Whether to use multi-core for CPU emulation
148# 0: Disabled, 1 (default): Enabled
149use_multi_core =
150
151# Enable unsafe extended guest system memory layout (8GB DRAM)
152# 0 (default): Disabled, 1: Enabled
153use_unsafe_extended_memory_layout =
154
155[Cpu]
156# Adjusts various optimizations.
157# Auto-select mode enables choice unsafe optimizations.
158# Accurate enables only safe optimizations.
159# Unsafe allows any unsafe optimizations.
160# 0 (default): Auto-select, 1: Accurate, 2: Enable unsafe optimizations
161cpu_accuracy =
162
163# Allow disabling safe optimizations.
164# 0 (default): Disabled, 1: Enabled
165cpu_debug_mode =
166
167# Enable inline page tables optimization (faster guest memory access)
168# 0: Disabled, 1 (default): Enabled
169cpuopt_page_tables =
170
171# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps)
172# 0: Disabled, 1 (default): Enabled
173cpuopt_block_linking =
174
175# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns)
176# 0: Disabled, 1 (default): Enabled
177cpuopt_return_stack_buffer =
178
179# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture)
180# 0: Disabled, 1 (default): Enabled
181cpuopt_fast_dispatcher =
182
183# Enable context elimination CPU Optimization (reduce host memory use for guest context)
184# 0: Disabled, 1 (default): Enabled
185cpuopt_context_elimination =
186
187# Enable constant propagation CPU optimization (basic IR optimization)
188# 0: Disabled, 1 (default): Enabled
189cpuopt_const_prop =
190
191# Enable miscellaneous CPU optimizations (basic IR optimization)
192# 0: Disabled, 1 (default): Enabled
193cpuopt_misc_ir =
194
195# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access)
196# 0: Disabled, 1 (default): Enabled
197cpuopt_reduce_misalign_checks =
198
199# Enable Host MMU Emulation (faster guest memory access)
200# 0: Disabled, 1 (default): Enabled
201cpuopt_fastmem =
202
203# Enable Host MMU Emulation for exclusive memory instructions (faster guest memory access)
204# 0: Disabled, 1 (default): Enabled
205cpuopt_fastmem_exclusives =
206
207# Enable fallback on failure of fastmem of exclusive memory instructions (faster guest memory access)
208# 0: Disabled, 1 (default): Enabled
209cpuopt_recompile_exclusives =
210
211# Enable optimization to ignore invalid memory accesses (faster guest memory access)
212# 0: Disabled, 1 (default): Enabled
213cpuopt_ignore_memory_aborts =
214
215# Enable unfuse FMA (improve performance on CPUs without FMA)
216# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
217# 0: Disabled, 1 (default): Enabled
218cpuopt_unsafe_unfuse_fma =
219
220# Enable faster FRSQRTE and FRECPE
221# Only enabled if cpu_accuracy is set to Unsafe.
222# 0: Disabled, 1 (default): Enabled
223cpuopt_unsafe_reduce_fp_error =
224
225# Enable faster ASIMD instructions (32 bits only)
226# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
227# 0: Disabled, 1 (default): Enabled
228cpuopt_unsafe_ignore_standard_fpcr =
229
230# Enable inaccurate NaN handling
231# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
232# 0: Disabled, 1 (default): Enabled
233cpuopt_unsafe_inaccurate_nan =
234
235# Disable address space checks (64 bits only)
236# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
237# 0: Disabled, 1 (default): Enabled
238cpuopt_unsafe_fastmem_check =
239
240# Enable faster exclusive instructions
241# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select.
242# 0: Disabled, 1 (default): Enabled
243cpuopt_unsafe_ignore_global_monitor =
244
245[Renderer]
246# Which backend API to use.
247# 0: OpenGL (unsupported), 1 (default): Vulkan, 2: Null
248backend =
249
250# Whether to enable asynchronous presentation (Vulkan only)
251# 0: Off, 1 (default): On
252async_presentation =
253
254# Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied).
255# 0 (default): Disabled, 1: Enabled
256force_max_clock =
257
258# Enable graphics API debugging mode.
259# 0 (default): Disabled, 1: Enabled
260debug =
261
262# Enable shader feedback.
263# 0 (default): Disabled, 1: Enabled
264renderer_shader_feedback =
265
266# Enable Nsight Aftermath crash dumps
267# 0 (default): Disabled, 1: Enabled
268nsight_aftermath =
269
270# Disable shader loop safety checks, executing the shader without loop logic changes
271# 0 (default): Disabled, 1: Enabled
272disable_shader_loop_safety_checks =
273
274# Which Vulkan physical device to use (defaults to 0)
275vulkan_device =
276
277# 0: 0.5x (360p/540p) [EXPERIMENTAL]
278# 1: 0.75x (540p/810p) [EXPERIMENTAL]
279# 2 (default): 1x (720p/1080p)
280# 3: 2x (1440p/2160p)
281# 4: 3x (2160p/3240p)
282# 5: 4x (2880p/4320p)
283# 6: 5x (3600p/5400p)
284# 7: 6x (4320p/6480p)
285resolution_setup =
286
287# Pixel filter to use when up- or down-sampling rendered frames.
288# 0: Nearest Neighbor
289# 1 (default): Bilinear
290# 2: Bicubic
291# 3: Gaussian
292# 4: ScaleForce
293# 5: AMD FidelityFX™️ Super Resolution [Vulkan Only]
294scaling_filter =
295
296# Anti-Aliasing (AA)
297# 0 (default): None, 1: FXAA
298anti_aliasing =
299
300# Whether to use fullscreen or borderless window mode
301# 0 (Windows default): Borderless window, 1 (All other default): Exclusive fullscreen
302fullscreen_mode =
303
304# Aspect ratio
305# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Force 16:10, 4: Stretch to Window
306aspect_ratio =
307
308# Anisotropic filtering
309# 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x
310max_anisotropy =
311
312# Whether to enable VSync or not.
313# OpenGL: Values other than 0 enable VSync
314# Vulkan: FIFO is selected if the requested mode is not supported by the driver.
315# FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh rate.
316# FIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down.
317# Mailbox can have lower latency than FIFO and does not tear but may drop frames.
318# Immediate (no synchronization) just presents whatever is available and can exhibit tearing.
319# 0: Immediate (Off), 1 (Default): Mailbox (On), 2: FIFO, 3: FIFO Relaxed
320use_vsync =
321
322# Selects the OpenGL shader backend. NV_gpu_program5 is required for GLASM. If NV_gpu_program5 is
323# not available and GLASM is selected, GLSL will be used.
324# 0: GLSL, 1 (default): GLASM, 2: SPIR-V
325shader_backend =
326
327# Whether to allow asynchronous shader building.
328# 0 (default): Off, 1: On
329use_asynchronous_shaders =
330
331# Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory.
332# 0 (default): Off, 1: On
333use_reactive_flushing =
334
335# NVDEC emulation.
336# 0: Disabled, 1: CPU Decoding, 2 (default): GPU Decoding
337nvdec_emulation =
338
339# Accelerate ASTC texture decoding.
340# 0 (default): Off, 1: On
341accelerate_astc =
342
343# Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value
344# 0: Off, 1: On (default)
345use_speed_limit =
346
347# Limits the speed of the game to run no faster than this value as a percentage of target speed
348# 1 - 9999: Speed limit as a percentage of target game speed. 100 (default)
349speed_limit =
350
351# Whether to use disk based shader cache
352# 0: Off, 1 (default): On
353use_disk_shader_cache =
354
355# Which gpu accuracy level to use
356# 0 (default): Normal, 1: High, 2: Extreme (Very slow)
357gpu_accuracy =
358
359# Whether to use asynchronous GPU emulation
360# 0 : Off (slow), 1 (default): On (fast)
361use_asynchronous_gpu_emulation =
362
363# Inform the guest that GPU operations completed more quickly than they did.
364# 0: Off, 1 (default): On
365use_fast_gpu_time =
366
367# Force unmodified buffers to be flushed, which can cost performance.
368# 0: Off (default), 1: On
369use_pessimistic_flushes =
370
371# Whether to use garbage collection or not for GPU caches.
372# 0 (default): Off, 1: On
373use_caches_gc =
374
375# The clear color for the renderer. What shows up on the sides of the bottom screen.
376# Must be in range of 0-255. Defaults to 0 for all.
377bg_red =
378bg_blue =
379bg_green =
380
381[Audio]
382# Which audio output engine to use.
383# auto (default): Auto-select
384# cubeb: Cubeb audio engine (if available)
385# sdl2: SDL2 audio engine (if available)
386# null: No audio output
387output_engine =
388
389# Which audio device to use.
390# auto (default): Auto-select
391output_device =
392
393# Output volume.
394# 100 (default): 100%, 0; mute
395volume =
396
397[Data Storage]
398# Whether to create a virtual SD card.
399# 1: Yes, 0 (default): No
400use_virtual_sd =
401
402# Whether or not to enable gamecard emulation
403# 1: Yes, 0 (default): No
404gamecard_inserted =
405
406# Whether or not the gamecard should be emulated as the current game
407# If 'gamecard_inserted' is 0 this setting is irrelevant
408# 1: Yes, 0 (default): No
409gamecard_current_game =
410
411# Path to an XCI file to use as the gamecard
412# If 'gamecard_inserted' is 0 this setting is irrelevant
413# If 'gamecard_current_game' is 1 this setting is irrelevant
414gamecard_path =
415
416[System]
417# Whether the system is docked
418# 1 (default): Yes, 0: No
419use_docked_mode =
420
421# Sets the seed for the RNG generator built into the switch
422# rng_seed will be ignored and randomly generated if rng_seed_enabled is false
423rng_seed_enabled =
424rng_seed =
425
426# Sets the current time (in seconds since 12:00 AM Jan 1, 1970) that will be used by the time service
427# This will auto-increment, with the time set being the time the game is started
428# This override will only occur if custom_rtc_enabled is true, otherwise the current time is used
429custom_rtc_enabled =
430custom_rtc =
431
432# Sets the systems language index
433# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese,
434# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French,
435# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Brazilian Portuguese
436language_index =
437
438# The system region that yuzu will use during emulation
439# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan
440region_index =
441
442# The system time zone that yuzu will use during emulation
443# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone
444time_zone_index =
445
446# Sets the sound output mode.
447# 0: Mono, 1 (default): Stereo, 2: Surround
448sound_index =
449
450[Miscellaneous]
451# A filter which removes logs below a certain logging level.
452# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical
453log_filter = *:Trace
454
455# Use developer keys
456# 0 (default): Disabled, 1: Enabled
457use_dev_keys =
458
459[Debugging]
460# Record frame time data, can be found in the log directory. Boolean value
461record_frame_times =
462# Determines whether or not yuzu will dump the ExeFS of all games it attempts to load while loading them
463dump_exefs=false
464# Determines whether or not yuzu will dump all NSOs it attempts to load while loading them
465dump_nso=false
466# Determines whether or not yuzu will save the filesystem access log.
467enable_fs_access_log=false
468# Enables verbose reporting services
469reporting_services =
470# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode
471# false: Retail/Normal Mode (default), true: Kiosk Mode
472quest_flag =
473# Determines whether debug asserts should be enabled, which will throw an exception on asserts.
474# false: Disabled (default), true: Enabled
475use_debug_asserts =
476# Determines whether unimplemented HLE service calls should be automatically stubbed.
477# false: Disabled (default), true: Enabled
478use_auto_stub =
479# Enables/Disables the macro JIT compiler
480disable_macro_jit=false
481# Determines whether to enable the GDB stub and wait for the debugger to attach before running.
482# false: Disabled (default), true: Enabled
483use_gdbstub=false
484# The port to use for the GDB server, if it is enabled.
485gdbstub_port=6543
486
487[WebService]
488# Whether or not to enable telemetry
489# 0: No, 1 (default): Yes
490enable_telemetry =
491# URL for Web API
492web_api_url = https://api.yuzu-emu.org
493# Username and token for yuzu Web Service
494# See https://profile.yuzu-emu.org/ for more info
495yuzu_username =
496yuzu_token =
497
498[Network]
499# Name of the network interface device to use with yuzu LAN play.
500# e.g. On *nix: 'enp7s0', 'wlp6s0u1u3u3', 'lo'
501# e.g. On Windows: 'Ethernet', 'Wi-Fi'
502network_interface =
503
504[AddOns]
505# Used to disable add-ons
506# List of title IDs of games that will have add-ons disabled (separated by '|'):
507title_ids =
508# For each title ID, have a key/value pair called `disabled_<title_id>` equal to the names of the add-ons to disable (sep. by '|')
509# e.x. disabled_0100000000010000 = Update|DLC <- disables Updates and DLC on Super Mario Odyssey
510)";
511} // namespace DefaultINI
diff --git a/src/android/app/src/main/jni/native.cpp b/src/android/app/src/main/jni/native.cpp
index 64663b084..617288ae4 100644
--- a/src/android/app/src/main/jni/native.cpp
+++ b/src/android/app/src/main/jni/native.cpp
@@ -52,8 +52,8 @@
52#include "core/hle/service/am/applets/applets.h" 52#include "core/hle/service/am/applets/applets.h"
53#include "core/hle/service/filesystem/filesystem.h" 53#include "core/hle/service/filesystem/filesystem.h"
54#include "core/loader/loader.h" 54#include "core/loader/loader.h"
55#include "frontend_common/config.h"
55#include "jni/android_common/android_common.h" 56#include "jni/android_common/android_common.h"
56#include "jni/config.h"
57#include "jni/id_cache.h" 57#include "jni/id_cache.h"
58#include "jni/native.h" 58#include "jni/native.h"
59#include "video_core/renderer_base.h" 59#include "video_core/renderer_base.h"
@@ -664,8 +664,6 @@ void Java_org_yuzu_yuzu_1emu_NativeLibrary_onTouchReleased(JNIEnv* env, jclass c
664 664
665void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass clazz, 665void Java_org_yuzu_yuzu_1emu_NativeLibrary_initializeSystem(JNIEnv* env, jclass clazz,
666 jboolean reload) { 666 jboolean reload) {
667 // Create the default config.ini.
668 Config{};
669 // Initialize the emulated system. 667 // Initialize the emulated system.
670 if (!reload) { 668 if (!reload) {
671 EmulationSession::GetInstance().System().Initialize(); 669 EmulationSession::GetInstance().System().Initialize();
@@ -680,17 +678,6 @@ jint Java_org_yuzu_yuzu_1emu_NativeLibrary_defaultCPUCore(JNIEnv* env, jclass cl
680void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2Ljava_lang_String_2Z( 678void Java_org_yuzu_yuzu_1emu_NativeLibrary_run__Ljava_lang_String_2Ljava_lang_String_2Z(
681 JNIEnv* env, jclass clazz, jstring j_file, jstring j_savestate, jboolean j_delete_savestate) {} 679 JNIEnv* env, jclass clazz, jstring j_file, jstring j_savestate, jboolean j_delete_savestate) {}
682 680
683void Java_org_yuzu_yuzu_1emu_NativeLibrary_reloadSettings(JNIEnv* env, jclass clazz) {
684 Config{};
685}
686
687void Java_org_yuzu_yuzu_1emu_NativeLibrary_initGameIni(JNIEnv* env, jclass clazz,
688 jstring j_game_id) {
689 std::string_view game_id = env->GetStringUTFChars(j_game_id, 0);
690
691 env->ReleaseStringUTFChars(j_game_id, game_id.data());
692}
693
694jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPerfStats(JNIEnv* env, jclass clazz) { 681jdoubleArray Java_org_yuzu_yuzu_1emu_NativeLibrary_getPerfStats(JNIEnv* env, jclass clazz) {
695 jdoubleArray j_stats = env->NewDoubleArray(4); 682 jdoubleArray j_stats = env->NewDoubleArray(4);
696 683
diff --git a/src/android/app/src/main/jni/native_config.cpp b/src/android/app/src/main/jni/native_config.cpp
index 8a704960c..8e81816e5 100644
--- a/src/android/app/src/main/jni/native_config.cpp
+++ b/src/android/app/src/main/jni/native_config.cpp
@@ -5,11 +5,14 @@
5 5
6#include <jni.h> 6#include <jni.h>
7 7
8#include "android_config.h"
9#include "android_settings.h"
8#include "common/logging/log.h" 10#include "common/logging/log.h"
9#include "common/settings.h" 11#include "common/settings.h"
12#include "frontend_common/config.h"
10#include "jni/android_common/android_common.h" 13#include "jni/android_common/android_common.h"
11#include "jni/config.h" 14
12#include "uisettings.h" 15std::unique_ptr<AndroidConfig> config;
13 16
14template <typename T> 17template <typename T>
15Settings::Setting<T>* getSetting(JNIEnv* env, jstring jkey) { 18Settings::Setting<T>* getSetting(JNIEnv* env, jstring jkey) {
@@ -28,6 +31,22 @@ Settings::Setting<T>* getSetting(JNIEnv* env, jstring jkey) {
28 31
29extern "C" { 32extern "C" {
30 33
34void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_initializeConfig(JNIEnv* env, jobject obj) {
35 config = std::make_unique<AndroidConfig>();
36}
37
38void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_unloadConfig(JNIEnv* env, jobject obj) {
39 config.reset();
40}
41
42void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_reloadSettings(JNIEnv* env, jobject obj) {
43 config->AndroidConfig::ReloadAllValues();
44}
45
46void Java_org_yuzu_yuzu_1emu_utils_NativeConfig_saveSettings(JNIEnv* env, jobject obj) {
47 config->AndroidConfig::SaveAllValues();
48}
49
31jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getBoolean(JNIEnv* env, jobject obj, 50jboolean Java_org_yuzu_yuzu_1emu_utils_NativeConfig_getBoolean(JNIEnv* env, jobject obj,
32 jstring jkey, jboolean getDefault) { 51 jstring jkey, jboolean getDefault) {
33 auto setting = getSetting<bool>(env, jkey); 52 auto setting = getSetting<bool>(env, jkey);