config: Unify config handling under frontend_common

Replaces every way of handling config for each frontend with SimpleIni. frontend_common's Config class is at the center where it saves and loads all of the cross-platform settings and provides a set of pure virtual functions for platform specific settings.

As a result of making config handling platform specific, several parts had to be moved to each platform's own config class or to other parts. Default keys were put in platform specific config classes and translatable strings for Qt were moved to shared_translation. Default hotkeys, default_theme, window geometry, and qt metatypes were moved to uisettings. Additionally, to reduce dependence on Qt, QStrings were converted to std::strings where applicable.
This commit is contained in:
t895
2023-11-12 02:03:01 -05:00
parent 8da5bd27e9
commit da14c7b8e4
57 changed files with 2546 additions and 3439 deletions

View File

@ -38,8 +38,6 @@ add_executable(yuzu
compatdb.ui
compatibility_list.cpp
compatibility_list.h
configuration/config.cpp
configuration/config.h
configuration/configuration_shared.cpp
configuration/configuration_shared.h
configuration/configure.ui
@ -147,6 +145,8 @@ add_executable(yuzu
configuration/shared_translation.h
configuration/shared_widget.cpp
configuration/shared_widget.h
configuration/qt_config.cpp
configuration/qt_config.h
debugger/console.cpp
debugger/console.h
debugger/controller.cpp
@ -344,7 +344,7 @@ endif()
create_target_directory_groups(yuzu)
target_link_libraries(yuzu PRIVATE common core input_common network video_core)
target_link_libraries(yuzu PRIVATE common core input_common frontend_common network video_core)
target_link_libraries(yuzu PRIVATE Boost::headers glad Qt${QT_MAJOR_VERSION}::Widgets)
target_link_libraries(yuzu PRIVATE ${PLATFORM_LIBRARIES} Threads::Threads)

File diff suppressed because it is too large Load Diff

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);

View File

@ -10,10 +10,10 @@
#include <QStandardItemModel>
#include <QTimer>
#include "common/settings.h"
#include "input_common/drivers/camera.h"
#include "input_common/main.h"
#include "ui_configure_camera.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_camera.h"
ConfigureCamera::ConfigureCamera(QWidget* parent, InputCommon::InputSubsystem* input_subsystem_)

View File

@ -8,7 +8,6 @@
#include "core/core.h"
#include "ui_configure.h"
#include "vk_device_info.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_audio.h"
#include "yuzu/configuration/configure_cpu.h"
#include "yuzu/configuration/configure_debug_tab.h"

View File

@ -9,10 +9,11 @@
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "frontend_common/config.h"
#include "ui_configure_hotkeys.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_hotkeys.h"
#include "yuzu/hotkeys.h"
#include "yuzu/uisettings.h"
#include "yuzu/util/sequence_dialog/sequence_dialog.h"
constexpr int name_column = 0;
@ -62,18 +63,21 @@ ConfigureHotkeys::~ConfigureHotkeys() = default;
void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) {
for (const auto& group : registry.hotkey_groups) {
QString parent_item_data = QString::fromStdString(group.first);
auto* parent_item =
new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(group.first)));
new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(parent_item_data)));
parent_item->setEditable(false);
parent_item->setData(group.first);
parent_item->setData(parent_item_data);
for (const auto& hotkey : group.second) {
auto* action =
new QStandardItem(QCoreApplication::translate("Hotkeys", qPrintable(hotkey.first)));
QString hotkey_action_data = QString::fromStdString(hotkey.first);
auto* action = new QStandardItem(
QCoreApplication::translate("Hotkeys", qPrintable(hotkey_action_data)));
auto* keyseq =
new QStandardItem(hotkey.second.keyseq.toString(QKeySequence::NativeText));
auto* controller_keyseq = new QStandardItem(hotkey.second.controller_keyseq);
auto* controller_keyseq =
new QStandardItem(QString::fromStdString(hotkey.second.controller_keyseq));
action->setEditable(false);
action->setData(hotkey.first);
action->setData(hotkey_action_data);
keyseq->setEditable(false);
controller_keyseq->setEditable(false);
parent_item->appendRow({action, keyseq, controller_keyseq});
@ -301,13 +305,13 @@ void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) {
const QStandardItem* controller_keyseq =
parent->child(key_column_id, controller_column);
for (auto& [group, sub_actions] : registry.hotkey_groups) {
if (group != parent->data())
if (group != parent->data().toString().toStdString())
continue;
for (auto& [action_name, hotkey] : sub_actions) {
if (action_name != action->data())
if (action_name != action->data().toString().toStdString())
continue;
hotkey.keyseq = QKeySequence(keyseq->text());
hotkey.controller_keyseq = controller_keyseq->text();
hotkey.controller_keyseq = controller_keyseq->text().toStdString();
}
}
}
@ -319,7 +323,7 @@ void ConfigureHotkeys::ApplyConfiguration(HotkeyRegistry& registry) {
void ConfigureHotkeys::RestoreDefaults() {
for (int r = 0; r < model->rowCount(); ++r) {
const QStandardItem* parent = model->item(r, 0);
const int hotkey_size = static_cast<int>(Config::default_hotkeys.size());
const int hotkey_size = static_cast<int>(UISettings::default_hotkeys.size());
if (hotkey_size != parent->rowCount()) {
QMessageBox::warning(this, tr("Invalid hotkey settings"),
@ -330,10 +334,11 @@ void ConfigureHotkeys::RestoreDefaults() {
for (int r2 = 0; r2 < parent->rowCount(); ++r2) {
model->item(r, 0)
->child(r2, hotkey_column)
->setText(Config::default_hotkeys[r2].shortcut.keyseq);
->setText(QString::fromStdString(UISettings::default_hotkeys[r2].shortcut.keyseq));
model->item(r, 0)
->child(r2, controller_column)
->setText(Config::default_hotkeys[r2].shortcut.controller_keyseq);
->setText(QString::fromStdString(
UISettings::default_hotkeys[r2].shortcut.controller_keyseq));
}
}
}
@ -379,7 +384,7 @@ void ConfigureHotkeys::PopupContextMenu(const QPoint& menu_location) {
void ConfigureHotkeys::RestoreControllerHotkey(QModelIndex index) {
const QString& default_key_sequence =
Config::default_hotkeys[index.row()].shortcut.controller_keyseq;
QString::fromStdString(UISettings::default_hotkeys[index.row()].shortcut.controller_keyseq);
const auto [key_sequence_used, used_action] = IsUsedControllerKey(default_key_sequence);
if (key_sequence_used && default_key_sequence != model->data(index).toString()) {
@ -393,7 +398,8 @@ void ConfigureHotkeys::RestoreControllerHotkey(QModelIndex index) {
void ConfigureHotkeys::RestoreHotkey(QModelIndex index) {
const QKeySequence& default_key_sequence = QKeySequence::fromString(
Config::default_hotkeys[index.row()].shortcut.keyseq, QKeySequence::NativeText);
QString::fromStdString(UISettings::default_hotkeys[index.row()].shortcut.keyseq),
QKeySequence::NativeText);
const auto [key_sequence_used, used_action] = IsUsedKey(default_key_sequence);
if (key_sequence_used && default_key_sequence != QKeySequence(model->data(index).toString())) {

View File

@ -5,12 +5,12 @@
#include "core/core.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "frontend_common/config.h"
#include "ui_configure_input_per_game.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input_per_game.h"
#include "yuzu/configuration/input_profiles.h"
ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, Config* config_,
ConfigureInputPerGame::ConfigureInputPerGame(Core::System& system_, QtConfig* config_,
QWidget* parent)
: QWidget(parent), ui(std::make_unique<Ui::ConfigureInputPerGame>()),
profiles(std::make_unique<InputProfiles>()), system{system_}, config{config_} {
@ -110,6 +110,6 @@ void ConfigureInputPerGame::SaveConfiguration() {
// Clear all controls from the config in case the user reverted back to globals
config->ClearControlPlayerValues();
for (size_t index = 0; index < Settings::values.players.GetValue().size(); ++index) {
config->SaveControlPlayerValue(index);
config->SaveQtControlPlayerValues(index);
}
}

View File

@ -9,6 +9,7 @@
#include "ui_configure_input_per_game.h"
#include "yuzu/configuration/input_profiles.h"
#include "yuzu/configuration/qt_config.h"
class QComboBox;
@ -22,7 +23,7 @@ class ConfigureInputPerGame : public QWidget {
Q_OBJECT
public:
explicit ConfigureInputPerGame(Core::System& system_, Config* config_,
explicit ConfigureInputPerGame(Core::System& system_, QtConfig* config_,
QWidget* parent = nullptr);
/// Load and Save configurations to settings file.
@ -41,5 +42,5 @@ private:
std::array<QComboBox*, 8> profile_comboboxes;
Core::System& system;
Config* config;
QtConfig* config;
};

View File

@ -12,15 +12,16 @@
#include <QTimer>
#include "common/assert.h"
#include "common/param_package.h"
#include "configuration/qt_config.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "core/hid/hid_types.h"
#include "frontend_common/config.h"
#include "input_common/drivers/keyboard.h"
#include "input_common/drivers/mouse.h"
#include "input_common/main.h"
#include "ui_configure_input_player.h"
#include "yuzu/bootmanager.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input_player.h"
#include "yuzu/configuration/configure_input_player_widget.h"
#include "yuzu/configuration/configure_mouse_panning.h"
@ -1397,25 +1398,25 @@ void ConfigureInputPlayer::UpdateMappingWithDefaults() {
for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; ++button_id) {
emulated_controller->SetButtonParam(
button_id, Common::ParamPackage{InputCommon::GenerateKeyboardParam(
Config::default_buttons[button_id])});
QtConfig::default_buttons[button_id])});
}
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; ++analog_id) {
Common::ParamPackage analog_param{};
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; ++sub_button_id) {
Common::ParamPackage params{InputCommon::GenerateKeyboardParam(
Config::default_analogs[analog_id][sub_button_id])};
QtConfig::default_analogs[analog_id][sub_button_id])};
SetAnalogParam(params, analog_param, analog_sub_buttons[sub_button_id]);
}
analog_param.Set("modifier", InputCommon::GenerateKeyboardParam(
Config::default_stick_mod[analog_id]));
QtConfig::default_stick_mod[analog_id]));
emulated_controller->SetStickParam(analog_id, analog_param);
}
for (int motion_id = 0; motion_id < Settings::NativeMotion::NumMotions; ++motion_id) {
emulated_controller->SetMotionParam(
motion_id, Common::ParamPackage{InputCommon::GenerateKeyboardParam(
Config::default_motions[motion_id])});
QtConfig::default_motions[motion_id])});
}
// If mouse is selected we want to override with mappings from the driver

View File

@ -25,8 +25,8 @@
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/xts_archive.h"
#include "core/loader/loader.h"
#include "frontend_common/config.h"
#include "ui_configure_per_game.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configuration_shared.h"
#include "yuzu/configuration/configure_audio.h"
#include "yuzu/configuration/configure_cpu.h"
@ -50,8 +50,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id_, const std::st
const auto file_path = std::filesystem::path(Common::FS::ToU8String(file_name));
const auto config_file_name = title_id == 0 ? Common::FS::PathToUTF8String(file_path.filename())
: fmt::format("{:016X}", title_id);
game_config = std::make_unique<Config>(config_file_name, Config::ConfigType::PerGameConfig);
game_config = std::make_unique<QtConfig>(config_file_name, Config::ConfigType::PerGameConfig);
addons_tab = std::make_unique<ConfigurePerGameAddons>(system_, this);
audio_tab = std::make_unique<ConfigureAudio>(system_, tab_group, *builder, this);
cpu_tab = std::make_unique<ConfigureCpu>(system_, tab_group, *builder, this);
@ -108,7 +107,7 @@ void ConfigurePerGame::ApplyConfiguration() {
system.ApplySettings();
Settings::LogSettings();
game_config->Save();
game_config->SaveAllValues();
}
void ConfigurePerGame::changeEvent(QEvent* event) {

View File

@ -12,9 +12,10 @@
#include "configuration/shared_widget.h"
#include "core/file_sys/vfs_types.h"
#include "frontend_common/config.h"
#include "vk_device_info.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configuration_shared.h"
#include "yuzu/configuration/qt_config.h"
#include "yuzu/configuration/shared_translation.h"
namespace Core {
@ -72,7 +73,7 @@ private:
QGraphicsScene* scene;
std::unique_ptr<Config> game_config;
std::unique_ptr<QtConfig> game_config;
Core::System& system;
std::unique_ptr<ConfigurationShared::Builder> builder;

View File

@ -19,7 +19,6 @@
#include "core/file_sys/xts_archive.h"
#include "core/loader/loader.h"
#include "ui_configure_per_game_addons.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_input.h"
#include "yuzu/configuration/configure_per_game_addons.h"
#include "yuzu/uisettings.h"

View File

@ -8,6 +8,7 @@
#include <QTimer>
#include <fmt/format.h>
#include "configuration/qt_config.h"
#include "core/hid/emulated_controller.h"
#include "core/hid/hid_core.h"
#include "input_common/drivers/keyboard.h"
@ -15,7 +16,6 @@
#include "input_common/main.h"
#include "ui_configure_ringcon.h"
#include "yuzu/bootmanager.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_ringcon.h"
const std::array<std::string, ConfigureRingController::ANALOG_SUB_BUTTONS_NUM>
@ -270,7 +270,7 @@ void ConfigureRingController::LoadConfiguration() {
void ConfigureRingController::RestoreDefaults() {
const std::string default_ring_string = InputCommon::GenerateAnalogParamFromKeys(
0, 0, Config::default_ringcon_analogs[0], Config::default_ringcon_analogs[1], 0, 0.05f);
0, 0, QtConfig::default_ringcon_analogs[0], QtConfig::default_ringcon_analogs[1], 0, 0.05f);
emulated_controller->SetRingParam(Common::ParamPackage(default_ring_string));
UpdateUI();
}

View File

@ -16,7 +16,6 @@
#include "core/core.h"
#include "core/hle/service/time/time_manager.h"
#include "ui_configure_system.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configuration_shared.h"
#include "yuzu/configuration/configure_system.h"
#include "yuzu/configuration/shared_widget.h"

View File

@ -2,8 +2,8 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <memory>
#include "common/settings.h"
#include "ui_configure_touchscreen_advanced.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_touchscreen_advanced.h"
ConfigureTouchscreenAdvanced::ConfigureTouchscreenAdvanced(QWidget* parent)

View File

@ -164,7 +164,7 @@ ConfigureUi::~ConfigureUi() = default;
void ConfigureUi::ApplyConfiguration() {
UISettings::values.theme =
ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString();
ui->theme_combobox->itemData(ui->theme_combobox->currentIndex()).toString().toStdString();
UISettings::values.show_add_ons = ui->show_add_ons->isChecked();
UISettings::values.show_compat = ui->show_compat->isChecked();
UISettings::values.show_size = ui->show_size->isChecked();
@ -191,9 +191,10 @@ void ConfigureUi::RequestGameListUpdate() {
}
void ConfigureUi::SetConfiguration() {
ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
ui->theme_combobox->setCurrentIndex(
ui->theme_combobox->findData(QString::fromStdString(UISettings::values.theme)));
ui->language_combobox->setCurrentIndex(
ui->language_combobox->findData(UISettings::values.language));
ui->language_combobox->findData(QString::fromStdString(UISettings::values.language)));
ui->show_add_ons->setChecked(UISettings::values.show_add_ons.GetValue());
ui->show_compat->setChecked(UISettings::values.show_compat.GetValue());
ui->show_size->setChecked(UISettings::values.show_size.GetValue());

View File

@ -5,7 +5,7 @@
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
#include "yuzu/configuration/config.h"
#include "frontend_common/config.h"
#include "yuzu/configuration/input_profiles.h"
namespace FS = Common::FS;
@ -44,7 +44,7 @@ InputProfiles::InputProfiles() {
if (IsINI(filename) && IsProfileNameValid(name_without_ext)) {
map_profiles.insert_or_assign(
name_without_ext,
std::make_unique<Config>(name_without_ext, Config::ConfigType::InputProfile));
std::make_unique<QtConfig>(name_without_ext, Config::ConfigType::InputProfile));
}
return true;
@ -85,7 +85,7 @@ bool InputProfiles::CreateProfile(const std::string& profile_name, std::size_t p
}
map_profiles.insert_or_assign(
profile_name, std::make_unique<Config>(profile_name, Config::ConfigType::InputProfile));
profile_name, std::make_unique<QtConfig>(profile_name, Config::ConfigType::InputProfile));
return SaveProfile(profile_name, player_index);
}
@ -113,7 +113,7 @@ bool InputProfiles::LoadProfile(const std::string& profile_name, std::size_t pla
return false;
}
map_profiles[profile_name]->ReadControlPlayerValue(player_index);
map_profiles[profile_name]->ReadQtControlPlayerValues(player_index);
return true;
}
@ -122,7 +122,7 @@ bool InputProfiles::SaveProfile(const std::string& profile_name, std::size_t pla
return false;
}
map_profiles[profile_name]->SaveControlPlayerValue(player_index);
map_profiles[profile_name]->SaveQtControlPlayerValues(player_index);
return true;
}

View File

@ -6,6 +6,8 @@
#include <string>
#include <unordered_map>
#include "configuration/qt_config.h"
namespace Core {
class System;
}
@ -30,5 +32,5 @@ public:
private:
bool ProfileExistsInMap(const std::string& profile_name) const;
std::unordered_map<std::string, std::unique_ptr<Config>> map_profiles;
std::unordered_map<std::string, std::unique_ptr<QtConfig>> map_profiles;
};

View File

@ -0,0 +1,548 @@
// 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(ReadIntegerSetting(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();
}

View File

@ -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;
};

View File

@ -10,6 +10,7 @@
#include <vector>
#include <QString>
#include "common/common_types.h"
#include "common/settings.h"
class QWidget;
@ -22,4 +23,46 @@ std::unique_ptr<TranslationMap> InitializeTranslations(QWidget* parent);
std::unique_ptr<ComboboxTranslationMap> ComboboxEnumeration(QWidget* parent);
static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map = {
{Settings::AntiAliasing::None, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "None"))},
{Settings::AntiAliasing::Fxaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FXAA"))},
{Settings::AntiAliasing::Smaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "SMAA"))},
};
static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map = {
{Settings::ScalingFilter::NearestNeighbor,
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Nearest"))},
{Settings::ScalingFilter::Bilinear,
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))},
{Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))},
{Settings::ScalingFilter::Gaussian,
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Gaussian"))},
{Settings::ScalingFilter::ScaleForce,
QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))},
{Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))},
};
static const std::map<Settings::ConsoleMode, QString> use_docked_mode_texts_map = {
{Settings::ConsoleMode::Docked, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))},
{Settings::ConsoleMode::Handheld, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))},
};
static const std::map<Settings::GpuAccuracy, QString> gpu_accuracy_texts_map = {
{Settings::GpuAccuracy::Normal, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Normal"))},
{Settings::GpuAccuracy::High, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "High"))},
{Settings::GpuAccuracy::Extreme, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Extreme"))},
};
static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map = {
{Settings::RendererBackend::Vulkan, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Vulkan"))},
{Settings::RendererBackend::OpenGL, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "OpenGL"))},
{Settings::RendererBackend::Null, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Null"))},
};
static const std::map<Settings::ShaderBackend, QString> shader_backend_texts_map = {
{Settings::ShaderBackend::Glsl, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "GLSL"))},
{Settings::ShaderBackend::Glasm, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "GLASM"))},
{Settings::ShaderBackend::SpirV, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "SPIRV"))},
};
} // namespace ConfigurationShared

View File

@ -36,10 +36,8 @@ constexpr std::array<std::array<Qt::GlobalColor, 2>, 10> WaitTreeColors{{
bool IsDarkTheme() {
const auto& theme = UISettings::values.theme;
return theme == QStringLiteral("qdarkstyle") ||
theme == QStringLiteral("qdarkstyle_midnight_blue") ||
theme == QStringLiteral("colorful_dark") ||
theme == QStringLiteral("colorful_midnight_blue");
return theme == std::string("qdarkstyle") || theme == std::string("qdarkstyle_midnight_blue") ||
theme == std::string("colorful_dark") || theme == std::string("colorful_midnight_blue");
}
} // namespace

View File

@ -278,7 +278,7 @@ void GameList::OnUpdateThemedIcons() {
case GameListItemType::CustomDir: {
const UISettings::GameDir& game_dir =
UISettings::values.game_dirs[child->data(GameListDir::GameDirRole).toInt()];
const QString icon_name = QFileInfo::exists(game_dir.path)
const QString icon_name = QFileInfo::exists(QString::fromStdString(game_dir.path))
? QStringLiteral("folder")
: QStringLiteral("bad_folder");
child->setData(
@ -727,7 +727,8 @@ void GameList::AddPermDirPopup(QMenu& context_menu, QModelIndex selected) {
});
connect(open_directory_location, &QAction::triggered, [this, game_dir_index] {
emit OpenDirectory(UISettings::values.game_dirs[game_dir_index].path);
emit OpenDirectory(
QString::fromStdString(UISettings::values.game_dirs[game_dir_index].path));
});
}
@ -869,7 +870,7 @@ const QStringList GameList::supported_file_extensions = {
QStringLiteral("xci"), QStringLiteral("nsp"), QStringLiteral("kip")};
void GameList::RefreshGameDirectory() {
if (!UISettings::values.game_dirs.isEmpty() && current_worker != nullptr) {
if (!UISettings::values.game_dirs.empty() && current_worker != nullptr) {
LOG_INFO(Frontend, "Change detected in the games directory. Reloading game list.");
PopulateAsync(UISettings::values.game_dirs);
}

View File

@ -286,13 +286,13 @@ public:
setData(QObject::tr("System Titles"), Qt::DisplayRole);
break;
case GameListItemType::CustomDir: {
const QString icon_name = QFileInfo::exists(game_dir->path)
? QStringLiteral("folder")
: QStringLiteral("bad_folder");
const QString path = QString::fromStdString(game_dir->path);
const QString icon_name =
QFileInfo::exists(path) ? QStringLiteral("folder") : QStringLiteral("bad_folder");
setData(QIcon::fromTheme(icon_name).pixmap(icon_size).scaled(
icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
Qt::DecorationRole);
setData(game_dir->path, Qt::DisplayRole);
setData(path, Qt::DisplayRole);
break;
}
default:

View File

@ -456,26 +456,26 @@ void GameListWorker::run() {
break;
}
if (game_dir.path == QStringLiteral("SDMC")) {
if (game_dir.path == std::string("SDMC")) {
auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SdmcDir);
DirEntryReady(game_list_dir);
AddTitlesToGameList(game_list_dir);
} else if (game_dir.path == QStringLiteral("UserNAND")) {
} else if (game_dir.path == std::string("UserNAND")) {
auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::UserNandDir);
DirEntryReady(game_list_dir);
AddTitlesToGameList(game_list_dir);
} else if (game_dir.path == QStringLiteral("SysNAND")) {
} else if (game_dir.path == std::string("SysNAND")) {
auto* const game_list_dir = new GameListDir(game_dir, GameListItemType::SysNandDir);
DirEntryReady(game_list_dir);
AddTitlesToGameList(game_list_dir);
} else {
watch_list.append(game_dir.path);
watch_list.append(QString::fromStdString(game_dir.path));
auto* const game_list_dir = new GameListDir(game_dir);
DirEntryReady(game_list_dir);
ScanFileSystem(ScanTarget::FillManualContentProvider, game_dir.path.toStdString(),
game_dir.deep_scan, game_list_dir);
ScanFileSystem(ScanTarget::PopulateGameList, game_dir.path.toStdString(),
game_dir.deep_scan, game_list_dir);
ScanFileSystem(ScanTarget::FillManualContentProvider, game_dir.path, game_dir.deep_scan,
game_list_dir);
ScanFileSystem(ScanTarget::PopulateGameList, game_dir.path, game_dir.deep_scan,
game_list_dir);
}
}

View File

@ -19,7 +19,7 @@ void HotkeyRegistry::SaveHotkeys() {
for (const auto& hotkey : group.second) {
UISettings::values.shortcuts.push_back(
{hotkey.first, group.first,
UISettings::ContextualShortcut({hotkey.second.keyseq.toString(),
UISettings::ContextualShortcut({hotkey.second.keyseq.toString().toStdString(),
hotkey.second.controller_keyseq,
hotkey.second.context, hotkey.second.repeat})});
}
@ -31,12 +31,12 @@ void HotkeyRegistry::LoadHotkeys() {
// beginGroup()
for (auto shortcut : UISettings::values.shortcuts) {
Hotkey& hk = hotkey_groups[shortcut.group][shortcut.name];
if (!shortcut.shortcut.keyseq.isEmpty()) {
hk.keyseq =
QKeySequence::fromString(shortcut.shortcut.keyseq, QKeySequence::NativeText);
if (!shortcut.shortcut.keyseq.empty()) {
hk.keyseq = QKeySequence::fromString(QString::fromStdString(shortcut.shortcut.keyseq),
QKeySequence::NativeText);
hk.context = static_cast<Qt::ShortcutContext>(shortcut.shortcut.context);
}
if (!shortcut.shortcut.controller_keyseq.isEmpty()) {
if (!shortcut.shortcut.controller_keyseq.empty()) {
hk.controller_keyseq = shortcut.shortcut.controller_keyseq;
}
if (hk.shortcut) {
@ -51,7 +51,8 @@ void HotkeyRegistry::LoadHotkeys() {
}
}
QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action, QWidget* widget) {
QShortcut* HotkeyRegistry::GetHotkey(const std::string& group, const std::string& action,
QWidget* widget) {
Hotkey& hk = hotkey_groups[group][action];
if (!hk.shortcut) {
@ -62,7 +63,8 @@ QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action
return hk.shortcut;
}
ControllerShortcut* HotkeyRegistry::GetControllerHotkey(const QString& group, const QString& action,
ControllerShortcut* HotkeyRegistry::GetControllerHotkey(const std::string& group,
const std::string& action,
Core::HID::EmulatedController* controller) {
Hotkey& hk = hotkey_groups[group][action];
@ -74,12 +76,12 @@ ControllerShortcut* HotkeyRegistry::GetControllerHotkey(const QString& group, co
return hk.controller_shortcut;
}
QKeySequence HotkeyRegistry::GetKeySequence(const QString& group, const QString& action) {
QKeySequence HotkeyRegistry::GetKeySequence(const std::string& group, const std::string& action) {
return hotkey_groups[group][action].keyseq;
}
Qt::ShortcutContext HotkeyRegistry::GetShortcutContext(const QString& group,
const QString& action) {
Qt::ShortcutContext HotkeyRegistry::GetShortcutContext(const std::string& group,
const std::string& action) {
return hotkey_groups[group][action].context;
}
@ -101,10 +103,10 @@ void ControllerShortcut::SetKey(const ControllerButtonSequence& buttons) {
button_sequence = buttons;
}
void ControllerShortcut::SetKey(const QString& buttons_shortcut) {
void ControllerShortcut::SetKey(const std::string& buttons_shortcut) {
ControllerButtonSequence sequence{};
name = buttons_shortcut.toStdString();
std::istringstream command_line(buttons_shortcut.toStdString());
name = buttons_shortcut;
std::istringstream command_line(buttons_shortcut);
std::string line;
while (std::getline(command_line, line, '+')) {
if (line.empty()) {

View File

@ -33,7 +33,7 @@ public:
~ControllerShortcut();
void SetKey(const ControllerButtonSequence& buttons);
void SetKey(const QString& buttons_shortcut);
void SetKey(const std::string& buttons_shortcut);
ControllerButtonSequence ButtonSequence() const;
@ -88,8 +88,8 @@ public:
* will be the same. Thus, you shouldn't rely on the caller really being the
* QShortcut's parent.
*/
QShortcut* GetHotkey(const QString& group, const QString& action, QWidget* widget);
ControllerShortcut* GetControllerHotkey(const QString& group, const QString& action,
QShortcut* GetHotkey(const std::string& group, const std::string& action, QWidget* widget);
ControllerShortcut* GetControllerHotkey(const std::string& group, const std::string& action,
Core::HID::EmulatedController* controller);
/**
@ -98,7 +98,7 @@ public:
* @param group General group this hotkey belongs to (e.g. "Main Window", "Debugger").
* @param action Name of the action (e.g. "Start Emulation", "Load Image").
*/
QKeySequence GetKeySequence(const QString& group, const QString& action);
QKeySequence GetKeySequence(const std::string& group, const std::string& action);
/**
* Returns a Qt::ShortcutContext object who can be connected to other
@ -108,20 +108,20 @@ public:
* "Debugger").
* @param action Name of the action (e.g. "Start Emulation", "Load Image").
*/
Qt::ShortcutContext GetShortcutContext(const QString& group, const QString& action);
Qt::ShortcutContext GetShortcutContext(const std::string& group, const std::string& action);
private:
struct Hotkey {
QKeySequence keyseq;
QString controller_keyseq;
std::string controller_keyseq;
QShortcut* shortcut = nullptr;
ControllerShortcut* controller_shortcut = nullptr;
Qt::ShortcutContext context = Qt::WindowShortcut;
bool repeat;
};
using HotkeyMap = std::map<QString, Hotkey>;
using HotkeyGroupMap = std::map<QString, HotkeyMap>;
using HotkeyMap = std::map<std::string, Hotkey>;
using HotkeyGroupMap = std::map<std::string, HotkeyMap>;
HotkeyGroupMap hotkey_groups;
};

View File

@ -128,6 +128,7 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "core/loader/loader.h"
#include "core/perf_stats.h"
#include "core/telemetry_session.h"
#include "frontend_common/config.h"
#include "input_common/drivers/tas_input.h"
#include "input_common/drivers/virtual_amiibo.h"
#include "input_common/main.h"
@ -140,9 +141,9 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
#include "yuzu/bootmanager.h"
#include "yuzu/compatdb.h"
#include "yuzu/compatibility_list.h"
#include "yuzu/configuration/config.h"
#include "yuzu/configuration/configure_dialog.h"
#include "yuzu/configuration/configure_input_per_game.h"
#include "yuzu/configuration/qt_config.h"
#include "yuzu/debugger/console.h"
#include "yuzu/debugger/controller.h"
#include "yuzu/debugger/profiler.h"
@ -311,7 +312,7 @@ bool GMainWindow::CheckDarkMode() {
#endif // __unix__
}
GMainWindow::GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan)
GMainWindow::GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulkan)
: ui{std::make_unique<Ui::MainWindow>()}, system{std::make_unique<Core::System>()},
input_subsystem{std::make_shared<InputCommon::InputSubsystem>()}, config{std::move(config_)},
vfs{std::make_shared<FileSys::RealVfsFilesystem>()},
@ -676,7 +677,7 @@ void GMainWindow::ControllerSelectorReconfigureControllers(
// Don't forget to apply settings.
system->HIDCore().DisableAllControllerConfiguration();
system->ApplySettings();
config->Save();
config->SaveAllValues();
UpdateStatusButtons();
@ -1129,7 +1130,7 @@ void GMainWindow::InitializeWidgets() {
connect(aa_status_button, &QPushButton::customContextMenuRequested,
[this](const QPoint& menu_location) {
QMenu context_menu;
for (auto const& aa_text_pair : Config::anti_aliasing_texts_map) {
for (auto const& aa_text_pair : ConfigurationShared::anti_aliasing_texts_map) {
context_menu.addAction(aa_text_pair.second, [this, aa_text_pair] {
Settings::values.anti_aliasing.SetValue(aa_text_pair.first);
UpdateAAText();
@ -1153,7 +1154,7 @@ void GMainWindow::InitializeWidgets() {
connect(filter_status_button, &QPushButton::customContextMenuRequested,
[this](const QPoint& menu_location) {
QMenu context_menu;
for (auto const& filter_text_pair : Config::scaling_filter_texts_map) {
for (auto const& filter_text_pair : ConfigurationShared::scaling_filter_texts_map) {
context_menu.addAction(filter_text_pair.second, [this, filter_text_pair] {
Settings::values.scaling_filter.SetValue(filter_text_pair.first);
UpdateFilterText();
@ -1176,7 +1177,7 @@ void GMainWindow::InitializeWidgets() {
[this](const QPoint& menu_location) {
QMenu context_menu;
for (auto const& pair : Config::use_docked_mode_texts_map) {
for (auto const& pair : ConfigurationShared::use_docked_mode_texts_map) {
context_menu.addAction(pair.second, [this, &pair] {
if (pair.first != Settings::values.use_docked_mode.GetValue()) {
OnToggleDockedMode();
@ -1200,7 +1201,7 @@ void GMainWindow::InitializeWidgets() {
[this](const QPoint& menu_location) {
QMenu context_menu;
for (auto const& gpu_accuracy_pair : Config::gpu_accuracy_texts_map) {
for (auto const& gpu_accuracy_pair : ConfigurationShared::gpu_accuracy_texts_map) {
if (gpu_accuracy_pair.first == Settings::GpuAccuracy::Extreme) {
continue;
}
@ -1229,7 +1230,8 @@ void GMainWindow::InitializeWidgets() {
[this](const QPoint& menu_location) {
QMenu context_menu;
for (auto const& renderer_backend_pair : Config::renderer_backend_texts_map) {
for (auto const& renderer_backend_pair :
ConfigurationShared::renderer_backend_texts_map) {
if (renderer_backend_pair.first == Settings::RendererBackend::Null) {
continue;
}
@ -1294,16 +1296,17 @@ void GMainWindow::InitializeRecentFileMenuActions() {
void GMainWindow::LinkActionShortcut(QAction* action, const QString& action_name,
const bool tas_allowed) {
static const QString main_window = QStringLiteral("Main Window");
action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name));
action->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, action_name));
static const auto main_window = std::string("Main Window");
action->setShortcut(hotkey_registry.GetKeySequence(main_window, action_name.toStdString()));
action->setShortcutContext(
hotkey_registry.GetShortcutContext(main_window, action_name.toStdString()));
action->setAutoRepeat(false);
this->addAction(action);
auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
const auto* controller_hotkey =
hotkey_registry.GetControllerHotkey(main_window, action_name, controller);
hotkey_registry.GetControllerHotkey(main_window, action_name.toStdString(), controller);
connect(
controller_hotkey, &ControllerShortcut::Activated, this,
[action, tas_allowed, this] {
@ -1335,10 +1338,11 @@ void GMainWindow::InitializeHotkeys() {
static const QString main_window = QStringLiteral("Main Window");
const auto connect_shortcut = [&]<typename Fn>(const QString& action_name, const Fn& function) {
const auto* hotkey = hotkey_registry.GetHotkey(main_window, action_name, this);
const auto* hotkey =
hotkey_registry.GetHotkey(main_window.toStdString(), action_name.toStdString(), this);
auto* controller = system->HIDCore().GetEmulatedController(Core::HID::NpadIdType::Player1);
const auto* controller_hotkey =
hotkey_registry.GetControllerHotkey(main_window, action_name, controller);
const auto* controller_hotkey = hotkey_registry.GetControllerHotkey(
main_window.toStdString(), action_name.toStdString(), controller);
connect(hotkey, &QShortcut::activated, this, function);
connect(controller_hotkey, &ControllerShortcut::Activated, this, function,
Qt::QueuedConnection);
@ -1918,7 +1922,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
// Save configurations
UpdateUISettings();
game_list->SaveInterfaceLayout();
config->Save();
config->SaveAllValues();
u64 title_id{0};
@ -1936,7 +1940,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t
const auto config_file_name = title_id == 0
? Common::FS::PathToUTF8String(file_path.filename())
: fmt::format("{:016X}", title_id);
Config per_game_config(config_file_name, Config::ConfigType::PerGameConfig);
QtConfig per_game_config(config_file_name, Config::ConfigType::PerGameConfig);
system->HIDCore().ReloadInputDevices();
system->ApplySettings();
}
@ -3135,7 +3139,7 @@ void GMainWindow::OnGameListAddDirectory() {
return;
}
UISettings::GameDir game_dir{dir_path, false, true};
UISettings::GameDir game_dir{dir_path.toStdString(), false, true};
if (!UISettings::values.game_dirs.contains(game_dir)) {
UISettings::values.game_dirs.append(game_dir);
game_list->PopulateAsync(UISettings::values.game_dirs);
@ -3181,14 +3185,14 @@ void GMainWindow::OnMenuLoadFile() {
"%1 is an identifier for the Switch executable file extensions.")
.arg(extensions);
const QString filename = QFileDialog::getOpenFileName(
this, tr("Load File"), UISettings::values.roms_path, file_filter);
this, tr("Load File"), QString::fromStdString(UISettings::values.roms_path), file_filter);
is_load_file_select_active = false;
if (filename.isEmpty()) {
return;
}
UISettings::values.roms_path = QFileInfo(filename).path();
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
BootGame(filename);
}
@ -3221,7 +3225,8 @@ void GMainWindow::OnMenuInstallToNAND() {
"Image (*.xci)");
QStringList filenames = QFileDialog::getOpenFileNames(
this, tr("Install Files"), UISettings::values.roms_path, file_filter);
this, tr("Install Files"), QString::fromStdString(UISettings::values.roms_path),
file_filter);
if (filenames.isEmpty()) {
return;
@ -3239,7 +3244,7 @@ void GMainWindow::OnMenuInstallToNAND() {
}
// Save folder location of the first selected file
UISettings::values.roms_path = QFileInfo(filenames[0]).path();
UISettings::values.roms_path = QFileInfo(filenames[0]).path().toStdString();
int remaining = filenames.size();
@ -3584,7 +3589,7 @@ void GMainWindow::OnExit() {
void GMainWindow::OnSaveConfig() {
system->ApplySettings();
config->Save();
config->SaveAllValues();
}
void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
@ -3840,7 +3845,7 @@ void GMainWindow::OnConfigure() {
Settings::values.disabled_addons.clear();
config = std::make_unique<Config>();
config = std::make_unique<QtConfig>();
UISettings::values.reset_to_defaults = false;
UISettings::values.game_dirs = std::move(old_game_dirs);
@ -3875,7 +3880,7 @@ void GMainWindow::OnConfigure() {
UISettings::values.configuration_applied = false;
config->Save();
config->SaveAllValues();
if ((UISettings::values.hide_mouse || Settings::values.mouse_panning) && emulation_running) {
render_window->installEventFilter(render_window);
@ -4091,7 +4096,7 @@ void GMainWindow::OpenPerGameConfiguration(u64 title_id, const std::string& file
UISettings::values.configuration_applied = false;
if (!is_powered_on) {
config->Save();
config->SaveAllValues();
}
}
@ -4324,7 +4329,7 @@ void GMainWindow::OnAlbum() {
system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::PhotoViewer);
const auto filename = QString::fromStdString(album_nca->GetFullPath());
UISettings::values.roms_path = QFileInfo(filename).path();
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
BootGame(filename, AlbumId);
}
@ -4348,7 +4353,7 @@ void GMainWindow::OnCabinet(Service::NFP::CabinetMode mode) {
system->GetAppletManager().SetCabinetMode(mode);
const auto filename = QString::fromStdString(cabinet_nca->GetFullPath());
UISettings::values.roms_path = QFileInfo(filename).path();
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
BootGame(filename, CabinetId);
}
@ -4371,7 +4376,7 @@ void GMainWindow::OnMiiEdit() {
system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::MiiEdit);
const auto filename = QString::fromStdString((mii_applet_nca->GetFullPath()));
UISettings::values.roms_path = QFileInfo(filename).path();
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
BootGame(filename, MiiEditId);
}
@ -4396,7 +4401,7 @@ void GMainWindow::OnOpenControllerMenu() {
system->GetAppletManager().SetCurrentAppletId(Service::AM::Applets::AppletId::Controller);
const auto filename = QString::fromStdString((controller_applet_nca->GetFullPath()));
UISettings::values.roms_path = QFileInfo(filename).path();
UISettings::values.roms_path = QFileInfo(filename).path().toStdString();
BootGame(filename, ControllerAppletId);
}
@ -4590,7 +4595,8 @@ void GMainWindow::UpdateStatusBar() {
void GMainWindow::UpdateGPUAccuracyButton() {
const auto gpu_accuracy = Settings::values.gpu_accuracy.GetValue();
const auto gpu_accuracy_text = Config::gpu_accuracy_texts_map.find(gpu_accuracy)->second;
const auto gpu_accuracy_text =
ConfigurationShared::gpu_accuracy_texts_map.find(gpu_accuracy)->second;
gpu_accuracy_button->setText(gpu_accuracy_text.toUpper());
gpu_accuracy_button->setChecked(gpu_accuracy != Settings::GpuAccuracy::Normal);
}
@ -4599,31 +4605,32 @@ void GMainWindow::UpdateDockedButton() {
const auto console_mode = Settings::values.use_docked_mode.GetValue();
dock_status_button->setChecked(Settings::IsDockedMode());
dock_status_button->setText(
Config::use_docked_mode_texts_map.find(console_mode)->second.toUpper());
ConfigurationShared::use_docked_mode_texts_map.find(console_mode)->second.toUpper());
}
void GMainWindow::UpdateAPIText() {
const auto api = Settings::values.renderer_backend.GetValue();
const auto renderer_status_text = Config::renderer_backend_texts_map.find(api)->second;
const auto renderer_status_text =
ConfigurationShared::renderer_backend_texts_map.find(api)->second;
renderer_status_button->setText(
api == Settings::RendererBackend::OpenGL
? tr("%1 %2").arg(
renderer_status_text.toUpper(),
Config::shader_backend_texts_map.find(Settings::values.shader_backend.GetValue())
->second)
? tr("%1 %2").arg(renderer_status_text.toUpper(),
ConfigurationShared::shader_backend_texts_map
.find(Settings::values.shader_backend.GetValue())
->second)
: renderer_status_text.toUpper());
}
void GMainWindow::UpdateFilterText() {
const auto filter = Settings::values.scaling_filter.GetValue();
const auto filter_text = Config::scaling_filter_texts_map.find(filter)->second;
const auto filter_text = ConfigurationShared::scaling_filter_texts_map.find(filter)->second;
filter_status_button->setText(filter == Settings::ScalingFilter::Fsr ? tr("FSR")
: filter_text.toUpper());
}
void GMainWindow::UpdateAAText() {
const auto aa_mode = Settings::values.anti_aliasing.GetValue();
const auto aa_text = Config::anti_aliasing_texts_map.find(aa_mode)->second;
const auto aa_text = ConfigurationShared::anti_aliasing_texts_map.find(aa_mode)->second;
aa_status_button->setText(aa_mode == Settings::AntiAliasing::None
? QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "NO AA"))
: aa_text.toUpper());
@ -4926,6 +4933,7 @@ void GMainWindow::closeEvent(QCloseEvent* event) {
UpdateUISettings();
game_list->SaveInterfaceLayout();
UISettings::SaveWindowState();
hotkey_registry.SaveHotkeys();
// Unload controllers early
@ -5080,9 +5088,9 @@ static void AdjustLinkColor() {
}
void GMainWindow::UpdateUITheme() {
const QString default_theme =
QString::fromUtf8(UISettings::themes[static_cast<size_t>(Config::default_theme)].second);
QString current_theme = UISettings::values.theme;
const QString default_theme = QString::fromUtf8(
UISettings::themes[static_cast<size_t>(UISettings::default_theme)].second);
QString current_theme = QString::fromStdString(UISettings::values.theme);
if (current_theme.isEmpty()) {
current_theme = default_theme;
@ -5110,7 +5118,7 @@ void GMainWindow::UpdateUITheme() {
QFile f(theme_uri);
if (!f.open(QFile::ReadOnly | QFile::Text)) {
LOG_ERROR(Frontend, "Unable to open style \"{}\", fallback to the default theme",
UISettings::values.theme.toStdString());
UISettings::values.theme);
current_theme = default_theme;
}
}
@ -5123,7 +5131,7 @@ void GMainWindow::UpdateUITheme() {
setStyleSheet(ts.readAll());
} else {
LOG_ERROR(Frontend, "Unable to set style \"{}\", stylesheet file not found",
UISettings::values.theme.toStdString());
UISettings::values.theme);
qApp->setStyleSheet({});
setStyleSheet({});
}
@ -5132,27 +5140,28 @@ void GMainWindow::UpdateUITheme() {
void GMainWindow::LoadTranslation() {
bool loaded;
if (UISettings::values.language.isEmpty()) {
if (UISettings::values.language.empty()) {
// If the selected language is empty, use system locale
loaded = translator.load(QLocale(), {}, {}, QStringLiteral(":/languages/"));
} else {
// Otherwise load from the specified file
loaded = translator.load(UISettings::values.language, QStringLiteral(":/languages/"));
loaded = translator.load(QString::fromStdString(UISettings::values.language),
QStringLiteral(":/languages/"));
}
if (loaded) {
qApp->installTranslator(&translator);
} else {
UISettings::values.language = QStringLiteral("en");
UISettings::values.language = std::string("en");
}
}
void GMainWindow::OnLanguageChanged(const QString& locale) {
if (UISettings::values.language != QStringLiteral("en")) {
if (UISettings::values.language != std::string("en")) {
qApp->removeTranslator(&translator);
}
UISettings::values.language = locale;
UISettings::values.language = locale.toStdString();
LoadTranslation();
ui->retranslateUi(this);
multiplayer_state->retranslateUi();
@ -5178,7 +5187,7 @@ void GMainWindow::changeEvent(QEvent* event) {
// UpdateUITheme is a decent work around
if (event->type() == QEvent::PaletteChange) {
const QPalette test_palette(qApp->palette());
const QString current_theme = UISettings::values.theme;
const QString current_theme = QString::fromStdString(UISettings::values.theme);
// Keeping eye on QPalette::Window to avoid looping. QPalette::Text might be useful too
static QColor last_window_color;
const QColor window_color = test_palette.color(QPalette::Active, QPalette::Window);
@ -5272,7 +5281,8 @@ static void SetHighDPIAttributes() {
}
int main(int argc, char* argv[]) {
std::unique_ptr<Config> config = std::make_unique<Config>();
std::unique_ptr<QtConfig> config = std::make_unique<QtConfig>();
UISettings::RestoreWindowState(config);
bool has_broken_vulkan = false;
bool is_child = false;
if (CheckEnvVars(&is_child)) {

View File

@ -15,6 +15,7 @@
#include "common/announce_multiplayer_room.h"
#include "common/common_types.h"
#include "configuration/qt_config.h"
#include "input_common/drivers/tas_input.h"
#include "yuzu/compatibility_list.h"
#include "yuzu/hotkeys.h"
@ -26,7 +27,7 @@
#include <QtDBus/QtDBus>
#endif
class Config;
class QtConfig;
class ClickableLabel;
class EmuThread;
class GameList;
@ -185,7 +186,7 @@ class GMainWindow : public QMainWindow {
public:
void filterBarSetChecked(bool state);
void UpdateUITheme();
explicit GMainWindow(std::unique_ptr<Config> config_, bool has_broken_vulkan);
explicit GMainWindow(std::unique_ptr<QtConfig> config_, bool has_broken_vulkan);
~GMainWindow() override;
bool DropAction(QDropEvent* event);
@ -521,7 +522,7 @@ private:
QSlider* volume_slider = nullptr;
QTimer status_bar_update_timer;
std::unique_ptr<Config> config;
std::unique_ptr<QtConfig> config;
// Whether emulation is currently running in yuzu.
bool emulation_running = false;

View File

@ -1,6 +1,9 @@
// SPDX-FileCopyrightText: 2016 Citra Emulator Project
// SPDX-License-Identifier: GPL-2.0-or-later
#include <QSettings>
#include "common/fs/fs.h"
#include "common/fs/path_util.h"
#include "yuzu/uisettings.h"
#ifndef CANNOT_EXPLICITLY_INSTANTIATE
@ -15,6 +18,8 @@ template class Setting<unsigned long long>;
} // namespace Settings
#endif
namespace FS = Common::FS;
namespace UISettings {
const Themes themes{{
@ -28,10 +33,8 @@ const Themes themes{{
bool IsDarkTheme() {
const auto& theme = UISettings::values.theme;
return theme == QStringLiteral("qdarkstyle") ||
theme == QStringLiteral("qdarkstyle_midnight_blue") ||
theme == QStringLiteral("colorful_dark") ||
theme == QStringLiteral("colorful_midnight_blue");
return theme == std::string("qdarkstyle") || theme == std::string("qdarkstyle_midnight_blue") ||
theme == std::string("colorful_dark") || theme == std::string("colorful_midnight_blue");
}
Values values = {};
@ -52,4 +55,58 @@ u32 CalculateWidth(u32 height, Settings::AspectRatio ratio) {
return height * 16 / 9;
}
void SaveWindowState() {
const auto window_state_config_loc =
FS::PathToUTF8String(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "window_state.ini");
void(FS::CreateParentDir(window_state_config_loc));
QSettings config(QString::fromStdString(window_state_config_loc), QSettings::IniFormat);
config.setValue(QStringLiteral("geometry"), values.geometry);
config.setValue(QStringLiteral("state"), values.state);
config.setValue(QStringLiteral("geometryRenderWindow"), values.renderwindow_geometry);
config.setValue(QStringLiteral("gameListHeaderState"), values.gamelist_header_state);
config.setValue(QStringLiteral("microProfileDialogGeometry"), values.microprofile_geometry);
config.sync();
}
void RestoreWindowState(std::unique_ptr<QtConfig>& qtConfig) {
const auto window_state_config_loc =
FS::PathToUTF8String(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "window_state.ini");
// Migrate window state from old location
if (!FS::Exists(window_state_config_loc) && qtConfig->Exists("UI", "UILayout\\geometry")) {
const auto config_loc =
FS::PathToUTF8String(FS::GetYuzuPath(FS::YuzuPath::ConfigDir) / "qt-config.ini");
QSettings config(QString::fromStdString(config_loc), QSettings::IniFormat);
config.beginGroup(QStringLiteral("UI"));
config.beginGroup(QStringLiteral("UILayout"));
values.geometry = config.value(QStringLiteral("geometry")).toByteArray();
values.state = config.value(QStringLiteral("state")).toByteArray();
values.renderwindow_geometry =
config.value(QStringLiteral("geometryRenderWindow")).toByteArray();
values.gamelist_header_state =
config.value(QStringLiteral("gameListHeaderState")).toByteArray();
values.microprofile_geometry =
config.value(QStringLiteral("microProfileDialogGeometry")).toByteArray();
config.endGroup();
config.endGroup();
return;
}
void(FS::CreateParentDir(window_state_config_loc));
const QSettings config(QString::fromStdString(window_state_config_loc), QSettings::IniFormat);
values.geometry = config.value(QStringLiteral("geometry")).toByteArray();
values.state = config.value(QStringLiteral("state")).toByteArray();
values.renderwindow_geometry =
config.value(QStringLiteral("geometryRenderWindow")).toByteArray();
values.gamelist_header_state =
config.value(QStringLiteral("gameListHeaderState")).toByteArray();
values.microprofile_geometry =
config.value(QStringLiteral("microProfileDialogGeometry")).toByteArray();
}
} // namespace UISettings

View File

@ -14,6 +14,7 @@
#include "common/common_types.h"
#include "common/settings.h"
#include "common/settings_enums.h"
#include "configuration/qt_config.h"
using Settings::Category;
using Settings::ConfirmStop;
@ -37,15 +38,15 @@ namespace UISettings {
bool IsDarkTheme();
struct ContextualShortcut {
QString keyseq;
QString controller_keyseq;
std::string keyseq;
std::string controller_keyseq;
int context;
bool repeat;
};
struct Shortcut {
QString name;
QString group;
std::string name;
std::string group;
ContextualShortcut shortcut;
};
@ -58,11 +59,19 @@ enum class Theme {
MidnightBlueColorful,
};
static constexpr Theme default_theme{
#ifdef _WIN32
Theme::DarkColorful
#else
Theme::DefaultColorful
#endif
};
using Themes = std::array<std::pair<const char*, const char*>, 6>;
extern const Themes themes;
struct GameDir {
QString path;
std::string path;
bool deep_scan = false;
bool expanded = false;
bool operator==(const GameDir& rhs) const {
@ -144,15 +153,15 @@ struct Values {
Category::Screenshots};
Setting<u32> screenshot_height{linkage, 0, "screenshot_height", Category::Screenshots};
QString roms_path;
QString symbols_path;
QString game_dir_deprecated;
std::string roms_path;
std::string symbols_path;
std::string game_dir_deprecated;
bool game_dir_deprecated_deepscan;
QVector<UISettings::GameDir> game_dirs;
QVector<GameDir> game_dirs;
QStringList recent_files;
QString language;
std::string language;
QString theme;
std::string theme;
// Shortcut name <Shortcut, context>
std::vector<Shortcut> shortcuts;
@ -206,6 +215,54 @@ extern Values values;
u32 CalculateWidth(u32 height, Settings::AspectRatio ratio);
void SaveWindowState();
void RestoreWindowState(std::unique_ptr<QtConfig>& qtConfig);
// This shouldn't have anything except static initializers (no functions). So
// QKeySequence(...).toString() is NOT ALLOWED HERE.
// This must be in alphabetical order according to action name as it must have the same order as
// UISetting::values.shortcuts, which is alphabetically ordered.
// clang-format off
const std::array<Shortcut, 23> default_hotkeys{{
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+M"), std::string("Home+Dpad_Right"), Qt::WindowShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("-"), std::string("Home+Dpad_Down"), Qt::ApplicationShortcut, true}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("="), std::string("Home+Dpad_Up"), Qt::ApplicationShortcut, true}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+P"), std::string("Screenshot"), Qt::WidgetWithChildrenShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F8"), std::string("Home+L"), Qt::ApplicationShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F10"), std::string("Home+X"), Qt::ApplicationShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change GPU Accuracy")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F9"), std::string("Home+R"), Qt::ApplicationShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Continue/Pause Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F4"), std::string("Home+Plus"), Qt::WindowShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit Fullscreen")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Esc"), std::string(""), Qt::WindowShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit yuzu")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+Q"), std::string("Home+Minus"), Qt::WindowShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F11"), std::string("Home+B"), Qt::WindowShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+O"), std::string(""), Qt::WidgetWithChildrenShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F2"), std::string("Home+A"), Qt::WidgetWithChildrenShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F6"), std::string("R+Plus+Minus"), Qt::WindowShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("F5"), std::string("L+Plus+Minus"), Qt::WindowShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F7"), std::string(""), Qt::ApplicationShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F6"), std::string(""), Qt::ApplicationShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F5"), std::string(""), Qt::ApplicationShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Filter Bar")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F"), std::string(""), Qt::WindowShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Framerate Limit")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+U"), std::string("Home+Y"), Qt::ApplicationShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Mouse Panning")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+F9"), std::string(""), Qt::ApplicationShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Renderdoc Capture")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string(""), std::string(""), Qt::ApplicationShortcut, false}},
{QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Status Bar")).toStdString(), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")).toStdString(), {std::string("Ctrl+S"), std::string(""), Qt::WindowShortcut, false}},
}};
// clang-format on
} // namespace UISettings
Q_DECLARE_METATYPE(UISettings::GameDir*);
// 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);