Browse Source
Merge pull request #11889 from t895/ini-lib
Merge pull request #11889 from t895/ini-lib
configuration: Unify config handling across frontendsnce_cpp
committed by
GitHub
69 changed files with 2697 additions and 3542 deletions
-
6.gitmodules
-
1CMakeLists.txt
-
27CMakeModules/Findinih.cmake
-
8externals/CMakeLists.txt
-
13externals/inih/CMakeLists.txt
-
1externals/inih/inih
-
1externals/simpleini
-
1src/CMakeLists.txt
-
1src/android/app/build.gradle.kts
-
2src/android/app/src/main/java/org/yuzu/yuzu_emu/NativeLibrary.kt
-
4src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/model/Settings.kt
-
4src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/ui/SettingsActivity.kt
-
42src/android/app/src/main/java/org/yuzu/yuzu_emu/features/settings/utils/SettingsFile.kt
-
2src/android/app/src/main/java/org/yuzu/yuzu_emu/ui/main/MainActivity.kt
-
1src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/DirectoryInitialization.kt
-
24src/android/app/src/main/java/org/yuzu/yuzu_emu/utils/NativeConfig.kt
-
11src/android/app/src/main/jni/CMakeLists.txt
-
70src/android/app/src/main/jni/android_config.cpp
-
41src/android/app/src/main/jni/android_config.h
-
2src/android/app/src/main/jni/android_settings.cpp
-
0src/android/app/src/main/jni/android_settings.h
-
330src/android/app/src/main/jni/config.cpp
-
47src/android/app/src/main/jni/config.h
-
511src/android/app/src/main/jni/default_ini.h
-
15src/android/app/src/main/jni/native.cpp
-
23src/android/app/src/main/jni/native_config.cpp
-
4src/common/settings.cpp
-
42src/common/settings.h
-
10src/frontend_common/CMakeLists.txt
-
1008src/frontend_common/config.cpp
-
210src/frontend_common/config.h
-
6src/yuzu/CMakeLists.txt
-
1309src/yuzu/configuration/config.cpp
-
179src/yuzu/configuration/config.h
-
2src/yuzu/configuration/configure_camera.cpp
-
1src/yuzu/configuration/configure_dialog.cpp
-
36src/yuzu/configuration/configure_hotkeys.cpp
-
6src/yuzu/configuration/configure_input_per_game.cpp
-
5src/yuzu/configuration/configure_input_per_game.h
-
11src/yuzu/configuration/configure_input_player.cpp
-
7src/yuzu/configuration/configure_per_game.cpp
-
5src/yuzu/configuration/configure_per_game.h
-
1src/yuzu/configuration/configure_per_game_addons.cpp
-
4src/yuzu/configuration/configure_ringcon.cpp
-
1src/yuzu/configuration/configure_system.cpp
-
2src/yuzu/configuration/configure_touchscreen_advanced.cpp
-
7src/yuzu/configuration/configure_ui.cpp
-
10src/yuzu/configuration/input_profiles.cpp
-
4src/yuzu/configuration/input_profiles.h
-
549src/yuzu/configuration/qt_config.cpp
-
55src/yuzu/configuration/qt_config.h
-
43src/yuzu/configuration/shared_translation.h
-
6src/yuzu/debugger/wait_tree.cpp
-
7src/yuzu/game_list.cpp
-
8src/yuzu/game_list_p.h
-
16src/yuzu/game_list_worker.cpp
-
28src/yuzu/hotkeys.cpp
-
16src/yuzu/hotkeys.h
-
112src/yuzu/main.cpp
-
7src/yuzu/main.h
-
65src/yuzu/uisettings.cpp
-
79src/yuzu/uisettings.h
-
9src/yuzu_cmd/CMakeLists.txt
-
279src/yuzu_cmd/config.cpp
-
38src/yuzu_cmd/config.h
-
553src/yuzu_cmd/default_ini.h
-
257src/yuzu_cmd/sdl_config.cpp
-
49src/yuzu_cmd/sdl_config.h
-
5src/yuzu_cmd/yuzu.cpp
@ -1,27 +0,0 @@ |
|||
# SPDX-FileCopyrightText: 2022 Alexandre Bouvier <contact@amb.tf> |
|||
# |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
find_package(PkgConfig QUIET) |
|||
pkg_search_module(INIH QUIET IMPORTED_TARGET inih) |
|||
if (INIReader IN_LIST inih_FIND_COMPONENTS) |
|||
pkg_search_module(INIREADER QUIET IMPORTED_TARGET INIReader) |
|||
if (INIREADER_FOUND) |
|||
set(inih_INIReader_FOUND TRUE) |
|||
endif() |
|||
endif() |
|||
|
|||
include(FindPackageHandleStandardArgs) |
|||
find_package_handle_standard_args(inih |
|||
REQUIRED_VARS INIH_LINK_LIBRARIES |
|||
VERSION_VAR INIH_VERSION |
|||
HANDLE_COMPONENTS |
|||
) |
|||
|
|||
if (inih_FOUND AND NOT TARGET inih::inih) |
|||
add_library(inih::inih ALIAS PkgConfig::INIH) |
|||
endif() |
|||
|
|||
if (inih_FOUND AND inih_INIReader_FOUND AND NOT TARGET inih::INIReader) |
|||
add_library(inih::INIReader ALIAS PkgConfig::INIREADER) |
|||
endif() |
|||
@ -1,13 +0,0 @@ |
|||
# SPDX-FileCopyrightText: 2014 Gui Andrade <admin@archshift.com> |
|||
# SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
add_library(inih |
|||
inih/ini.c |
|||
inih/ini.h |
|||
inih/cpp/INIReader.cpp |
|||
inih/cpp/INIReader.h |
|||
) |
|||
|
|||
create_target_directory_groups(inih) |
|||
target_include_directories(inih INTERFACE inih/cpp) |
|||
add_library(inih::INIReader ALIAS inih) |
|||
@ -0,0 +1,70 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "android_config.h"
|
|||
#include "android_settings.h"
|
|||
#include "common/settings_setting.h"
|
|||
|
|||
AndroidConfig::AndroidConfig(const std::string& config_name, ConfigType config_type) |
|||
: Config(config_type) { |
|||
Initialize(config_name); |
|||
if (config_type != ConfigType::InputProfile) { |
|||
ReadAndroidValues(); |
|||
SaveAndroidValues(); |
|||
} |
|||
} |
|||
|
|||
AndroidConfig::~AndroidConfig() { |
|||
if (global) { |
|||
AndroidConfig::SaveAllValues(); |
|||
} |
|||
} |
|||
|
|||
void AndroidConfig::ReloadAllValues() { |
|||
Reload(); |
|||
ReadAndroidValues(); |
|||
SaveAndroidValues(); |
|||
} |
|||
|
|||
void AndroidConfig::SaveAllValues() { |
|||
Save(); |
|||
SaveAndroidValues(); |
|||
} |
|||
|
|||
void AndroidConfig::ReadAndroidValues() { |
|||
if (global) { |
|||
ReadAndroidUIValues(); |
|||
} |
|||
} |
|||
|
|||
void AndroidConfig::ReadAndroidUIValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Android)); |
|||
|
|||
ReadCategory(Settings::Category::Android); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void AndroidConfig::SaveAndroidValues() { |
|||
if (global) { |
|||
SaveAndroidUIValues(); |
|||
} |
|||
|
|||
WriteToIni(); |
|||
} |
|||
|
|||
void AndroidConfig::SaveAndroidUIValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Android)); |
|||
|
|||
WriteCategory(Settings::Category::Android); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
std::vector<Settings::BasicSetting*>& AndroidConfig::FindRelevantList(Settings::Category category) { |
|||
auto& map = Settings::values.linkage.by_category; |
|||
if (map.contains(category)) { |
|||
return Settings::values.linkage.by_category[category]; |
|||
} |
|||
return AndroidSettings::values.linkage.by_category[category]; |
|||
} |
|||
@ -0,0 +1,41 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "frontend_common/config.h" |
|||
|
|||
class AndroidConfig final : public Config { |
|||
public: |
|||
explicit AndroidConfig(const std::string& config_name = "config", |
|||
ConfigType config_type = ConfigType::GlobalConfig); |
|||
~AndroidConfig() override; |
|||
|
|||
void ReloadAllValues() override; |
|||
void SaveAllValues() override; |
|||
|
|||
protected: |
|||
void ReadAndroidValues(); |
|||
void ReadAndroidUIValues(); |
|||
void ReadHidbusValues() override {} |
|||
void ReadDebugControlValues() override {} |
|||
void ReadPathValues() override {} |
|||
void ReadShortcutValues() override {} |
|||
void ReadUIValues() override {} |
|||
void ReadUIGamelistValues() override {} |
|||
void ReadUILayoutValues() override {} |
|||
void ReadMultiplayerValues() override {} |
|||
|
|||
void SaveAndroidValues(); |
|||
void SaveAndroidUIValues(); |
|||
void SaveHidbusValues() override {} |
|||
void SaveDebugControlValues() override {} |
|||
void SavePathValues() override {} |
|||
void SaveShortcutValues() override {} |
|||
void SaveUIValues() override {} |
|||
void SaveUIGamelistValues() override {} |
|||
void SaveUILayoutValues() override {} |
|||
void SaveMultiplayerValues() override {} |
|||
|
|||
std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) override; |
|||
}; |
|||
@ -1,7 +1,7 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "uisettings.h"
|
|||
#include "android_settings.h"
|
|||
|
|||
namespace AndroidSettings { |
|||
|
|||
@ -1,330 +0,0 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include <memory>
|
|||
#include <optional>
|
|||
#include <sstream>
|
|||
|
|||
#include <INIReader.h>
|
|||
#include "common/fs/file.h"
|
|||
#include "common/fs/fs.h"
|
|||
#include "common/fs/path_util.h"
|
|||
#include "common/logging/log.h"
|
|||
#include "common/settings.h"
|
|||
#include "common/settings_enums.h"
|
|||
#include "core/hle/service/acc/profile_manager.h"
|
|||
#include "input_common/main.h"
|
|||
#include "jni/config.h"
|
|||
#include "jni/default_ini.h"
|
|||
#include "uisettings.h"
|
|||
|
|||
namespace FS = Common::FS; |
|||
|
|||
Config::Config(const std::string& config_name, ConfigType config_type) |
|||
: type(config_type), global{config_type == ConfigType::GlobalConfig} { |
|||
Initialize(config_name); |
|||
} |
|||
|
|||
Config::~Config() = default; |
|||
|
|||
bool Config::LoadINI(const std::string& default_contents, bool retry) { |
|||
void(FS::CreateParentDir(config_loc)); |
|||
config = std::make_unique<INIReader>(FS::PathToUTF8String(config_loc)); |
|||
const auto config_loc_str = FS::PathToUTF8String(config_loc); |
|||
if (config->ParseError() < 0) { |
|||
if (retry) { |
|||
LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", |
|||
config_loc_str); |
|||
|
|||
void(FS::CreateParentDir(config_loc)); |
|||
void(FS::WriteStringToFile(config_loc, FS::FileType::TextFile, default_contents)); |
|||
|
|||
config = std::make_unique<INIReader>(config_loc_str); |
|||
|
|||
return LoadINI(default_contents, false); |
|||
} |
|||
LOG_ERROR(Config, "Failed."); |
|||
return false; |
|||
} |
|||
LOG_INFO(Config, "Successfully loaded {}", config_loc_str); |
|||
return true; |
|||
} |
|||
|
|||
template <> |
|||
void Config::ReadSetting(const std::string& group, Settings::Setting<std::string>& setting) { |
|||
std::string setting_value = config->Get(group, setting.GetLabel(), setting.GetDefault()); |
|||
if (setting_value.empty()) { |
|||
setting_value = setting.GetDefault(); |
|||
} |
|||
setting = std::move(setting_value); |
|||
} |
|||
|
|||
template <> |
|||
void Config::ReadSetting(const std::string& group, Settings::Setting<bool>& setting) { |
|||
setting = config->GetBoolean(group, setting.GetLabel(), setting.GetDefault()); |
|||
} |
|||
|
|||
template <typename Type, bool ranged> |
|||
void Config::ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting) { |
|||
setting = static_cast<Type>( |
|||
config->GetInteger(group, setting.GetLabel(), static_cast<long>(setting.GetDefault()))); |
|||
} |
|||
|
|||
void Config::ReadValues() { |
|||
ReadSetting("ControlsGeneral", Settings::values.mouse_enabled); |
|||
ReadSetting("ControlsGeneral", Settings::values.touch_device); |
|||
ReadSetting("ControlsGeneral", Settings::values.keyboard_enabled); |
|||
ReadSetting("ControlsGeneral", Settings::values.debug_pad_enabled); |
|||
ReadSetting("ControlsGeneral", Settings::values.vibration_enabled); |
|||
ReadSetting("ControlsGeneral", Settings::values.enable_accurate_vibrations); |
|||
ReadSetting("ControlsGeneral", Settings::values.motion_enabled); |
|||
Settings::values.touchscreen.enabled = |
|||
config->GetBoolean("ControlsGeneral", "touch_enabled", true); |
|||
Settings::values.touchscreen.rotation_angle = |
|||
config->GetInteger("ControlsGeneral", "touch_angle", 0); |
|||
Settings::values.touchscreen.diameter_x = |
|||
config->GetInteger("ControlsGeneral", "touch_diameter_x", 15); |
|||
Settings::values.touchscreen.diameter_y = |
|||
config->GetInteger("ControlsGeneral", "touch_diameter_y", 15); |
|||
|
|||
int num_touch_from_button_maps = |
|||
config->GetInteger("ControlsGeneral", "touch_from_button_map", 0); |
|||
if (num_touch_from_button_maps > 0) { |
|||
for (int i = 0; i < num_touch_from_button_maps; ++i) { |
|||
Settings::TouchFromButtonMap map; |
|||
map.name = config->Get("ControlsGeneral", |
|||
std::string("touch_from_button_maps_") + std::to_string(i) + |
|||
std::string("_name"), |
|||
"default"); |
|||
const int num_touch_maps = config->GetInteger( |
|||
"ControlsGeneral", |
|||
std::string("touch_from_button_maps_") + std::to_string(i) + std::string("_count"), |
|||
0); |
|||
map.buttons.reserve(num_touch_maps); |
|||
|
|||
for (int j = 0; j < num_touch_maps; ++j) { |
|||
std::string touch_mapping = |
|||
config->Get("ControlsGeneral", |
|||
std::string("touch_from_button_maps_") + std::to_string(i) + |
|||
std::string("_bind_") + std::to_string(j), |
|||
""); |
|||
map.buttons.emplace_back(std::move(touch_mapping)); |
|||
} |
|||
|
|||
Settings::values.touch_from_button_maps.emplace_back(std::move(map)); |
|||
} |
|||
} else { |
|||
Settings::values.touch_from_button_maps.emplace_back( |
|||
Settings::TouchFromButtonMap{"default", {}}); |
|||
num_touch_from_button_maps = 1; |
|||
} |
|||
Settings::values.touch_from_button_map_index = std::clamp( |
|||
Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1); |
|||
|
|||
ReadSetting("ControlsGeneral", Settings::values.udp_input_servers); |
|||
|
|||
// Data Storage
|
|||
ReadSetting("Data Storage", Settings::values.use_virtual_sd); |
|||
FS::SetYuzuPath(FS::YuzuPath::NANDDir, |
|||
config->Get("Data Storage", "nand_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::NANDDir))); |
|||
FS::SetYuzuPath(FS::YuzuPath::SDMCDir, |
|||
config->Get("Data Storage", "sdmc_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::SDMCDir))); |
|||
FS::SetYuzuPath(FS::YuzuPath::LoadDir, |
|||
config->Get("Data Storage", "load_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::LoadDir))); |
|||
FS::SetYuzuPath(FS::YuzuPath::DumpDir, |
|||
config->Get("Data Storage", "dump_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::DumpDir))); |
|||
ReadSetting("Data Storage", Settings::values.gamecard_inserted); |
|||
ReadSetting("Data Storage", Settings::values.gamecard_current_game); |
|||
ReadSetting("Data Storage", Settings::values.gamecard_path); |
|||
|
|||
// System
|
|||
ReadSetting("System", Settings::values.current_user); |
|||
Settings::values.current_user = std::clamp<int>(Settings::values.current_user.GetValue(), 0, |
|||
Service::Account::MAX_USERS - 1); |
|||
|
|||
// Disable docked mode by default on Android
|
|||
Settings::values.use_docked_mode.SetValue(config->GetBoolean("System", "use_docked_mode", false) |
|||
? Settings::ConsoleMode::Docked |
|||
: Settings::ConsoleMode::Handheld); |
|||
|
|||
const auto rng_seed_enabled = config->GetBoolean("System", "rng_seed_enabled", false); |
|||
if (rng_seed_enabled) { |
|||
Settings::values.rng_seed.SetValue(config->GetInteger("System", "rng_seed", 0)); |
|||
} else { |
|||
Settings::values.rng_seed.SetValue(0); |
|||
} |
|||
Settings::values.rng_seed_enabled.SetValue(rng_seed_enabled); |
|||
|
|||
const auto custom_rtc_enabled = config->GetBoolean("System", "custom_rtc_enabled", false); |
|||
if (custom_rtc_enabled) { |
|||
Settings::values.custom_rtc = config->GetInteger("System", "custom_rtc", 0); |
|||
} else { |
|||
Settings::values.custom_rtc = 0; |
|||
} |
|||
Settings::values.custom_rtc_enabled = custom_rtc_enabled; |
|||
|
|||
ReadSetting("System", Settings::values.language_index); |
|||
ReadSetting("System", Settings::values.region_index); |
|||
ReadSetting("System", Settings::values.time_zone_index); |
|||
ReadSetting("System", Settings::values.sound_index); |
|||
|
|||
// Core
|
|||
ReadSetting("Core", Settings::values.use_multi_core); |
|||
ReadSetting("Core", Settings::values.memory_layout_mode); |
|||
|
|||
// Cpu
|
|||
ReadSetting("Cpu", Settings::values.cpu_accuracy); |
|||
ReadSetting("Cpu", Settings::values.cpu_debug_mode); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_page_tables); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_block_linking); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_return_stack_buffer); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_fast_dispatcher); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_context_elimination); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_const_prop); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_misc_ir); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_reduce_misalign_checks); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_fastmem); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_fastmem_exclusives); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_recompile_exclusives); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_ignore_memory_aborts); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_unfuse_fma); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_reduce_fp_error); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_standard_fpcr); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_inaccurate_nan); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_fastmem_check); |
|||
ReadSetting("Cpu", Settings::values.cpuopt_unsafe_ignore_global_monitor); |
|||
|
|||
// Renderer
|
|||
ReadSetting("Renderer", Settings::values.renderer_backend); |
|||
ReadSetting("Renderer", Settings::values.renderer_debug); |
|||
ReadSetting("Renderer", Settings::values.renderer_shader_feedback); |
|||
ReadSetting("Renderer", Settings::values.enable_nsight_aftermath); |
|||
ReadSetting("Renderer", Settings::values.disable_shader_loop_safety_checks); |
|||
ReadSetting("Renderer", Settings::values.vulkan_device); |
|||
|
|||
ReadSetting("Renderer", Settings::values.resolution_setup); |
|||
ReadSetting("Renderer", Settings::values.scaling_filter); |
|||
ReadSetting("Renderer", Settings::values.fsr_sharpening_slider); |
|||
ReadSetting("Renderer", Settings::values.anti_aliasing); |
|||
ReadSetting("Renderer", Settings::values.fullscreen_mode); |
|||
ReadSetting("Renderer", Settings::values.aspect_ratio); |
|||
ReadSetting("Renderer", Settings::values.max_anisotropy); |
|||
ReadSetting("Renderer", Settings::values.use_speed_limit); |
|||
ReadSetting("Renderer", Settings::values.speed_limit); |
|||
ReadSetting("Renderer", Settings::values.use_disk_shader_cache); |
|||
ReadSetting("Renderer", Settings::values.use_asynchronous_gpu_emulation); |
|||
ReadSetting("Renderer", Settings::values.vsync_mode); |
|||
ReadSetting("Renderer", Settings::values.shader_backend); |
|||
ReadSetting("Renderer", Settings::values.use_asynchronous_shaders); |
|||
ReadSetting("Renderer", Settings::values.nvdec_emulation); |
|||
ReadSetting("Renderer", Settings::values.use_fast_gpu_time); |
|||
ReadSetting("Renderer", Settings::values.use_vulkan_driver_pipeline_cache); |
|||
|
|||
ReadSetting("Renderer", Settings::values.bg_red); |
|||
ReadSetting("Renderer", Settings::values.bg_green); |
|||
ReadSetting("Renderer", Settings::values.bg_blue); |
|||
|
|||
// Use GPU accuracy normal by default on Android
|
|||
Settings::values.gpu_accuracy = static_cast<Settings::GpuAccuracy>(config->GetInteger( |
|||
"Renderer", "gpu_accuracy", static_cast<u32>(Settings::GpuAccuracy::Normal))); |
|||
|
|||
// Use GPU default anisotropic filtering on Android
|
|||
Settings::values.max_anisotropy = |
|||
static_cast<Settings::AnisotropyMode>(config->GetInteger("Renderer", "max_anisotropy", 1)); |
|||
|
|||
// Disable ASTC compute by default on Android
|
|||
Settings::values.accelerate_astc.SetValue( |
|||
config->GetBoolean("Renderer", "accelerate_astc", false) ? Settings::AstcDecodeMode::Gpu |
|||
: Settings::AstcDecodeMode::Cpu); |
|||
|
|||
// Enable asynchronous presentation by default on Android
|
|||
Settings::values.async_presentation = |
|||
config->GetBoolean("Renderer", "async_presentation", true); |
|||
|
|||
// Disable force_max_clock by default on Android
|
|||
Settings::values.renderer_force_max_clock = |
|||
config->GetBoolean("Renderer", "force_max_clock", false); |
|||
|
|||
// Disable use_reactive_flushing by default on Android
|
|||
Settings::values.use_reactive_flushing = |
|||
config->GetBoolean("Renderer", "use_reactive_flushing", false); |
|||
|
|||
// Audio
|
|||
ReadSetting("Audio", Settings::values.sink_id); |
|||
ReadSetting("Audio", Settings::values.audio_output_device_id); |
|||
ReadSetting("Audio", Settings::values.volume); |
|||
|
|||
// Miscellaneous
|
|||
// log_filter has a different default here than from common
|
|||
Settings::values.log_filter = "*:Info"; |
|||
ReadSetting("Miscellaneous", Settings::values.use_dev_keys); |
|||
|
|||
// Debugging
|
|||
Settings::values.record_frame_times = |
|||
config->GetBoolean("Debugging", "record_frame_times", false); |
|||
ReadSetting("Debugging", Settings::values.dump_exefs); |
|||
ReadSetting("Debugging", Settings::values.dump_nso); |
|||
ReadSetting("Debugging", Settings::values.enable_fs_access_log); |
|||
ReadSetting("Debugging", Settings::values.reporting_services); |
|||
ReadSetting("Debugging", Settings::values.quest_flag); |
|||
ReadSetting("Debugging", Settings::values.use_debug_asserts); |
|||
ReadSetting("Debugging", Settings::values.use_auto_stub); |
|||
ReadSetting("Debugging", Settings::values.disable_macro_jit); |
|||
ReadSetting("Debugging", Settings::values.disable_macro_hle); |
|||
ReadSetting("Debugging", Settings::values.use_gdbstub); |
|||
ReadSetting("Debugging", Settings::values.gdbstub_port); |
|||
|
|||
const auto title_list = config->Get("AddOns", "title_ids", ""); |
|||
std::stringstream ss(title_list); |
|||
std::string line; |
|||
while (std::getline(ss, line, '|')) { |
|||
const auto title_id = std::strtoul(line.c_str(), nullptr, 16); |
|||
const auto disabled_list = config->Get("AddOns", "disabled_" + line, ""); |
|||
|
|||
std::stringstream inner_ss(disabled_list); |
|||
std::string inner_line; |
|||
std::vector<std::string> out; |
|||
while (std::getline(inner_ss, inner_line, '|')) { |
|||
out.push_back(inner_line); |
|||
} |
|||
|
|||
Settings::values.disabled_addons.insert_or_assign(title_id, out); |
|||
} |
|||
|
|||
// Web Service
|
|||
ReadSetting("WebService", Settings::values.enable_telemetry); |
|||
ReadSetting("WebService", Settings::values.web_api_url); |
|||
ReadSetting("WebService", Settings::values.yuzu_username); |
|||
ReadSetting("WebService", Settings::values.yuzu_token); |
|||
|
|||
// Network
|
|||
ReadSetting("Network", Settings::values.network_interface); |
|||
|
|||
// Android
|
|||
ReadSetting("Android", AndroidSettings::values.picture_in_picture); |
|||
ReadSetting("Android", AndroidSettings::values.screen_layout); |
|||
} |
|||
|
|||
void Config::Initialize(const std::string& config_name) { |
|||
const auto fs_config_loc = FS::GetYuzuPath(FS::YuzuPath::ConfigDir); |
|||
const auto config_file = fmt::format("{}.ini", config_name); |
|||
|
|||
switch (type) { |
|||
case ConfigType::GlobalConfig: |
|||
config_loc = FS::PathToUTF8String(fs_config_loc / config_file); |
|||
break; |
|||
case ConfigType::PerGameConfig: |
|||
config_loc = FS::PathToUTF8String(fs_config_loc / "custom" / FS::ToU8String(config_file)); |
|||
break; |
|||
case ConfigType::InputProfile: |
|||
config_loc = FS::PathToUTF8String(fs_config_loc / "input" / config_file); |
|||
LoadINI(DefaultINI::android_config_file); |
|||
return; |
|||
} |
|||
LoadINI(DefaultINI::android_config_file); |
|||
ReadValues(); |
|||
} |
|||
@ -1,47 +0,0 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <filesystem> |
|||
#include <memory> |
|||
#include <optional> |
|||
#include <string> |
|||
|
|||
#include "common/settings.h" |
|||
|
|||
class INIReader; |
|||
|
|||
class Config { |
|||
bool LoadINI(const std::string& default_contents = "", bool retry = true); |
|||
|
|||
public: |
|||
enum class ConfigType { |
|||
GlobalConfig, |
|||
PerGameConfig, |
|||
InputProfile, |
|||
}; |
|||
|
|||
explicit Config(const std::string& config_name = "config", |
|||
ConfigType config_type = ConfigType::GlobalConfig); |
|||
~Config(); |
|||
|
|||
void Initialize(const std::string& config_name); |
|||
|
|||
private: |
|||
/** |
|||
* Applies a value read from the config to a Setting. |
|||
* |
|||
* @param group The name of the INI group |
|||
* @param setting The yuzu setting to modify |
|||
*/ |
|||
template <typename Type, bool ranged> |
|||
void ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting); |
|||
|
|||
void ReadValues(); |
|||
|
|||
const ConfigType type; |
|||
std::unique_ptr<INIReader> config; |
|||
std::string config_loc; |
|||
const bool global; |
|||
}; |
|||
@ -1,511 +0,0 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
namespace DefaultINI { |
|||
|
|||
const char* android_config_file = R"( |
|||
|
|||
[ControlsP0] |
|||
# The input devices and parameters for each Switch native input |
|||
# The config section determines the player number where the config will be applied on. For example "ControlsP0", "ControlsP1", ... |
|||
# It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..." |
|||
# Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values |
|||
|
|||
# Indicates if this player should be connected at boot |
|||
connected= |
|||
|
|||
# for button input, the following devices are available: |
|||
# - "keyboard" (default) for keyboard input. Required parameters: |
|||
# - "code": the code of the key to bind |
|||
# - "sdl" for joystick input using SDL. Required parameters: |
|||
# - "guid": SDL identification GUID of the joystick |
|||
# - "port": the index of the joystick to bind |
|||
# - "button"(optional): the index of the button to bind |
|||
# - "hat"(optional): the index of the hat to bind as direction buttons |
|||
# - "axis"(optional): the index of the axis to bind |
|||
# - "direction"(only used for hat): the direction name of the hat to bind. Can be "up", "down", "left" or "right" |
|||
# - "threshold"(only used for axis): a float value in (-1.0, 1.0) which the button is |
|||
# triggered if the axis value crosses |
|||
# - "direction"(only used for axis): "+" means the button is triggered when the axis value |
|||
# is greater than the threshold; "-" means the button is triggered when the axis value |
|||
# is smaller than the threshold |
|||
button_a= |
|||
button_b= |
|||
button_x= |
|||
button_y= |
|||
button_lstick= |
|||
button_rstick= |
|||
button_l= |
|||
button_r= |
|||
button_zl= |
|||
button_zr= |
|||
button_plus= |
|||
button_minus= |
|||
button_dleft= |
|||
button_dup= |
|||
button_dright= |
|||
button_ddown= |
|||
button_lstick_left= |
|||
button_lstick_up= |
|||
button_lstick_right= |
|||
button_lstick_down= |
|||
button_sl= |
|||
button_sr= |
|||
button_home= |
|||
button_screenshot= |
|||
|
|||
# for analog input, the following devices are available: |
|||
# - "analog_from_button" (default) for emulating analog input from direction buttons. Required parameters: |
|||
# - "up", "down", "left", "right": sub-devices for each direction. |
|||
# Should be in the format as a button input devices using escape characters, for example, "engine$0keyboard$1code$00" |
|||
# - "modifier": sub-devices as a modifier. |
|||
# - "modifier_scale": a float number representing the applied modifier scale to the analog input. |
|||
# Must be in range of 0.0-1.0. Defaults to 0.5 |
|||
# - "sdl" for joystick input using SDL. Required parameters: |
|||
# - "guid": SDL identification GUID of the joystick |
|||
# - "port": the index of the joystick to bind |
|||
# - "axis_x": the index of the axis to bind as x-axis (default to 0) |
|||
# - "axis_y": the index of the axis to bind as y-axis (default to 1) |
|||
lstick= |
|||
rstick= |
|||
|
|||
# for motion input, the following devices are available: |
|||
# - "keyboard" (default) for emulating random motion input from buttons. Required parameters: |
|||
# - "code": the code of the key to bind |
|||
# - "sdl" for motion input using SDL. Required parameters: |
|||
# - "guid": SDL identification GUID of the joystick |
|||
# - "port": the index of the joystick to bind |
|||
# - "motion": the index of the motion sensor to bind |
|||
# - "cemuhookudp" for motion input using Cemu Hook protocol. Required parameters: |
|||
# - "guid": the IP address of the cemu hook server encoded to a hex string. for example 192.168.0.1 = "c0a80001" |
|||
# - "port": the port of the cemu hook server |
|||
# - "pad": the index of the joystick |
|||
# - "motion": the index of the motion sensor of the joystick to bind |
|||
motionleft= |
|||
motionright= |
|||
|
|||
[ControlsGeneral] |
|||
# To use the debug_pad, prepend `debug_pad_` before each button setting above. |
|||
# i.e. debug_pad_button_a= |
|||
|
|||
# Enable debug pad inputs to the guest |
|||
# 0 (default): Disabled, 1: Enabled |
|||
debug_pad_enabled = |
|||
|
|||
# Whether to enable or disable vibration |
|||
# 0: Disabled, 1 (default): Enabled |
|||
vibration_enabled= |
|||
|
|||
# Whether to enable or disable accurate vibrations |
|||
# 0 (default): Disabled, 1: Enabled |
|||
enable_accurate_vibrations= |
|||
|
|||
# Enables controller motion inputs |
|||
# 0: Disabled, 1 (default): Enabled |
|||
motion_enabled = |
|||
|
|||
# Defines the udp device's touch screen coordinate system for cemuhookudp devices |
|||
# - "min_x", "min_y", "max_x", "max_y" |
|||
touch_device= |
|||
|
|||
# for mapping buttons to touch inputs. |
|||
#touch_from_button_map=1 |
|||
#touch_from_button_maps_0_name=default |
|||
#touch_from_button_maps_0_count=2 |
|||
#touch_from_button_maps_0_bind_0=foo |
|||
#touch_from_button_maps_0_bind_1=bar |
|||
# etc. |
|||
|
|||
# List of Cemuhook UDP servers, delimited by ','. |
|||
# Default: 127.0.0.1:26760 |
|||
# Example: 127.0.0.1:26760,123.4.5.67:26761 |
|||
udp_input_servers = |
|||
|
|||
# Enable controlling an axis via a mouse input. |
|||
# 0 (default): Off, 1: On |
|||
mouse_panning = |
|||
|
|||
# Set mouse sensitivity. |
|||
# Default: 1.0 |
|||
mouse_panning_sensitivity = |
|||
|
|||
# Emulate an analog control stick from keyboard inputs. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
emulate_analog_keyboard = |
|||
|
|||
# Enable mouse inputs to the guest |
|||
# 0 (default): Disabled, 1: Enabled |
|||
mouse_enabled = |
|||
|
|||
# Enable keyboard inputs to the guest |
|||
# 0 (default): Disabled, 1: Enabled |
|||
keyboard_enabled = |
|||
|
|||
[Core] |
|||
# Whether to use multi-core for CPU emulation |
|||
# 0: Disabled, 1 (default): Enabled |
|||
use_multi_core = |
|||
|
|||
# Enable unsafe extended guest system memory layout (8GB DRAM) |
|||
# 0 (default): Disabled, 1: Enabled |
|||
use_unsafe_extended_memory_layout = |
|||
|
|||
[Cpu] |
|||
# Adjusts various optimizations. |
|||
# Auto-select mode enables choice unsafe optimizations. |
|||
# Accurate enables only safe optimizations. |
|||
# Unsafe allows any unsafe optimizations. |
|||
# 0 (default): Auto-select, 1: Accurate, 2: Enable unsafe optimizations |
|||
cpu_accuracy = |
|||
|
|||
# Allow disabling safe optimizations. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
cpu_debug_mode = |
|||
|
|||
# Enable inline page tables optimization (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_page_tables = |
|||
|
|||
# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_block_linking = |
|||
|
|||
# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_return_stack_buffer = |
|||
|
|||
# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_fast_dispatcher = |
|||
|
|||
# Enable context elimination CPU Optimization (reduce host memory use for guest context) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_context_elimination = |
|||
|
|||
# Enable constant propagation CPU optimization (basic IR optimization) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_const_prop = |
|||
|
|||
# Enable miscellaneous CPU optimizations (basic IR optimization) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_misc_ir = |
|||
|
|||
# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_reduce_misalign_checks = |
|||
|
|||
# Enable Host MMU Emulation (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_fastmem = |
|||
|
|||
# Enable Host MMU Emulation for exclusive memory instructions (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_fastmem_exclusives = |
|||
|
|||
# Enable fallback on failure of fastmem of exclusive memory instructions (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_recompile_exclusives = |
|||
|
|||
# Enable optimization to ignore invalid memory accesses (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_ignore_memory_aborts = |
|||
|
|||
# Enable unfuse FMA (improve performance on CPUs without FMA) |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_unfuse_fma = |
|||
|
|||
# Enable faster FRSQRTE and FRECPE |
|||
# Only enabled if cpu_accuracy is set to Unsafe. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_reduce_fp_error = |
|||
|
|||
# Enable faster ASIMD instructions (32 bits only) |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_ignore_standard_fpcr = |
|||
|
|||
# Enable inaccurate NaN handling |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_inaccurate_nan = |
|||
|
|||
# Disable address space checks (64 bits only) |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_fastmem_check = |
|||
|
|||
# Enable faster exclusive instructions |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_ignore_global_monitor = |
|||
|
|||
[Renderer] |
|||
# Which backend API to use. |
|||
# 0: OpenGL (unsupported), 1 (default): Vulkan, 2: Null |
|||
backend = |
|||
|
|||
# Whether to enable asynchronous presentation (Vulkan only) |
|||
# 0: Off, 1 (default): On |
|||
async_presentation = |
|||
|
|||
# Forces the GPU to run at the maximum possible clocks (thermal constraints will still be applied). |
|||
# 0 (default): Disabled, 1: Enabled |
|||
force_max_clock = |
|||
|
|||
# Enable graphics API debugging mode. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
debug = |
|||
|
|||
# Enable shader feedback. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
renderer_shader_feedback = |
|||
|
|||
# Enable Nsight Aftermath crash dumps |
|||
# 0 (default): Disabled, 1: Enabled |
|||
nsight_aftermath = |
|||
|
|||
# Disable shader loop safety checks, executing the shader without loop logic changes |
|||
# 0 (default): Disabled, 1: Enabled |
|||
disable_shader_loop_safety_checks = |
|||
|
|||
# Which Vulkan physical device to use (defaults to 0) |
|||
vulkan_device = |
|||
|
|||
# 0: 0.5x (360p/540p) [EXPERIMENTAL] |
|||
# 1: 0.75x (540p/810p) [EXPERIMENTAL] |
|||
# 2 (default): 1x (720p/1080p) |
|||
# 3: 2x (1440p/2160p) |
|||
# 4: 3x (2160p/3240p) |
|||
# 5: 4x (2880p/4320p) |
|||
# 6: 5x (3600p/5400p) |
|||
# 7: 6x (4320p/6480p) |
|||
resolution_setup = |
|||
|
|||
# Pixel filter to use when up- or down-sampling rendered frames. |
|||
# 0: Nearest Neighbor |
|||
# 1 (default): Bilinear |
|||
# 2: Bicubic |
|||
# 3: Gaussian |
|||
# 4: ScaleForce |
|||
# 5: AMD FidelityFX™️ Super Resolution [Vulkan Only] |
|||
scaling_filter = |
|||
|
|||
# Anti-Aliasing (AA) |
|||
# 0 (default): None, 1: FXAA |
|||
anti_aliasing = |
|||
|
|||
# Whether to use fullscreen or borderless window mode |
|||
# 0 (Windows default): Borderless window, 1 (All other default): Exclusive fullscreen |
|||
fullscreen_mode = |
|||
|
|||
# Aspect ratio |
|||
# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Force 16:10, 4: Stretch to Window |
|||
aspect_ratio = |
|||
|
|||
# Anisotropic filtering |
|||
# 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x |
|||
max_anisotropy = |
|||
|
|||
# Whether to enable VSync or not. |
|||
# OpenGL: Values other than 0 enable VSync |
|||
# Vulkan: FIFO is selected if the requested mode is not supported by the driver. |
|||
# FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh rate. |
|||
# FIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down. |
|||
# Mailbox can have lower latency than FIFO and does not tear but may drop frames. |
|||
# Immediate (no synchronization) just presents whatever is available and can exhibit tearing. |
|||
# 0: Immediate (Off), 1 (Default): Mailbox (On), 2: FIFO, 3: FIFO Relaxed |
|||
use_vsync = |
|||
|
|||
# Selects the OpenGL shader backend. NV_gpu_program5 is required for GLASM. If NV_gpu_program5 is |
|||
# not available and GLASM is selected, GLSL will be used. |
|||
# 0: GLSL, 1 (default): GLASM, 2: SPIR-V |
|||
shader_backend = |
|||
|
|||
# Whether to allow asynchronous shader building. |
|||
# 0 (default): Off, 1: On |
|||
use_asynchronous_shaders = |
|||
|
|||
# Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory. |
|||
# 0 (default): Off, 1: On |
|||
use_reactive_flushing = |
|||
|
|||
# NVDEC emulation. |
|||
# 0: Disabled, 1: CPU Decoding, 2 (default): GPU Decoding |
|||
nvdec_emulation = |
|||
|
|||
# Accelerate ASTC texture decoding. |
|||
# 0 (default): Off, 1: On |
|||
accelerate_astc = |
|||
|
|||
# Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value |
|||
# 0: Off, 1: On (default) |
|||
use_speed_limit = |
|||
|
|||
# Limits the speed of the game to run no faster than this value as a percentage of target speed |
|||
# 1 - 9999: Speed limit as a percentage of target game speed. 100 (default) |
|||
speed_limit = |
|||
|
|||
# Whether to use disk based shader cache |
|||
# 0: Off, 1 (default): On |
|||
use_disk_shader_cache = |
|||
|
|||
# Which gpu accuracy level to use |
|||
# 0 (default): Normal, 1: High, 2: Extreme (Very slow) |
|||
gpu_accuracy = |
|||
|
|||
# Whether to use asynchronous GPU emulation |
|||
# 0 : Off (slow), 1 (default): On (fast) |
|||
use_asynchronous_gpu_emulation = |
|||
|
|||
# Inform the guest that GPU operations completed more quickly than they did. |
|||
# 0: Off, 1 (default): On |
|||
use_fast_gpu_time = |
|||
|
|||
# Force unmodified buffers to be flushed, which can cost performance. |
|||
# 0: Off (default), 1: On |
|||
use_pessimistic_flushes = |
|||
|
|||
# Whether to use garbage collection or not for GPU caches. |
|||
# 0 (default): Off, 1: On |
|||
use_caches_gc = |
|||
|
|||
# The clear color for the renderer. What shows up on the sides of the bottom screen. |
|||
# Must be in range of 0-255. Defaults to 0 for all. |
|||
bg_red = |
|||
bg_blue = |
|||
bg_green = |
|||
|
|||
[Audio] |
|||
# Which audio output engine to use. |
|||
# auto (default): Auto-select |
|||
# cubeb: Cubeb audio engine (if available) |
|||
# sdl2: SDL2 audio engine (if available) |
|||
# null: No audio output |
|||
output_engine = |
|||
|
|||
# Which audio device to use. |
|||
# auto (default): Auto-select |
|||
output_device = |
|||
|
|||
# Output volume. |
|||
# 100 (default): 100%, 0; mute |
|||
volume = |
|||
|
|||
[Data Storage] |
|||
# Whether to create a virtual SD card. |
|||
# 1: Yes, 0 (default): No |
|||
use_virtual_sd = |
|||
|
|||
# Whether or not to enable gamecard emulation |
|||
# 1: Yes, 0 (default): No |
|||
gamecard_inserted = |
|||
|
|||
# Whether or not the gamecard should be emulated as the current game |
|||
# If 'gamecard_inserted' is 0 this setting is irrelevant |
|||
# 1: Yes, 0 (default): No |
|||
gamecard_current_game = |
|||
|
|||
# Path to an XCI file to use as the gamecard |
|||
# If 'gamecard_inserted' is 0 this setting is irrelevant |
|||
# If 'gamecard_current_game' is 1 this setting is irrelevant |
|||
gamecard_path = |
|||
|
|||
[System] |
|||
# Whether the system is docked |
|||
# 1 (default): Yes, 0: No |
|||
use_docked_mode = |
|||
|
|||
# Sets the seed for the RNG generator built into the switch |
|||
# rng_seed will be ignored and randomly generated if rng_seed_enabled is false |
|||
rng_seed_enabled = |
|||
rng_seed = |
|||
|
|||
# Sets the current time (in seconds since 12:00 AM Jan 1, 1970) that will be used by the time service |
|||
# This will auto-increment, with the time set being the time the game is started |
|||
# This override will only occur if custom_rtc_enabled is true, otherwise the current time is used |
|||
custom_rtc_enabled = |
|||
custom_rtc = |
|||
|
|||
# Sets the systems language index |
|||
# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese, |
|||
# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French, |
|||
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Brazilian Portuguese |
|||
language_index = |
|||
|
|||
# The system region that yuzu will use during emulation |
|||
# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan |
|||
region_index = |
|||
|
|||
# The system time zone that yuzu will use during emulation |
|||
# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone |
|||
time_zone_index = |
|||
|
|||
# Sets the sound output mode. |
|||
# 0: Mono, 1 (default): Stereo, 2: Surround |
|||
sound_index = |
|||
|
|||
[Miscellaneous] |
|||
# A filter which removes logs below a certain logging level. |
|||
# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical |
|||
log_filter = *:Trace |
|||
|
|||
# Use developer keys |
|||
# 0 (default): Disabled, 1: Enabled |
|||
use_dev_keys = |
|||
|
|||
[Debugging] |
|||
# Record frame time data, can be found in the log directory. Boolean value |
|||
record_frame_times = |
|||
# Determines whether or not yuzu will dump the ExeFS of all games it attempts to load while loading them |
|||
dump_exefs=false |
|||
# Determines whether or not yuzu will dump all NSOs it attempts to load while loading them |
|||
dump_nso=false |
|||
# Determines whether or not yuzu will save the filesystem access log. |
|||
enable_fs_access_log=false |
|||
# Enables verbose reporting services |
|||
reporting_services = |
|||
# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode |
|||
# false: Retail/Normal Mode (default), true: Kiosk Mode |
|||
quest_flag = |
|||
# Determines whether debug asserts should be enabled, which will throw an exception on asserts. |
|||
# false: Disabled (default), true: Enabled |
|||
use_debug_asserts = |
|||
# Determines whether unimplemented HLE service calls should be automatically stubbed. |
|||
# false: Disabled (default), true: Enabled |
|||
use_auto_stub = |
|||
# Enables/Disables the macro JIT compiler |
|||
disable_macro_jit=false |
|||
# Determines whether to enable the GDB stub and wait for the debugger to attach before running. |
|||
# false: Disabled (default), true: Enabled |
|||
use_gdbstub=false |
|||
# The port to use for the GDB server, if it is enabled. |
|||
gdbstub_port=6543 |
|||
|
|||
[WebService] |
|||
# Whether or not to enable telemetry |
|||
# 0: No, 1 (default): Yes |
|||
enable_telemetry = |
|||
# URL for Web API |
|||
web_api_url = https://api.yuzu-emu.org |
|||
# Username and token for yuzu Web Service |
|||
# See https://profile.yuzu-emu.org/ for more info |
|||
yuzu_username = |
|||
yuzu_token = |
|||
|
|||
[Network] |
|||
# Name of the network interface device to use with yuzu LAN play. |
|||
# e.g. On *nix: 'enp7s0', 'wlp6s0u1u3u3', 'lo' |
|||
# e.g. On Windows: 'Ethernet', 'Wi-Fi' |
|||
network_interface = |
|||
|
|||
[AddOns] |
|||
# Used to disable add-ons |
|||
# List of title IDs of games that will have add-ons disabled (separated by '|'): |
|||
title_ids = |
|||
# 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 '|') |
|||
# e.x. disabled_0100000000010000 = Update|DLC <- disables Updates and DLC on Super Mario Odyssey |
|||
)"; |
|||
} // namespace DefaultINI |
|||
@ -0,0 +1,10 @@ |
|||
# SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
# SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
add_library(frontend_common STATIC |
|||
config.cpp |
|||
config.h |
|||
) |
|||
|
|||
create_target_directory_groups(frontend_common) |
|||
target_link_libraries(frontend_common PUBLIC core SimpleIni PRIVATE common Boost::headers) |
|||
1008
src/frontend_common/config.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,210 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <memory> |
|||
#include <string> |
|||
#include "common/settings.h" |
|||
|
|||
#include <SimpleIni.h> |
|||
#include <boost/algorithm/string/replace.hpp> |
|||
|
|||
// Workaround for conflicting definition in libloaderapi.h caused by SimpleIni |
|||
#undef LoadString |
|||
#undef CreateFile |
|||
#undef DeleteFile |
|||
#undef CopyFile |
|||
#undef CreateDirectory |
|||
#undef MoveFile |
|||
|
|||
namespace Core { |
|||
class System; |
|||
} |
|||
|
|||
class Config { |
|||
public: |
|||
enum class ConfigType { |
|||
GlobalConfig, |
|||
PerGameConfig, |
|||
InputProfile, |
|||
}; |
|||
|
|||
virtual ~Config() = default; |
|||
|
|||
void ClearControlPlayerValues() const; |
|||
|
|||
[[nodiscard]] const std::string& GetConfigFilePath() const; |
|||
|
|||
[[nodiscard]] bool Exists(const std::string& section, const std::string& key) const; |
|||
|
|||
protected: |
|||
explicit Config(ConfigType config_type = ConfigType::GlobalConfig); |
|||
|
|||
void Initialize(const std::string& config_name = "config"); |
|||
void Initialize(std::optional<std::string> config_path); |
|||
|
|||
void WriteToIni() const; |
|||
|
|||
void SetUpIni(); |
|||
[[nodiscard]] bool IsCustomConfig() const; |
|||
|
|||
void Reload(); |
|||
void Save(); |
|||
|
|||
/** |
|||
* Derived config classes must implement this so they can reload all platform-specific |
|||
* values and global ones. |
|||
*/ |
|||
virtual void ReloadAllValues() = 0; |
|||
|
|||
/** |
|||
* Derived config classes must implement this so they can save all platform-specific |
|||
* and global values. |
|||
*/ |
|||
virtual void SaveAllValues() = 0; |
|||
|
|||
void ReadValues(); |
|||
void ReadPlayerValues(std::size_t player_index); |
|||
|
|||
void ReadTouchscreenValues(); |
|||
void ReadMotionTouchValues(); |
|||
|
|||
// Read functions bases off the respective config section names. |
|||
void ReadAudioValues(); |
|||
void ReadControlValues(); |
|||
void ReadCoreValues(); |
|||
void ReadDataStorageValues(); |
|||
void ReadDebuggingValues(); |
|||
void ReadServiceValues(); |
|||
void ReadDisabledAddOnValues(); |
|||
void ReadMiscellaneousValues(); |
|||
void ReadCpuValues(); |
|||
void ReadRendererValues(); |
|||
void ReadScreenshotValues(); |
|||
void ReadSystemValues(); |
|||
void ReadWebServiceValues(); |
|||
void ReadNetworkValues(); |
|||
|
|||
// Read platform specific sections |
|||
virtual void ReadHidbusValues() = 0; |
|||
virtual void ReadDebugControlValues() = 0; |
|||
virtual void ReadPathValues() = 0; |
|||
virtual void ReadShortcutValues() = 0; |
|||
virtual void ReadUIValues() = 0; |
|||
virtual void ReadUIGamelistValues() = 0; |
|||
virtual void ReadUILayoutValues() = 0; |
|||
virtual void ReadMultiplayerValues() = 0; |
|||
|
|||
void SaveValues(); |
|||
void SavePlayerValues(std::size_t player_index); |
|||
void SaveTouchscreenValues(); |
|||
void SaveMotionTouchValues(); |
|||
|
|||
// Save functions based off the respective config section names. |
|||
void SaveAudioValues(); |
|||
void SaveControlValues(); |
|||
void SaveCoreValues(); |
|||
void SaveDataStorageValues(); |
|||
void SaveDebuggingValues(); |
|||
void SaveNetworkValues(); |
|||
void SaveDisabledAddOnValues(); |
|||
void SaveMiscellaneousValues(); |
|||
void SaveCpuValues(); |
|||
void SaveRendererValues(); |
|||
void SaveScreenshotValues(); |
|||
void SaveSystemValues(); |
|||
void SaveWebServiceValues(); |
|||
|
|||
// Save platform specific sections |
|||
virtual void SaveHidbusValues() = 0; |
|||
virtual void SaveDebugControlValues() = 0; |
|||
virtual void SavePathValues() = 0; |
|||
virtual void SaveShortcutValues() = 0; |
|||
virtual void SaveUIValues() = 0; |
|||
virtual void SaveUIGamelistValues() = 0; |
|||
virtual void SaveUILayoutValues() = 0; |
|||
virtual void SaveMultiplayerValues() = 0; |
|||
|
|||
virtual std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) = 0; |
|||
|
|||
/** |
|||
* Reads a setting from the qt_config. |
|||
* |
|||
* @param key The setting's identifier |
|||
* @param default_value The value to use when the setting is not already present in the config |
|||
*/ |
|||
bool ReadBooleanSetting(const std::string& key, |
|||
std::optional<bool> default_value = std::nullopt); |
|||
s64 ReadIntegerSetting(const std::string& key, std::optional<s64> default_value = std::nullopt); |
|||
u64 ReadUnsignedIntegerSetting(const std::string& key, |
|||
std::optional<u64> default_value = std::nullopt); |
|||
double ReadDoubleSetting(const std::string& key, |
|||
std::optional<double> default_value = std::nullopt); |
|||
std::string ReadStringSetting(const std::string& key, |
|||
std::optional<std::string> default_value = std::nullopt); |
|||
|
|||
/** |
|||
* Writes a setting to the qt_config. |
|||
* |
|||
* @param key The setting's idetentifier |
|||
* @param value Value of the setting |
|||
* @param default_value Default of the setting if not present in config |
|||
* @param use_global Specifies if the custom or global config should be in use, for custom |
|||
* configs |
|||
*/ |
|||
template <typename Type = int> |
|||
void WriteSetting(const std::string& key, const Type& value, |
|||
const std::optional<Type>& default_value = std::nullopt, |
|||
const std::optional<bool>& use_global = std::nullopt); |
|||
void WriteSettingInternal(const std::string& key, const std::string& value); |
|||
|
|||
void ReadCategory(Settings::Category category); |
|||
void WriteCategory(Settings::Category category); |
|||
void ReadSettingGeneric(Settings::BasicSetting* setting); |
|||
void WriteSettingGeneric(const Settings::BasicSetting* setting); |
|||
|
|||
template <typename T> |
|||
[[nodiscard]] std::string ToString(const T& value_) { |
|||
if constexpr (std::is_same_v<T, std::string>) { |
|||
return value_; |
|||
} else if constexpr (std::is_same_v<T, std::optional<u32>>) { |
|||
return value_.has_value() ? std::to_string(*value_) : "none"; |
|||
} else if constexpr (std::is_same_v<T, bool>) { |
|||
return value_ ? "true" : "false"; |
|||
} else if constexpr (std::is_same_v<T, u64>) { |
|||
return std::to_string(static_cast<u64>(value_)); |
|||
} else { |
|||
return std::to_string(static_cast<s64>(value_)); |
|||
} |
|||
} |
|||
|
|||
void BeginGroup(const std::string& group); |
|||
void EndGroup(); |
|||
std::string GetSection(); |
|||
[[nodiscard]] std::string GetGroup() const; |
|||
static std::string AdjustKey(const std::string& key); |
|||
static std::string AdjustOutputString(const std::string& string); |
|||
std::string GetFullKey(const std::string& key, bool skipArrayIndex); |
|||
int BeginArray(const std::string& array); |
|||
void EndArray(); |
|||
void SetArrayIndex(int index); |
|||
|
|||
const ConfigType type; |
|||
std::unique_ptr<CSimpleIniA> config; |
|||
std::string config_loc; |
|||
const bool global; |
|||
|
|||
private: |
|||
inline static std::array<char, 19> special_characters = {'!', '#', '$', '%', '^', '&', '*', |
|||
'|', ';', '\'', '\"', ',', '<', '.', |
|||
'>', '?', '`', '~', '='}; |
|||
|
|||
struct ConfigArray { |
|||
std::string name; |
|||
int size; |
|||
int index; |
|||
}; |
|||
std::vector<ConfigArray> array_stack; |
|||
std::vector<std::string> key_stack; |
|||
}; |
|||
1309
src/yuzu/configuration/config.cpp
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -1,179 +0,0 @@ |
|||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <array> |
|||
#include <memory> |
|||
#include <string> |
|||
#include <QMetaType> |
|||
#include <QVariant> |
|||
#include "common/settings.h" |
|||
#include "common/settings_enums.h" |
|||
#include "yuzu/uisettings.h" |
|||
|
|||
class QSettings; |
|||
|
|||
namespace Core { |
|||
class System; |
|||
} |
|||
|
|||
class Config { |
|||
public: |
|||
enum class ConfigType { |
|||
GlobalConfig, |
|||
PerGameConfig, |
|||
InputProfile, |
|||
}; |
|||
|
|||
explicit Config(const std::string& config_name = "qt-config", |
|||
ConfigType config_type = ConfigType::GlobalConfig); |
|||
~Config(); |
|||
|
|||
void Reload(); |
|||
void Save(); |
|||
|
|||
void ReadControlPlayerValue(std::size_t player_index); |
|||
void SaveControlPlayerValue(std::size_t player_index); |
|||
void ClearControlPlayerValues(); |
|||
|
|||
const std::string& GetConfigFilePath() const; |
|||
|
|||
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons; |
|||
static const std::array<int, Settings::NativeMotion::NumMotions> default_motions; |
|||
static const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> default_analogs; |
|||
static const std::array<int, 2> default_stick_mod; |
|||
static const std::array<int, 2> default_ringcon_analogs; |
|||
static const std::array<int, Settings::NativeMouseButton::NumMouseButtons> |
|||
default_mouse_buttons; |
|||
static const std::array<int, Settings::NativeKeyboard::NumKeyboardKeys> default_keyboard_keys; |
|||
static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods; |
|||
static const std::array<UISettings::Shortcut, 23> default_hotkeys; |
|||
|
|||
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map; |
|||
static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map; |
|||
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map; |
|||
static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map; |
|||
static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map; |
|||
static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map; |
|||
|
|||
static constexpr UISettings::Theme default_theme{ |
|||
#ifdef _WIN32 |
|||
UISettings::Theme::DarkColorful |
|||
#else |
|||
UISettings::Theme::DefaultColorful |
|||
#endif |
|||
}; |
|||
|
|||
private: |
|||
void Initialize(const std::string& config_name); |
|||
bool IsCustomConfig(); |
|||
|
|||
void ReadValues(); |
|||
void ReadPlayerValue(std::size_t player_index); |
|||
void ReadDebugValues(); |
|||
void ReadKeyboardValues(); |
|||
void ReadMouseValues(); |
|||
void ReadTouchscreenValues(); |
|||
void ReadMotionTouchValues(); |
|||
void ReadHidbusValues(); |
|||
void ReadIrCameraValues(); |
|||
|
|||
// Read functions bases off the respective config section names. |
|||
void ReadAudioValues(); |
|||
void ReadControlValues(); |
|||
void ReadCoreValues(); |
|||
void ReadDataStorageValues(); |
|||
void ReadDebuggingValues(); |
|||
void ReadServiceValues(); |
|||
void ReadDisabledAddOnValues(); |
|||
void ReadMiscellaneousValues(); |
|||
void ReadPathValues(); |
|||
void ReadCpuValues(); |
|||
void ReadRendererValues(); |
|||
void ReadScreenshotValues(); |
|||
void ReadShortcutValues(); |
|||
void ReadSystemValues(); |
|||
void ReadUIValues(); |
|||
void ReadUIGamelistValues(); |
|||
void ReadUILayoutValues(); |
|||
void ReadWebServiceValues(); |
|||
void ReadMultiplayerValues(); |
|||
void ReadNetworkValues(); |
|||
|
|||
void SaveValues(); |
|||
void SavePlayerValue(std::size_t player_index); |
|||
void SaveDebugValues(); |
|||
void SaveMouseValues(); |
|||
void SaveTouchscreenValues(); |
|||
void SaveMotionTouchValues(); |
|||
void SaveHidbusValues(); |
|||
void SaveIrCameraValues(); |
|||
|
|||
// Save functions based off the respective config section names. |
|||
void SaveAudioValues(); |
|||
void SaveControlValues(); |
|||
void SaveCoreValues(); |
|||
void SaveDataStorageValues(); |
|||
void SaveDebuggingValues(); |
|||
void SaveNetworkValues(); |
|||
void SaveDisabledAddOnValues(); |
|||
void SaveMiscellaneousValues(); |
|||
void SavePathValues(); |
|||
void SaveCpuValues(); |
|||
void SaveRendererValues(); |
|||
void SaveScreenshotValues(); |
|||
void SaveShortcutValues(); |
|||
void SaveSystemValues(); |
|||
void SaveUIValues(); |
|||
void SaveUIGamelistValues(); |
|||
void SaveUILayoutValues(); |
|||
void SaveWebServiceValues(); |
|||
void SaveMultiplayerValues(); |
|||
|
|||
/** |
|||
* Reads a setting from the qt_config. |
|||
* |
|||
* @param name The setting's identifier |
|||
* @param default_value The value to use when the setting is not already present in the config |
|||
*/ |
|||
QVariant ReadSetting(const QString& name) const; |
|||
QVariant ReadSetting(const QString& name, const QVariant& default_value) const; |
|||
|
|||
/** |
|||
* Writes a setting to the qt_config. |
|||
* |
|||
* @param name The setting's idetentifier |
|||
* @param value Value of the setting |
|||
* @param default_value Default of the setting if not present in qt_config |
|||
* @param use_global Specifies if the custom or global config should be in use, for custom |
|||
* configs |
|||
*/ |
|||
void WriteSetting(const QString& name, const QVariant& value); |
|||
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value); |
|||
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value, |
|||
bool use_global); |
|||
|
|||
void ReadCategory(Settings::Category category); |
|||
void WriteCategory(Settings::Category category); |
|||
void ReadSettingGeneric(Settings::BasicSetting* const setting); |
|||
void WriteSettingGeneric(Settings::BasicSetting* const setting) const; |
|||
|
|||
const ConfigType type; |
|||
std::unique_ptr<QSettings> qt_config; |
|||
std::string qt_config_loc; |
|||
const bool global; |
|||
}; |
|||
|
|||
// These metatype declarations cannot be in common/settings.h because core is devoid of QT |
|||
Q_DECLARE_METATYPE(Settings::CpuAccuracy); |
|||
Q_DECLARE_METATYPE(Settings::GpuAccuracy); |
|||
Q_DECLARE_METATYPE(Settings::FullscreenMode); |
|||
Q_DECLARE_METATYPE(Settings::NvdecEmulation); |
|||
Q_DECLARE_METATYPE(Settings::ResolutionSetup); |
|||
Q_DECLARE_METATYPE(Settings::ScalingFilter); |
|||
Q_DECLARE_METATYPE(Settings::AntiAliasing); |
|||
Q_DECLARE_METATYPE(Settings::RendererBackend); |
|||
Q_DECLARE_METATYPE(Settings::ShaderBackend); |
|||
Q_DECLARE_METATYPE(Settings::AstcRecompression); |
|||
Q_DECLARE_METATYPE(Settings::AstcDecodeMode); |
|||
@ -0,0 +1,549 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include "input_common/main.h"
|
|||
#include "qt_config.h"
|
|||
#include "uisettings.h"
|
|||
|
|||
const std::array<int, Settings::NativeButton::NumButtons> QtConfig::default_buttons = { |
|||
Qt::Key_C, Qt::Key_X, Qt::Key_V, Qt::Key_Z, Qt::Key_F, |
|||
Qt::Key_G, Qt::Key_Q, Qt::Key_E, Qt::Key_R, Qt::Key_T, |
|||
Qt::Key_M, Qt::Key_N, Qt::Key_Left, Qt::Key_Up, Qt::Key_Right, |
|||
Qt::Key_Down, Qt::Key_Q, Qt::Key_E, 0, 0, |
|||
Qt::Key_Q, Qt::Key_E, |
|||
}; |
|||
|
|||
const std::array<int, Settings::NativeMotion::NumMotions> QtConfig::default_motions = { |
|||
Qt::Key_7, |
|||
Qt::Key_8, |
|||
}; |
|||
|
|||
const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> QtConfig::default_analogs{{ |
|||
{ |
|||
Qt::Key_W, |
|||
Qt::Key_S, |
|||
Qt::Key_A, |
|||
Qt::Key_D, |
|||
}, |
|||
{ |
|||
Qt::Key_I, |
|||
Qt::Key_K, |
|||
Qt::Key_J, |
|||
Qt::Key_L, |
|||
}, |
|||
}}; |
|||
|
|||
const std::array<int, 2> QtConfig::default_stick_mod = { |
|||
Qt::Key_Shift, |
|||
0, |
|||
}; |
|||
|
|||
const std::array<int, 2> QtConfig::default_ringcon_analogs{{ |
|||
Qt::Key_A, |
|||
Qt::Key_D, |
|||
}}; |
|||
|
|||
QtConfig::QtConfig(const std::string& config_name, const ConfigType config_type) |
|||
: Config(config_type) { |
|||
Initialize(config_name); |
|||
if (config_type != ConfigType::InputProfile) { |
|||
ReadQtValues(); |
|||
SaveQtValues(); |
|||
} |
|||
} |
|||
|
|||
QtConfig::~QtConfig() { |
|||
if (global) { |
|||
QtConfig::SaveAllValues(); |
|||
} |
|||
} |
|||
|
|||
void QtConfig::ReloadAllValues() { |
|||
Reload(); |
|||
ReadQtValues(); |
|||
SaveQtValues(); |
|||
} |
|||
|
|||
void QtConfig::SaveAllValues() { |
|||
Save(); |
|||
SaveQtValues(); |
|||
} |
|||
|
|||
void QtConfig::ReadQtValues() { |
|||
if (global) { |
|||
ReadUIValues(); |
|||
} |
|||
ReadQtControlValues(); |
|||
} |
|||
|
|||
void QtConfig::ReadQtPlayerValues(const std::size_t player_index) { |
|||
std::string player_prefix; |
|||
if (type != ConfigType::InputProfile) { |
|||
player_prefix.append("player_").append(ToString(player_index)).append("_"); |
|||
} |
|||
|
|||
auto& player = Settings::values.players.GetValue()[player_index]; |
|||
if (IsCustomConfig()) { |
|||
const auto profile_name = |
|||
ReadStringSetting(std::string(player_prefix).append("profile_name")); |
|||
if (profile_name.empty()) { |
|||
// Use the global input config
|
|||
player = Settings::values.players.GetValue(true)[player_index]; |
|||
return; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
auto& player_buttons = player.buttons[i]; |
|||
|
|||
player_buttons = ReadStringSetting( |
|||
std::string(player_prefix).append(Settings::NativeButton::mapping[i]), default_param); |
|||
if (player_buttons.empty()) { |
|||
player_buttons = default_param; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_stick_mod[i], 0.5f); |
|||
auto& player_analogs = player.analogs[i]; |
|||
|
|||
player_analogs = ReadStringSetting( |
|||
std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]), default_param); |
|||
if (player_analogs.empty()) { |
|||
player_analogs = default_param; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]); |
|||
auto& player_motions = player.motions[i]; |
|||
|
|||
player_motions = ReadStringSetting( |
|||
std::string(player_prefix).append(Settings::NativeMotion::mapping[i]), default_param); |
|||
if (player_motions.empty()) { |
|||
player_motions = default_param; |
|||
} |
|||
} |
|||
} |
|||
|
|||
void QtConfig::ReadHidbusValues() { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f); |
|||
auto& ringcon_analogs = Settings::values.ringcon_analogs; |
|||
|
|||
ringcon_analogs = ReadStringSetting(std::string("ring_controller"), default_param); |
|||
if (ringcon_analogs.empty()) { |
|||
ringcon_analogs = default_param; |
|||
} |
|||
} |
|||
|
|||
void QtConfig::ReadDebugControlValues() { |
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
auto& debug_pad_buttons = Settings::values.debug_pad_buttons[i]; |
|||
|
|||
debug_pad_buttons = ReadStringSetting( |
|||
std::string("debug_pad_").append(Settings::NativeButton::mapping[i]), default_param); |
|||
if (debug_pad_buttons.empty()) { |
|||
debug_pad_buttons = default_param; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_stick_mod[i], 0.5f); |
|||
auto& debug_pad_analogs = Settings::values.debug_pad_analogs[i]; |
|||
|
|||
debug_pad_analogs = ReadStringSetting( |
|||
std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]), default_param); |
|||
if (debug_pad_analogs.empty()) { |
|||
debug_pad_analogs = default_param; |
|||
} |
|||
} |
|||
} |
|||
|
|||
void QtConfig::ReadQtControlValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Controls)); |
|||
|
|||
Settings::values.players.SetGlobal(!IsCustomConfig()); |
|||
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { |
|||
ReadQtPlayerValues(p); |
|||
} |
|||
if (IsCustomConfig()) { |
|||
EndGroup(); |
|||
return; |
|||
} |
|||
ReadDebugControlValues(); |
|||
ReadHidbusValues(); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::ReadPathValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Paths)); |
|||
|
|||
UISettings::values.roms_path = ReadStringSetting(std::string("romsPath")); |
|||
UISettings::values.symbols_path = ReadStringSetting(std::string("symbolsPath")); |
|||
UISettings::values.game_dir_deprecated = |
|||
ReadStringSetting(std::string("gameListRootDir"), std::string(".")); |
|||
UISettings::values.game_dir_deprecated_deepscan = |
|||
ReadBooleanSetting(std::string("gameListDeepScan"), std::make_optional(false)); |
|||
|
|||
const int gamedirs_size = BeginArray(std::string("gamedirs")); |
|||
for (int i = 0; i < gamedirs_size; ++i) { |
|||
SetArrayIndex(i); |
|||
UISettings::GameDir game_dir; |
|||
game_dir.path = ReadStringSetting(std::string("path")); |
|||
game_dir.deep_scan = |
|||
ReadBooleanSetting(std::string("deep_scan"), std::make_optional(false)); |
|||
game_dir.expanded = ReadBooleanSetting(std::string("expanded"), std::make_optional(true)); |
|||
UISettings::values.game_dirs.append(game_dir); |
|||
} |
|||
EndArray(); |
|||
|
|||
// Create NAND and SD card directories if empty, these are not removable through the UI,
|
|||
// also carries over old game list settings if present
|
|||
if (UISettings::values.game_dirs.empty()) { |
|||
UISettings::GameDir game_dir; |
|||
game_dir.path = std::string("SDMC"); |
|||
game_dir.expanded = true; |
|||
UISettings::values.game_dirs.append(game_dir); |
|||
game_dir.path = std::string("UserNAND"); |
|||
UISettings::values.game_dirs.append(game_dir); |
|||
game_dir.path = std::string("SysNAND"); |
|||
UISettings::values.game_dirs.append(game_dir); |
|||
if (UISettings::values.game_dir_deprecated != std::string(".")) { |
|||
game_dir.path = UISettings::values.game_dir_deprecated; |
|||
game_dir.deep_scan = UISettings::values.game_dir_deprecated_deepscan; |
|||
UISettings::values.game_dirs.append(game_dir); |
|||
} |
|||
} |
|||
UISettings::values.recent_files = |
|||
QString::fromStdString(ReadStringSetting(std::string("recentFiles"))) |
|||
.split(QStringLiteral(", "), Qt::SkipEmptyParts, Qt::CaseSensitive); |
|||
UISettings::values.language = ReadStringSetting(std::string("language"), std::string("")); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::ReadShortcutValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Shortcuts)); |
|||
|
|||
for (const auto& [name, group, shortcut] : UISettings::default_hotkeys) { |
|||
BeginGroup(group); |
|||
BeginGroup(name); |
|||
|
|||
// No longer using ReadSetting for shortcut.second as it inaccurately returns a value of 1
|
|||
// for WidgetWithChildrenShortcut which is a value of 3. Needed to fix shortcuts the open
|
|||
// a file dialog in windowed mode
|
|||
UISettings::values.shortcuts.push_back( |
|||
{name, |
|||
group, |
|||
{ReadStringSetting(std::string("KeySeq"), shortcut.keyseq), |
|||
ReadStringSetting(std::string("Controller_KeySeq"), shortcut.controller_keyseq), |
|||
shortcut.context, |
|||
ReadBooleanSetting(std::string("Repeat"), std::optional(shortcut.repeat))}}); |
|||
|
|||
EndGroup(); // name
|
|||
EndGroup(); // group
|
|||
} |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::ReadUIValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Ui)); |
|||
|
|||
UISettings::values.theme = ReadStringSetting( |
|||
std::string("theme"), |
|||
std::string(UISettings::themes[static_cast<size_t>(UISettings::default_theme)].second)); |
|||
|
|||
ReadUIGamelistValues(); |
|||
ReadUILayoutValues(); |
|||
ReadPathValues(); |
|||
ReadScreenshotValues(); |
|||
ReadShortcutValues(); |
|||
ReadMultiplayerValues(); |
|||
|
|||
ReadCategory(Settings::Category::Ui); |
|||
ReadCategory(Settings::Category::UiGeneral); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::ReadUIGamelistValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::UiGameList)); |
|||
|
|||
ReadCategory(Settings::Category::UiGameList); |
|||
|
|||
const int favorites_size = BeginArray("favorites"); |
|||
for (int i = 0; i < favorites_size; i++) { |
|||
SetArrayIndex(i); |
|||
UISettings::values.favorited_ids.append( |
|||
ReadUnsignedIntegerSetting(std::string("program_id"))); |
|||
} |
|||
EndArray(); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::ReadUILayoutValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::UiGameList)); |
|||
|
|||
ReadCategory(Settings::Category::UiLayout); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::ReadMultiplayerValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Multiplayer)); |
|||
|
|||
ReadCategory(Settings::Category::Multiplayer); |
|||
|
|||
// Read ban list back
|
|||
int size = BeginArray(std::string("username_ban_list")); |
|||
UISettings::values.multiplayer_ban_list.first.resize(size); |
|||
for (int i = 0; i < size; ++i) { |
|||
SetArrayIndex(i); |
|||
UISettings::values.multiplayer_ban_list.first[i] = |
|||
ReadStringSetting(std::string("username"), std::string("")); |
|||
} |
|||
EndArray(); |
|||
|
|||
size = BeginArray(std::string("ip_ban_list")); |
|||
UISettings::values.multiplayer_ban_list.second.resize(size); |
|||
for (int i = 0; i < size; ++i) { |
|||
UISettings::values.multiplayer_ban_list.second[i] = |
|||
ReadStringSetting("username", std::string("")); |
|||
} |
|||
EndArray(); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::SaveQtValues() { |
|||
if (global) { |
|||
SaveUIValues(); |
|||
} |
|||
SaveQtControlValues(); |
|||
|
|||
WriteToIni(); |
|||
} |
|||
|
|||
void QtConfig::SaveQtPlayerValues(const std::size_t player_index) { |
|||
std::string player_prefix; |
|||
if (type != ConfigType::InputProfile) { |
|||
player_prefix = std::string("player_").append(ToString(player_index)).append("_"); |
|||
} |
|||
|
|||
const auto& player = Settings::values.players.GetValue()[player_index]; |
|||
if (IsCustomConfig() && player.profile_name.empty()) { |
|||
// No custom profile selected
|
|||
return; |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
WriteSetting(std::string(player_prefix).append(Settings::NativeButton::mapping[i]), |
|||
player.buttons[i], std::make_optional(default_param)); |
|||
} |
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_stick_mod[i], 0.5f); |
|||
WriteSetting(std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]), |
|||
player.analogs[i], std::make_optional(default_param)); |
|||
} |
|||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]); |
|||
WriteSetting(std::string(player_prefix).append(Settings::NativeMotion::mapping[i]), |
|||
player.motions[i], std::make_optional(default_param)); |
|||
} |
|||
} |
|||
|
|||
void QtConfig::SaveDebugControlValues() { |
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
WriteSetting(std::string("debug_pad_").append(Settings::NativeButton::mapping[i]), |
|||
Settings::values.debug_pad_buttons[i], std::make_optional(default_param)); |
|||
} |
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_stick_mod[i], 0.5f); |
|||
WriteSetting(std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]), |
|||
Settings::values.debug_pad_analogs[i], std::make_optional(default_param)); |
|||
} |
|||
} |
|||
|
|||
void QtConfig::SaveHidbusValues() { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f); |
|||
WriteSetting(std::string("ring_controller"), Settings::values.ringcon_analogs, |
|||
std::make_optional(default_param)); |
|||
} |
|||
|
|||
void QtConfig::SaveQtControlValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Controls)); |
|||
|
|||
Settings::values.players.SetGlobal(!IsCustomConfig()); |
|||
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { |
|||
SaveQtPlayerValues(p); |
|||
} |
|||
if (IsCustomConfig()) { |
|||
EndGroup(); |
|||
return; |
|||
} |
|||
SaveDebugControlValues(); |
|||
SaveHidbusValues(); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::SavePathValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Paths)); |
|||
|
|||
WriteSetting(std::string("romsPath"), UISettings::values.roms_path); |
|||
WriteSetting(std::string("symbolsPath"), UISettings::values.symbols_path); |
|||
BeginArray(std::string("gamedirs")); |
|||
for (int i = 0; i < UISettings::values.game_dirs.size(); ++i) { |
|||
SetArrayIndex(i); |
|||
const auto& game_dir = UISettings::values.game_dirs[i]; |
|||
WriteSetting(std::string("path"), game_dir.path); |
|||
WriteSetting(std::string("deep_scan"), game_dir.deep_scan, std::make_optional(false)); |
|||
WriteSetting(std::string("expanded"), game_dir.expanded, std::make_optional(true)); |
|||
} |
|||
EndArray(); |
|||
|
|||
WriteSetting(std::string("recentFiles"), |
|||
UISettings::values.recent_files.join(QStringLiteral(", ")).toStdString()); |
|||
WriteSetting(std::string("language"), UISettings::values.language); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::SaveShortcutValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Shortcuts)); |
|||
|
|||
// Lengths of UISettings::values.shortcuts & default_hotkeys are same.
|
|||
// However, their ordering must also be the same.
|
|||
for (std::size_t i = 0; i < UISettings::default_hotkeys.size(); i++) { |
|||
const auto& [name, group, shortcut] = UISettings::values.shortcuts[i]; |
|||
const auto& default_hotkey = UISettings::default_hotkeys[i].shortcut; |
|||
|
|||
BeginGroup(group); |
|||
BeginGroup(name); |
|||
|
|||
WriteSetting(std::string("KeySeq"), shortcut.keyseq, |
|||
std::make_optional(default_hotkey.keyseq)); |
|||
WriteSetting(std::string("Controller_KeySeq"), shortcut.controller_keyseq, |
|||
std::make_optional(default_hotkey.controller_keyseq)); |
|||
WriteSetting(std::string("Context"), shortcut.context, |
|||
std::make_optional(default_hotkey.context)); |
|||
WriteSetting(std::string("Repeat"), shortcut.repeat, |
|||
std::make_optional(default_hotkey.repeat)); |
|||
|
|||
EndGroup(); // name
|
|||
EndGroup(); // group
|
|||
} |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::SaveUIValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Ui)); |
|||
|
|||
WriteCategory(Settings::Category::Ui); |
|||
WriteCategory(Settings::Category::UiGeneral); |
|||
|
|||
WriteSetting(std::string("theme"), UISettings::values.theme, |
|||
std::make_optional(std::string( |
|||
UISettings::themes[static_cast<size_t>(UISettings::default_theme)].second))); |
|||
|
|||
SaveUIGamelistValues(); |
|||
SaveUILayoutValues(); |
|||
SavePathValues(); |
|||
SaveScreenshotValues(); |
|||
SaveShortcutValues(); |
|||
SaveMultiplayerValues(); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::SaveUIGamelistValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::UiGameList)); |
|||
|
|||
WriteCategory(Settings::Category::UiGameList); |
|||
|
|||
BeginArray(std::string("favorites")); |
|||
for (int i = 0; i < UISettings::values.favorited_ids.size(); i++) { |
|||
SetArrayIndex(i); |
|||
WriteSetting(std::string("program_id"), UISettings::values.favorited_ids[i]); |
|||
} |
|||
EndArray(); // favorites
|
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::SaveUILayoutValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::UiLayout)); |
|||
|
|||
WriteCategory(Settings::Category::UiLayout); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::SaveMultiplayerValues() { |
|||
BeginGroup(std::string("Multiplayer")); |
|||
|
|||
WriteCategory(Settings::Category::Multiplayer); |
|||
|
|||
// Write ban list
|
|||
BeginArray(std::string("username_ban_list")); |
|||
for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.first.size(); ++i) { |
|||
SetArrayIndex(static_cast<int>(i)); |
|||
WriteSetting(std::string("username"), UISettings::values.multiplayer_ban_list.first[i]); |
|||
} |
|||
EndArray(); // username_ban_list
|
|||
|
|||
BeginArray(std::string("ip_ban_list")); |
|||
for (std::size_t i = 0; i < UISettings::values.multiplayer_ban_list.second.size(); ++i) { |
|||
SetArrayIndex(static_cast<int>(i)); |
|||
WriteSetting(std::string("ip"), UISettings::values.multiplayer_ban_list.second[i]); |
|||
} |
|||
EndArray(); // ip_ban_list
|
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
std::vector<Settings::BasicSetting*>& QtConfig::FindRelevantList(Settings::Category category) { |
|||
auto& map = Settings::values.linkage.by_category; |
|||
if (map.contains(category)) { |
|||
return Settings::values.linkage.by_category[category]; |
|||
} |
|||
return UISettings::values.linkage.by_category[category]; |
|||
} |
|||
|
|||
void QtConfig::ReadQtControlPlayerValues(std::size_t player_index) { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Controls)); |
|||
|
|||
ReadPlayerValues(player_index); |
|||
ReadQtPlayerValues(player_index); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void QtConfig::SaveQtControlPlayerValues(std::size_t player_index) { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Controls)); |
|||
|
|||
SavePlayerValues(player_index); |
|||
SaveQtPlayerValues(player_index); |
|||
|
|||
EndGroup(); |
|||
|
|||
WriteToIni(); |
|||
} |
|||
@ -0,0 +1,55 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <QMetaType> |
|||
|
|||
#include "frontend_common/config.h" |
|||
|
|||
class QtConfig final : public Config { |
|||
public: |
|||
explicit QtConfig(const std::string& config_name = "qt-config", |
|||
ConfigType config_type = ConfigType::GlobalConfig); |
|||
~QtConfig() override; |
|||
|
|||
void ReloadAllValues() override; |
|||
void SaveAllValues() override; |
|||
|
|||
void ReadQtControlPlayerValues(std::size_t player_index); |
|||
void SaveQtControlPlayerValues(std::size_t player_index); |
|||
|
|||
protected: |
|||
void ReadQtValues(); |
|||
void ReadQtPlayerValues(std::size_t player_index); |
|||
void ReadQtControlValues(); |
|||
void ReadHidbusValues() override; |
|||
void ReadDebugControlValues() override; |
|||
void ReadPathValues() override; |
|||
void ReadShortcutValues() override; |
|||
void ReadUIValues() override; |
|||
void ReadUIGamelistValues() override; |
|||
void ReadUILayoutValues() override; |
|||
void ReadMultiplayerValues() override; |
|||
|
|||
void SaveQtValues(); |
|||
void SaveQtPlayerValues(std::size_t player_index); |
|||
void SaveQtControlValues(); |
|||
void SaveHidbusValues() override; |
|||
void SaveDebugControlValues() override; |
|||
void SavePathValues() override; |
|||
void SaveShortcutValues() override; |
|||
void SaveUIValues() override; |
|||
void SaveUIGamelistValues() override; |
|||
void SaveUILayoutValues() override; |
|||
void SaveMultiplayerValues() override; |
|||
|
|||
std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) override; |
|||
|
|||
public: |
|||
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons; |
|||
static const std::array<int, Settings::NativeMotion::NumMotions> default_motions; |
|||
static const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> default_analogs; |
|||
static const std::array<int, 2> default_stick_mod; |
|||
static const std::array<int, 2> default_ringcon_analogs; |
|||
}; |
|||
@ -1,279 +0,0 @@ |
|||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
#include <memory>
|
|||
#include <optional>
|
|||
#include <sstream>
|
|||
#include <INIReader.h>
|
|||
#include <SDL.h>
|
|||
#include "common/fs/file.h"
|
|||
#include "common/fs/fs.h"
|
|||
#include "common/fs/path_util.h"
|
|||
#include "common/logging/log.h"
|
|||
#include "common/settings.h"
|
|||
#include "core/hle/service/acc/profile_manager.h"
|
|||
#include "input_common/main.h"
|
|||
#include "yuzu_cmd/config.h"
|
|||
#include "yuzu_cmd/default_ini.h"
|
|||
|
|||
namespace FS = Common::FS; |
|||
|
|||
const std::filesystem::path default_config_path = |
|||
FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "sdl2-config.ini"; |
|||
|
|||
Config::Config(std::optional<std::filesystem::path> config_path) |
|||
: sdl2_config_loc{config_path.value_or(default_config_path)}, |
|||
sdl2_config{std::make_unique<INIReader>(FS::PathToUTF8String(sdl2_config_loc))} { |
|||
Reload(); |
|||
} |
|||
|
|||
Config::~Config() = default; |
|||
|
|||
bool Config::LoadINI(const std::string& default_contents, bool retry) { |
|||
const auto config_loc_str = FS::PathToUTF8String(sdl2_config_loc); |
|||
if (sdl2_config->ParseError() < 0) { |
|||
if (retry) { |
|||
LOG_WARNING(Config, "Failed to load {}. Creating file from defaults...", |
|||
config_loc_str); |
|||
|
|||
void(FS::CreateParentDir(sdl2_config_loc)); |
|||
void(FS::WriteStringToFile(sdl2_config_loc, FS::FileType::TextFile, default_contents)); |
|||
|
|||
sdl2_config = std::make_unique<INIReader>(config_loc_str); |
|||
|
|||
return LoadINI(default_contents, false); |
|||
} |
|||
LOG_ERROR(Config, "Failed."); |
|||
return false; |
|||
} |
|||
LOG_INFO(Config, "Successfully loaded {}", config_loc_str); |
|||
return true; |
|||
} |
|||
|
|||
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons = { |
|||
SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T, |
|||
SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W, |
|||
SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B, |
|||
}; |
|||
|
|||
static const std::array<int, Settings::NativeMotion::NumMotions> default_motions = { |
|||
SDL_SCANCODE_7, |
|||
SDL_SCANCODE_8, |
|||
}; |
|||
|
|||
static const std::array<std::array<int, 5>, Settings::NativeAnalog::NumAnalogs> default_analogs{{ |
|||
{ |
|||
SDL_SCANCODE_UP, |
|||
SDL_SCANCODE_DOWN, |
|||
SDL_SCANCODE_LEFT, |
|||
SDL_SCANCODE_RIGHT, |
|||
SDL_SCANCODE_D, |
|||
}, |
|||
{ |
|||
SDL_SCANCODE_I, |
|||
SDL_SCANCODE_K, |
|||
SDL_SCANCODE_J, |
|||
SDL_SCANCODE_L, |
|||
SDL_SCANCODE_D, |
|||
}, |
|||
}}; |
|||
|
|||
template <> |
|||
void Config::ReadSetting(const std::string& group, Settings::Setting<std::string>& setting) { |
|||
std::string setting_value = sdl2_config->Get(group, setting.GetLabel(), setting.GetDefault()); |
|||
if (setting_value.empty()) { |
|||
setting_value = setting.GetDefault(); |
|||
} |
|||
setting = std::move(setting_value); |
|||
} |
|||
|
|||
template <> |
|||
void Config::ReadSetting(const std::string& group, Settings::Setting<bool>& setting) { |
|||
setting = sdl2_config->GetBoolean(group, setting.GetLabel(), setting.GetDefault()); |
|||
} |
|||
|
|||
template <typename Type, bool ranged> |
|||
void Config::ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting) { |
|||
setting = static_cast<Type>(sdl2_config->GetInteger(group, setting.GetLabel(), |
|||
static_cast<long>(setting.GetDefault()))); |
|||
} |
|||
|
|||
void Config::ReadCategory(Settings::Category category) { |
|||
for (const auto setting : Settings::values.linkage.by_category[category]) { |
|||
const char* category_name = [&]() { |
|||
if (category == Settings::Category::Controls) { |
|||
// For compatibility with older configs
|
|||
return "ControlsGeneral"; |
|||
} else { |
|||
return Settings::TranslateCategory(category); |
|||
} |
|||
}(); |
|||
std::string setting_value = |
|||
sdl2_config->Get(category_name, setting->GetLabel(), setting->DefaultToString()); |
|||
setting->LoadString(setting_value); |
|||
} |
|||
} |
|||
|
|||
void Config::ReadValues() { |
|||
// Controls
|
|||
ReadCategory(Settings::Category::Controls); |
|||
|
|||
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { |
|||
auto& player = Settings::values.players.GetValue()[p]; |
|||
|
|||
const auto group = fmt::format("ControlsP{}", p); |
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
player.buttons[i] = |
|||
sdl2_config->Get(group, Settings::NativeButton::mapping[i], default_param); |
|||
if (player.buttons[i].empty()) { |
|||
player.buttons[i] = default_param; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_analogs[i][4], 0.5f); |
|||
player.analogs[i] = |
|||
sdl2_config->Get(group, Settings::NativeAnalog::mapping[i], default_param); |
|||
if (player.analogs[i].empty()) { |
|||
player.analogs[i] = default_param; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) { |
|||
const std::string default_param = |
|||
InputCommon::GenerateKeyboardParam(default_motions[i]); |
|||
auto& player_motions = player.motions[i]; |
|||
|
|||
player_motions = |
|||
sdl2_config->Get(group, Settings::NativeMotion::mapping[i], default_param); |
|||
if (player_motions.empty()) { |
|||
player_motions = default_param; |
|||
} |
|||
} |
|||
|
|||
player.connected = sdl2_config->GetBoolean(group, "connected", false); |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
Settings::values.debug_pad_buttons[i] = sdl2_config->Get( |
|||
"ControlsGeneral", std::string("debug_pad_") + Settings::NativeButton::mapping[i], |
|||
default_param); |
|||
if (Settings::values.debug_pad_buttons[i].empty()) |
|||
Settings::values.debug_pad_buttons[i] = default_param; |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_analogs[i][4], 0.5f); |
|||
Settings::values.debug_pad_analogs[i] = sdl2_config->Get( |
|||
"ControlsGeneral", std::string("debug_pad_") + Settings::NativeAnalog::mapping[i], |
|||
default_param); |
|||
if (Settings::values.debug_pad_analogs[i].empty()) |
|||
Settings::values.debug_pad_analogs[i] = default_param; |
|||
} |
|||
|
|||
Settings::values.touchscreen.enabled = |
|||
sdl2_config->GetBoolean("ControlsGeneral", "touch_enabled", true); |
|||
Settings::values.touchscreen.rotation_angle = |
|||
sdl2_config->GetInteger("ControlsGeneral", "touch_angle", 0); |
|||
Settings::values.touchscreen.diameter_x = |
|||
sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_x", 15); |
|||
Settings::values.touchscreen.diameter_y = |
|||
sdl2_config->GetInteger("ControlsGeneral", "touch_diameter_y", 15); |
|||
|
|||
int num_touch_from_button_maps = |
|||
sdl2_config->GetInteger("ControlsGeneral", "touch_from_button_map", 0); |
|||
if (num_touch_from_button_maps > 0) { |
|||
for (int i = 0; i < num_touch_from_button_maps; ++i) { |
|||
Settings::TouchFromButtonMap map; |
|||
map.name = sdl2_config->Get("ControlsGeneral", |
|||
std::string("touch_from_button_maps_") + std::to_string(i) + |
|||
std::string("_name"), |
|||
"default"); |
|||
const int num_touch_maps = sdl2_config->GetInteger( |
|||
"ControlsGeneral", |
|||
std::string("touch_from_button_maps_") + std::to_string(i) + std::string("_count"), |
|||
0); |
|||
map.buttons.reserve(num_touch_maps); |
|||
|
|||
for (int j = 0; j < num_touch_maps; ++j) { |
|||
std::string touch_mapping = |
|||
sdl2_config->Get("ControlsGeneral", |
|||
std::string("touch_from_button_maps_") + std::to_string(i) + |
|||
std::string("_bind_") + std::to_string(j), |
|||
""); |
|||
map.buttons.emplace_back(std::move(touch_mapping)); |
|||
} |
|||
|
|||
Settings::values.touch_from_button_maps.emplace_back(std::move(map)); |
|||
} |
|||
} else { |
|||
Settings::values.touch_from_button_maps.emplace_back( |
|||
Settings::TouchFromButtonMap{"default", {}}); |
|||
num_touch_from_button_maps = 1; |
|||
} |
|||
Settings::values.touch_from_button_map_index = std::clamp( |
|||
Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1); |
|||
|
|||
ReadCategory(Settings::Category::Audio); |
|||
ReadCategory(Settings::Category::Core); |
|||
ReadCategory(Settings::Category::Cpu); |
|||
ReadCategory(Settings::Category::CpuDebug); |
|||
ReadCategory(Settings::Category::CpuUnsafe); |
|||
ReadCategory(Settings::Category::Renderer); |
|||
ReadCategory(Settings::Category::RendererAdvanced); |
|||
ReadCategory(Settings::Category::RendererDebug); |
|||
ReadCategory(Settings::Category::System); |
|||
ReadCategory(Settings::Category::SystemAudio); |
|||
ReadCategory(Settings::Category::DataStorage); |
|||
ReadCategory(Settings::Category::Debugging); |
|||
ReadCategory(Settings::Category::DebuggingGraphics); |
|||
ReadCategory(Settings::Category::Miscellaneous); |
|||
ReadCategory(Settings::Category::Network); |
|||
ReadCategory(Settings::Category::WebService); |
|||
|
|||
// Data Storage
|
|||
FS::SetYuzuPath(FS::YuzuPath::NANDDir, |
|||
sdl2_config->Get("Data Storage", "nand_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::NANDDir))); |
|||
FS::SetYuzuPath(FS::YuzuPath::SDMCDir, |
|||
sdl2_config->Get("Data Storage", "sdmc_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::SDMCDir))); |
|||
FS::SetYuzuPath(FS::YuzuPath::LoadDir, |
|||
sdl2_config->Get("Data Storage", "load_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::LoadDir))); |
|||
FS::SetYuzuPath(FS::YuzuPath::DumpDir, |
|||
sdl2_config->Get("Data Storage", "dump_directory", |
|||
FS::GetYuzuPathString(FS::YuzuPath::DumpDir))); |
|||
|
|||
// Debugging
|
|||
Settings::values.record_frame_times = |
|||
sdl2_config->GetBoolean("Debugging", "record_frame_times", false); |
|||
|
|||
const auto title_list = sdl2_config->Get("AddOns", "title_ids", ""); |
|||
std::stringstream ss(title_list); |
|||
std::string line; |
|||
while (std::getline(ss, line, '|')) { |
|||
const auto title_id = std::strtoul(line.c_str(), nullptr, 16); |
|||
const auto disabled_list = sdl2_config->Get("AddOns", "disabled_" + line, ""); |
|||
|
|||
std::stringstream inner_ss(disabled_list); |
|||
std::string inner_line; |
|||
std::vector<std::string> out; |
|||
while (std::getline(inner_ss, inner_line, '|')) { |
|||
out.push_back(inner_line); |
|||
} |
|||
|
|||
Settings::values.disabled_addons.insert_or_assign(title_id, out); |
|||
} |
|||
} |
|||
|
|||
void Config::Reload() { |
|||
LoadINI(DefaultINI::sdl2_config_file); |
|||
ReadValues(); |
|||
} |
|||
@ -1,38 +0,0 @@ |
|||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include <filesystem> |
|||
#include <memory> |
|||
#include <optional> |
|||
#include <string> |
|||
|
|||
#include "common/settings.h" |
|||
|
|||
class INIReader; |
|||
|
|||
class Config { |
|||
std::filesystem::path sdl2_config_loc; |
|||
std::unique_ptr<INIReader> sdl2_config; |
|||
|
|||
bool LoadINI(const std::string& default_contents = "", bool retry = true); |
|||
void ReadValues(); |
|||
|
|||
public: |
|||
explicit Config(std::optional<std::filesystem::path> config_path); |
|||
~Config(); |
|||
|
|||
void Reload(); |
|||
|
|||
private: |
|||
/** |
|||
* Applies a value read from the sdl2_config to a Setting. |
|||
* |
|||
* @param group The name of the INI group |
|||
* @param setting The yuzu setting to modify |
|||
*/ |
|||
template <typename Type, bool ranged> |
|||
void ReadSetting(const std::string& group, Settings::Setting<Type, ranged>& setting); |
|||
void ReadCategory(Settings::Category category); |
|||
}; |
|||
@ -1,553 +0,0 @@ |
|||
// SPDX-FileCopyrightText: 2014 Citra Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
namespace DefaultINI { |
|||
|
|||
const char* sdl2_config_file = |
|||
R"( |
|||
[ControlsP0] |
|||
# The input devices and parameters for each Switch native input |
|||
# The config section determines the player number where the config will be applied on. For example "ControlsP0", "ControlsP1", ... |
|||
# It should be in the format of "engine:[engine_name],[param1]:[value1],[param2]:[value2]..." |
|||
# Escape characters $0 (for ':'), $1 (for ',') and $2 (for '$') can be used in values |
|||
|
|||
# Indicates if this player should be connected at boot |
|||
# 0 (default): Disabled, 1: Enabled |
|||
connected= |
|||
|
|||
# for button input, the following devices are available: |
|||
# - "keyboard" (default) for keyboard input. Required parameters: |
|||
# - "code": the code of the key to bind |
|||
# - "sdl" for joystick input using SDL. Required parameters: |
|||
# - "guid": SDL identification GUID of the joystick |
|||
# - "port": the index of the joystick to bind |
|||
# - "button"(optional): the index of the button to bind |
|||
# - "hat"(optional): the index of the hat to bind as direction buttons |
|||
# - "axis"(optional): the index of the axis to bind |
|||
# - "direction"(only used for hat): the direction name of the hat to bind. Can be "up", "down", "left" or "right" |
|||
# - "threshold"(only used for axis): a float value in (-1.0, 1.0) which the button is |
|||
# triggered if the axis value crosses |
|||
# - "direction"(only used for axis): "+" means the button is triggered when the axis value |
|||
# is greater than the threshold; "-" means the button is triggered when the axis value |
|||
# is smaller than the threshold |
|||
button_a= |
|||
button_b= |
|||
button_x= |
|||
button_y= |
|||
button_lstick= |
|||
button_rstick= |
|||
button_l= |
|||
button_r= |
|||
button_zl= |
|||
button_zr= |
|||
button_plus= |
|||
button_minus= |
|||
button_dleft= |
|||
button_dup= |
|||
button_dright= |
|||
button_ddown= |
|||
button_lstick_left= |
|||
button_lstick_up= |
|||
button_lstick_right= |
|||
button_lstick_down= |
|||
button_sl= |
|||
button_sr= |
|||
button_home= |
|||
button_screenshot= |
|||
|
|||
# for analog input, the following devices are available: |
|||
# - "analog_from_button" (default) for emulating analog input from direction buttons. Required parameters: |
|||
# - "up", "down", "left", "right": sub-devices for each direction. |
|||
# Should be in the format as a button input devices using escape characters, for example, "engine$0keyboard$1code$00" |
|||
# - "modifier": sub-devices as a modifier. |
|||
# - "modifier_scale": a float number representing the applied modifier scale to the analog input. |
|||
# Must be in range of 0.0-1.0. Defaults to 0.5 |
|||
# - "sdl" for joystick input using SDL. Required parameters: |
|||
# - "guid": SDL identification GUID of the joystick |
|||
# - "port": the index of the joystick to bind |
|||
# - "axis_x": the index of the axis to bind as x-axis (default to 0) |
|||
# - "axis_y": the index of the axis to bind as y-axis (default to 1) |
|||
lstick= |
|||
rstick= |
|||
|
|||
# for motion input, the following devices are available: |
|||
# - "keyboard" (default) for emulating random motion input from buttons. Required parameters: |
|||
# - "code": the code of the key to bind |
|||
# - "sdl" for motion input using SDL. Required parameters: |
|||
# - "guid": SDL identification GUID of the joystick |
|||
# - "port": the index of the joystick to bind |
|||
# - "motion": the index of the motion sensor to bind |
|||
# - "cemuhookudp" for motion input using Cemu Hook protocol. Required parameters: |
|||
# - "guid": the IP address of the cemu hook server encoded to a hex string. for example 192.168.0.1 = "c0a80001" |
|||
# - "port": the port of the cemu hook server |
|||
# - "pad": the index of the joystick |
|||
# - "motion": the index of the motion sensor of the joystick to bind |
|||
motionleft= |
|||
motionright= |
|||
|
|||
[ControlsGeneral] |
|||
# To use the debug_pad, prepend `debug_pad_` before each button setting above. |
|||
# i.e. debug_pad_button_a= |
|||
|
|||
# Enable debug pad inputs to the guest |
|||
# 0 (default): Disabled, 1: Enabled |
|||
debug_pad_enabled = |
|||
|
|||
# Enable sdl raw input. Allows to configure up to 8 xinput controllers. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
enable_raw_input = |
|||
|
|||
# Enable yuzu joycon driver instead of SDL drive. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
enable_joycon_driver = |
|||
|
|||
# Emulates an analog input from buttons. Allowing to dial any angle. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
emulate_analog_keyboard = |
|||
|
|||
# Whether to enable or disable vibration |
|||
# 0: Disabled, 1 (default): Enabled |
|||
vibration_enabled= |
|||
|
|||
# Whether to enable or disable accurate vibrations |
|||
# 0 (default): Disabled, 1: Enabled |
|||
enable_accurate_vibrations= |
|||
|
|||
# Enables controller motion inputs |
|||
# 0: Disabled, 1 (default): Enabled |
|||
motion_enabled = |
|||
|
|||
# Defines the udp device's touch screen coordinate system for cemuhookudp devices |
|||
# - "min_x", "min_y", "max_x", "max_y" |
|||
touch_device= |
|||
|
|||
# for mapping buttons to touch inputs. |
|||
#touch_from_button_map=1 |
|||
#touch_from_button_maps_0_name=default |
|||
#touch_from_button_maps_0_count=2 |
|||
#touch_from_button_maps_0_bind_0=foo |
|||
#touch_from_button_maps_0_bind_1=bar |
|||
# etc. |
|||
|
|||
# List of Cemuhook UDP servers, delimited by ','. |
|||
# Default: 127.0.0.1:26760 |
|||
# Example: 127.0.0.1:26760,123.4.5.67:26761 |
|||
udp_input_servers = |
|||
|
|||
# Enable controlling an axis via a mouse input. |
|||
# 0 (default): Off, 1: On |
|||
mouse_panning = |
|||
|
|||
# Set mouse panning horizontal sensitivity. |
|||
# Default: 50.0 |
|||
mouse_panning_x_sensitivity = |
|||
|
|||
# Set mouse panning vertical sensitivity. |
|||
# Default: 50.0 |
|||
mouse_panning_y_sensitivity = |
|||
|
|||
# Set mouse panning deadzone horizontal counterweight. |
|||
# Default: 0.0 |
|||
mouse_panning_deadzone_x_counterweight = |
|||
|
|||
# Set mouse panning deadzone vertical counterweight. |
|||
# Default: 0.0 |
|||
mouse_panning_deadzone_y_counterweight = |
|||
|
|||
# Set mouse panning stick decay strength. |
|||
# Default: 22.0 |
|||
mouse_panning_decay_strength = |
|||
|
|||
# Set mouse panning stick minimum decay. |
|||
# Default: 5.0 |
|||
mouse_panning_minimum_decay = |
|||
|
|||
# Emulate an analog control stick from keyboard inputs. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
emulate_analog_keyboard = |
|||
|
|||
# Enable mouse inputs to the guest |
|||
# 0 (default): Disabled, 1: Enabled |
|||
mouse_enabled = |
|||
|
|||
# Enable keyboard inputs to the guest |
|||
# 0 (default): Disabled, 1: Enabled |
|||
keyboard_enabled = |
|||
|
|||
)" |
|||
R"( |
|||
[Core] |
|||
# Whether to use multi-core for CPU emulation |
|||
# 0: Disabled, 1 (default): Enabled |
|||
use_multi_core = |
|||
|
|||
# Enable unsafe extended guest system memory layout (8GB DRAM) |
|||
# 0 (default): Disabled, 1: Enabled |
|||
use_unsafe_extended_memory_layout = |
|||
|
|||
[Cpu] |
|||
# Adjusts various optimizations. |
|||
# Auto-select mode enables choice unsafe optimizations. |
|||
# Accurate enables only safe optimizations. |
|||
# Unsafe allows any unsafe optimizations. |
|||
# 0 (default): Auto-select, 1: Accurate, 2: Enable unsafe optimizations |
|||
cpu_accuracy = |
|||
|
|||
# Allow disabling safe optimizations. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
cpu_debug_mode = |
|||
|
|||
# Enable inline page tables optimization (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_page_tables = |
|||
|
|||
# Enable block linking CPU optimization (reduce block dispatcher use during predictable jumps) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_block_linking = |
|||
|
|||
# Enable return stack buffer CPU optimization (reduce block dispatcher use during predictable returns) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_return_stack_buffer = |
|||
|
|||
# Enable fast dispatcher CPU optimization (use a two-tiered dispatcher architecture) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_fast_dispatcher = |
|||
|
|||
# Enable context elimination CPU Optimization (reduce host memory use for guest context) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_context_elimination = |
|||
|
|||
# Enable constant propagation CPU optimization (basic IR optimization) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_const_prop = |
|||
|
|||
# Enable miscellaneous CPU optimizations (basic IR optimization) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_misc_ir = |
|||
|
|||
# Enable reduction of memory misalignment checks (reduce memory fallbacks for misaligned access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_reduce_misalign_checks = |
|||
|
|||
# Enable Host MMU Emulation (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_fastmem = |
|||
|
|||
# Enable Host MMU Emulation for exclusive memory instructions (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_fastmem_exclusives = |
|||
|
|||
# Enable fallback on failure of fastmem of exclusive memory instructions (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_recompile_exclusives = |
|||
|
|||
# Enable optimization to ignore invalid memory accesses (faster guest memory access) |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_ignore_memory_aborts = |
|||
|
|||
# Enable unfuse FMA (improve performance on CPUs without FMA) |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_unfuse_fma = |
|||
|
|||
# Enable faster FRSQRTE and FRECPE |
|||
# Only enabled if cpu_accuracy is set to Unsafe. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_reduce_fp_error = |
|||
|
|||
# Enable faster ASIMD instructions (32 bits only) |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_ignore_standard_fpcr = |
|||
|
|||
# Enable inaccurate NaN handling |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_inaccurate_nan = |
|||
|
|||
# Disable address space checks (64 bits only) |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_fastmem_check = |
|||
|
|||
# Enable faster exclusive instructions |
|||
# Only enabled if cpu_accuracy is set to Unsafe. Automatically chosen with cpu_accuracy = Auto-select. |
|||
# 0: Disabled, 1 (default): Enabled |
|||
cpuopt_unsafe_ignore_global_monitor = |
|||
|
|||
)" |
|||
R"( |
|||
[Renderer] |
|||
# Which backend API to use. |
|||
# 0: OpenGL, 1 (default): Vulkan |
|||
backend = |
|||
|
|||
# Whether to enable asynchronous presentation (Vulkan only) |
|||
# 0 (default): Off, 1: On |
|||
async_presentation = |
|||
|
|||
# Enable graphics API debugging mode. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
debug = |
|||
|
|||
# Enable shader feedback. |
|||
# 0 (default): Disabled, 1: Enabled |
|||
renderer_shader_feedback = |
|||
|
|||
# Enable Nsight Aftermath crash dumps |
|||
# 0 (default): Disabled, 1: Enabled |
|||
nsight_aftermath = |
|||
|
|||
# Disable shader loop safety checks, executing the shader without loop logic changes |
|||
# 0 (default): Disabled, 1: Enabled |
|||
disable_shader_loop_safety_checks = |
|||
|
|||
# Which Vulkan physical device to use (defaults to 0) |
|||
vulkan_device = |
|||
|
|||
# 0: 0.5x (360p/540p) [EXPERIMENTAL] |
|||
# 1: 0.75x (540p/810p) [EXPERIMENTAL] |
|||
# 2 (default): 1x (720p/1080p) |
|||
# 3: 1.5x (1080p/1620p) [EXPERIMENTAL] |
|||
# 4: 2x (1440p/2160p) |
|||
# 5: 3x (2160p/3240p) |
|||
# 6: 4x (2880p/4320p) |
|||
# 7: 5x (3600p/5400p) |
|||
# 8: 6x (4320p/6480p) |
|||
# 9: 7x (5040p/7560p) |
|||
# 10: 8x (5760/8640p) |
|||
resolution_setup = |
|||
|
|||
# Pixel filter to use when up- or down-sampling rendered frames. |
|||
# 0: Nearest Neighbor |
|||
# 1 (default): Bilinear |
|||
# 2: Bicubic |
|||
# 3: Gaussian |
|||
# 4: ScaleForce |
|||
# 5: AMD FidelityFX™️ Super Resolution |
|||
scaling_filter = |
|||
|
|||
# Anti-Aliasing (AA) |
|||
# 0 (default): None, 1: FXAA, 2: SMAA |
|||
anti_aliasing = |
|||
|
|||
# Whether to use fullscreen or borderless window mode |
|||
# 0 (Windows default): Borderless window, 1 (All other default): Exclusive fullscreen |
|||
fullscreen_mode = |
|||
|
|||
# Aspect ratio |
|||
# 0: Default (16:9), 1: Force 4:3, 2: Force 21:9, 3: Force 16:10, 4: Stretch to Window |
|||
aspect_ratio = |
|||
|
|||
# Anisotropic filtering |
|||
# 0: Default, 1: 2x, 2: 4x, 3: 8x, 4: 16x |
|||
max_anisotropy = |
|||
|
|||
# Whether to enable VSync or not. |
|||
# OpenGL: Values other than 0 enable VSync |
|||
# Vulkan: FIFO is selected if the requested mode is not supported by the driver. |
|||
# FIFO (VSync) does not drop frames or exhibit tearing but is limited by the screen refresh rate. |
|||
# FIFO Relaxed is similar to FIFO but allows tearing as it recovers from a slow down. |
|||
# Mailbox can have lower latency than FIFO and does not tear but may drop frames. |
|||
# Immediate (no synchronization) just presents whatever is available and can exhibit tearing. |
|||
# 0: Immediate (Off), 1: Mailbox, 2 (Default): FIFO (On), 3: FIFO Relaxed |
|||
use_vsync = |
|||
|
|||
# Selects the OpenGL shader backend. NV_gpu_program5 is required for GLASM. If NV_gpu_program5 is |
|||
# not available and GLASM is selected, GLSL will be used. |
|||
# 0: GLSL, 1 (default): GLASM, 2: SPIR-V |
|||
shader_backend = |
|||
|
|||
# Uses reactive flushing instead of predictive flushing. Allowing a more accurate syncing of memory. |
|||
# 0: Off, 1 (default): On |
|||
use_reactive_flushing = |
|||
|
|||
# Whether to allow asynchronous shader building. |
|||
# 0 (default): Off, 1: On |
|||
use_asynchronous_shaders = |
|||
|
|||
# NVDEC emulation. |
|||
# 0: Disabled, 1: CPU Decoding, 2 (default): GPU Decoding |
|||
nvdec_emulation = |
|||
|
|||
# Accelerate ASTC texture decoding. |
|||
# 0: Off, 1 (default): On |
|||
accelerate_astc = |
|||
|
|||
# Decode ASTC textures asynchronously. |
|||
# 0 (default): Off, 1: On |
|||
async_astc = |
|||
|
|||
# Recompress ASTC textures to a different format. |
|||
# 0 (default): Uncompressed, 1: BC1 (Low quality), 2: BC3: (Medium quality) |
|||
async_astc = |
|||
|
|||
# Turns on the speed limiter, which will limit the emulation speed to the desired speed limit value |
|||
# 0: Off, 1: On (default) |
|||
use_speed_limit = |
|||
|
|||
# Limits the speed of the game to run no faster than this value as a percentage of target speed |
|||
# 1 - 9999: Speed limit as a percentage of target game speed. 100 (default) |
|||
speed_limit = |
|||
|
|||
# Whether to use disk based shader cache |
|||
# 0: Off, 1 (default): On |
|||
use_disk_shader_cache = |
|||
|
|||
# Which gpu accuracy level to use |
|||
# 0: Normal, 1 (default): High, 2: Extreme (Very slow) |
|||
gpu_accuracy = |
|||
|
|||
# Whether to use asynchronous GPU emulation |
|||
# 0 : Off (slow), 1 (default): On (fast) |
|||
use_asynchronous_gpu_emulation = |
|||
|
|||
# Inform the guest that GPU operations completed more quickly than they did. |
|||
# 0: Off, 1 (default): On |
|||
use_fast_gpu_time = |
|||
|
|||
# Whether to use garbage collection or not for GPU caches. |
|||
# 0 (default): Off, 1: On |
|||
use_caches_gc = |
|||
|
|||
# The clear color for the renderer. What shows up on the sides of the bottom screen. |
|||
# Must be in range of 0-255. Defaults to 0 for all. |
|||
bg_red = |
|||
bg_blue = |
|||
bg_green = |
|||
|
|||
)" |
|||
R"( |
|||
[Audio] |
|||
# Which audio output engine to use. |
|||
# auto (default): Auto-select |
|||
# cubeb: Cubeb audio engine (if available) |
|||
# sdl2: SDL2 audio engine (if available) |
|||
# null: No audio output |
|||
output_engine = |
|||
|
|||
# Which audio device to use. |
|||
# auto (default): Auto-select |
|||
output_device = |
|||
|
|||
# Output volume. |
|||
# 100 (default): 100%, 0; mute |
|||
volume = |
|||
|
|||
[Data Storage] |
|||
# Whether to create a virtual SD card. |
|||
# 1 (default): Yes, 0: No |
|||
use_virtual_sd = |
|||
|
|||
# Whether or not to enable gamecard emulation |
|||
# 1: Yes, 0 (default): No |
|||
gamecard_inserted = |
|||
|
|||
# Whether or not the gamecard should be emulated as the current game |
|||
# If 'gamecard_inserted' is 0 this setting is irrelevant |
|||
# 1: Yes, 0 (default): No |
|||
gamecard_current_game = |
|||
|
|||
# Path to an XCI file to use as the gamecard |
|||
# If 'gamecard_inserted' is 0 this setting is irrelevant |
|||
# If 'gamecard_current_game' is 1 this setting is irrelevant |
|||
gamecard_path = |
|||
|
|||
[System] |
|||
# Whether the system is docked |
|||
# 1 (default): Yes, 0: No |
|||
use_docked_mode = |
|||
|
|||
# Sets the seed for the RNG generator built into the switch |
|||
# rng_seed will be ignored and randomly generated if rng_seed_enabled is false |
|||
rng_seed_enabled = |
|||
rng_seed = |
|||
|
|||
# Sets the current time (in seconds since 12:00 AM Jan 1, 1970) that will be used by the time service |
|||
# This will auto-increment, with the time set being the time the game is started |
|||
# This override will only occur if custom_rtc_enabled is true, otherwise the current time is used |
|||
custom_rtc_enabled = |
|||
custom_rtc = |
|||
|
|||
# Sets the systems language index |
|||
# 0: Japanese, 1: English (default), 2: French, 3: German, 4: Italian, 5: Spanish, 6: Chinese, |
|||
# 7: Korean, 8: Dutch, 9: Portuguese, 10: Russian, 11: Taiwanese, 12: British English, 13: Canadian French, |
|||
# 14: Latin American Spanish, 15: Simplified Chinese, 16: Traditional Chinese, 17: Brazilian Portuguese |
|||
language_index = |
|||
|
|||
# The system region that yuzu will use during emulation |
|||
# -1: Auto-select (default), 0: Japan, 1: USA, 2: Europe, 3: Australia, 4: China, 5: Korea, 6: Taiwan |
|||
region_index = |
|||
|
|||
# The system time zone that yuzu will use during emulation |
|||
# 0: Auto-select (default), 1: Default (system archive value), Others: Index for specified time zone |
|||
time_zone_index = |
|||
|
|||
# Sets the sound output mode. |
|||
# 0: Mono, 1 (default): Stereo, 2: Surround |
|||
sound_index = |
|||
|
|||
[Miscellaneous] |
|||
# A filter which removes logs below a certain logging level. |
|||
# Examples: *:Debug Kernel.SVC:Trace Service.*:Critical |
|||
log_filter = *:Trace |
|||
|
|||
# Use developer keys |
|||
# 0 (default): Disabled, 1: Enabled |
|||
use_dev_keys = |
|||
|
|||
[Debugging] |
|||
# Record frame time data, can be found in the log directory. Boolean value |
|||
record_frame_times = |
|||
# Determines whether or not yuzu will dump the ExeFS of all games it attempts to load while loading them |
|||
dump_exefs=false |
|||
# Determines whether or not yuzu will dump all NSOs it attempts to load while loading them |
|||
dump_nso=false |
|||
# Determines whether or not yuzu will save the filesystem access log. |
|||
enable_fs_access_log=false |
|||
# Enables verbose reporting services |
|||
reporting_services = |
|||
# Determines whether or not yuzu will report to the game that the emulated console is in Kiosk Mode |
|||
# false: Retail/Normal Mode (default), true: Kiosk Mode |
|||
quest_flag = |
|||
# Determines whether debug asserts should be enabled, which will throw an exception on asserts. |
|||
# false: Disabled (default), true: Enabled |
|||
use_debug_asserts = |
|||
# Determines whether unimplemented HLE service calls should be automatically stubbed. |
|||
# false: Disabled (default), true: Enabled |
|||
use_auto_stub = |
|||
# Enables/Disables the macro JIT compiler |
|||
disable_macro_jit=false |
|||
# Determines whether to enable the GDB stub and wait for the debugger to attach before running. |
|||
# false: Disabled (default), true: Enabled |
|||
use_gdbstub=false |
|||
# The port to use for the GDB server, if it is enabled. |
|||
gdbstub_port=6543 |
|||
|
|||
[WebService] |
|||
# Whether or not to enable telemetry |
|||
# 0: No, 1 (default): Yes |
|||
enable_telemetry = |
|||
# URL for Web API |
|||
web_api_url = https://api.yuzu-emu.org |
|||
# Username and token for yuzu Web Service |
|||
# See https://profile.yuzu-emu.org/ for more info |
|||
yuzu_username = |
|||
yuzu_token = |
|||
|
|||
[Network] |
|||
# Name of the network interface device to use with yuzu LAN play. |
|||
# e.g. On *nix: 'enp7s0', 'wlp6s0u1u3u3', 'lo' |
|||
# e.g. On Windows: 'Ethernet', 'Wi-Fi' |
|||
network_interface = |
|||
|
|||
[AddOns] |
|||
# Used to disable add-ons |
|||
# List of title IDs of games that will have add-ons disabled (separated by '|'): |
|||
title_ids = |
|||
# 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 '|') |
|||
# e.x. disabled_0100000000010000 = Update|DLC <- disables Updates and DLC on Super Mario Odyssey |
|||
)"; |
|||
} // namespace DefaultINI |
|||
@ -0,0 +1,257 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project
|
|||
// SPDX-License-Identifier: GPL-2.0-or-later
|
|||
|
|||
// SDL will break our main function in yuzu-cmd if we don't define this before adding SDL.h
|
|||
#define SDL_MAIN_HANDLED
|
|||
#include <SDL.h>
|
|||
|
|||
#include "input_common/main.h"
|
|||
#include "sdl_config.h"
|
|||
|
|||
const std::array<int, Settings::NativeButton::NumButtons> SdlConfig::default_buttons = { |
|||
SDL_SCANCODE_A, SDL_SCANCODE_S, SDL_SCANCODE_Z, SDL_SCANCODE_X, SDL_SCANCODE_T, |
|||
SDL_SCANCODE_G, SDL_SCANCODE_F, SDL_SCANCODE_H, SDL_SCANCODE_Q, SDL_SCANCODE_W, |
|||
SDL_SCANCODE_M, SDL_SCANCODE_N, SDL_SCANCODE_1, SDL_SCANCODE_2, SDL_SCANCODE_B, |
|||
}; |
|||
|
|||
const std::array<int, Settings::NativeMotion::NumMotions> SdlConfig::default_motions = { |
|||
SDL_SCANCODE_7, |
|||
SDL_SCANCODE_8, |
|||
}; |
|||
|
|||
const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> SdlConfig::default_analogs{ |
|||
{ |
|||
{ |
|||
SDL_SCANCODE_UP, |
|||
SDL_SCANCODE_DOWN, |
|||
SDL_SCANCODE_LEFT, |
|||
SDL_SCANCODE_RIGHT, |
|||
}, |
|||
{ |
|||
SDL_SCANCODE_I, |
|||
SDL_SCANCODE_K, |
|||
SDL_SCANCODE_J, |
|||
SDL_SCANCODE_L, |
|||
}, |
|||
}}; |
|||
|
|||
const std::array<int, 2> SdlConfig::default_stick_mod = { |
|||
SDL_SCANCODE_D, |
|||
0, |
|||
}; |
|||
|
|||
const std::array<int, 2> SdlConfig::default_ringcon_analogs{{ |
|||
0, |
|||
0, |
|||
}}; |
|||
|
|||
SdlConfig::SdlConfig(const std::optional<std::string> config_path) { |
|||
Initialize(config_path); |
|||
ReadSdlValues(); |
|||
SaveSdlValues(); |
|||
} |
|||
|
|||
SdlConfig::~SdlConfig() { |
|||
if (global) { |
|||
SdlConfig::SaveAllValues(); |
|||
} |
|||
} |
|||
|
|||
void SdlConfig::ReloadAllValues() { |
|||
Reload(); |
|||
ReadSdlValues(); |
|||
SaveSdlValues(); |
|||
} |
|||
|
|||
void SdlConfig::SaveAllValues() { |
|||
Save(); |
|||
SaveSdlValues(); |
|||
} |
|||
|
|||
void SdlConfig::ReadSdlValues() { |
|||
ReadSdlControlValues(); |
|||
} |
|||
|
|||
void SdlConfig::ReadSdlControlValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Controls)); |
|||
|
|||
Settings::values.players.SetGlobal(!IsCustomConfig()); |
|||
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { |
|||
ReadSdlPlayerValues(p); |
|||
} |
|||
if (IsCustomConfig()) { |
|||
EndGroup(); |
|||
return; |
|||
} |
|||
ReadDebugControlValues(); |
|||
ReadHidbusValues(); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void SdlConfig::ReadSdlPlayerValues(const std::size_t player_index) { |
|||
std::string player_prefix; |
|||
if (type != ConfigType::InputProfile) { |
|||
player_prefix.append("player_").append(ToString(player_index)).append("_"); |
|||
} |
|||
|
|||
auto& player = Settings::values.players.GetValue()[player_index]; |
|||
if (IsCustomConfig()) { |
|||
const auto profile_name = |
|||
ReadStringSetting(std::string(player_prefix).append("profile_name")); |
|||
if (profile_name.empty()) { |
|||
// Use the global input config
|
|||
player = Settings::values.players.GetValue(true)[player_index]; |
|||
return; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
auto& player_buttons = player.buttons[i]; |
|||
|
|||
player_buttons = ReadStringSetting( |
|||
std::string(player_prefix).append(Settings::NativeButton::mapping[i]), default_param); |
|||
if (player_buttons.empty()) { |
|||
player_buttons = default_param; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_stick_mod[i], 0.5f); |
|||
auto& player_analogs = player.analogs[i]; |
|||
|
|||
player_analogs = ReadStringSetting( |
|||
std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]), default_param); |
|||
if (player_analogs.empty()) { |
|||
player_analogs = default_param; |
|||
} |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]); |
|||
auto& player_motions = player.motions[i]; |
|||
|
|||
player_motions = ReadStringSetting( |
|||
std::string(player_prefix).append(Settings::NativeMotion::mapping[i]), default_param); |
|||
if (player_motions.empty()) { |
|||
player_motions = default_param; |
|||
} |
|||
} |
|||
} |
|||
|
|||
void SdlConfig::ReadDebugControlValues() { |
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
auto& debug_pad_buttons = Settings::values.debug_pad_buttons[i]; |
|||
debug_pad_buttons = ReadStringSetting( |
|||
std::string("debug_pad_").append(Settings::NativeButton::mapping[i]), default_param); |
|||
if (debug_pad_buttons.empty()) { |
|||
debug_pad_buttons = default_param; |
|||
} |
|||
} |
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_stick_mod[i], 0.5f); |
|||
auto& debug_pad_analogs = Settings::values.debug_pad_analogs[i]; |
|||
debug_pad_analogs = ReadStringSetting( |
|||
std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]), default_param); |
|||
if (debug_pad_analogs.empty()) { |
|||
debug_pad_analogs = default_param; |
|||
} |
|||
} |
|||
} |
|||
|
|||
void SdlConfig::ReadHidbusValues() { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f); |
|||
auto& ringcon_analogs = Settings::values.ringcon_analogs; |
|||
|
|||
ringcon_analogs = ReadStringSetting(std::string("ring_controller"), default_param); |
|||
if (ringcon_analogs.empty()) { |
|||
ringcon_analogs = default_param; |
|||
} |
|||
} |
|||
|
|||
void SdlConfig::SaveSdlValues() { |
|||
SaveSdlControlValues(); |
|||
|
|||
WriteToIni(); |
|||
} |
|||
|
|||
void SdlConfig::SaveSdlControlValues() { |
|||
BeginGroup(Settings::TranslateCategory(Settings::Category::Controls)); |
|||
|
|||
Settings::values.players.SetGlobal(!IsCustomConfig()); |
|||
for (std::size_t p = 0; p < Settings::values.players.GetValue().size(); ++p) { |
|||
SaveSdlPlayerValues(p); |
|||
} |
|||
if (IsCustomConfig()) { |
|||
EndGroup(); |
|||
return; |
|||
} |
|||
SaveDebugControlValues(); |
|||
SaveHidbusValues(); |
|||
|
|||
EndGroup(); |
|||
} |
|||
|
|||
void SdlConfig::SaveSdlPlayerValues(const std::size_t player_index) { |
|||
std::string player_prefix; |
|||
if (type != ConfigType::InputProfile) { |
|||
player_prefix = std::string("player_").append(ToString(player_index)).append("_"); |
|||
} |
|||
|
|||
const auto& player = Settings::values.players.GetValue()[player_index]; |
|||
if (IsCustomConfig() && player.profile_name.empty()) { |
|||
// No custom profile selected
|
|||
return; |
|||
} |
|||
|
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
WriteSetting(std::string(player_prefix).append(Settings::NativeButton::mapping[i]), |
|||
player.buttons[i], std::make_optional(default_param)); |
|||
} |
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_stick_mod[i], 0.5f); |
|||
WriteSetting(std::string(player_prefix).append(Settings::NativeAnalog::mapping[i]), |
|||
player.analogs[i], std::make_optional(default_param)); |
|||
} |
|||
for (int i = 0; i < Settings::NativeMotion::NumMotions; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_motions[i]); |
|||
WriteSetting(std::string(player_prefix).append(Settings::NativeMotion::mapping[i]), |
|||
player.motions[i], std::make_optional(default_param)); |
|||
} |
|||
} |
|||
|
|||
void SdlConfig::SaveDebugControlValues() { |
|||
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) { |
|||
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]); |
|||
WriteSetting(std::string("debug_pad_").append(Settings::NativeButton::mapping[i]), |
|||
Settings::values.debug_pad_buttons[i], std::make_optional(default_param)); |
|||
} |
|||
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
default_analogs[i][0], default_analogs[i][1], default_analogs[i][2], |
|||
default_analogs[i][3], default_stick_mod[i], 0.5f); |
|||
WriteSetting(std::string("debug_pad_").append(Settings::NativeAnalog::mapping[i]), |
|||
Settings::values.debug_pad_analogs[i], std::make_optional(default_param)); |
|||
} |
|||
} |
|||
|
|||
void SdlConfig::SaveHidbusValues() { |
|||
const std::string default_param = InputCommon::GenerateAnalogParamFromKeys( |
|||
0, 0, default_ringcon_analogs[0], default_ringcon_analogs[1], 0, 0.05f); |
|||
WriteSetting(std::string("ring_controller"), Settings::values.ringcon_analogs, |
|||
std::make_optional(default_param)); |
|||
} |
|||
|
|||
std::vector<Settings::BasicSetting*>& SdlConfig::FindRelevantList(Settings::Category category) { |
|||
return Settings::values.linkage.by_category[category]; |
|||
} |
|||
@ -0,0 +1,49 @@ |
|||
// SPDX-FileCopyrightText: 2023 yuzu Emulator Project |
|||
// SPDX-License-Identifier: GPL-2.0-or-later |
|||
|
|||
#pragma once |
|||
|
|||
#include "frontend_common/config.h" |
|||
|
|||
class SdlConfig final : public Config { |
|||
public: |
|||
explicit SdlConfig(std::optional<std::string> config_path); |
|||
~SdlConfig() override; |
|||
|
|||
void ReloadAllValues() override; |
|||
void SaveAllValues() override; |
|||
|
|||
protected: |
|||
void ReadSdlValues(); |
|||
void ReadSdlPlayerValues(std::size_t player_index); |
|||
void ReadSdlControlValues(); |
|||
void ReadHidbusValues() override; |
|||
void ReadDebugControlValues() override; |
|||
void ReadPathValues() override {} |
|||
void ReadShortcutValues() override {} |
|||
void ReadUIValues() override {} |
|||
void ReadUIGamelistValues() override {} |
|||
void ReadUILayoutValues() override {} |
|||
void ReadMultiplayerValues() override {} |
|||
|
|||
void SaveSdlValues(); |
|||
void SaveSdlPlayerValues(std::size_t player_index); |
|||
void SaveSdlControlValues(); |
|||
void SaveHidbusValues() override; |
|||
void SaveDebugControlValues() override; |
|||
void SavePathValues() override {} |
|||
void SaveShortcutValues() override {} |
|||
void SaveUIValues() override {} |
|||
void SaveUIGamelistValues() override {} |
|||
void SaveUILayoutValues() override {} |
|||
void SaveMultiplayerValues() override {} |
|||
|
|||
std::vector<Settings::BasicSetting*>& FindRelevantList(Settings::Category category) override; |
|||
|
|||
public: |
|||
static const std::array<int, Settings::NativeButton::NumButtons> default_buttons; |
|||
static const std::array<int, Settings::NativeMotion::NumMotions> default_motions; |
|||
static const std::array<std::array<int, 4>, Settings::NativeAnalog::NumAnalogs> default_analogs; |
|||
static const std::array<int, 2> default_stick_mod; |
|||
static const std::array<int, 2> default_ringcon_analogs; |
|||
}; |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue