summaryrefslogtreecommitdiff
path: root/src/yuzu
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu')
-rw-r--r--src/yuzu/CMakeLists.txt6
-rw-r--r--src/yuzu/about_dialog.cpp8
-rw-r--r--src/yuzu/applets/error.cpp8
-rw-r--r--src/yuzu/applets/profile_select.cpp4
-rw-r--r--src/yuzu/applets/software_keyboard.cpp23
-rw-r--r--src/yuzu/applets/software_keyboard.h1
-rw-r--r--src/yuzu/bootmanager.cpp28
-rw-r--r--src/yuzu/bootmanager.h3
-rw-r--r--src/yuzu/compatdb.cpp6
-rw-r--r--src/yuzu/configuration/config.cpp926
-rw-r--r--src/yuzu/configuration/config.h37
-rw-r--r--src/yuzu/configuration/configure_audio.cpp14
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp7
-rw-r--r--src/yuzu/configuration/configure_gamelist.cpp8
-rw-r--r--src/yuzu/configuration/configure_general.cpp3
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp8
-rw-r--r--src/yuzu/configuration/configure_hotkeys.cpp38
-rw-r--r--src/yuzu/configuration/configure_hotkeys.h6
-rw-r--r--src/yuzu/configuration/configure_input.cpp13
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp153
-rw-r--r--src/yuzu/configuration/configure_mouse_advanced.cpp75
-rw-r--r--src/yuzu/configuration/configure_per_general.cpp24
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp2
-rw-r--r--src/yuzu/configuration/configure_system.cpp5
-rw-r--r--src/yuzu/configuration/configure_web.cpp24
-rw-r--r--src/yuzu/debugger/graphics/graphics_breakpoints.cpp2
-rw-r--r--src/yuzu/debugger/profiler.cpp4
-rw-r--r--src/yuzu/debugger/wait_tree.cpp39
-rw-r--r--src/yuzu/game_list.cpp103
-rw-r--r--src/yuzu/game_list.h2
-rw-r--r--src/yuzu/game_list_p.h25
-rw-r--r--src/yuzu/game_list_worker.cpp128
-rw-r--r--src/yuzu/hotkeys.h2
-rw-r--r--src/yuzu/loading_screen.cpp18
-rw-r--r--src/yuzu/main.cpp287
-rw-r--r--src/yuzu/main.h1
-rw-r--r--src/yuzu/ui_settings.h1
-rw-r--r--src/yuzu/util/sequence_dialog/sequence_dialog.cpp13
-rw-r--r--src/yuzu/util/spinbox.cpp278
-rw-r--r--src/yuzu/util/spinbox.h86
-rw-r--r--src/yuzu/util/util.cpp18
41 files changed, 1299 insertions, 1138 deletions
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 5138bd9a3..3ea7b55d0 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -82,8 +82,6 @@ add_executable(yuzu
util/limitable_input_dialog.h
util/sequence_dialog/sequence_dialog.cpp
util/sequence_dialog/sequence_dialog.h
- util/spinbox.cpp
- util/spinbox.h
util/util.cpp
util/util.h
compatdb.cpp
@@ -157,6 +155,10 @@ target_compile_definitions(yuzu PRIVATE
# Use QStringBuilder for string concatenation to reduce
# the overall number of temporary strings created.
-DQT_USE_QSTRINGBUILDER
+
+ # Disable implicit conversions from/to C strings
+ -DQT_NO_CAST_FROM_ASCII
+ -DQT_NO_CAST_TO_ASCII
)
if (YUZU_ENABLE_COMPATIBILITY_REPORTING)
diff --git a/src/yuzu/about_dialog.cpp b/src/yuzu/about_dialog.cpp
index 3efa65a38..d39b3f07a 100644
--- a/src/yuzu/about_dialog.cpp
+++ b/src/yuzu/about_dialog.cpp
@@ -9,10 +9,10 @@
AboutDialog::AboutDialog(QWidget* parent) : QDialog(parent), ui(new Ui::AboutDialog) {
ui->setupUi(this);
- ui->labelLogo->setPixmap(QIcon::fromTheme("yuzu").pixmap(200));
- ui->labelBuildInfo->setText(
- ui->labelBuildInfo->text().arg(Common::g_build_fullname, Common::g_scm_branch,
- Common::g_scm_desc, QString(Common::g_build_date).left(10)));
+ ui->labelLogo->setPixmap(QIcon::fromTheme(QStringLiteral("yuzu")).pixmap(200));
+ ui->labelBuildInfo->setText(ui->labelBuildInfo->text().arg(
+ QString::fromUtf8(Common::g_build_fullname), QString::fromUtf8(Common::g_scm_branch),
+ QString::fromUtf8(Common::g_scm_desc), QString::fromUtf8(Common::g_build_date).left(10)));
}
AboutDialog::~AboutDialog() = default;
diff --git a/src/yuzu/applets/error.cpp b/src/yuzu/applets/error.cpp
index 1fb2fe277..08ed57355 100644
--- a/src/yuzu/applets/error.cpp
+++ b/src/yuzu/applets/error.cpp
@@ -29,11 +29,13 @@ void QtErrorDisplay::ShowError(ResultCode error, std::function<void()> finished)
void QtErrorDisplay::ShowErrorWithTimestamp(ResultCode error, std::chrono::seconds time,
std::function<void()> finished) const {
this->callback = std::move(finished);
+
+ const QDateTime date_time = QDateTime::fromSecsSinceEpoch(time.count());
emit MainWindowDisplayError(
tr("An error occured on %1 at %2.\nPlease try again or contact the "
"developer of the software.\n\nError Code: %3-%4 (0x%5)")
- .arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("dddd, MMMM d, yyyy"))
- .arg(QDateTime::fromSecsSinceEpoch(time.count()).toString("h:mm:ss A"))
+ .arg(date_time.toString(QStringLiteral("dddd, MMMM d, yyyy")))
+ .arg(date_time.toString(QStringLiteral("h:mm:ss A")))
.arg(static_cast<u32>(error.module.Value()) + 2000, 4, 10, QChar::fromLatin1('0'))
.arg(error.description, 4, 10, QChar::fromLatin1('0'))
.arg(error.raw, 8, 16, QChar::fromLatin1('0')));
@@ -54,6 +56,6 @@ void QtErrorDisplay::ShowCustomErrorText(ResultCode error, std::string dialog_te
void QtErrorDisplay::MainWindowFinishedError() {
// Acquire the HLE mutex
- std::lock_guard<std::recursive_mutex> lock(HLE::g_hle_lock);
+ std::lock_guard lock{HLE::g_hle_lock};
callback();
}
diff --git a/src/yuzu/applets/profile_select.cpp b/src/yuzu/applets/profile_select.cpp
index 812b0142f..42e26b978 100644
--- a/src/yuzu/applets/profile_select.cpp
+++ b/src/yuzu/applets/profile_select.cpp
@@ -84,10 +84,10 @@ QtProfileSelectionDialog::QtProfileSelectionDialog(QWidget* parent)
tree_view->setContextMenuPolicy(Qt::NoContextMenu);
item_model->insertColumns(0, 1);
- item_model->setHeaderData(0, Qt::Horizontal, "Users");
+ item_model->setHeaderData(0, Qt::Horizontal, tr("Users"));
// We must register all custom types with the Qt Automoc system so that we are able to use it
- // with signals/slots. In this case, QList falls under the umbrells of custom types.
+ // with signals/slots. In this case, QList falls under the umbrella of custom types.
qRegisterMetaType<QList<QStandardItem*>>("QList<QStandardItem*>");
layout->setContentsMargins(0, 0, 0, 0);
diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/software_keyboard.cpp
index f3eb29b25..5223ec977 100644
--- a/src/yuzu/applets/software_keyboard.cpp
+++ b/src/yuzu/applets/software_keyboard.cpp
@@ -18,23 +18,30 @@ QtSoftwareKeyboardValidator::QtSoftwareKeyboardValidator(
: parameters(std::move(parameters)) {}
QValidator::State QtSoftwareKeyboardValidator::validate(QString& input, int& pos) const {
- if (input.size() > parameters.max_length)
+ if (input.size() > static_cast<s64>(parameters.max_length)) {
return Invalid;
- if (parameters.disable_space && input.contains(' '))
+ }
+ if (parameters.disable_space && input.contains(QLatin1Char{' '})) {
return Invalid;
- if (parameters.disable_address && input.contains('@'))
+ }
+ if (parameters.disable_address && input.contains(QLatin1Char{'@'})) {
return Invalid;
- if (parameters.disable_percent && input.contains('%'))
+ }
+ if (parameters.disable_percent && input.contains(QLatin1Char{'%'})) {
return Invalid;
- if (parameters.disable_slash && (input.contains('/') || input.contains('\\')))
+ }
+ if (parameters.disable_slash &&
+ (input.contains(QLatin1Char{'/'}) || input.contains(QLatin1Char{'\\'}))) {
return Invalid;
+ }
if (parameters.disable_number &&
std::any_of(input.begin(), input.end(), [](QChar c) { return c.isDigit(); })) {
return Invalid;
}
- if (parameters.disable_download_code &&
- std::any_of(input.begin(), input.end(), [](QChar c) { return c == 'O' || c == 'I'; })) {
+ if (parameters.disable_download_code && std::any_of(input.begin(), input.end(), [](QChar c) {
+ return c == QLatin1Char{'O'} || c == QLatin1Char{'I'};
+ })) {
return Invalid;
}
@@ -142,7 +149,7 @@ void QtSoftwareKeyboard::SendTextCheckDialog(std::u16string error_message,
void QtSoftwareKeyboard::MainWindowFinishedText(std::optional<std::u16string> text) {
// Acquire the HLE mutex
std::lock_guard lock{HLE::g_hle_lock};
- text_output(text);
+ text_output(std::move(text));
}
void QtSoftwareKeyboard::MainWindowFinishedCheckDialog() {
diff --git a/src/yuzu/applets/software_keyboard.h b/src/yuzu/applets/software_keyboard.h
index c63720ba4..78c5a042b 100644
--- a/src/yuzu/applets/software_keyboard.h
+++ b/src/yuzu/applets/software_keyboard.h
@@ -6,7 +6,6 @@
#include <QDialog>
#include <QValidator>
-#include "common/assert.h"
#include "core/frontend/applets/software_keyboard.h"
class GMainWindow;
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 5c98636c5..9e420b359 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -91,25 +91,25 @@ void EmuThread::run() {
class GGLContext : public Core::Frontend::GraphicsContext {
public:
- explicit GGLContext(QOpenGLContext* shared_context)
- : context{std::make_unique<QOpenGLContext>(shared_context)} {
- surface.setFormat(shared_context->format());
- surface.create();
+ explicit GGLContext(QOpenGLContext* shared_context) : shared_context{shared_context} {
+ context.setFormat(shared_context->format());
+ context.setShareContext(shared_context);
+ context.create();
}
void MakeCurrent() override {
- context->makeCurrent(&surface);
+ context.makeCurrent(shared_context->surface());
}
void DoneCurrent() override {
- context->doneCurrent();
+ context.doneCurrent();
}
void SwapBuffers() override {}
private:
- std::unique_ptr<QOpenGLContext> context;
- QOffscreenSurface surface;
+ QOpenGLContext* shared_context;
+ QOpenGLContext context;
};
// This class overrides paintEvent and resizeEvent to prevent the GUI thread from stealing GL
@@ -188,7 +188,9 @@ private:
GRenderWindow::GRenderWindow(QWidget* parent, EmuThread* emu_thread)
: QWidget(parent), emu_thread(emu_thread) {
setWindowTitle(QStringLiteral("yuzu %1 | %2-%3")
- .arg(Common::g_build_name, Common::g_scm_branch, Common::g_scm_desc));
+ .arg(QString::fromUtf8(Common::g_build_name),
+ QString::fromUtf8(Common::g_scm_branch),
+ QString::fromUtf8(Common::g_scm_desc)));
setAttribute(Qt::WA_AcceptTouchEvents);
InputCommon::Init();
@@ -217,7 +219,7 @@ void GRenderWindow::SwapBuffers() {
// However:
// - The Qt debug runtime prints a bogus warning on the console if `makeCurrent` wasn't called
// since the last time `swapBuffers` was executed;
- // - On macOS, if `makeCurrent` isn't called explicitely, resizing the buffer breaks.
+ // - On macOS, if `makeCurrent` isn't called explicitly, resizing the buffer breaks.
context->makeCurrent(child);
context->swapBuffers(child);
@@ -356,7 +358,7 @@ void GRenderWindow::OnClientAreaResized(unsigned width, unsigned height) {
}
std::unique_ptr<Core::Frontend::GraphicsContext> GRenderWindow::CreateSharedContext() const {
- return std::make_unique<GGLContext>(shared_context.get());
+ return std::make_unique<GGLContext>(context.get());
}
void GRenderWindow::InitRenderTarget() {
@@ -379,6 +381,7 @@ void GRenderWindow::InitRenderTarget() {
fmt.setVersion(4, 3);
if (Settings::values.use_compatibility_profile) {
fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
+ fmt.setOption(QSurfaceFormat::FormatOption::DeprecatedFunctions);
} else {
fmt.setProfile(QSurfaceFormat::CoreProfile);
}
@@ -437,8 +440,7 @@ void GRenderWindow::CaptureScreenshot(u16 res_scale, const QString& screenshot_p
layout);
}
-void GRenderWindow::OnMinimalClientAreaChangeRequest(
- const std::pair<unsigned, unsigned>& minimal_size) {
+void GRenderWindow::OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) {
setMinimumSize(minimal_size.first, minimal_size.second);
}
diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h
index 3df33aca1..7f9f8e8e3 100644
--- a/src/yuzu/bootmanager.h
+++ b/src/yuzu/bootmanager.h
@@ -162,8 +162,7 @@ private:
void TouchUpdateEvent(const QTouchEvent* event);
void TouchEndEvent();
- void OnMinimalClientAreaChangeRequest(
- const std::pair<unsigned, unsigned>& minimal_size) override;
+ void OnMinimalClientAreaChangeRequest(std::pair<unsigned, unsigned> minimal_size) override;
QWidget* container = nullptr;
GGLWidgetInternal* child = nullptr;
diff --git a/src/yuzu/compatdb.cpp b/src/yuzu/compatdb.cpp
index c8b0a5ec0..5477f050c 100644
--- a/src/yuzu/compatdb.cpp
+++ b/src/yuzu/compatdb.cpp
@@ -58,7 +58,7 @@ void CompatDB::Submit() {
button(NextButton)->setEnabled(false);
button(NextButton)->setText(tr("Submitting"));
- button(QWizard::CancelButton)->setVisible(false);
+ button(CancelButton)->setVisible(false);
testcase_watcher.setFuture(QtConcurrent::run(
[] { return Core::System::GetInstance().TelemetrySession().SubmitTestcase(); }));
@@ -74,12 +74,12 @@ void CompatDB::OnTestcaseSubmitted() {
tr("An error occured while sending the Testcase"));
button(NextButton)->setEnabled(true);
button(NextButton)->setText(tr("Next"));
- button(QWizard::CancelButton)->setVisible(true);
+ button(CancelButton)->setVisible(true);
} else {
next();
// older versions of QT don't support the "NoCancelButtonOnLastPage" option, this is a
// workaround
- button(QWizard::CancelButton)->setVisible(false);
+ button(CancelButton)->setVisible(false);
}
}
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 6c6f047d8..b1942bedc 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -11,6 +11,7 @@
#include "core/hle/service/hid/controllers/npad.h"
#include "input_common/main.h"
#include "yuzu/configuration/config.h"
+#include "yuzu/ui_settings.h"
Config::Config() {
// TODO: Don't hardcode the path; let the frontend decide where to put the config files.
@@ -206,79 +207,91 @@ const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> Config::default
};
// This shouldn't have anything except static initializers (no functions). So
-// QKeySequnce(...).toString() is NOT ALLOWED HERE.
+// 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.
-const std::array<UISettings::Shortcut, 15> Config::default_hotkeys{
- {{"Capture Screenshot", "Main Window", {"Ctrl+P", Qt::ApplicationShortcut}},
- {"Continue/Pause Emulation", "Main Window", {"F4", Qt::WindowShortcut}},
- {"Decrease Speed Limit", "Main Window", {"-", Qt::ApplicationShortcut}},
- {"Exit yuzu", "Main Window", {"Ctrl+Q", Qt::WindowShortcut}},
- {"Exit Fullscreen", "Main Window", {"Esc", Qt::WindowShortcut}},
- {"Fullscreen", "Main Window", {"F11", Qt::WindowShortcut}},
- {"Increase Speed Limit", "Main Window", {"+", Qt::ApplicationShortcut}},
- {"Load Amiibo", "Main Window", {"F2", Qt::ApplicationShortcut}},
- {"Load File", "Main Window", {"Ctrl+O", Qt::WindowShortcut}},
- {"Restart Emulation", "Main Window", {"F6", Qt::WindowShortcut}},
- {"Stop Emulation", "Main Window", {"F5", Qt::WindowShortcut}},
- {"Toggle Filter Bar", "Main Window", {"Ctrl+F", Qt::WindowShortcut}},
- {"Toggle Speed Limit", "Main Window", {"Ctrl+Z", Qt::ApplicationShortcut}},
- {"Toggle Status Bar", "Main Window", {"Ctrl+S", Qt::WindowShortcut}},
- {"Change Docked Mode", "Main Window", {"F10", Qt::ApplicationShortcut}}}};
+// clang-format off
+const std::array<UISettings::Shortcut, 15> default_hotkeys{{
+ {QStringLiteral("Capture Screenshot"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+P"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Continue/Pause Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F4"), Qt::WindowShortcut}},
+ {QStringLiteral("Decrease Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("-"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Exit yuzu"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Q"), Qt::WindowShortcut}},
+ {QStringLiteral("Exit Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("Esc"), Qt::WindowShortcut}},
+ {QStringLiteral("Fullscreen"), QStringLiteral("Main Window"), {QStringLiteral("F11"), Qt::WindowShortcut}},
+ {QStringLiteral("Increase Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("+"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Load Amiibo"), QStringLiteral("Main Window"), {QStringLiteral("F2"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Load File"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+O"), Qt::WindowShortcut}},
+ {QStringLiteral("Restart Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F6"), Qt::WindowShortcut}},
+ {QStringLiteral("Stop Emulation"), QStringLiteral("Main Window"), {QStringLiteral("F5"), Qt::WindowShortcut}},
+ {QStringLiteral("Toggle Filter Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+F"), Qt::WindowShortcut}},
+ {QStringLiteral("Toggle Speed Limit"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+Z"), Qt::ApplicationShortcut}},
+ {QStringLiteral("Toggle Status Bar"), QStringLiteral("Main Window"), {QStringLiteral("Ctrl+S"), Qt::WindowShortcut}},
+ {QStringLiteral("Change Docked Mode"), QStringLiteral("Main Window"), {QStringLiteral("F10"), Qt::ApplicationShortcut}},
+}};
+// clang-format on
void Config::ReadPlayerValues() {
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
auto& player = Settings::values.players[p];
- player.connected = ReadSetting(QString("player_%1_connected").arg(p), false).toBool();
+ player.connected =
+ ReadSetting(QStringLiteral("player_%1_connected").arg(p), false).toBool();
player.type = static_cast<Settings::ControllerType>(
qt_config
- ->value(QString("player_%1_type").arg(p),
+ ->value(QStringLiteral("player_%1_type").arg(p),
static_cast<u8>(Settings::ControllerType::DualJoycon))
.toUInt());
player.body_color_left = qt_config
- ->value(QString("player_%1_body_color_left").arg(p),
+ ->value(QStringLiteral("player_%1_body_color_left").arg(p),
Settings::JOYCON_BODY_NEON_BLUE)
.toUInt();
player.body_color_right = qt_config
- ->value(QString("player_%1_body_color_right").arg(p),
+ ->value(QStringLiteral("player_%1_body_color_right").arg(p),
Settings::JOYCON_BODY_NEON_RED)
.toUInt();
player.button_color_left = qt_config
- ->value(QString("player_%1_button_color_left").arg(p),
+ ->value(QStringLiteral("player_%1_button_color_left").arg(p),
Settings::JOYCON_BUTTONS_NEON_BLUE)
.toUInt();
- player.button_color_right = qt_config
- ->value(QString("player_%1_button_color_right").arg(p),
- Settings::JOYCON_BUTTONS_NEON_RED)
- .toUInt();
+ player.button_color_right =
+ qt_config
+ ->value(QStringLiteral("player_%1_button_color_right").arg(p),
+ Settings::JOYCON_BUTTONS_NEON_RED)
+ .toUInt();
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- player.buttons[i] =
- qt_config
- ->value(QString("player_%1_").arg(p) + Settings::NativeButton::mapping[i],
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (player.buttons[i].empty())
- player.buttons[i] = default_param;
+ const std::string default_param =
+ InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ auto& player_buttons = player.buttons[i];
+
+ player_buttons = qt_config
+ ->value(QStringLiteral("player_%1_").arg(p) +
+ QString::fromUtf8(Settings::NativeButton::mapping[i]),
+ QString::fromStdString(default_param))
+ .toString()
+ .toStdString();
+ if (player_buttons.empty()) {
+ player_buttons = default_param;
+ }
}
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ const 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] =
- qt_config
- ->value(QString("player_%1_").arg(p) + Settings::NativeAnalog::mapping[i],
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (player.analogs[i].empty())
- player.analogs[i] = default_param;
+ auto& player_analogs = player.analogs[i];
+
+ player_analogs = qt_config
+ ->value(QStringLiteral("player_%1_").arg(p) +
+ QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
+ QString::fromStdString(default_param))
+ .toString()
+ .toStdString();
+ if (player_analogs.empty()) {
+ player_analogs = default_param;
+ }
}
}
@@ -290,36 +303,45 @@ void Config::ReadPlayerValues() {
}
void Config::ReadDebugValues() {
- Settings::values.debug_pad_enabled = ReadSetting("debug_pad_enabled", false).toBool();
+ Settings::values.debug_pad_enabled =
+ ReadSetting(QStringLiteral("debug_pad_enabled"), false).toBool();
+
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- Settings::values.debug_pad_buttons[i] =
- qt_config
- ->value(QString("debug_pad_") + Settings::NativeButton::mapping[i],
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (Settings::values.debug_pad_buttons[i].empty())
- Settings::values.debug_pad_buttons[i] = default_param;
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ auto& debug_pad_buttons = Settings::values.debug_pad_buttons[i];
+
+ debug_pad_buttons = qt_config
+ ->value(QStringLiteral("debug_pad_") +
+ QString::fromUtf8(Settings::NativeButton::mapping[i]),
+ QString::fromStdString(default_param))
+ .toString()
+ .toStdString();
+ if (debug_pad_buttons.empty()) {
+ debug_pad_buttons = default_param;
+ }
}
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ const 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] =
- qt_config
- ->value(QString("debug_pad_") + Settings::NativeAnalog::mapping[i],
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (Settings::values.debug_pad_analogs[i].empty())
- Settings::values.debug_pad_analogs[i] = default_param;
+ auto& debug_pad_analogs = Settings::values.debug_pad_analogs[i];
+
+ debug_pad_analogs = qt_config
+ ->value(QStringLiteral("debug_pad_") +
+ QString::fromUtf8(Settings::NativeAnalog::mapping[i]),
+ QString::fromStdString(default_param))
+ .toString()
+ .toStdString();
+ if (debug_pad_analogs.empty()) {
+ debug_pad_analogs = default_param;
+ }
}
}
void Config::ReadKeyboardValues() {
- Settings::values.keyboard_enabled = ReadSetting("keyboard_enabled", false).toBool();
+ Settings::values.keyboard_enabled =
+ ReadSetting(QStringLiteral("keyboard_enabled"), false).toBool();
std::transform(default_keyboard_keys.begin(), default_keyboard_keys.end(),
Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam);
@@ -332,31 +354,41 @@ void Config::ReadKeyboardValues() {
}
void Config::ReadMouseValues() {
- Settings::values.mouse_enabled = ReadSetting("mouse_enabled", false).toBool();
+ Settings::values.mouse_enabled = ReadSetting(QStringLiteral("mouse_enabled"), false).toBool();
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
- std::string default_param = InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]);
- Settings::values.mouse_buttons[i] =
- qt_config
- ->value(QString("mouse_") + Settings::NativeMouseButton::mapping[i],
- QString::fromStdString(default_param))
- .toString()
- .toStdString();
- if (Settings::values.mouse_buttons[i].empty())
- Settings::values.mouse_buttons[i] = default_param;
+ const std::string default_param =
+ InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]);
+ auto& mouse_buttons = Settings::values.mouse_buttons[i];
+
+ mouse_buttons = qt_config
+ ->value(QStringLiteral("mouse_") +
+ QString::fromUtf8(Settings::NativeMouseButton::mapping[i]),
+ QString::fromStdString(default_param))
+ .toString()
+ .toStdString();
+ if (mouse_buttons.empty()) {
+ mouse_buttons = default_param;
+ }
}
}
void Config::ReadTouchscreenValues() {
- Settings::values.touchscreen.enabled = ReadSetting("touchscreen_enabled", true).toBool();
+ Settings::values.touchscreen.enabled =
+ ReadSetting(QStringLiteral("touchscreen_enabled"), true).toBool();
Settings::values.touchscreen.device =
- ReadSetting("touchscreen_device", "engine:emu_window").toString().toStdString();
+ ReadSetting(QStringLiteral("touchscreen_device"), QStringLiteral("engine:emu_window"))
+ .toString()
+ .toStdString();
- Settings::values.touchscreen.finger = ReadSetting("touchscreen_finger", 0).toUInt();
- Settings::values.touchscreen.rotation_angle = ReadSetting("touchscreen_angle", 0).toUInt();
- Settings::values.touchscreen.diameter_x = ReadSetting("touchscreen_diameter_x", 15).toUInt();
- Settings::values.touchscreen.diameter_y = ReadSetting("touchscreen_diameter_y", 15).toUInt();
- qt_config->endGroup();
+ Settings::values.touchscreen.finger =
+ ReadSetting(QStringLiteral("touchscreen_finger"), 0).toUInt();
+ Settings::values.touchscreen.rotation_angle =
+ ReadSetting(QStringLiteral("touchscreen_angle"), 0).toUInt();
+ Settings::values.touchscreen.diameter_x =
+ ReadSetting(QStringLiteral("touchscreen_diameter_x"), 15).toUInt();
+ Settings::values.touchscreen.diameter_y =
+ ReadSetting(QStringLiteral("touchscreen_diameter_y"), 15).toUInt();
}
void Config::ApplyDefaultProfileIfInputInvalid() {
@@ -366,8 +398,25 @@ void Config::ApplyDefaultProfileIfInputInvalid() {
}
}
-void Config::ReadValues() {
- qt_config->beginGroup("Controls");
+void Config::ReadAudioValues() {
+ qt_config->beginGroup(QStringLiteral("Audio"));
+
+ Settings::values.sink_id = ReadSetting(QStringLiteral("output_engine"), QStringLiteral("auto"))
+ .toString()
+ .toStdString();
+ Settings::values.enable_audio_stretching =
+ ReadSetting(QStringLiteral("enable_audio_stretching"), true).toBool();
+ Settings::values.audio_device_id =
+ ReadSetting(QStringLiteral("output_device"), QStringLiteral("auto"))
+ .toString()
+ .toStdString();
+ Settings::values.volume = ReadSetting(QStringLiteral("volume"), 1).toFloat();
+
+ qt_config->endGroup();
+}
+
+void Config::ReadControlValues() {
+ qt_config->beginGroup(QStringLiteral("Controls"));
ReadPlayerValues();
ReadDebugValues();
@@ -376,220 +425,310 @@ void Config::ReadValues() {
ReadTouchscreenValues();
Settings::values.motion_device =
- ReadSetting("motion_device", "engine:motion_emu,update_period:100,sensitivity:0.01")
+ ReadSetting(QStringLiteral("motion_device"),
+ QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01"))
.toString()
.toStdString();
- qt_config->beginGroup("Core");
- Settings::values.use_cpu_jit = ReadSetting("use_cpu_jit", true).toBool();
- Settings::values.use_multi_core = ReadSetting("use_multi_core", false).toBool();
qt_config->endGroup();
+}
- qt_config->beginGroup("Renderer");
- Settings::values.resolution_factor = ReadSetting("resolution_factor", 1.0).toFloat();
- Settings::values.use_frame_limit = ReadSetting("use_frame_limit", true).toBool();
- Settings::values.frame_limit = ReadSetting("frame_limit", 100).toInt();
- Settings::values.use_compatibility_profile =
- ReadSetting("use_compatibility_profile", true).toBool();
- Settings::values.use_disk_shader_cache = ReadSetting("use_disk_shader_cache", true).toBool();
- Settings::values.use_accurate_gpu_emulation =
- ReadSetting("use_accurate_gpu_emulation", false).toBool();
- Settings::values.use_asynchronous_gpu_emulation =
- ReadSetting("use_asynchronous_gpu_emulation", false).toBool();
- Settings::values.force_30fps_mode = ReadSetting("force_30fps_mode", false).toBool();
+void Config::ReadCoreValues() {
+ qt_config->beginGroup(QStringLiteral("Core"));
- Settings::values.bg_red = ReadSetting("bg_red", 0.0).toFloat();
- Settings::values.bg_green = ReadSetting("bg_green", 0.0).toFloat();
- Settings::values.bg_blue = ReadSetting("bg_blue", 0.0).toFloat();
- qt_config->endGroup();
+ Settings::values.use_cpu_jit = ReadSetting(QStringLiteral("use_cpu_jit"), true).toBool();
+ Settings::values.use_multi_core = ReadSetting(QStringLiteral("use_multi_core"), false).toBool();
- qt_config->beginGroup("Audio");
- Settings::values.sink_id = ReadSetting("output_engine", "auto").toString().toStdString();
- Settings::values.enable_audio_stretching =
- ReadSetting("enable_audio_stretching", true).toBool();
- Settings::values.audio_device_id =
- ReadSetting("output_device", "auto").toString().toStdString();
- Settings::values.volume = ReadSetting("volume", 1).toFloat();
qt_config->endGroup();
+}
+
+void Config::ReadDataStorageValues() {
+ qt_config->beginGroup(QStringLiteral("Data Storage"));
- qt_config->beginGroup("Data Storage");
- Settings::values.use_virtual_sd = ReadSetting("use_virtual_sd", true).toBool();
+ Settings::values.use_virtual_sd = ReadSetting(QStringLiteral("use_virtual_sd"), true).toBool();
FileUtil::GetUserPath(
FileUtil::UserPath::NANDDir,
qt_config
- ->value("nand_directory",
+ ->value(QStringLiteral("nand_directory"),
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)))
.toString()
.toStdString());
FileUtil::GetUserPath(
FileUtil::UserPath::SDMCDir,
qt_config
- ->value("sdmc_directory",
+ ->value(QStringLiteral("sdmc_directory"),
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)))
.toString()
.toStdString());
- qt_config->endGroup();
- qt_config->beginGroup("Core");
- Settings::values.use_cpu_jit = ReadSetting("use_cpu_jit", true).toBool();
- Settings::values.use_multi_core = ReadSetting("use_multi_core", false).toBool();
qt_config->endGroup();
+}
- qt_config->beginGroup("System");
- Settings::values.use_docked_mode = ReadSetting("use_docked_mode", false).toBool();
-
- Settings::values.current_user =
- std::clamp<int>(ReadSetting("current_user", 0).toInt(), 0, Service::Account::MAX_USERS - 1);
-
- Settings::values.language_index = ReadSetting("language_index", 1).toInt();
-
- const auto rng_seed_enabled = ReadSetting("rng_seed_enabled", false).toBool();
- if (rng_seed_enabled) {
- Settings::values.rng_seed = ReadSetting("rng_seed", 0).toULongLong();
- } else {
- Settings::values.rng_seed = std::nullopt;
- }
-
- const auto custom_rtc_enabled = ReadSetting("custom_rtc_enabled", false).toBool();
- if (custom_rtc_enabled) {
- Settings::values.custom_rtc =
- std::chrono::seconds(ReadSetting("custom_rtc", 0).toULongLong());
- } else {
- Settings::values.custom_rtc = std::nullopt;
- }
-
- qt_config->endGroup();
+void Config::ReadDebuggingValues() {
+ qt_config->beginGroup(QStringLiteral("Debugging"));
- qt_config->beginGroup("Miscellaneous");
- Settings::values.log_filter = ReadSetting("log_filter", "*:Info").toString().toStdString();
- Settings::values.use_dev_keys = ReadSetting("use_dev_keys", false).toBool();
- qt_config->endGroup();
+ Settings::values.use_gdbstub = ReadSetting(QStringLiteral("use_gdbstub"), false).toBool();
+ Settings::values.gdbstub_port = ReadSetting(QStringLiteral("gdbstub_port"), 24689).toInt();
+ Settings::values.program_args =
+ ReadSetting(QStringLiteral("program_args"), QStringLiteral("")).toString().toStdString();
+ Settings::values.dump_exefs = ReadSetting(QStringLiteral("dump_exefs"), false).toBool();
+ Settings::values.dump_nso = ReadSetting(QStringLiteral("dump_nso"), false).toBool();
- qt_config->beginGroup("Debugging");
- Settings::values.use_gdbstub = ReadSetting("use_gdbstub", false).toBool();
- Settings::values.gdbstub_port = ReadSetting("gdbstub_port", 24689).toInt();
- Settings::values.program_args = ReadSetting("program_args", "").toString().toStdString();
- Settings::values.dump_exefs = ReadSetting("dump_exefs", false).toBool();
- Settings::values.dump_nso = ReadSetting("dump_nso", false).toBool();
qt_config->endGroup();
+}
- qt_config->beginGroup("WebService");
- Settings::values.enable_telemetry = ReadSetting("enable_telemetry", true).toBool();
- Settings::values.web_api_url =
- ReadSetting("web_api_url", "https://api.yuzu-emu.org").toString().toStdString();
- Settings::values.yuzu_username = ReadSetting("yuzu_username").toString().toStdString();
- Settings::values.yuzu_token = ReadSetting("yuzu_token").toString().toStdString();
- qt_config->endGroup();
+void Config::ReadDisabledAddOnValues() {
+ const auto size = qt_config->beginReadArray(QStringLiteral("DisabledAddOns"));
- const auto size = qt_config->beginReadArray("DisabledAddOns");
for (int i = 0; i < size; ++i) {
qt_config->setArrayIndex(i);
- const auto title_id = ReadSetting("title_id", 0).toULongLong();
+ const auto title_id = ReadSetting(QStringLiteral("title_id"), 0).toULongLong();
std::vector<std::string> out;
- const auto d_size = qt_config->beginReadArray("disabled");
+ const auto d_size = qt_config->beginReadArray(QStringLiteral("disabled"));
for (int j = 0; j < d_size; ++j) {
qt_config->setArrayIndex(j);
- out.push_back(ReadSetting("d", "").toString().toStdString());
+ out.push_back(
+ ReadSetting(QStringLiteral("d"), QStringLiteral("")).toString().toStdString());
}
qt_config->endArray();
Settings::values.disabled_addons.insert_or_assign(title_id, out);
}
+
qt_config->endArray();
+}
+
+void Config::ReadMiscellaneousValues() {
+ qt_config->beginGroup(QStringLiteral("Miscellaneous"));
+
+ Settings::values.log_filter =
+ ReadSetting(QStringLiteral("log_filter"), QStringLiteral("*:Info"))
+ .toString()
+ .toStdString();
+ Settings::values.use_dev_keys = ReadSetting(QStringLiteral("use_dev_keys"), false).toBool();
- qt_config->beginGroup("UI");
- UISettings::values.theme = ReadSetting("theme", UISettings::themes[0].second).toString();
- UISettings::values.enable_discord_presence =
- ReadSetting("enable_discord_presence", true).toBool();
- UISettings::values.screenshot_resolution_factor =
- static_cast<u16>(ReadSetting("screenshot_resolution_factor", 0).toUInt());
- UISettings::values.select_user_on_boot = ReadSetting("select_user_on_boot", false).toBool();
-
- qt_config->beginGroup("UIGameList");
- UISettings::values.show_unknown = ReadSetting("show_unknown", true).toBool();
- UISettings::values.show_add_ons = ReadSetting("show_add_ons", true).toBool();
- UISettings::values.icon_size = ReadSetting("icon_size", 64).toUInt();
- UISettings::values.row_1_text_id = ReadSetting("row_1_text_id", 3).toUInt();
- UISettings::values.row_2_text_id = ReadSetting("row_2_text_id", 2).toUInt();
qt_config->endGroup();
+}
+
+void Config::ReadPathValues() {
+ qt_config->beginGroup(QStringLiteral("Paths"));
+
+ UISettings::values.roms_path = ReadSetting(QStringLiteral("romsPath")).toString();
+ UISettings::values.symbols_path = ReadSetting(QStringLiteral("symbolsPath")).toString();
+ UISettings::values.game_directory_path =
+ ReadSetting(QStringLiteral("gameListRootDir"), QStringLiteral(".")).toString();
+ UISettings::values.game_directory_deepscan =
+ ReadSetting(QStringLiteral("gameListDeepScan"), false).toBool();
+ UISettings::values.recent_files = ReadSetting(QStringLiteral("recentFiles")).toStringList();
- qt_config->beginGroup("UILayout");
- UISettings::values.geometry = ReadSetting("geometry").toByteArray();
- UISettings::values.state = ReadSetting("state").toByteArray();
- UISettings::values.renderwindow_geometry = ReadSetting("geometryRenderWindow").toByteArray();
- UISettings::values.gamelist_header_state = ReadSetting("gameListHeaderState").toByteArray();
- UISettings::values.microprofile_geometry =
- ReadSetting("microProfileDialogGeometry").toByteArray();
- UISettings::values.microprofile_visible =
- ReadSetting("microProfileDialogVisible", false).toBool();
qt_config->endGroup();
+}
+
+void Config::ReadRendererValues() {
+ qt_config->beginGroup(QStringLiteral("Renderer"));
+
+ Settings::values.resolution_factor =
+ ReadSetting(QStringLiteral("resolution_factor"), 1.0).toFloat();
+ Settings::values.use_frame_limit =
+ ReadSetting(QStringLiteral("use_frame_limit"), true).toBool();
+ Settings::values.frame_limit = ReadSetting(QStringLiteral("frame_limit"), 100).toInt();
+ Settings::values.use_compatibility_profile =
+ ReadSetting(QStringLiteral("use_compatibility_profile"), true).toBool();
+ Settings::values.use_disk_shader_cache =
+ ReadSetting(QStringLiteral("use_disk_shader_cache"), true).toBool();
+ Settings::values.use_accurate_gpu_emulation =
+ ReadSetting(QStringLiteral("use_accurate_gpu_emulation"), false).toBool();
+ Settings::values.use_asynchronous_gpu_emulation =
+ ReadSetting(QStringLiteral("use_asynchronous_gpu_emulation"), false).toBool();
+ Settings::values.force_30fps_mode =
+ ReadSetting(QStringLiteral("force_30fps_mode"), false).toBool();
+
+ Settings::values.bg_red = ReadSetting(QStringLiteral("bg_red"), 0.0).toFloat();
+ Settings::values.bg_green = ReadSetting(QStringLiteral("bg_green"), 0.0).toFloat();
+ Settings::values.bg_blue = ReadSetting(QStringLiteral("bg_blue"), 0.0).toFloat();
- qt_config->beginGroup("Paths");
- UISettings::values.roms_path = ReadSetting("romsPath").toString();
- UISettings::values.symbols_path = ReadSetting("symbolsPath").toString();
- UISettings::values.game_directory_path = ReadSetting("gameListRootDir", ".").toString();
- UISettings::values.game_directory_deepscan = ReadSetting("gameListDeepScan", false).toBool();
- UISettings::values.recent_files = ReadSetting("recentFiles").toStringList();
qt_config->endGroup();
+}
+
+void Config::ReadShortcutValues() {
+ qt_config->beginGroup(QStringLiteral("Shortcuts"));
- qt_config->beginGroup("Shortcuts");
- for (auto [name, group, shortcut] : default_hotkeys) {
- auto [keyseq, context] = shortcut;
+ for (const auto& [name, group, shortcut] : default_hotkeys) {
+ const auto& [keyseq, context] = shortcut;
qt_config->beginGroup(group);
qt_config->beginGroup(name);
UISettings::values.shortcuts.push_back(
{name,
group,
- {ReadSetting("KeySeq", keyseq).toString(), ReadSetting("Context", context).toInt()}});
+ {ReadSetting(QStringLiteral("KeySeq"), keyseq).toString(),
+ ReadSetting(QStringLiteral("Context"), context).toInt()}});
qt_config->endGroup();
qt_config->endGroup();
}
+
+ qt_config->endGroup();
+}
+
+void Config::ReadSystemValues() {
+ qt_config->beginGroup(QStringLiteral("System"));
+
+ Settings::values.use_docked_mode =
+ ReadSetting(QStringLiteral("use_docked_mode"), false).toBool();
+
+ Settings::values.current_user = std::clamp<int>(
+ ReadSetting(QStringLiteral("current_user"), 0).toInt(), 0, Service::Account::MAX_USERS - 1);
+
+ Settings::values.language_index = ReadSetting(QStringLiteral("language_index"), 1).toInt();
+
+ const auto rng_seed_enabled = ReadSetting(QStringLiteral("rng_seed_enabled"), false).toBool();
+ if (rng_seed_enabled) {
+ Settings::values.rng_seed = ReadSetting(QStringLiteral("rng_seed"), 0).toULongLong();
+ } else {
+ Settings::values.rng_seed = std::nullopt;
+ }
+
+ const auto custom_rtc_enabled =
+ ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool();
+ if (custom_rtc_enabled) {
+ Settings::values.custom_rtc =
+ std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong());
+ } else {
+ Settings::values.custom_rtc = std::nullopt;
+ }
+
qt_config->endGroup();
+}
+
+void Config::ReadUIValues() {
+ qt_config->beginGroup(QStringLiteral("UI"));
- UISettings::values.single_window_mode = ReadSetting("singleWindowMode", true).toBool();
- UISettings::values.fullscreen = ReadSetting("fullscreen", false).toBool();
- UISettings::values.display_titlebar = ReadSetting("displayTitleBars", true).toBool();
- UISettings::values.show_filter_bar = ReadSetting("showFilterBar", true).toBool();
- UISettings::values.show_status_bar = ReadSetting("showStatusBar", true).toBool();
- UISettings::values.confirm_before_closing = ReadSetting("confirmClose", true).toBool();
- UISettings::values.first_start = ReadSetting("firstStart", true).toBool();
- UISettings::values.callout_flags = ReadSetting("calloutFlags", 0).toUInt();
- UISettings::values.show_console = ReadSetting("showConsole", false).toBool();
- UISettings::values.profile_index = ReadSetting("profileIndex", 0).toUInt();
+ UISettings::values.theme =
+ ReadSetting(QStringLiteral("theme"), QString::fromUtf8(UISettings::themes[0].second))
+ .toString();
+ UISettings::values.enable_discord_presence =
+ ReadSetting(QStringLiteral("enable_discord_presence"), true).toBool();
+ UISettings::values.screenshot_resolution_factor =
+ static_cast<u16>(ReadSetting(QStringLiteral("screenshot_resolution_factor"), 0).toUInt());
+ UISettings::values.select_user_on_boot =
+ ReadSetting(QStringLiteral("select_user_on_boot"), false).toBool();
+
+ ReadUIGamelistValues();
+ ReadUILayoutValues();
+ ReadPathValues();
+ ReadShortcutValues();
+
+ UISettings::values.single_window_mode =
+ ReadSetting(QStringLiteral("singleWindowMode"), true).toBool();
+ UISettings::values.fullscreen = ReadSetting(QStringLiteral("fullscreen"), false).toBool();
+ UISettings::values.display_titlebar =
+ ReadSetting(QStringLiteral("displayTitleBars"), true).toBool();
+ UISettings::values.show_filter_bar =
+ ReadSetting(QStringLiteral("showFilterBar"), true).toBool();
+ UISettings::values.show_status_bar =
+ ReadSetting(QStringLiteral("showStatusBar"), true).toBool();
+ UISettings::values.confirm_before_closing =
+ ReadSetting(QStringLiteral("confirmClose"), true).toBool();
+ UISettings::values.first_start = ReadSetting(QStringLiteral("firstStart"), true).toBool();
+ UISettings::values.callout_flags = ReadSetting(QStringLiteral("calloutFlags"), 0).toUInt();
+ UISettings::values.show_console = ReadSetting(QStringLiteral("showConsole"), false).toBool();
+ UISettings::values.profile_index = ReadSetting(QStringLiteral("profileIndex"), 0).toUInt();
ApplyDefaultProfileIfInputInvalid();
qt_config->endGroup();
}
+void Config::ReadUIGamelistValues() {
+ qt_config->beginGroup(QStringLiteral("UIGameList"));
+
+ UISettings::values.show_unknown = ReadSetting(QStringLiteral("show_unknown"), true).toBool();
+ UISettings::values.show_add_ons = ReadSetting(QStringLiteral("show_add_ons"), true).toBool();
+ UISettings::values.icon_size = ReadSetting(QStringLiteral("icon_size"), 64).toUInt();
+ UISettings::values.row_1_text_id = ReadSetting(QStringLiteral("row_1_text_id"), 3).toUInt();
+ UISettings::values.row_2_text_id = ReadSetting(QStringLiteral("row_2_text_id"), 2).toUInt();
+ UISettings::values.cache_game_list =
+ ReadSetting(QStringLiteral("cache_game_list"), true).toBool();
+
+ qt_config->endGroup();
+}
+
+void Config::ReadUILayoutValues() {
+ qt_config->beginGroup(QStringLiteral("UILayout"));
+
+ UISettings::values.geometry = ReadSetting(QStringLiteral("geometry")).toByteArray();
+ UISettings::values.state = ReadSetting(QStringLiteral("state")).toByteArray();
+ UISettings::values.renderwindow_geometry =
+ ReadSetting(QStringLiteral("geometryRenderWindow")).toByteArray();
+ UISettings::values.gamelist_header_state =
+ ReadSetting(QStringLiteral("gameListHeaderState")).toByteArray();
+ UISettings::values.microprofile_geometry =
+ ReadSetting(QStringLiteral("microProfileDialogGeometry")).toByteArray();
+ UISettings::values.microprofile_visible =
+ ReadSetting(QStringLiteral("microProfileDialogVisible"), false).toBool();
+
+ qt_config->endGroup();
+}
+
+void Config::ReadWebServiceValues() {
+ qt_config->beginGroup(QStringLiteral("WebService"));
+
+ Settings::values.enable_telemetry =
+ ReadSetting(QStringLiteral("enable_telemetry"), true).toBool();
+ Settings::values.web_api_url =
+ ReadSetting(QStringLiteral("web_api_url"), QStringLiteral("https://api.yuzu-emu.org"))
+ .toString()
+ .toStdString();
+ Settings::values.yuzu_username =
+ ReadSetting(QStringLiteral("yuzu_username")).toString().toStdString();
+ Settings::values.yuzu_token =
+ ReadSetting(QStringLiteral("yuzu_token")).toString().toStdString();
+
+ qt_config->endGroup();
+}
+
+void Config::ReadValues() {
+ ReadControlValues();
+ ReadCoreValues();
+ ReadRendererValues();
+ ReadAudioValues();
+ ReadDataStorageValues();
+ ReadSystemValues();
+ ReadMiscellaneousValues();
+ ReadDebugValues();
+ ReadWebServiceValues();
+ ReadDisabledAddOnValues();
+ ReadUIValues();
+}
+
void Config::SavePlayerValues() {
for (std::size_t p = 0; p < Settings::values.players.size(); ++p) {
const auto& player = Settings::values.players[p];
- WriteSetting(QString("player_%1_connected").arg(p), player.connected, false);
- WriteSetting(QString("player_%1_type").arg(p), static_cast<u8>(player.type),
+ WriteSetting(QStringLiteral("player_%1_connected").arg(p), player.connected, false);
+ WriteSetting(QStringLiteral("player_%1_type").arg(p), static_cast<u8>(player.type),
static_cast<u8>(Settings::ControllerType::DualJoycon));
- WriteSetting(QString("player_%1_body_color_left").arg(p), player.body_color_left,
+ WriteSetting(QStringLiteral("player_%1_body_color_left").arg(p), player.body_color_left,
Settings::JOYCON_BODY_NEON_BLUE);
- WriteSetting(QString("player_%1_body_color_right").arg(p), player.body_color_right,
+ WriteSetting(QStringLiteral("player_%1_body_color_right").arg(p), player.body_color_right,
Settings::JOYCON_BODY_NEON_RED);
- WriteSetting(QString("player_%1_button_color_left").arg(p), player.button_color_left,
+ WriteSetting(QStringLiteral("player_%1_button_color_left").arg(p), player.button_color_left,
Settings::JOYCON_BUTTONS_NEON_BLUE);
- WriteSetting(QString("player_%1_button_color_right").arg(p), player.button_color_right,
- Settings::JOYCON_BUTTONS_NEON_RED);
+ WriteSetting(QStringLiteral("player_%1_button_color_right").arg(p),
+ player.button_color_right, Settings::JOYCON_BUTTONS_NEON_RED);
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- WriteSetting(QString("player_%1_").arg(p) +
+ const std::string default_param =
+ InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ WriteSetting(QStringLiteral("player_%1_").arg(p) +
QString::fromStdString(Settings::NativeButton::mapping[i]),
QString::fromStdString(player.buttons[i]),
QString::fromStdString(default_param));
}
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ const 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);
- WriteSetting(QString("player_%1_").arg(p) +
+ WriteSetting(QStringLiteral("player_%1_").arg(p) +
QString::fromStdString(Settings::NativeAnalog::mapping[i]),
QString::fromStdString(player.analogs[i]),
QString::fromStdString(default_param));
@@ -598,19 +737,19 @@ void Config::SavePlayerValues() {
}
void Config::SaveDebugValues() {
- WriteSetting("debug_pad_enabled", Settings::values.debug_pad_enabled, false);
+ WriteSetting(QStringLiteral("debug_pad_enabled"), Settings::values.debug_pad_enabled, false);
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
- std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
- WriteSetting(QString("debug_pad_") +
+ const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
+ WriteSetting(QStringLiteral("debug_pad_") +
QString::fromStdString(Settings::NativeButton::mapping[i]),
QString::fromStdString(Settings::values.debug_pad_buttons[i]),
QString::fromStdString(default_param));
}
for (int i = 0; i < Settings::NativeAnalog::NumAnalogs; ++i) {
- std::string default_param = InputCommon::GenerateAnalogParamFromKeys(
+ const 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);
- WriteSetting(QString("debug_pad_") +
+ WriteSetting(QStringLiteral("debug_pad_") +
QString::fromStdString(Settings::NativeAnalog::mapping[i]),
QString::fromStdString(Settings::values.debug_pad_analogs[i]),
QString::fromStdString(default_param));
@@ -618,11 +757,12 @@ void Config::SaveDebugValues() {
}
void Config::SaveMouseValues() {
- WriteSetting("mouse_enabled", Settings::values.mouse_enabled, false);
+ WriteSetting(QStringLiteral("mouse_enabled"), Settings::values.mouse_enabled, false);
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
- std::string default_param = InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]);
- WriteSetting(QString("mouse_") +
+ const std::string default_param =
+ InputCommon::GenerateKeyboardParam(default_mouse_buttons[i]);
+ WriteSetting(QStringLiteral("mouse_") +
QString::fromStdString(Settings::NativeMouseButton::mapping[i]),
QString::fromStdString(Settings::values.mouse_buttons[i]),
QString::fromStdString(default_param));
@@ -630,178 +770,278 @@ void Config::SaveMouseValues() {
}
void Config::SaveTouchscreenValues() {
- WriteSetting("touchscreen_enabled", Settings::values.touchscreen.enabled, true);
- WriteSetting("touchscreen_device", QString::fromStdString(Settings::values.touchscreen.device),
- "engine:emu_window");
+ const auto& touchscreen = Settings::values.touchscreen;
+
+ WriteSetting(QStringLiteral("touchscreen_enabled"), touchscreen.enabled, true);
+ WriteSetting(QStringLiteral("touchscreen_device"), QString::fromStdString(touchscreen.device),
+ QStringLiteral("engine:emu_window"));
- WriteSetting("touchscreen_finger", Settings::values.touchscreen.finger, 0);
- WriteSetting("touchscreen_angle", Settings::values.touchscreen.rotation_angle, 0);
- WriteSetting("touchscreen_diameter_x", Settings::values.touchscreen.diameter_x, 15);
- WriteSetting("touchscreen_diameter_y", Settings::values.touchscreen.diameter_y, 15);
+ WriteSetting(QStringLiteral("touchscreen_finger"), touchscreen.finger, 0);
+ WriteSetting(QStringLiteral("touchscreen_angle"), touchscreen.rotation_angle, 0);
+ WriteSetting(QStringLiteral("touchscreen_diameter_x"), touchscreen.diameter_x, 15);
+ WriteSetting(QStringLiteral("touchscreen_diameter_y"), touchscreen.diameter_y, 15);
}
void Config::SaveValues() {
- qt_config->beginGroup("Controls");
+ SaveControlValues();
+ SaveCoreValues();
+ SaveRendererValues();
+ SaveAudioValues();
+ SaveDataStorageValues();
+ SaveSystemValues();
+ SaveMiscellaneousValues();
+ SaveDebuggingValues();
+ SaveWebServiceValues();
+ SaveDisabledAddOnValues();
+ SaveUIValues();
+}
+
+void Config::SaveAudioValues() {
+ qt_config->beginGroup(QStringLiteral("Audio"));
+
+ WriteSetting(QStringLiteral("output_engine"), QString::fromStdString(Settings::values.sink_id),
+ QStringLiteral("auto"));
+ WriteSetting(QStringLiteral("enable_audio_stretching"),
+ Settings::values.enable_audio_stretching, true);
+ WriteSetting(QStringLiteral("output_device"),
+ QString::fromStdString(Settings::values.audio_device_id), QStringLiteral("auto"));
+ WriteSetting(QStringLiteral("volume"), Settings::values.volume, 1.0f);
+
+ qt_config->endGroup();
+}
+
+void Config::SaveControlValues() {
+ qt_config->beginGroup(QStringLiteral("Controls"));
SavePlayerValues();
SaveDebugValues();
SaveMouseValues();
SaveTouchscreenValues();
- WriteSetting("motion_device", QString::fromStdString(Settings::values.motion_device),
- "engine:motion_emu,update_period:100,sensitivity:0.01");
- WriteSetting("keyboard_enabled", Settings::values.keyboard_enabled, false);
+ WriteSetting(QStringLiteral("motion_device"),
+ QString::fromStdString(Settings::values.motion_device),
+ QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01"));
+ WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false);
qt_config->endGroup();
+}
- qt_config->beginGroup("Core");
- WriteSetting("use_cpu_jit", Settings::values.use_cpu_jit, true);
- WriteSetting("use_multi_core", Settings::values.use_multi_core, false);
- qt_config->endGroup();
+void Config::SaveCoreValues() {
+ qt_config->beginGroup(QStringLiteral("Core"));
- qt_config->beginGroup("Renderer");
- WriteSetting("resolution_factor", (double)Settings::values.resolution_factor, 1.0);
- WriteSetting("use_frame_limit", Settings::values.use_frame_limit, true);
- WriteSetting("frame_limit", Settings::values.frame_limit, 100);
- WriteSetting("use_compatibility_profile", Settings::values.use_compatibility_profile, true);
- WriteSetting("use_disk_shader_cache", Settings::values.use_disk_shader_cache, true);
- WriteSetting("use_accurate_gpu_emulation", Settings::values.use_accurate_gpu_emulation, false);
- WriteSetting("use_asynchronous_gpu_emulation", Settings::values.use_asynchronous_gpu_emulation,
- false);
- WriteSetting("force_30fps_mode", Settings::values.force_30fps_mode, false);
+ WriteSetting(QStringLiteral("use_cpu_jit"), Settings::values.use_cpu_jit, true);
+ WriteSetting(QStringLiteral("use_multi_core"), Settings::values.use_multi_core, false);
- // Cast to double because Qt's written float values are not human-readable
- WriteSetting("bg_red", (double)Settings::values.bg_red, 0.0);
- WriteSetting("bg_green", (double)Settings::values.bg_green, 0.0);
- WriteSetting("bg_blue", (double)Settings::values.bg_blue, 0.0);
qt_config->endGroup();
+}
- qt_config->beginGroup("Audio");
- WriteSetting("output_engine", QString::fromStdString(Settings::values.sink_id), "auto");
- WriteSetting("enable_audio_stretching", Settings::values.enable_audio_stretching, true);
- WriteSetting("output_device", QString::fromStdString(Settings::values.audio_device_id), "auto");
- WriteSetting("volume", Settings::values.volume, 1.0f);
- qt_config->endGroup();
+void Config::SaveDataStorageValues() {
+ qt_config->beginGroup(QStringLiteral("Data Storage"));
- qt_config->beginGroup("Data Storage");
- WriteSetting("use_virtual_sd", Settings::values.use_virtual_sd, true);
- WriteSetting("nand_directory",
+ WriteSetting(QStringLiteral("use_virtual_sd"), Settings::values.use_virtual_sd, true);
+ WriteSetting(QStringLiteral("nand_directory"),
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)),
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::NANDDir)));
- WriteSetting("sdmc_directory",
+ WriteSetting(QStringLiteral("sdmc_directory"),
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)),
QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::SDMCDir)));
- qt_config->endGroup();
-
- qt_config->beginGroup("System");
- WriteSetting("use_docked_mode", Settings::values.use_docked_mode, false);
- WriteSetting("current_user", Settings::values.current_user, 0);
- WriteSetting("language_index", Settings::values.language_index, 1);
-
- WriteSetting("rng_seed_enabled", Settings::values.rng_seed.has_value(), false);
- WriteSetting("rng_seed", Settings::values.rng_seed.value_or(0), 0);
-
- WriteSetting("custom_rtc_enabled", Settings::values.custom_rtc.has_value(), false);
- WriteSetting("custom_rtc",
- QVariant::fromValue<long long>(
- Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()),
- 0);
qt_config->endGroup();
+}
- qt_config->beginGroup("Miscellaneous");
- WriteSetting("log_filter", QString::fromStdString(Settings::values.log_filter), "*:Info");
- WriteSetting("use_dev_keys", Settings::values.use_dev_keys, false);
- qt_config->endGroup();
+void Config::SaveDebuggingValues() {
+ qt_config->beginGroup(QStringLiteral("Debugging"));
- qt_config->beginGroup("Debugging");
- WriteSetting("use_gdbstub", Settings::values.use_gdbstub, false);
- WriteSetting("gdbstub_port", Settings::values.gdbstub_port, 24689);
- WriteSetting("program_args", QString::fromStdString(Settings::values.program_args), "");
- WriteSetting("dump_exefs", Settings::values.dump_exefs, false);
- WriteSetting("dump_nso", Settings::values.dump_nso, false);
- qt_config->endGroup();
+ WriteSetting(QStringLiteral("use_gdbstub"), Settings::values.use_gdbstub, false);
+ WriteSetting(QStringLiteral("gdbstub_port"), Settings::values.gdbstub_port, 24689);
+ WriteSetting(QStringLiteral("program_args"),
+ QString::fromStdString(Settings::values.program_args), QStringLiteral(""));
+ WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false);
+ WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false);
- qt_config->beginGroup("WebService");
- WriteSetting("enable_telemetry", Settings::values.enable_telemetry, true);
- WriteSetting("web_api_url", QString::fromStdString(Settings::values.web_api_url),
- "https://api.yuzu-emu.org");
- WriteSetting("yuzu_username", QString::fromStdString(Settings::values.yuzu_username));
- WriteSetting("yuzu_token", QString::fromStdString(Settings::values.yuzu_token));
qt_config->endGroup();
+}
+
+void Config::SaveDisabledAddOnValues() {
+ qt_config->beginWriteArray(QStringLiteral("DisabledAddOns"));
- qt_config->beginWriteArray("DisabledAddOns");
int i = 0;
for (const auto& elem : Settings::values.disabled_addons) {
qt_config->setArrayIndex(i);
- WriteSetting("title_id", QVariant::fromValue<u64>(elem.first), 0);
- qt_config->beginWriteArray("disabled");
+ WriteSetting(QStringLiteral("title_id"), QVariant::fromValue<u64>(elem.first), 0);
+ qt_config->beginWriteArray(QStringLiteral("disabled"));
for (std::size_t j = 0; j < elem.second.size(); ++j) {
qt_config->setArrayIndex(static_cast<int>(j));
- WriteSetting("d", QString::fromStdString(elem.second[j]), "");
+ WriteSetting(QStringLiteral("d"), QString::fromStdString(elem.second[j]),
+ QStringLiteral(""));
}
qt_config->endArray();
++i;
}
+
qt_config->endArray();
+}
+
+void Config::SaveMiscellaneousValues() {
+ qt_config->beginGroup(QStringLiteral("Miscellaneous"));
+
+ WriteSetting(QStringLiteral("log_filter"), QString::fromStdString(Settings::values.log_filter),
+ QStringLiteral("*:Info"));
+ WriteSetting(QStringLiteral("use_dev_keys"), Settings::values.use_dev_keys, false);
- qt_config->beginGroup("UI");
- WriteSetting("theme", UISettings::values.theme, UISettings::themes[0].second);
- WriteSetting("enable_discord_presence", UISettings::values.enable_discord_presence, true);
- WriteSetting("screenshot_resolution_factor", UISettings::values.screenshot_resolution_factor,
- 0);
- WriteSetting("select_user_on_boot", UISettings::values.select_user_on_boot, false);
-
- qt_config->beginGroup("UIGameList");
- WriteSetting("show_unknown", UISettings::values.show_unknown, true);
- WriteSetting("show_add_ons", UISettings::values.show_add_ons, true);
- WriteSetting("icon_size", UISettings::values.icon_size, 64);
- WriteSetting("row_1_text_id", UISettings::values.row_1_text_id, 3);
- WriteSetting("row_2_text_id", UISettings::values.row_2_text_id, 2);
qt_config->endGroup();
+}
+
+void Config::SavePathValues() {
+ qt_config->beginGroup(QStringLiteral("Paths"));
+
+ WriteSetting(QStringLiteral("romsPath"), UISettings::values.roms_path);
+ WriteSetting(QStringLiteral("symbolsPath"), UISettings::values.symbols_path);
+ WriteSetting(QStringLiteral("screenshotPath"), UISettings::values.screenshot_path);
+ WriteSetting(QStringLiteral("gameListRootDir"), UISettings::values.game_directory_path,
+ QStringLiteral("."));
+ WriteSetting(QStringLiteral("gameListDeepScan"), UISettings::values.game_directory_deepscan,
+ false);
+ WriteSetting(QStringLiteral("recentFiles"), UISettings::values.recent_files);
- qt_config->beginGroup("UILayout");
- WriteSetting("geometry", UISettings::values.geometry);
- WriteSetting("state", UISettings::values.state);
- WriteSetting("geometryRenderWindow", UISettings::values.renderwindow_geometry);
- WriteSetting("gameListHeaderState", UISettings::values.gamelist_header_state);
- WriteSetting("microProfileDialogGeometry", UISettings::values.microprofile_geometry);
- WriteSetting("microProfileDialogVisible", UISettings::values.microprofile_visible, false);
qt_config->endGroup();
+}
+
+void Config::SaveRendererValues() {
+ qt_config->beginGroup(QStringLiteral("Renderer"));
+
+ WriteSetting(QStringLiteral("resolution_factor"),
+ static_cast<double>(Settings::values.resolution_factor), 1.0);
+ WriteSetting(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true);
+ WriteSetting(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100);
+ WriteSetting(QStringLiteral("use_compatibility_profile"),
+ Settings::values.use_compatibility_profile, true);
+ WriteSetting(QStringLiteral("use_disk_shader_cache"), Settings::values.use_disk_shader_cache,
+ true);
+ WriteSetting(QStringLiteral("use_accurate_gpu_emulation"),
+ Settings::values.use_accurate_gpu_emulation, false);
+ WriteSetting(QStringLiteral("use_asynchronous_gpu_emulation"),
+ Settings::values.use_asynchronous_gpu_emulation, false);
+ WriteSetting(QStringLiteral("force_30fps_mode"), Settings::values.force_30fps_mode, false);
+
+ // Cast to double because Qt's written float values are not human-readable
+ WriteSetting(QStringLiteral("bg_red"), static_cast<double>(Settings::values.bg_red), 0.0);
+ WriteSetting(QStringLiteral("bg_green"), static_cast<double>(Settings::values.bg_green), 0.0);
+ WriteSetting(QStringLiteral("bg_blue"), static_cast<double>(Settings::values.bg_blue), 0.0);
- qt_config->beginGroup("Paths");
- WriteSetting("romsPath", UISettings::values.roms_path);
- WriteSetting("symbolsPath", UISettings::values.symbols_path);
- WriteSetting("screenshotPath", UISettings::values.screenshot_path);
- WriteSetting("gameListRootDir", UISettings::values.game_directory_path, ".");
- WriteSetting("gameListDeepScan", UISettings::values.game_directory_deepscan, false);
- WriteSetting("recentFiles", UISettings::values.recent_files);
qt_config->endGroup();
+}
+
+void Config::SaveShortcutValues() {
+ qt_config->beginGroup(QStringLiteral("Shortcuts"));
- qt_config->beginGroup("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 < default_hotkeys.size(); i++) {
- auto [name, group, shortcut] = UISettings::values.shortcuts[i];
+ const auto& [name, group, shortcut] = UISettings::values.shortcuts[i];
+ const auto& default_hotkey = default_hotkeys[i].shortcut;
+
qt_config->beginGroup(group);
qt_config->beginGroup(name);
- WriteSetting("KeySeq", shortcut.first, default_hotkeys[i].shortcut.first);
- WriteSetting("Context", shortcut.second, default_hotkeys[i].shortcut.second);
+ WriteSetting(QStringLiteral("KeySeq"), shortcut.first, default_hotkey.first);
+ WriteSetting(QStringLiteral("Context"), shortcut.second, default_hotkey.second);
qt_config->endGroup();
qt_config->endGroup();
}
+
+ qt_config->endGroup();
+}
+
+void Config::SaveSystemValues() {
+ qt_config->beginGroup(QStringLiteral("System"));
+
+ WriteSetting(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, false);
+ WriteSetting(QStringLiteral("current_user"), Settings::values.current_user, 0);
+ WriteSetting(QStringLiteral("language_index"), Settings::values.language_index, 1);
+
+ WriteSetting(QStringLiteral("rng_seed_enabled"), Settings::values.rng_seed.has_value(), false);
+ WriteSetting(QStringLiteral("rng_seed"), Settings::values.rng_seed.value_or(0), 0);
+
+ WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(),
+ false);
+ WriteSetting(QStringLiteral("custom_rtc"),
+ QVariant::fromValue<long long>(
+ Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()),
+ 0);
+
+ qt_config->endGroup();
+}
+
+void Config::SaveUIValues() {
+ qt_config->beginGroup(QStringLiteral("UI"));
+
+ WriteSetting(QStringLiteral("theme"), UISettings::values.theme,
+ QString::fromUtf8(UISettings::themes[0].second));
+ WriteSetting(QStringLiteral("enable_discord_presence"),
+ UISettings::values.enable_discord_presence, true);
+ WriteSetting(QStringLiteral("screenshot_resolution_factor"),
+ UISettings::values.screenshot_resolution_factor, 0);
+ WriteSetting(QStringLiteral("select_user_on_boot"), UISettings::values.select_user_on_boot,
+ false);
+
+ SaveUIGamelistValues();
+ SaveUILayoutValues();
+ SavePathValues();
+ SaveShortcutValues();
+
+ WriteSetting(QStringLiteral("singleWindowMode"), UISettings::values.single_window_mode, true);
+ WriteSetting(QStringLiteral("fullscreen"), UISettings::values.fullscreen, false);
+ WriteSetting(QStringLiteral("displayTitleBars"), UISettings::values.display_titlebar, true);
+ WriteSetting(QStringLiteral("showFilterBar"), UISettings::values.show_filter_bar, true);
+ WriteSetting(QStringLiteral("showStatusBar"), UISettings::values.show_status_bar, true);
+ WriteSetting(QStringLiteral("confirmClose"), UISettings::values.confirm_before_closing, true);
+ WriteSetting(QStringLiteral("firstStart"), UISettings::values.first_start, true);
+ WriteSetting(QStringLiteral("calloutFlags"), UISettings::values.callout_flags, 0);
+ WriteSetting(QStringLiteral("showConsole"), UISettings::values.show_console, false);
+ WriteSetting(QStringLiteral("profileIndex"), UISettings::values.profile_index, 0);
+
+ qt_config->endGroup();
+}
+
+void Config::SaveUIGamelistValues() {
+ qt_config->beginGroup(QStringLiteral("UIGameList"));
+
+ WriteSetting(QStringLiteral("show_unknown"), UISettings::values.show_unknown, true);
+ WriteSetting(QStringLiteral("show_add_ons"), UISettings::values.show_add_ons, true);
+ WriteSetting(QStringLiteral("icon_size"), UISettings::values.icon_size, 64);
+ WriteSetting(QStringLiteral("row_1_text_id"), UISettings::values.row_1_text_id, 3);
+ WriteSetting(QStringLiteral("row_2_text_id"), UISettings::values.row_2_text_id, 2);
+ WriteSetting(QStringLiteral("cache_game_list"), UISettings::values.cache_game_list, true);
+
+ qt_config->endGroup();
+}
+
+void Config::SaveUILayoutValues() {
+ qt_config->beginGroup(QStringLiteral("UILayout"));
+
+ WriteSetting(QStringLiteral("geometry"), UISettings::values.geometry);
+ WriteSetting(QStringLiteral("state"), UISettings::values.state);
+ WriteSetting(QStringLiteral("geometryRenderWindow"), UISettings::values.renderwindow_geometry);
+ WriteSetting(QStringLiteral("gameListHeaderState"), UISettings::values.gamelist_header_state);
+ WriteSetting(QStringLiteral("microProfileDialogGeometry"),
+ UISettings::values.microprofile_geometry);
+ WriteSetting(QStringLiteral("microProfileDialogVisible"),
+ UISettings::values.microprofile_visible, false);
+
qt_config->endGroup();
+}
+
+void Config::SaveWebServiceValues() {
+ qt_config->beginGroup(QStringLiteral("WebService"));
+
+ WriteSetting(QStringLiteral("enable_telemetry"), Settings::values.enable_telemetry, true);
+ WriteSetting(QStringLiteral("web_api_url"),
+ QString::fromStdString(Settings::values.web_api_url),
+ QStringLiteral("https://api.yuzu-emu.org"));
+ WriteSetting(QStringLiteral("yuzu_username"),
+ QString::fromStdString(Settings::values.yuzu_username));
+ WriteSetting(QStringLiteral("yuzu_token"), QString::fromStdString(Settings::values.yuzu_token));
- WriteSetting("singleWindowMode", UISettings::values.single_window_mode, true);
- WriteSetting("fullscreen", UISettings::values.fullscreen, false);
- WriteSetting("displayTitleBars", UISettings::values.display_titlebar, true);
- WriteSetting("showFilterBar", UISettings::values.show_filter_bar, true);
- WriteSetting("showStatusBar", UISettings::values.show_status_bar, true);
- WriteSetting("confirmClose", UISettings::values.confirm_before_closing, true);
- WriteSetting("firstStart", UISettings::values.first_start, true);
- WriteSetting("calloutFlags", UISettings::values.callout_flags, 0);
- WriteSetting("showConsole", UISettings::values.show_console, false);
- WriteSetting("profileIndex", UISettings::values.profile_index, 0);
qt_config->endGroup();
}
@@ -811,7 +1051,7 @@ QVariant Config::ReadSetting(const QString& name) const {
QVariant Config::ReadSetting(const QString& name, const QVariant& default_value) const {
QVariant result;
- if (qt_config->value(name + "/default", false).toBool()) {
+ if (qt_config->value(name + QStringLiteral("/default"), false).toBool()) {
result = default_value;
} else {
result = qt_config->value(name, default_value);
@@ -825,7 +1065,7 @@ void Config::WriteSetting(const QString& name, const QVariant& value) {
void Config::WriteSetting(const QString& name, const QVariant& value,
const QVariant& default_value) {
- qt_config->setValue(name + "/default", value == default_value);
+ qt_config->setValue(name + QStringLiteral("/default"), value == default_value);
qt_config->setValue(name, value);
}
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index 221d2364c..6b523ecdd 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -9,7 +9,6 @@
#include <string>
#include <QVariant>
#include "core/settings.h"
-#include "yuzu/ui_settings.h"
class QSettings;
@@ -37,19 +36,51 @@ private:
void ReadTouchscreenValues();
void ApplyDefaultProfileIfInputInvalid();
+ // Read functions bases off the respective config section names.
+ void ReadAudioValues();
+ void ReadControlValues();
+ void ReadCoreValues();
+ void ReadDataStorageValues();
+ void ReadDebuggingValues();
+ void ReadDisabledAddOnValues();
+ void ReadMiscellaneousValues();
+ void ReadPathValues();
+ void ReadRendererValues();
+ void ReadShortcutValues();
+ void ReadSystemValues();
+ void ReadUIValues();
+ void ReadUIGamelistValues();
+ void ReadUILayoutValues();
+ void ReadWebServiceValues();
+
void SaveValues();
void SavePlayerValues();
void SaveDebugValues();
void SaveMouseValues();
void SaveTouchscreenValues();
+ // Save functions based off the respective config section names.
+ void SaveAudioValues();
+ void SaveControlValues();
+ void SaveCoreValues();
+ void SaveDataStorageValues();
+ void SaveDebuggingValues();
+ void SaveDisabledAddOnValues();
+ void SaveMiscellaneousValues();
+ void SavePathValues();
+ void SaveRendererValues();
+ void SaveShortcutValues();
+ void SaveSystemValues();
+ void SaveUIValues();
+ void SaveUIGamelistValues();
+ void SaveUILayoutValues();
+ void SaveWebServiceValues();
+
QVariant ReadSetting(const QString& name) const;
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
void WriteSetting(const QString& name, const QVariant& value);
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
- static const std::array<UISettings::Shortcut, 15> default_hotkeys;
-
std::unique_ptr<QSettings> qt_config;
std::string qt_config_loc;
};
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index 5d9ccc6e8..b0f9b814d 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -16,21 +16,21 @@ ConfigureAudio::ConfigureAudio(QWidget* parent)
ui->setupUi(this);
ui->output_sink_combo_box->clear();
- ui->output_sink_combo_box->addItem("auto");
+ ui->output_sink_combo_box->addItem(QString::fromUtf8(AudioCore::auto_device_name));
for (const char* id : AudioCore::GetSinkIDs()) {
- ui->output_sink_combo_box->addItem(id);
+ ui->output_sink_combo_box->addItem(QString::fromUtf8(id));
}
connect(ui->volume_slider, &QSlider::valueChanged, this,
&ConfigureAudio::setVolumeIndicatorText);
this->setConfiguration();
- connect(ui->output_sink_combo_box,
- static_cast<void (QComboBox::*)(int)>(&QComboBox::currentIndexChanged), this,
+ connect(ui->output_sink_combo_box, qOverload<int>(&QComboBox::currentIndexChanged), this,
&ConfigureAudio::updateAudioDevices);
- ui->output_sink_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
- ui->audio_device_combo_box->setEnabled(!Core::System::GetInstance().IsPoweredOn());
+ const bool is_powered_on = Core::System::GetInstance().IsPoweredOn();
+ ui->output_sink_combo_box->setEnabled(!is_powered_on);
+ ui->audio_device_combo_box->setEnabled(!is_powered_on);
}
ConfigureAudio::~ConfigureAudio() = default;
@@ -94,7 +94,7 @@ void ConfigureAudio::applyConfiguration() {
void ConfigureAudio::updateAudioDevices(int sink_index) {
ui->audio_device_combo_box->clear();
- ui->audio_device_combo_box->addItem(AudioCore::auto_device_name);
+ ui->audio_device_combo_box->addItem(QString::fromUtf8(AudioCore::auto_device_name));
const std::string sink_id = ui->output_sink_combo_box->itemText(sink_index).toStdString();
for (const auto& device : AudioCore::GetDeviceListForSink(sink_id)) {
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index a5218b051..8086f9d6b 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -17,13 +17,14 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry)
ui->hotkeysTab->Populate(registry);
this->setConfiguration();
this->PopulateSelectionList();
+
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
&ConfigureDialog::UpdateVisibleTabs);
+
adjustSize();
ui->selectorList->setCurrentRow(0);
-
- // Synchronise lists upon initialisation
- ui->hotkeysTab->EmitHotkeysChanged();
}
ConfigureDialog::~ConfigureDialog() = default;
diff --git a/src/yuzu/configuration/configure_gamelist.cpp b/src/yuzu/configuration/configure_gamelist.cpp
index ae8cac243..6f0d75605 100644
--- a/src/yuzu/configuration/configure_gamelist.cpp
+++ b/src/yuzu/configuration/configure_gamelist.cpp
@@ -100,13 +100,15 @@ void ConfigureGameList::RetranslateUI() {
void ConfigureGameList::InitializeIconSizeComboBox() {
for (const auto& size : default_icon_sizes) {
- ui->icon_size_combobox->addItem(size.second, size.first);
+ ui->icon_size_combobox->addItem(QString::fromUtf8(size.second), size.first);
}
}
void ConfigureGameList::InitializeRowComboBoxes() {
for (std::size_t i = 0; i < row_text_names.size(); ++i) {
- ui->row_1_text_combobox->addItem(row_text_names[i], QVariant::fromValue(i));
- ui->row_2_text_combobox->addItem(row_text_names[i], QVariant::fromValue(i));
+ const QString row_text_name = QString::fromUtf8(row_text_names[i]);
+
+ ui->row_1_text_combobox->addItem(row_text_name, QVariant::fromValue(i));
+ ui->row_2_text_combobox->addItem(row_text_name, QVariant::fromValue(i));
}
}
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index e48f4f5a3..dd25dc6e1 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -14,7 +14,8 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
ui->setupUi(this);
for (const auto& theme : UISettings::themes) {
- ui->theme_combobox->addItem(theme.first, theme.second);
+ ui->theme_combobox->addItem(QString::fromUtf8(theme.first),
+ QString::fromUtf8(theme.second));
}
this->setConfiguration();
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index c299c0b5b..08ea41b0f 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -69,16 +69,20 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
ConfigureGraphics::~ConfigureGraphics() = default;
void ConfigureGraphics::setConfiguration() {
+ const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
+
ui->resolution_factor_combobox->setCurrentIndex(
static_cast<int>(FromResolutionFactor(Settings::values.resolution_factor)));
ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit);
ui->frame_limit->setValue(Settings::values.frame_limit);
+ ui->use_compatibility_profile->setEnabled(runtime_lock);
ui->use_compatibility_profile->setChecked(Settings::values.use_compatibility_profile);
+ ui->use_disk_shader_cache->setEnabled(runtime_lock);
ui->use_disk_shader_cache->setChecked(Settings::values.use_disk_shader_cache);
ui->use_accurate_gpu_emulation->setChecked(Settings::values.use_accurate_gpu_emulation);
- ui->use_asynchronous_gpu_emulation->setEnabled(!Core::System::GetInstance().IsPoweredOn());
+ ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock);
ui->use_asynchronous_gpu_emulation->setChecked(Settings::values.use_asynchronous_gpu_emulation);
- ui->force_30fps_mode->setEnabled(!Core::System::GetInstance().IsPoweredOn());
+ ui->force_30fps_mode->setEnabled(runtime_lock);
ui->force_30fps_mode->setChecked(Settings::values.force_30fps_mode);
UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red, Settings::values.bg_green,
Settings::values.bg_blue));
diff --git a/src/yuzu/configuration/configure_hotkeys.cpp b/src/yuzu/configuration/configure_hotkeys.cpp
index a7a8752e5..9fb970c21 100644
--- a/src/yuzu/configuration/configure_hotkeys.cpp
+++ b/src/yuzu/configuration/configure_hotkeys.cpp
@@ -31,22 +31,6 @@ ConfigureHotkeys::ConfigureHotkeys(QWidget* parent)
ConfigureHotkeys::~ConfigureHotkeys() = default;
-void ConfigureHotkeys::EmitHotkeysChanged() {
- emit HotkeysChanged(GetUsedKeyList());
-}
-
-QList<QKeySequence> ConfigureHotkeys::GetUsedKeyList() const {
- QList<QKeySequence> list;
- for (int r = 0; r < model->rowCount(); r++) {
- const QStandardItem* parent = model->item(r, 0);
- for (int r2 = 0; r2 < parent->rowCount(); r2++) {
- const QStandardItem* keyseq = parent->child(r2, 1);
- list << QKeySequence::fromString(keyseq->text(), QKeySequence::NativeText);
- }
- }
- return list;
-}
-
void ConfigureHotkeys::Populate(const HotkeyRegistry& registry) {
for (const auto& group : registry.hotkey_groups) {
auto* parent_item = new QStandardItem(group.first);
@@ -83,16 +67,29 @@ void ConfigureHotkeys::Configure(QModelIndex index) {
}
if (IsUsedKey(key_sequence) && key_sequence != QKeySequence(previous_key.toString())) {
- QMessageBox::critical(this, tr("Error in inputted key"),
- tr("You're using a key that's already bound."));
+ QMessageBox::warning(this, tr("Conflicting Key Sequence"),
+ tr("The entered key sequence is already assigned to another hotkey."));
} else {
model->setData(index, key_sequence.toString(QKeySequence::NativeText));
- EmitHotkeysChanged();
}
}
bool ConfigureHotkeys::IsUsedKey(QKeySequence key_sequence) const {
- return GetUsedKeyList().contains(key_sequence);
+ for (int r = 0; r < model->rowCount(); r++) {
+ const QStandardItem* const parent = model->item(r, 0);
+
+ for (int r2 = 0; r2 < parent->rowCount(); r2++) {
+ const QStandardItem* const key_seq_item = parent->child(r2, 1);
+ const auto key_seq_str = key_seq_item->text();
+ const auto key_seq = QKeySequence::fromString(key_seq_str, QKeySequence::NativeText);
+
+ if (key_sequence == key_seq) {
+ return true;
+ }
+ }
+ }
+
+ return false;
}
void ConfigureHotkeys::applyConfiguration(HotkeyRegistry& registry) {
@@ -114,7 +111,6 @@ void ConfigureHotkeys::applyConfiguration(HotkeyRegistry& registry) {
}
registry.SaveHotkeys();
- Settings::Apply();
}
void ConfigureHotkeys::retranslateUi() {
diff --git a/src/yuzu/configuration/configure_hotkeys.h b/src/yuzu/configuration/configure_hotkeys.h
index 73fb8a175..e77d73c35 100644
--- a/src/yuzu/configuration/configure_hotkeys.h
+++ b/src/yuzu/configuration/configure_hotkeys.h
@@ -24,8 +24,6 @@ public:
void applyConfiguration(HotkeyRegistry& registry);
void retranslateUi();
- void EmitHotkeysChanged();
-
/**
* Populates the hotkey list widget using data from the provided registry.
* Called everytime the Configure dialog is opened.
@@ -33,13 +31,9 @@ public:
*/
void Populate(const HotkeyRegistry& registry);
-signals:
- void HotkeysChanged(QList<QKeySequence> new_key_list);
-
private:
void Configure(QModelIndex index);
bool IsUsedKey(QKeySequence key_sequence) const;
- QList<QKeySequence> GetUsedKeyList() const;
std::unique_ptr<Ui::ConfigureHotkeys> ui;
diff --git a/src/yuzu/configuration/configure_input.cpp b/src/yuzu/configuration/configure_input.cpp
index f39d57998..87e459714 100644
--- a/src/yuzu/configuration/configure_input.cpp
+++ b/src/yuzu/configuration/configure_input.cpp
@@ -75,8 +75,8 @@ ConfigureInput::ConfigureInput(QWidget* parent)
};
for (auto* controller_box : players_controller) {
- controller_box->addItems({"None", "Pro Controller", "Dual Joycons", "Single Right Joycon",
- "Single Left Joycon"});
+ controller_box->addItems({tr("None"), tr("Pro Controller"), tr("Dual Joycons"),
+ tr("Single Right Joycon"), tr("Single Left Joycon")});
}
this->loadConfiguration();
@@ -85,9 +85,10 @@ ConfigureInput::ConfigureInput(QWidget* parent)
connect(ui->restore_defaults_button, &QPushButton::pressed, this,
&ConfigureInput::restoreDefaults);
- for (auto* enabled : players_controller)
+ for (auto* enabled : players_controller) {
connect(enabled, QOverload<int>::of(&QComboBox::currentIndexChanged), this,
&ConfigureInput::updateUIEnabled);
+ }
connect(ui->use_docked_mode, &QCheckBox::stateChanged, this, &ConfigureInput::updateUIEnabled);
connect(ui->handheld_connected, &QCheckBox::stateChanged, this,
&ConfigureInput::updateUIEnabled);
@@ -147,10 +148,12 @@ void ConfigureInput::updateUIEnabled() {
bool hit_disabled = false;
for (auto* player : players_controller) {
player->setDisabled(hit_disabled);
- if (hit_disabled)
+ if (hit_disabled) {
player->setCurrentIndex(0);
- if (!hit_disabled && player->currentIndex() == 0)
+ }
+ if (!hit_disabled && player->currentIndex() == 0) {
hit_disabled = true;
+ }
}
for (std::size_t i = 0; i < players_controller.size(); ++i) {
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index c5a245ebe..95b0a656a 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -45,7 +45,7 @@ static QString GetKeyName(int key_code) {
case Qt::Key_Alt:
return QObject::tr("Alt");
case Qt::Key_Meta:
- return "";
+ return {};
default:
return QKeySequence(key_code).toString();
}
@@ -65,46 +65,70 @@ static void SetAnalogButton(const Common::ParamPackage& input_param,
static QString ButtonToText(const Common::ParamPackage& param) {
if (!param.Has("engine")) {
return QObject::tr("[not set]");
- } else if (param.Get("engine", "") == "keyboard") {
+ }
+
+ if (param.Get("engine", "") == "keyboard") {
return GetKeyName(param.Get("code", 0));
- } else if (param.Get("engine", "") == "sdl") {
+ }
+
+ if (param.Get("engine", "") == "sdl") {
if (param.Has("hat")) {
- return QString(QObject::tr("Hat %1 %2"))
- .arg(param.Get("hat", "").c_str(), param.Get("direction", "").c_str());
+ const QString hat_str = QString::fromStdString(param.Get("hat", ""));
+ const QString direction_str = QString::fromStdString(param.Get("direction", ""));
+
+ return QObject::tr("Hat %1 %2").arg(hat_str, direction_str);
}
+
if (param.Has("axis")) {
- return QString(QObject::tr("Axis %1%2"))
- .arg(param.Get("axis", "").c_str(), param.Get("direction", "").c_str());
+ const QString axis_str = QString::fromStdString(param.Get("axis", ""));
+ const QString direction_str = QString::fromStdString(param.Get("direction", ""));
+
+ return QObject::tr("Axis %1%2").arg(axis_str, direction_str);
}
+
if (param.Has("button")) {
- return QString(QObject::tr("Button %1")).arg(param.Get("button", "").c_str());
+ const QString button_str = QString::fromStdString(param.Get("button", ""));
+
+ return QObject::tr("Button %1").arg(button_str);
}
- return QString();
- } else {
- return QObject::tr("[unknown]");
+
+ return {};
}
-};
+
+ return QObject::tr("[unknown]");
+}
static QString AnalogToText(const Common::ParamPackage& param, const std::string& dir) {
if (!param.Has("engine")) {
return QObject::tr("[not set]");
- } else if (param.Get("engine", "") == "analog_from_button") {
+ }
+
+ if (param.Get("engine", "") == "analog_from_button") {
return ButtonToText(Common::ParamPackage{param.Get(dir, "")});
- } else if (param.Get("engine", "") == "sdl") {
+ }
+
+ if (param.Get("engine", "") == "sdl") {
if (dir == "modifier") {
- return QString(QObject::tr("[unused]"));
+ return QObject::tr("[unused]");
}
if (dir == "left" || dir == "right") {
- return QString(QObject::tr("Axis %1")).arg(param.Get("axis_x", "").c_str());
- } else if (dir == "up" || dir == "down") {
- return QString(QObject::tr("Axis %1")).arg(param.Get("axis_y", "").c_str());
+ const QString axis_x_str = QString::fromStdString(param.Get("axis_x", ""));
+
+ return QObject::tr("Axis %1").arg(axis_x_str);
}
- return QString();
- } else {
- return QObject::tr("[unknown]");
+
+ if (dir == "up" || dir == "down") {
+ const QString axis_y_str = QString::fromStdString(param.Get("axis_y", ""));
+
+ return QObject::tr("Axis %1").arg(axis_y_str);
+ }
+
+ return {};
}
-};
+
+ return QObject::tr("[unknown]");
+}
ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_index, bool debug)
: QDialog(parent), ui(std::make_unique<Ui::ConfigureInputPlayer>()), player_index(player_index),
@@ -214,38 +238,42 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
analog_map_stick = {ui->buttonLStickAnalog, ui->buttonRStickAnalog};
for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
- if (!button_map[button_id])
+ auto* const button = button_map[button_id];
+ if (button == nullptr) {
continue;
- button_map[button_id]->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(button_map[button_id], &QPushButton::released, [=]() {
+ }
+
+ button->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(button, &QPushButton::released, [=] {
handleClick(
button_map[button_id],
[=](const Common::ParamPackage& params) { buttons_param[button_id] = params; },
InputCommon::Polling::DeviceType::Button);
});
- connect(button_map[button_id], &QPushButton::customContextMenuRequested,
- [=](const QPoint& menu_location) {
- QMenu context_menu;
- context_menu.addAction(tr("Clear"), [&] {
- buttons_param[button_id].Clear();
- button_map[button_id]->setText(tr("[not set]"));
- });
- context_menu.addAction(tr("Restore Default"), [&] {
- buttons_param[button_id] = Common::ParamPackage{
- InputCommon::GenerateKeyboardParam(Config::default_buttons[button_id])};
- button_map[button_id]->setText(ButtonToText(buttons_param[button_id]));
- });
- context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
- });
+ connect(button, &QPushButton::customContextMenuRequested, [=](const QPoint& menu_location) {
+ QMenu context_menu;
+ context_menu.addAction(tr("Clear"), [&] {
+ buttons_param[button_id].Clear();
+ button_map[button_id]->setText(tr("[not set]"));
+ });
+ context_menu.addAction(tr("Restore Default"), [&] {
+ buttons_param[button_id] = Common::ParamPackage{
+ InputCommon::GenerateKeyboardParam(Config::default_buttons[button_id])};
+ button_map[button_id]->setText(ButtonToText(buttons_param[button_id]));
+ });
+ context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
+ });
}
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) {
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) {
- if (!analog_map_buttons[analog_id][sub_button_id])
+ auto* const analog_button = analog_map_buttons[analog_id][sub_button_id];
+ if (analog_button == nullptr) {
continue;
- analog_map_buttons[analog_id][sub_button_id]->setContextMenuPolicy(
- Qt::CustomContextMenu);
- connect(analog_map_buttons[analog_id][sub_button_id], &QPushButton::released, [=]() {
+ }
+
+ analog_button->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(analog_button, &QPushButton::released, [=]() {
handleClick(analog_map_buttons[analog_id][sub_button_id],
[=](const Common::ParamPackage& params) {
SetAnalogButton(params, analogs_param[analog_id],
@@ -253,8 +281,8 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
},
InputCommon::Polling::DeviceType::Button);
});
- connect(analog_map_buttons[analog_id][sub_button_id],
- &QPushButton::customContextMenuRequested, [=](const QPoint& menu_location) {
+ connect(analog_button, &QPushButton::customContextMenuRequested,
+ [=](const QPoint& menu_location) {
QMenu context_menu;
context_menu.addAction(tr("Clear"), [&] {
analogs_param[analog_id].Erase(analog_sub_buttons[sub_button_id]);
@@ -272,7 +300,7 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
menu_location));
});
}
- connect(analog_map_stick[analog_id], &QPushButton::released, [=]() {
+ connect(analog_map_stick[analog_id], &QPushButton::released, [=] {
QMessageBox::information(this, tr("Information"),
tr("After pressing OK, first move your joystick horizontally, "
"and then vertically."));
@@ -351,7 +379,7 @@ void ConfigureInputPlayer::OnControllerButtonClick(int i) {
return;
controller_colors[i] = new_bg_color;
controller_color_buttons[i]->setStyleSheet(
- QString("QPushButton { background-color: %1 }").arg(controller_colors[i].name()));
+ QStringLiteral("QPushButton { background-color: %1 }").arg(controller_colors[i].name()));
}
void ConfigureInputPlayer::loadConfiguration() {
@@ -388,7 +416,8 @@ void ConfigureInputPlayer::loadConfiguration() {
for (std::size_t i = 0; i < colors.size(); ++i) {
controller_color_buttons[i]->setStyleSheet(
- QString("QPushButton { background-color: %1 }").arg(controller_colors[i].name()));
+ QStringLiteral("QPushButton { background-color: %1 }")
+ .arg(controller_colors[i].name()));
}
}
@@ -410,14 +439,22 @@ void ConfigureInputPlayer::restoreDefaults() {
void ConfigureInputPlayer::ClearAll() {
for (int button_id = 0; button_id < Settings::NativeButton::NumButtons; button_id++) {
- if (button_map[button_id] && button_map[button_id]->isEnabled())
- buttons_param[button_id].Clear();
+ const auto* const button = button_map[button_id];
+ if (button == nullptr || !button->isEnabled()) {
+ continue;
+ }
+
+ buttons_param[button_id].Clear();
}
+
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) {
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) {
- if (analog_map_buttons[analog_id][sub_button_id] &&
- analog_map_buttons[analog_id][sub_button_id]->isEnabled())
- analogs_param[analog_id].Erase(analog_sub_buttons[sub_button_id]);
+ const auto* const analog_button = analog_map_buttons[analog_id][sub_button_id];
+ if (analog_button == nullptr || !analog_button->isEnabled()) {
+ continue;
+ }
+
+ analogs_param[analog_id].Erase(analog_sub_buttons[sub_button_id]);
}
}
@@ -431,10 +468,14 @@ void ConfigureInputPlayer::updateButtonLabels() {
for (int analog_id = 0; analog_id < Settings::NativeAnalog::NumAnalogs; analog_id++) {
for (int sub_button_id = 0; sub_button_id < ANALOG_SUB_BUTTONS_NUM; sub_button_id++) {
- if (analog_map_buttons[analog_id][sub_button_id]) {
- analog_map_buttons[analog_id][sub_button_id]->setText(
- AnalogToText(analogs_param[analog_id], analog_sub_buttons[sub_button_id]));
+ auto* const analog_button = analog_map_buttons[analog_id][sub_button_id];
+
+ if (analog_button == nullptr) {
+ continue;
}
+
+ analog_button->setText(
+ AnalogToText(analogs_param[analog_id], analog_sub_buttons[sub_button_id]));
}
analog_map_stick[analog_id]->setText(tr("Set Analog Stick"));
}
diff --git a/src/yuzu/configuration/configure_mouse_advanced.cpp b/src/yuzu/configuration/configure_mouse_advanced.cpp
index ef857035e..a14bb1475 100644
--- a/src/yuzu/configuration/configure_mouse_advanced.cpp
+++ b/src/yuzu/configuration/configure_mouse_advanced.cpp
@@ -25,7 +25,7 @@ static QString GetKeyName(int key_code) {
case Qt::Key_Alt:
return QObject::tr("Alt");
case Qt::Key_Meta:
- return "";
+ return {};
default:
return QKeySequence(key_code).toString();
}
@@ -34,24 +34,36 @@ static QString GetKeyName(int key_code) {
static QString ButtonToText(const Common::ParamPackage& param) {
if (!param.Has("engine")) {
return QObject::tr("[not set]");
- } else if (param.Get("engine", "") == "keyboard") {
+ }
+
+ if (param.Get("engine", "") == "keyboard") {
return GetKeyName(param.Get("code", 0));
- } else if (param.Get("engine", "") == "sdl") {
+ }
+
+ if (param.Get("engine", "") == "sdl") {
if (param.Has("hat")) {
- return QString(QObject::tr("Hat %1 %2"))
- .arg(param.Get("hat", "").c_str(), param.Get("direction", "").c_str());
+ const QString hat_str = QString::fromStdString(param.Get("hat", ""));
+ const QString direction_str = QString::fromStdString(param.Get("direction", ""));
+
+ return QObject::tr("Hat %1 %2").arg(hat_str, direction_str);
}
+
if (param.Has("axis")) {
- return QString(QObject::tr("Axis %1%2"))
- .arg(param.Get("axis", "").c_str(), param.Get("direction", "").c_str());
+ const QString axis_str = QString::fromStdString(param.Get("axis", ""));
+ const QString direction_str = QString::fromStdString(param.Get("direction", ""));
+
+ return QObject::tr("Axis %1%2").arg(axis_str, direction_str);
}
+
if (param.Has("button")) {
- return QString(QObject::tr("Button %1")).arg(param.Get("button", "").c_str());
+ const QString button_str = QString::fromStdString(param.Get("button", ""));
+
+ return QObject::tr("Button %1").arg(button_str);
}
- return QString();
- } else {
- return QObject::tr("[unknown]");
+ return {};
}
+
+ return QObject::tr("[unknown]");
}
ConfigureMouseAdvanced::ConfigureMouseAdvanced(QWidget* parent)
@@ -65,30 +77,31 @@ ConfigureMouseAdvanced::ConfigureMouseAdvanced(QWidget* parent)
};
for (int button_id = 0; button_id < Settings::NativeMouseButton::NumMouseButtons; button_id++) {
- if (!button_map[button_id])
+ auto* const button = button_map[button_id];
+ if (button == nullptr) {
continue;
- button_map[button_id]->setContextMenuPolicy(Qt::CustomContextMenu);
- connect(button_map[button_id], &QPushButton::released, [=]() {
+ }
+
+ button->setContextMenuPolicy(Qt::CustomContextMenu);
+ connect(button, &QPushButton::released, [=] {
handleClick(
button_map[button_id],
[=](const Common::ParamPackage& params) { buttons_param[button_id] = params; },
InputCommon::Polling::DeviceType::Button);
});
- connect(button_map[button_id], &QPushButton::customContextMenuRequested,
- [=](const QPoint& menu_location) {
- QMenu context_menu;
- context_menu.addAction(tr("Clear"), [&] {
- buttons_param[button_id].Clear();
- button_map[button_id]->setText(tr("[not set]"));
- });
- context_menu.addAction(tr("Restore Default"), [&] {
- buttons_param[button_id] =
- Common::ParamPackage{InputCommon::GenerateKeyboardParam(
- Config::default_mouse_buttons[button_id])};
- button_map[button_id]->setText(ButtonToText(buttons_param[button_id]));
- });
- context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
- });
+ connect(button, &QPushButton::customContextMenuRequested, [=](const QPoint& menu_location) {
+ QMenu context_menu;
+ context_menu.addAction(tr("Clear"), [&] {
+ buttons_param[button_id].Clear();
+ button_map[button_id]->setText(tr("[not set]"));
+ });
+ context_menu.addAction(tr("Restore Default"), [&] {
+ buttons_param[button_id] = Common::ParamPackage{
+ InputCommon::GenerateKeyboardParam(Config::default_mouse_buttons[button_id])};
+ button_map[button_id]->setText(ButtonToText(buttons_param[button_id]));
+ });
+ context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
+ });
}
connect(ui->buttonClearAll, &QPushButton::released, [this] { ClearAll(); });
@@ -138,8 +151,10 @@ void ConfigureMouseAdvanced::restoreDefaults() {
void ConfigureMouseAdvanced::ClearAll() {
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
- if (button_map[i] && button_map[i]->isEnabled())
+ const auto* const button = button_map[i];
+ if (button != nullptr && button->isEnabled()) {
buttons_param[i].Clear();
+ }
}
updateButtonLabels();
diff --git a/src/yuzu/configuration/configure_per_general.cpp b/src/yuzu/configuration/configure_per_general.cpp
index 022b94609..c3e68fdf5 100644
--- a/src/yuzu/configuration/configure_per_general.cpp
+++ b/src/yuzu/configuration/configure_per_general.cpp
@@ -13,6 +13,8 @@
#include <QTimer>
#include <QTreeView>
+#include "common/common_paths.h"
+#include "common/file_util.h"
#include "core/file_sys/control_metadata.h"
#include "core/file_sys/patch_manager.h"
#include "core/file_sys/xts_archive.h"
@@ -79,6 +81,14 @@ void ConfigurePerGameGeneral::applyConfiguration() {
disabled_addons.push_back(item.front()->text().toStdString());
}
+ auto current = Settings::values.disabled_addons[title_id];
+ std::sort(disabled_addons.begin(), disabled_addons.end());
+ std::sort(current.begin(), current.end());
+ if (disabled_addons != current) {
+ FileUtil::Delete(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP +
+ "game_list" + DIR_SEP + fmt::format("{:016X}.pv.txt", title_id));
+ }
+
Settings::values.disabled_addons[title_id] = disabled_addons;
}
@@ -88,15 +98,15 @@ void ConfigurePerGameGeneral::loadFromFile(FileSys::VirtualFile file) {
}
void ConfigurePerGameGeneral::loadConfiguration() {
- if (file == nullptr)
+ if (file == nullptr) {
return;
+ }
- const auto loader = Loader::GetLoader(file);
-
- ui->display_title_id->setText(fmt::format("{:016X}", title_id).c_str());
+ ui->display_title_id->setText(QString::fromStdString(fmt::format("{:016X}", title_id)));
FileSys::PatchManager pm{title_id};
const auto control = pm.GetControlMetadata();
+ const auto loader = Loader::GetLoader(file);
if (control.first != nullptr) {
ui->display_version->setText(QString::fromStdString(control.first->GetVersionString()));
@@ -142,8 +152,10 @@ void ConfigurePerGameGeneral::loadConfiguration() {
const auto& disabled = Settings::values.disabled_addons[title_id];
for (const auto& patch : pm.GetPatchVersionNames(update_raw)) {
- QStandardItem* first_item = new QStandardItem;
- const auto name = QString::fromStdString(patch.first).replace("[D] ", "");
+ const auto name =
+ QString::fromStdString(patch.first).replace(QStringLiteral("[D] "), QString{});
+
+ auto* const first_item = new QStandardItem;
first_item->setText(name);
first_item->setCheckable(true);
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index 10f8ba041..6d7d04c98 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -97,7 +97,7 @@ ConfigureProfileManager ::ConfigureProfileManager(QWidget* parent)
tree_view->setContextMenuPolicy(Qt::NoContextMenu);
item_model->insertColumns(0, 1);
- item_model->setHeaderData(0, Qt::Horizontal, "Users");
+ item_model->setHeaderData(0, Qt::Horizontal, tr("Users"));
// We must register all custom types with the Qt Automoc system so that we are able to use it
// with signals/slots. In this case, QList falls under the umbrells of custom types.
diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index 10645a2b3..ff18ace40 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -66,8 +66,9 @@ void ConfigureSystem::setConfiguration() {
ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.has_value());
ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.has_value());
- const auto rng_seed =
- QString("%1").arg(Settings::values.rng_seed.value_or(0), 8, 16, QLatin1Char{'0'}).toUpper();
+ const auto rng_seed = QStringLiteral("%1")
+ .arg(Settings::values.rng_seed.value_or(0), 8, 16, QLatin1Char{'0'})
+ .toUpper();
ui->rng_seed_edit->setText(rng_seed);
ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value());
diff --git a/src/yuzu/configuration/configure_web.cpp b/src/yuzu/configuration/configure_web.cpp
index 18566d028..9dc34412d 100644
--- a/src/yuzu/configuration/configure_web.cpp
+++ b/src/yuzu/configuration/configure_web.cpp
@@ -78,12 +78,16 @@ void ConfigureWeb::RefreshTelemetryID() {
void ConfigureWeb::OnLoginChanged() {
if (ui->edit_username->text().isEmpty() && ui->edit_token->text().isEmpty()) {
user_verified = true;
- ui->label_username_verified->setPixmap(QIcon::fromTheme("checked").pixmap(16));
- ui->label_token_verified->setPixmap(QIcon::fromTheme("checked").pixmap(16));
+
+ const QPixmap pixmap = QIcon::fromTheme(QStringLiteral("checked")).pixmap(16);
+ ui->label_username_verified->setPixmap(pixmap);
+ ui->label_token_verified->setPixmap(pixmap);
} else {
user_verified = false;
- ui->label_username_verified->setPixmap(QIcon::fromTheme("failed").pixmap(16));
- ui->label_token_verified->setPixmap(QIcon::fromTheme("failed").pixmap(16));
+
+ const QPixmap pixmap = QIcon::fromTheme(QStringLiteral("failed")).pixmap(16);
+ ui->label_username_verified->setPixmap(pixmap);
+ ui->label_token_verified->setPixmap(pixmap);
}
}
@@ -101,11 +105,15 @@ void ConfigureWeb::OnLoginVerified() {
ui->button_verify_login->setText(tr("Verify"));
if (verify_watcher.result()) {
user_verified = true;
- ui->label_username_verified->setPixmap(QIcon::fromTheme("checked").pixmap(16));
- ui->label_token_verified->setPixmap(QIcon::fromTheme("checked").pixmap(16));
+
+ const QPixmap pixmap = QIcon::fromTheme(QStringLiteral("checked")).pixmap(16);
+ ui->label_username_verified->setPixmap(pixmap);
+ ui->label_token_verified->setPixmap(pixmap);
} else {
- ui->label_username_verified->setPixmap(QIcon::fromTheme("failed").pixmap(16));
- ui->label_token_verified->setPixmap(QIcon::fromTheme("failed").pixmap(16));
+ const QPixmap pixmap = QIcon::fromTheme(QStringLiteral("failed")).pixmap(16);
+ ui->label_username_verified->setPixmap(pixmap);
+ ui->label_token_verified->setPixmap(pixmap);
+
QMessageBox::critical(
this, tr("Verification failed"),
tr("Verification failed. Check that you have entered your username and token "
diff --git a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
index 67ed0ba6d..1c80082a4 100644
--- a/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
+++ b/src/yuzu/debugger/graphics/graphics_breakpoints.cpp
@@ -135,7 +135,7 @@ GraphicsBreakPointsWidget::GraphicsBreakPointsWidget(
std::shared_ptr<Tegra::DebugContext> debug_context, QWidget* parent)
: QDockWidget(tr("Maxwell Breakpoints"), parent), Tegra::DebugContext::BreakPointObserver(
debug_context) {
- setObjectName("TegraBreakPointsWidget");
+ setObjectName(QStringLiteral("TegraBreakPointsWidget"));
status_text = new QLabel(tr("Emulation running"));
resume_button = new QPushButton(tr("Resume"));
diff --git a/src/yuzu/debugger/profiler.cpp b/src/yuzu/debugger/profiler.cpp
index 86e03e46d..f594ef076 100644
--- a/src/yuzu/debugger/profiler.cpp
+++ b/src/yuzu/debugger/profiler.cpp
@@ -47,7 +47,7 @@ private:
#endif
MicroProfileDialog::MicroProfileDialog(QWidget* parent) : QWidget(parent, Qt::Dialog) {
- setObjectName("MicroProfile");
+ setObjectName(QStringLiteral("MicroProfile"));
setWindowTitle(tr("MicroProfile"));
resize(1000, 600);
// Remove the "?" button from the titlebar and enable the maximize button
@@ -191,7 +191,7 @@ void MicroProfileDrawText(int x, int y, u32 hex_color, const char* text, u32 tex
for (u32 i = 0; i < text_length; ++i) {
// Position the text baseline 1 pixel above the bottom of the text cell, this gives nice
// vertical alignment of text for a wide range of tested fonts.
- mp_painter->drawText(x, y + MICROPROFILE_TEXT_HEIGHT - 2, QChar(text[i]));
+ mp_painter->drawText(x, y + MICROPROFILE_TEXT_HEIGHT - 2, QString{QLatin1Char{text[i]}});
x += MICROPROFILE_TEXT_WIDTH + 1;
}
}
diff --git a/src/yuzu/debugger/wait_tree.cpp b/src/yuzu/debugger/wait_tree.cpp
index 85b095688..cd8180f8b 100644
--- a/src/yuzu/debugger/wait_tree.cpp
+++ b/src/yuzu/debugger/wait_tree.cpp
@@ -91,19 +91,19 @@ WaitTreeMutexInfo::WaitTreeMutexInfo(VAddr mutex_address, const Kernel::HandleTa
WaitTreeMutexInfo::~WaitTreeMutexInfo() = default;
QString WaitTreeMutexInfo::GetText() const {
- return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char('0'));
+ return tr("waiting for mutex 0x%1").arg(mutex_address, 16, 16, QLatin1Char{'0'});
}
std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeMutexInfo::GetChildren() const {
- std::vector<std::unique_ptr<WaitTreeItem>> list;
-
- bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0;
+ const bool has_waiters = (mutex_value & Kernel::Mutex::MutexHasWaitersFlag) != 0;
+ std::vector<std::unique_ptr<WaitTreeItem>> list;
list.push_back(std::make_unique<WaitTreeText>(tr("has waiters: %1").arg(has_waiters)));
list.push_back(std::make_unique<WaitTreeText>(
- tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char('0'))));
- if (owner != nullptr)
+ tr("owner handle: 0x%1").arg(owner_handle, 8, 16, QLatin1Char{'0'})));
+ if (owner != nullptr) {
list.push_back(std::make_unique<WaitTreeThread>(*owner));
+ }
return list;
}
@@ -121,11 +121,14 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeCallstack::GetChildren() cons
u64 base_pointer = thread.GetContext().cpu_registers[BaseRegister];
while (base_pointer != 0) {
- u64 lr = Memory::Read64(base_pointer + sizeof(u64));
- if (lr == 0)
+ const u64 lr = Memory::Read64(base_pointer + sizeof(u64));
+ if (lr == 0) {
break;
- list.push_back(
- std::make_unique<WaitTreeText>(tr("0x%1").arg(lr - sizeof(u32), 16, 16, QChar('0'))));
+ }
+
+ list.push_back(std::make_unique<WaitTreeText>(
+ tr("0x%1").arg(lr - sizeof(u32), 16, 16, QLatin1Char{'0'})));
+
base_pointer = Memory::Read64(base_pointer);
}
@@ -174,10 +177,10 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeWaitObject::GetChildren() con
QString WaitTreeWaitObject::GetResetTypeQString(Kernel::ResetType reset_type) {
switch (reset_type) {
- case Kernel::ResetType::OneShot:
- return tr("one shot");
- case Kernel::ResetType::Sticky:
- return tr("sticky");
+ case Kernel::ResetType::Automatic:
+ return tr("automatic reset");
+ case Kernel::ResetType::Manual:
+ return tr("manual reset");
}
UNREACHABLE();
return {};
@@ -249,9 +252,9 @@ QString WaitTreeThread::GetText() const {
const auto& context = thread.GetContext();
const QString pc_info = tr(" PC = 0x%1 LR = 0x%2")
- .arg(context.pc, 8, 16, QLatin1Char('0'))
- .arg(context.cpu_registers[30], 8, 16, QLatin1Char('0'));
- return WaitTreeWaitObject::GetText() + pc_info + " (" + status + ") ";
+ .arg(context.pc, 8, 16, QLatin1Char{'0'})
+ .arg(context.cpu_registers[30], 8, 16, QLatin1Char{'0'});
+ return QStringLiteral("%1%2 (%3) ").arg(WaitTreeWaitObject::GetText(), pc_info, status);
}
QColor WaitTreeThread::GetColor() const {
@@ -424,7 +427,7 @@ void WaitTreeModel::InitItems() {
}
WaitTreeWidget::WaitTreeWidget(QWidget* parent) : QDockWidget(tr("Wait Tree"), parent) {
- setObjectName("WaitTreeWidget");
+ setObjectName(QStringLiteral("WaitTreeWidget"));
view = new QTreeView(this);
view->setHeaderHidden(true);
setWidget(view);
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index b0ca766ec..83d675773 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -14,7 +14,6 @@
#include <QMenu>
#include <QThreadPool>
#include <fmt/format.h>
-#include "common/common_paths.h"
#include "common/common_types.h"
#include "common/logging/log.h"
#include "core/file_sys/patch_manager.h"
@@ -48,7 +47,7 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve
return QObject::eventFilter(obj, event);
} else {
gamelist->search_field->edit_filter->clear();
- edit_filter_text = "";
+ edit_filter_text.clear();
}
break;
}
@@ -71,9 +70,9 @@ bool GameListSearchField::KeyReleaseEater::eventFilter(QObject* obj, QEvent* eve
}
if (resultCount == 1) {
// To avoid loading error dialog loops while confirming them using enter
- // Also users usually want to run a diffrent game after closing one
- gamelist->search_field->edit_filter->setText("");
- edit_filter_text = "";
+ // Also users usually want to run a different game after closing one
+ gamelist->search_field->edit_filter->clear();
+ edit_filter_text.clear();
emit gamelist->GameChosen(file_path);
} else {
return QObject::eventFilter(obj, event);
@@ -93,7 +92,7 @@ void GameListSearchField::setFilterResult(int visible, int total) {
}
void GameListSearchField::clear() {
- edit_filter->setText("");
+ edit_filter->clear();
}
void GameListSearchField::setFocus() {
@@ -103,25 +102,26 @@ void GameListSearchField::setFocus() {
}
GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
- KeyReleaseEater* keyReleaseEater = new KeyReleaseEater(parent);
+ auto* const key_release_eater = new KeyReleaseEater(parent);
layout_filter = new QHBoxLayout;
layout_filter->setMargin(8);
label_filter = new QLabel;
label_filter->setText(tr("Filter:"));
edit_filter = new QLineEdit;
- edit_filter->setText("");
+ edit_filter->clear();
edit_filter->setPlaceholderText(tr("Enter pattern to filter"));
- edit_filter->installEventFilter(keyReleaseEater);
+ edit_filter->installEventFilter(key_release_eater);
edit_filter->setClearButtonEnabled(true);
connect(edit_filter, &QLineEdit::textChanged, parent, &GameList::onTextChanged);
label_filter_result = new QLabel;
button_filter_close = new QToolButton(this);
- button_filter_close->setText("X");
+ button_filter_close->setText(QStringLiteral("X"));
button_filter_close->setCursor(Qt::ArrowCursor);
- button_filter_close->setStyleSheet("QToolButton{ border: none; padding: 0px; color: "
- "#000000; font-weight: bold; background: #F0F0F0; }"
- "QToolButton:hover{ border: none; padding: 0px; color: "
- "#EEEEEE; font-weight: bold; background: #E81123}");
+ button_filter_close->setStyleSheet(
+ QStringLiteral("QToolButton{ border: none; padding: 0px; color: "
+ "#000000; font-weight: bold; background: #F0F0F0; }"
+ "QToolButton:hover{ border: none; padding: 0px; color: "
+ "#EEEEEE; font-weight: bold; background: #E81123}"));
connect(button_filter_close, &QToolButton::clicked, parent, &GameList::onFilterCloseClicked);
layout_filter->setSpacing(10);
layout_filter->addWidget(label_filter);
@@ -141,36 +141,34 @@ GameListSearchField::GameListSearchField(GameList* parent) : QWidget{parent} {
*/
static bool ContainsAllWords(const QString& haystack, const QString& userinput) {
const QStringList userinput_split =
- userinput.split(' ', QString::SplitBehavior::SkipEmptyParts);
+ userinput.split(QLatin1Char{' '}, QString::SplitBehavior::SkipEmptyParts);
return std::all_of(userinput_split.begin(), userinput_split.end(),
[&haystack](const QString& s) { return haystack.contains(s); });
}
// Event in order to filter the gamelist after editing the searchfield
-void GameList::onTextChanged(const QString& newText) {
- int rowCount = tree_view->model()->rowCount();
- QString edit_filter_text = newText.toLower();
-
- QModelIndex root_index = item_model->invisibleRootItem()->index();
+void GameList::onTextChanged(const QString& new_text) {
+ const int row_count = tree_view->model()->rowCount();
+ const QString edit_filter_text = new_text.toLower();
+ const QModelIndex root_index = item_model->invisibleRootItem()->index();
// If the searchfield is empty every item is visible
// Otherwise the filter gets applied
if (edit_filter_text.isEmpty()) {
- for (int i = 0; i < rowCount; ++i) {
+ for (int i = 0; i < row_count; ++i) {
tree_view->setRowHidden(i, root_index, false);
}
- search_field->setFilterResult(rowCount, rowCount);
+ search_field->setFilterResult(row_count, row_count);
} else {
int result_count = 0;
- for (int i = 0; i < rowCount; ++i) {
+ for (int i = 0; i < row_count; ++i) {
const QStandardItem* child_file = item_model->item(i, 0);
const QString file_path =
child_file->data(GameListItemPath::FullPathRole).toString().toLower();
- QString file_name = file_path.mid(file_path.lastIndexOf('/') + 1);
const QString file_title =
child_file->data(GameListItemPath::TitleRole).toString().toLower();
- const QString file_programmid =
+ const QString file_program_id =
child_file->data(GameListItemPath::ProgramIdRole).toString().toLower();
// Only items which filename in combination with its title contains all words
@@ -178,14 +176,16 @@ void GameList::onTextChanged(const QString& newText) {
// The search is case insensitive because of toLower()
// I decided not to use Qt::CaseInsensitive in containsAllWords to prevent
// multiple conversions of edit_filter_text for each game in the gamelist
- if (ContainsAllWords(file_name.append(' ').append(file_title), edit_filter_text) ||
- (file_programmid.count() == 16 && edit_filter_text.contains(file_programmid))) {
+ const QString file_name = file_path.mid(file_path.lastIndexOf(QLatin1Char{'/'}) + 1) +
+ QLatin1Char{' '} + file_title;
+ if (ContainsAllWords(file_name, edit_filter_text) ||
+ (file_program_id.count() == 16 && edit_filter_text.contains(file_program_id))) {
tree_view->setRowHidden(i, root_index, false);
++result_count;
} else {
tree_view->setRowHidden(i, root_index, true);
}
- search_field->setFilterResult(result_count, rowCount);
+ search_field->setFilterResult(result_count, row_count);
}
}
}
@@ -216,7 +216,7 @@ GameList::GameList(FileSys::VirtualFilesystem vfs, FileSys::ManualContentProvide
tree_view->setEditTriggers(QHeaderView::NoEditTriggers);
tree_view->setUniformRowHeights(true);
tree_view->setContextMenuPolicy(Qt::CustomContextMenu);
- tree_view->setStyleSheet("QTreeView{ border: none; }");
+ tree_view->setStyleSheet(QStringLiteral("QTreeView{ border: none; }"));
item_model->insertColumns(0, UISettings::values.show_add_ons ? COLUMN_COUNT : COLUMN_COUNT - 1);
item_model->setHeaderData(COLUMN_NAME, Qt::Horizontal, tr("Name"));
@@ -282,9 +282,9 @@ void GameList::ValidateEntry(const QModelIndex& item) {
const QFileInfo file_info{file_path};
if (file_info.isDir()) {
const QDir dir{file_path};
- const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
+ const QStringList matching_main = dir.entryList({QStringLiteral("main")}, QDir::Files);
if (matching_main.size() == 1) {
- emit GameChosen(dir.path() + DIR_SEP + matching_main[0]);
+ emit GameChosen(dir.path() + QDir::separator() + matching_main[0]);
}
return;
}
@@ -360,7 +360,7 @@ void GameList::PopupContextMenu(const QPoint& menu_location) {
}
void GameList::LoadCompatibilityList() {
- QFile compat_list{":compatibility_list/compatibility_list.json"};
+ QFile compat_list{QStringLiteral(":compatibility_list/compatibility_list.json")};
if (!compat_list.open(QFile::ReadOnly | QFile::Text)) {
LOG_ERROR(Frontend, "Unable to open game compatibility list");
@@ -378,25 +378,27 @@ void GameList::LoadCompatibilityList() {
return;
}
- const QString string_content = content;
- QJsonDocument json = QJsonDocument::fromJson(string_content.toUtf8());
- QJsonArray arr = json.array();
+ const QJsonDocument json = QJsonDocument::fromJson(content);
+ const QJsonArray arr = json.array();
- for (const QJsonValueRef value : arr) {
- QJsonObject game = value.toObject();
+ for (const QJsonValue value : arr) {
+ const QJsonObject game = value.toObject();
+ const QString compatibility_key = QStringLiteral("compatibility");
- if (game.contains("compatibility") && game["compatibility"].isDouble()) {
- int compatibility = game["compatibility"].toInt();
- QString directory = game["directory"].toString();
- QJsonArray ids = game["releases"].toArray();
+ if (!game.contains(compatibility_key) || !game[compatibility_key].isDouble()) {
+ continue;
+ }
- for (const QJsonValueRef id_ref : ids) {
- QJsonObject id_object = id_ref.toObject();
- QString id = id_object["id"].toString();
- compatibility_list.emplace(
- id.toUpper().toStdString(),
- std::make_pair(QString::number(compatibility), directory));
- }
+ const int compatibility = game[compatibility_key].toInt();
+ const QString directory = game[QStringLiteral("directory")].toString();
+ const QJsonArray ids = game[QStringLiteral("releases")].toArray();
+
+ for (const QJsonValue id_ref : ids) {
+ const QJsonObject id_object = id_ref.toObject();
+ const QString id = id_object[QStringLiteral("id")].toString();
+
+ compatibility_list.emplace(id.toUpper().toStdString(),
+ std::make_pair(QString::number(compatibility), directory));
}
}
}
@@ -464,7 +466,10 @@ void GameList::LoadInterfaceLayout() {
item_model->sort(header->sortIndicatorSection(), header->sortIndicatorOrder());
}
-const QStringList GameList::supported_file_extensions = {"nso", "nro", "nca", "xci", "nsp"};
+const QStringList GameList::supported_file_extensions = {
+ QStringLiteral("nso"), QStringLiteral("nro"), QStringLiteral("nca"),
+ QStringLiteral("xci"), QStringLiteral("nsp"),
+};
void GameList::RefreshGameDirectory() {
if (!UISettings::values.game_directory_path.isEmpty() && current_worker != nullptr) {
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index 56007eef8..f8f8bd6c5 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -76,7 +76,7 @@ signals:
void OpenPerGameGeneralRequested(const std::string& file);
private slots:
- void onTextChanged(const QString& newText);
+ void onTextChanged(const QString& new_text);
void onFilterCloseClicked();
private:
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 2cf5c58a0..0b458ef48 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -4,11 +4,9 @@
#pragma once
-#include <algorithm>
#include <array>
#include <map>
#include <string>
-#include <unordered_map>
#include <utility>
#include <QCoreApplication>
@@ -25,8 +23,8 @@
#include "yuzu/util/util.h"
/**
- * Gets the default icon (for games without valid SMDH)
- * @param large If true, returns large icon (48x48), otherwise returns small icon (24x24)
+ * Gets the default icon (for games without valid title metadata)
+ * @param size The desired width and height of the default icon.
* @return QPixmap default icon
*/
static QPixmap GetDefaultIcon(u32 size) {
@@ -46,7 +44,7 @@ public:
* A specialization of GameListItem for path values.
* This class ensures that for every full path value it holds, a correct string representation
* of just the filename (with no extension) will be displayed to the user.
- * If this class receives valid SMDH data, it will also display game icons and titles.
+ * If this class receives valid title metadata, it will also display game icons and titles.
*/
class GameListItemPath : public GameListItem {
public:
@@ -95,7 +93,7 @@ public:
if (row2.isEmpty())
return row1;
- return QString(row1 + "\n " + row2);
+ return QString(row1 + QStringLiteral("\n ") + row2);
}
return GameListItem::data(role);
@@ -115,13 +113,14 @@ public:
};
// clang-format off
static const std::map<QString, CompatStatus> status_data = {
- {"0", {"#5c93ed", QT_TR_NOOP("Perfect"), QT_TR_NOOP("Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without\nany workarounds needed.")}},
- {"1", {"#47d35c", QT_TR_NOOP("Great"), QT_TR_NOOP("Game functions with minor graphical or audio glitches and is playable from start to finish. May require some\nworkarounds.")}},
- {"2", {"#94b242", QT_TR_NOOP("Okay"), QT_TR_NOOP("Game functions with major graphical or audio glitches, but game is playable from start to finish with\nworkarounds.")}},
- {"3", {"#f2d624", QT_TR_NOOP("Bad"), QT_TR_NOOP("Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches\neven with workarounds.")}},
- {"4", {"#FF0000", QT_TR_NOOP("Intro/Menu"), QT_TR_NOOP("Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start\nScreen.")}},
- {"5", {"#828282", QT_TR_NOOP("Won't Boot"), QT_TR_NOOP("The game crashes when attempting to startup.")}},
- {"99", {"#000000", QT_TR_NOOP("Not Tested"), QT_TR_NOOP("The game has not yet been tested.")}}};
+ {QStringLiteral("0"), {QStringLiteral("#5c93ed"), QT_TR_NOOP("Perfect"), QT_TR_NOOP("Game functions flawless with no audio or graphical glitches, all tested functionality works as intended without\nany workarounds needed.")}},
+ {QStringLiteral("1"), {QStringLiteral("#47d35c"), QT_TR_NOOP("Great"), QT_TR_NOOP("Game functions with minor graphical or audio glitches and is playable from start to finish. May require some\nworkarounds.")}},
+ {QStringLiteral("2"), {QStringLiteral("#94b242"), QT_TR_NOOP("Okay"), QT_TR_NOOP("Game functions with major graphical or audio glitches, but game is playable from start to finish with\nworkarounds.")}},
+ {QStringLiteral("3"), {QStringLiteral("#f2d624"), QT_TR_NOOP("Bad"), QT_TR_NOOP("Game functions, but with major graphical or audio glitches. Unable to progress in specific areas due to glitches\neven with workarounds.")}},
+ {QStringLiteral("4"), {QStringLiteral("#FF0000"), QT_TR_NOOP("Intro/Menu"), QT_TR_NOOP("Game is completely unplayable due to major graphical or audio glitches. Unable to progress past the Start\nScreen.")}},
+ {QStringLiteral("5"), {QStringLiteral("#828282"), QT_TR_NOOP("Won't Boot"), QT_TR_NOOP("The game crashes when attempting to startup.")}},
+ {QStringLiteral("99"), {QStringLiteral("#000000"), QT_TR_NOOP("Not Tested"), QT_TR_NOOP("The game has not yet been tested.")}},
+ };
// clang-format on
auto iterator = status_data.find(compatibility);
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index 8687e7c5a..4d951a4e7 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -9,6 +9,7 @@
#include <QDir>
#include <QFileInfo>
+#include <QSettings>
#include "common/common_paths.h"
#include "common/file_util.h"
@@ -30,13 +31,119 @@
#include "yuzu/ui_settings.h"
namespace {
+
+template <typename T>
+T GetGameListCachedObject(const std::string& filename, const std::string& ext,
+ const std::function<T()>& generator);
+
+template <>
+QString GetGameListCachedObject(const std::string& filename, const std::string& ext,
+ const std::function<QString()>& generator) {
+ if (!UISettings::values.cache_game_list || filename == "0000000000000000") {
+ return generator();
+ }
+
+ const auto path = FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP + "game_list" +
+ DIR_SEP + filename + '.' + ext;
+
+ FileUtil::CreateFullPath(path);
+
+ if (!FileUtil::Exists(path)) {
+ const auto str = generator();
+
+ std::ofstream stream(path);
+ if (stream) {
+ stream << str.toStdString();
+ }
+
+ return str;
+ }
+
+ std::ifstream stream(path);
+
+ if (stream) {
+ const std::string out(std::istreambuf_iterator<char>{stream},
+ std::istreambuf_iterator<char>{});
+ return QString::fromStdString(out);
+ }
+
+ return generator();
+}
+
+template <>
+std::pair<std::vector<u8>, std::string> GetGameListCachedObject(
+ const std::string& filename, const std::string& ext,
+ const std::function<std::pair<std::vector<u8>, std::string>()>& generator) {
+ if (!UISettings::values.cache_game_list || filename == "0000000000000000") {
+ return generator();
+ }
+
+ const auto path1 = FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP + "game_list" +
+ DIR_SEP + filename + ".jpeg";
+ const auto path2 = FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) + DIR_SEP + "game_list" +
+ DIR_SEP + filename + ".appname.txt";
+
+ FileUtil::CreateFullPath(path1);
+
+ if (!FileUtil::Exists(path1) || !FileUtil::Exists(path2)) {
+ const auto [icon, nacp] = generator();
+
+ FileUtil::IOFile file1(path1, "wb");
+ if (!file1.IsOpen()) {
+ LOG_ERROR(Frontend, "Failed to open cache file.");
+ return generator();
+ }
+
+ if (!file1.Resize(icon.size())) {
+ LOG_ERROR(Frontend, "Failed to resize cache file to necessary size.");
+ return generator();
+ }
+
+ if (file1.WriteBytes(icon.data(), icon.size()) != icon.size()) {
+ LOG_ERROR(Frontend, "Failed to write data to cache file.");
+ return generator();
+ }
+
+ std::ofstream stream2(path2, std::ios::out);
+ if (stream2) {
+ stream2 << nacp;
+ }
+
+ return std::make_pair(icon, nacp);
+ }
+
+ FileUtil::IOFile file1(path1, "rb");
+ std::ifstream stream2(path2);
+
+ if (!file1.IsOpen()) {
+ LOG_ERROR(Frontend, "Failed to open cache file for reading.");
+ return generator();
+ }
+
+ if (!stream2) {
+ LOG_ERROR(Frontend, "Failed to open cache file for reading.");
+ return generator();
+ }
+
+ std::vector<u8> vec(file1.GetSize());
+ file1.ReadBytes(vec.data(), vec.size());
+
+ if (stream2 && !vec.empty()) {
+ const std::string out(std::istreambuf_iterator<char>{stream2},
+ std::istreambuf_iterator<char>{});
+ return std::make_pair(vec, out);
+ }
+
+ return generator();
+}
+
void GetMetadataFromControlNCA(const FileSys::PatchManager& patch_manager, const FileSys::NCA& nca,
std::vector<u8>& icon, std::string& name) {
- auto [nacp, icon_file] = patch_manager.ParseControlNCA(nca);
- if (icon_file != nullptr)
- icon = icon_file->ReadAllBytes();
- if (nacp != nullptr)
- name = nacp->GetApplicationName();
+ std::tie(icon, name) = GetGameListCachedObject<std::pair<std::vector<u8>, std::string>>(
+ fmt::format("{:016X}", patch_manager.GetTitleID()), {}, [&patch_manager, &nca] {
+ const auto [nacp, icon_f] = patch_manager.ParseControlNCA(nca);
+ return std::make_pair(icon_f->ReadAllBytes(), nacp->GetApplicationName());
+ });
}
bool HasSupportedFileExtension(const std::string& file_name) {
@@ -45,7 +152,7 @@ bool HasSupportedFileExtension(const std::string& file_name) {
}
bool IsExtractedNCAMain(const std::string& file_name) {
- return QFileInfo(QString::fromStdString(file_name)).fileName() == "main";
+ return QFileInfo(QString::fromStdString(file_name)).fileName() == QStringLiteral("main");
}
QString FormatGameName(const std::string& physical_name) {
@@ -97,7 +204,7 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri
const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
// The game list uses this as compatibility number for untested games
- QString compatibility{"99"};
+ QString compatibility{QStringLiteral("99")};
if (it != compatibility_list.end()) {
compatibility = it->second.first;
}
@@ -114,8 +221,11 @@ QList<QStandardItem*> MakeGameListEntry(const std::string& path, const std::stri
};
if (UISettings::values.show_add_ons) {
- list.insert(
- 2, new GameListItem(FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable())));
+ const auto patch_versions = GetGameListCachedObject<QString>(
+ fmt::format("{:016X}", patch.GetTitleID()), "pv.txt", [&patch, &loader] {
+ return FormatPatchNameVersions(patch, loader, loader.IsRomFSUpdatable());
+ });
+ list.insert(2, new GameListItem(patch_versions));
}
return list;
diff --git a/src/yuzu/hotkeys.h b/src/yuzu/hotkeys.h
index 4f526dc7e..248fadaf3 100644
--- a/src/yuzu/hotkeys.h
+++ b/src/yuzu/hotkeys.h
@@ -67,8 +67,6 @@ public:
private:
struct Hotkey {
- Hotkey() : shortcut(nullptr), context(Qt::WindowShortcut) {}
-
QKeySequence keyseq;
QShortcut* shortcut = nullptr;
Qt::ShortcutContext context = Qt::WindowShortcut;
diff --git a/src/yuzu/loading_screen.cpp b/src/yuzu/loading_screen.cpp
index 4e2d988cd..4f2bfab48 100644
--- a/src/yuzu/loading_screen.cpp
+++ b/src/yuzu/loading_screen.cpp
@@ -30,11 +30,11 @@
#include <QMovie>
#endif
-constexpr const char PROGRESSBAR_STYLE_PREPARE[] = R"(
+constexpr char PROGRESSBAR_STYLE_PREPARE[] = R"(
QProgressBar {}
QProgressBar::chunk {})";
-constexpr const char PROGRESSBAR_STYLE_DECOMPILE[] = R"(
+constexpr char PROGRESSBAR_STYLE_DECOMPILE[] = R"(
QProgressBar {
background-color: black;
border: 2px solid white;
@@ -46,7 +46,7 @@ QProgressBar::chunk {
width: 1px;
})";
-constexpr const char PROGRESSBAR_STYLE_BUILD[] = R"(
+constexpr char PROGRESSBAR_STYLE_BUILD[] = R"(
QProgressBar {
background-color: black;
border: 2px solid white;
@@ -58,7 +58,7 @@ QProgressBar::chunk {
width: 1px;
})";
-constexpr const char PROGRESSBAR_STYLE_COMPLETE[] = R"(
+constexpr char PROGRESSBAR_STYLE_COMPLETE[] = R"(
QProgressBar {
background-color: #0ab9e6;
border: 2px solid white;
@@ -149,10 +149,10 @@ void LoadingScreen::OnLoadComplete() {
void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size_t value,
std::size_t total) {
using namespace std::chrono;
- auto now = high_resolution_clock::now();
+ const auto now = high_resolution_clock::now();
// reset the timer if the stage changes
if (stage != previous_stage) {
- ui->progress_bar->setStyleSheet(progressbar_style[stage]);
+ ui->progress_bar->setStyleSheet(QString::fromUtf8(progressbar_style[stage]));
// Hide the progress bar during the prepare stage
if (stage == VideoCore::LoadCallbackStage::Prepare) {
ui->progress_bar->hide();
@@ -178,16 +178,16 @@ void LoadingScreen::OnLoadProgress(VideoCore::LoadCallbackStage stage, std::size
slow_shader_first_value = value;
}
// only calculate an estimate time after a second has passed since stage change
- auto diff = duration_cast<milliseconds>(now - slow_shader_start);
+ const auto diff = duration_cast<milliseconds>(now - slow_shader_start);
if (diff > seconds{1}) {
- auto eta_mseconds =
+ const auto eta_mseconds =
static_cast<long>(static_cast<double>(total - slow_shader_first_value) /
(value - slow_shader_first_value) * diff.count());
estimate =
tr("Estimated Time %1")
.arg(QTime(0, 0, 0, 0)
.addMSecs(std::max<long>(eta_mseconds - diff.count() + 1000, 1000))
- .toString("mm:ss"));
+ .toString(QStringLiteral("mm:ss")));
}
}
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index e33e3aaaf..f8a0daebd 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -198,11 +198,11 @@ GMainWindow::GMainWindow()
ConnectMenuEvents();
ConnectWidgetEvents();
+
LOG_INFO(Frontend, "yuzu Version: {} | {}-{}", Common::g_build_fullname, Common::g_scm_branch,
Common::g_scm_desc);
+ UpdateWindowTitle();
- setWindowTitle(QString("yuzu %1| %2-%3")
- .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));
show();
Core::System::GetInstance().SetContentProvider(
@@ -281,7 +281,7 @@ void GMainWindow::SoftwareKeyboardInvokeCheckDialog(std::u16string error_message
void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view additional_args) {
NXInputWebEngineView web_browser_view(this);
- // Scope to contain the QProgressDialog for initalization
+ // Scope to contain the QProgressDialog for initialization
{
QProgressDialog progress(this);
progress.setMinimumDuration(200);
@@ -301,7 +301,7 @@ void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view
QWebEngineScript nx_shim;
nx_shim.setSourceCode(GetNXShimInjectionScript());
nx_shim.setWorldId(QWebEngineScript::MainWorld);
- nx_shim.setName("nx_inject.js");
+ nx_shim.setName(QStringLiteral("nx_inject.js"));
nx_shim.setInjectionPoint(QWebEngineScript::DocumentCreation);
nx_shim.setRunsOnSubFrames(true);
web_browser_view.page()->profile()->scripts()->insert(nx_shim);
@@ -347,7 +347,7 @@ void GMainWindow::WebBrowserOpenPage(std::string_view filename, std::string_view
const auto fire_js_keypress = [&web_browser_view](u32 key_code) {
web_browser_view.page()->runJavaScript(
QStringLiteral("document.dispatchEvent(new KeyboardEvent('keydown', {'key': %1}));")
- .arg(QString::fromStdString(std::to_string(key_code))));
+ .arg(key_code));
};
QMessageBox::information(
@@ -468,7 +468,7 @@ void GMainWindow::InitializeWidgets() {
statusBar()->addPermanentWidget(label, 0);
}
statusBar()->setVisible(true);
- setStyleSheet("QStatusBar::item{border: none;}");
+ setStyleSheet(QStringLiteral("QStatusBar::item{border: none;}"));
}
void GMainWindow::InitializeDebugWidgets() {
@@ -518,58 +518,67 @@ void GMainWindow::InitializeRecentFileMenuActions() {
void GMainWindow::InitializeHotkeys() {
hotkey_registry.LoadHotkeys();
- ui.action_Load_File->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Load File"));
+ const QString main_window = QStringLiteral("Main Window");
+ const QString load_file = QStringLiteral("Load File");
+ const QString exit_yuzu = QStringLiteral("Exit yuzu");
+ const QString stop_emulation = QStringLiteral("Stop Emulation");
+ const QString toggle_filter_bar = QStringLiteral("Toggle Filter Bar");
+ const QString toggle_status_bar = QStringLiteral("Toggle Status Bar");
+ const QString fullscreen = QStringLiteral("Fullscreen");
+
+ ui.action_Load_File->setShortcut(hotkey_registry.GetKeySequence(main_window, load_file));
ui.action_Load_File->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Load File"));
+ hotkey_registry.GetShortcutContext(main_window, load_file));
- ui.action_Exit->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Exit yuzu"));
- ui.action_Exit->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Exit yuzu"));
+ ui.action_Exit->setShortcut(hotkey_registry.GetKeySequence(main_window, exit_yuzu));
+ ui.action_Exit->setShortcutContext(hotkey_registry.GetShortcutContext(main_window, exit_yuzu));
- ui.action_Stop->setShortcut(hotkey_registry.GetKeySequence("Main Window", "Stop Emulation"));
+ ui.action_Stop->setShortcut(hotkey_registry.GetKeySequence(main_window, stop_emulation));
ui.action_Stop->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Stop Emulation"));
+ hotkey_registry.GetShortcutContext(main_window, stop_emulation));
ui.action_Show_Filter_Bar->setShortcut(
- hotkey_registry.GetKeySequence("Main Window", "Toggle Filter Bar"));
+ hotkey_registry.GetKeySequence(main_window, toggle_filter_bar));
ui.action_Show_Filter_Bar->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Toggle Filter Bar"));
+ hotkey_registry.GetShortcutContext(main_window, toggle_filter_bar));
ui.action_Show_Status_Bar->setShortcut(
- hotkey_registry.GetKeySequence("Main Window", "Toggle Status Bar"));
+ hotkey_registry.GetKeySequence(main_window, toggle_status_bar));
ui.action_Show_Status_Bar->setShortcutContext(
- hotkey_registry.GetShortcutContext("Main Window", "Toggle Status Bar"));
-
- connect(hotkey_registry.GetHotkey("Main Window", "Load File", this), &QShortcut::activated,
- this, &GMainWindow::OnMenuLoadFile);
- connect(hotkey_registry.GetHotkey("Main Window", "Continue/Pause Emulation", this),
- &QShortcut::activated, this, [&] {
- if (emulation_running) {
- if (emu_thread->IsRunning()) {
- OnPauseGame();
- } else {
- OnStartGame();
- }
+ hotkey_registry.GetShortcutContext(main_window, toggle_status_bar));
+
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load File"), this),
+ &QShortcut::activated, this, &GMainWindow::OnMenuLoadFile);
+ connect(
+ hotkey_registry.GetHotkey(main_window, QStringLiteral("Continue/Pause Emulation"), this),
+ &QShortcut::activated, this, [&] {
+ if (emulation_running) {
+ if (emu_thread->IsRunning()) {
+ OnPauseGame();
+ } else {
+ OnStartGame();
}
- });
- connect(hotkey_registry.GetHotkey("Main Window", "Restart Emulation", this),
+ }
+ });
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Restart Emulation"), this),
&QShortcut::activated, this, [this] {
- if (!Core::System::GetInstance().IsPoweredOn())
+ if (!Core::System::GetInstance().IsPoweredOn()) {
return;
- BootGame(QString(game_path));
+ }
+ BootGame(game_path);
});
- connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window),
+ connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
&QShortcut::activated, ui.action_Fullscreen, &QAction::trigger);
- connect(hotkey_registry.GetHotkey("Main Window", "Fullscreen", render_window),
+ connect(hotkey_registry.GetHotkey(main_window, fullscreen, render_window),
&QShortcut::activatedAmbiguously, ui.action_Fullscreen, &QAction::trigger);
- connect(hotkey_registry.GetHotkey("Main Window", "Exit Fullscreen", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Exit Fullscreen"), this),
&QShortcut::activated, this, [&] {
if (emulation_running) {
ui.action_Fullscreen->setChecked(false);
ToggleFullscreen();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Toggle Speed Limit", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this),
&QShortcut::activated, this, [&] {
Settings::values.use_frame_limit = !Settings::values.use_frame_limit;
UpdateStatusBar();
@@ -578,33 +587,33 @@ void GMainWindow::InitializeHotkeys() {
// MSVC occurs and we make it a requirement (see:
// https://developercommunity.visualstudio.com/content/problem/93922/constexprs-are-trying-to-be-captured-in-lambda-fun.html)
static constexpr u16 SPEED_LIMIT_STEP = 5;
- connect(hotkey_registry.GetHotkey("Main Window", "Increase Speed Limit", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this),
&QShortcut::activated, this, [&] {
if (Settings::values.frame_limit < 9999 - SPEED_LIMIT_STEP) {
Settings::values.frame_limit += SPEED_LIMIT_STEP;
UpdateStatusBar();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Decrease Speed Limit", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this),
&QShortcut::activated, this, [&] {
if (Settings::values.frame_limit > SPEED_LIMIT_STEP) {
Settings::values.frame_limit -= SPEED_LIMIT_STEP;
UpdateStatusBar();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Load Amiibo", this), &QShortcut::activated,
- this, [&] {
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Load Amiibo"), this),
+ &QShortcut::activated, this, [&] {
if (ui.action_Load_Amiibo->isEnabled()) {
OnLoadAmiibo();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Capture Screenshot", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Capture Screenshot"), this),
&QShortcut::activated, this, [&] {
if (emu_thread->IsRunning()) {
OnCaptureScreenshot();
}
});
- connect(hotkey_registry.GetHotkey("Main Window", "Change Docked Mode", this),
+ connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Change Docked Mode"), this),
&QShortcut::activated, this, [&] {
Settings::values.use_docked_mode = !Settings::values.use_docked_mode;
OnDockedModeChanged(!Settings::values.use_docked_mode,
@@ -705,7 +714,9 @@ void GMainWindow::ConnectMenuEvents() {
// Fullscreen
ui.action_Fullscreen->setShortcut(
- hotkey_registry.GetHotkey("Main Window", "Fullscreen", this)->key());
+ hotkey_registry
+ .GetHotkey(QStringLiteral("Main Window"), QStringLiteral("Fullscreen"), this)
+ ->key());
connect(ui.action_Fullscreen, &QAction::triggered, this, &GMainWindow::ToggleFullscreen);
// Movie
@@ -742,25 +753,33 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
QStringList GMainWindow::GetUnsupportedGLExtensions() {
QStringList unsupported_ext;
- if (!GLAD_GL_ARB_direct_state_access)
- unsupported_ext.append("ARB_direct_state_access");
- if (!GLAD_GL_ARB_vertex_type_10f_11f_11f_rev)
- unsupported_ext.append("ARB_vertex_type_10f_11f_11f_rev");
- if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge)
- unsupported_ext.append("ARB_texture_mirror_clamp_to_edge");
- if (!GLAD_GL_ARB_multi_bind)
- unsupported_ext.append("ARB_multi_bind");
+ if (!GLAD_GL_ARB_direct_state_access) {
+ unsupported_ext.append(QStringLiteral("ARB_direct_state_access"));
+ }
+ if (!GLAD_GL_ARB_vertex_type_10f_11f_11f_rev) {
+ unsupported_ext.append(QStringLiteral("ARB_vertex_type_10f_11f_11f_rev"));
+ }
+ if (!GLAD_GL_ARB_texture_mirror_clamp_to_edge) {
+ unsupported_ext.append(QStringLiteral("ARB_texture_mirror_clamp_to_edge"));
+ }
+ if (!GLAD_GL_ARB_multi_bind) {
+ unsupported_ext.append(QStringLiteral("ARB_multi_bind"));
+ }
// Extensions required to support some texture formats.
- if (!GLAD_GL_EXT_texture_compression_s3tc)
- unsupported_ext.append("EXT_texture_compression_s3tc");
- if (!GLAD_GL_ARB_texture_compression_rgtc)
- unsupported_ext.append("ARB_texture_compression_rgtc");
- if (!GLAD_GL_ARB_depth_buffer_float)
- unsupported_ext.append("ARB_depth_buffer_float");
-
- for (const QString& ext : unsupported_ext)
+ if (!GLAD_GL_EXT_texture_compression_s3tc) {
+ unsupported_ext.append(QStringLiteral("EXT_texture_compression_s3tc"));
+ }
+ if (!GLAD_GL_ARB_texture_compression_rgtc) {
+ unsupported_ext.append(QStringLiteral("ARB_texture_compression_rgtc"));
+ }
+ if (!GLAD_GL_ARB_depth_buffer_float) {
+ unsupported_ext.append(QStringLiteral("ARB_depth_buffer_float"));
+ }
+
+ for (const QString& ext : unsupported_ext) {
LOG_CRITICAL(Frontend, "Unsupported GL extension: {}", ext.toStdString());
+ }
return unsupported_ext;
}
@@ -782,13 +801,13 @@ bool GMainWindow::LoadROM(const QString& filename) {
}
}
- QStringList unsupported_gl_extensions = GetUnsupportedGLExtensions();
+ const QStringList unsupported_gl_extensions = GetUnsupportedGLExtensions();
if (!unsupported_gl_extensions.empty()) {
QMessageBox::critical(this, tr("Error while initializing OpenGL Core!"),
tr("Your GPU may not support one or more required OpenGL"
"extensions. Please ensure you have the latest graphics "
"driver.<br><br>Unsupported extensions:<br>") +
- unsupported_gl_extensions.join("<br>"));
+ unsupported_gl_extensions.join(QStringLiteral("<br>")));
return false;
}
@@ -936,9 +955,7 @@ void GMainWindow::BootGame(const QString& filename) {
title_name = FileUtil::GetFilename(filename.toStdString());
}
- setWindowTitle(QString("yuzu %1| %4 | %2-%3")
- .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc,
- QString::fromStdString(title_name)));
+ UpdateWindowTitle(QString::fromStdString(title_name));
loading_screen->Prepare(Core::System::GetInstance().GetAppLoader());
loading_screen->show();
@@ -979,8 +996,8 @@ void GMainWindow::ShutdownGame() {
loading_screen->Clear();
game_list->show();
game_list->setFilterFocus();
- setWindowTitle(QString("yuzu %1| %2-%3")
- .arg(Common::g_build_fullname, Common::g_scm_branch, Common::g_scm_desc));
+
+ UpdateWindowTitle();
// Disable status bar updates
status_bar_update_timer.stop();
@@ -1009,7 +1026,7 @@ void GMainWindow::UpdateRecentFiles() {
std::min(UISettings::values.recent_files.size(), max_recent_files_item);
for (int i = 0; i < num_recent_files; i++) {
- const QString text = QString("&%1. %2").arg(i + 1).arg(
+ const QString text = QStringLiteral("&%1. %2").arg(i + 1).arg(
QFileInfo(UISettings::values.recent_files[i]).fileName());
actions_recent_files[i]->setText(text);
actions_recent_files[i]->setData(UISettings::values.recent_files[i]);
@@ -1031,10 +1048,10 @@ void GMainWindow::OnGameListLoadFile(QString game_path) {
void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target) {
std::string path;
- std::string open_target;
+ QString open_target;
switch (target) {
case GameListOpenTarget::SaveData: {
- open_target = "Save Data";
+ open_target = tr("Save Data");
const std::string nand_dir = FileUtil::GetUserPath(FileUtil::UserPath::NANDDir);
ASSERT(program_id != 0);
@@ -1071,7 +1088,7 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
break;
}
case GameListOpenTarget::ModData: {
- open_target = "Mod Data";
+ open_target = tr("Mod Data");
const auto load_dir = FileUtil::GetUserPath(FileUtil::UserPath::LoadDir);
path = fmt::format("{}{:016X}", load_dir, program_id);
break;
@@ -1081,27 +1098,26 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
}
const QString qpath = QString::fromStdString(path);
-
const QDir dir(qpath);
if (!dir.exists()) {
- QMessageBox::warning(this,
- tr("Error Opening %1 Folder").arg(QString::fromStdString(open_target)),
+ QMessageBox::warning(this, tr("Error Opening %1 Folder").arg(open_target),
tr("Folder does not exist!"));
return;
}
- LOG_INFO(Frontend, "Opening {} path for program_id={:016x}", open_target, program_id);
+ LOG_INFO(Frontend, "Opening {} path for program_id={:016x}", open_target.toStdString(),
+ program_id);
QDesktopServices::openUrl(QUrl::fromLocalFile(qpath));
}
void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
ASSERT(program_id != 0);
+ const QString shader_dir =
+ QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir));
const QString tranferable_shader_cache_folder_path =
- QString::fromStdString(FileUtil::GetUserPath(FileUtil::UserPath::ShaderDir)) + "opengl" +
- DIR_SEP + "transferable";
-
+ shader_dir + QStringLiteral("opengl") + QDir::separator() + QStringLiteral("transferable");
const QString transferable_shader_cache_file_path =
- tranferable_shader_cache_folder_path + DIR_SEP +
+ tranferable_shader_cache_folder_path + QDir::separator() +
QString::fromStdString(fmt::format("{:016X}.bin", program_id));
if (!QFile::exists(transferable_shader_cache_file_path)) {
@@ -1218,20 +1234,21 @@ void GMainWindow::OnGameListDumpRomFS(u64 program_id, const std::string& game_pa
return;
}
- bool ok;
+ bool ok = false;
+ const QStringList selections{tr("Full"), tr("Skeleton")};
const auto res = QInputDialog::getItem(
this, tr("Select RomFS Dump Mode"),
tr("Please select the how you would like the RomFS dumped.<br>Full will copy all of the "
"files into the new directory while <br>skeleton will only create the directory "
"structure."),
- {"Full", "Skeleton"}, 0, false, &ok);
+ selections, 0, false, &ok);
if (!ok) {
failed();
vfs->DeleteDirectory(path);
return;
}
- const auto full = res == "Full";
+ const auto full = res == selections.constFirst();
const auto entry_size = CalculateRomFSEntrySize(extracted, full);
QProgressDialog progress(tr("Extracting RomFS..."), tr("Cancel"), 0,
@@ -1261,10 +1278,11 @@ void GMainWindow::OnGameListNavigateToGamedbEntry(u64 program_id,
const auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
QString directory;
- if (it != compatibility_list.end())
+ if (it != compatibility_list.end()) {
directory = it->second.second;
+ }
- QDesktopServices::openUrl(QUrl("https://yuzu-emu.org/game/" + directory));
+ QDesktopServices::openUrl(QUrl(QStringLiteral("https://yuzu-emu.org/game/") + directory));
}
void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
@@ -1295,7 +1313,9 @@ void GMainWindow::OnGameListOpenPerGameProperties(const std::string& file) {
void GMainWindow::OnMenuLoadFile() {
const QString extensions =
- QString("*.").append(GameList::supported_file_extensions.join(" *.")).append(" main");
+ QStringLiteral("*.")
+ .append(GameList::supported_file_extensions.join(QStringLiteral(" *.")))
+ .append(QStringLiteral(" main"));
const QString file_filter = tr("Switch Executable (%1);;All Files (*.*)",
"%1 is an identifier for the Switch executable file extensions.")
.arg(extensions);
@@ -1319,9 +1339,9 @@ void GMainWindow::OnMenuLoadFolder() {
}
const QDir dir{dir_path};
- const QStringList matching_main = dir.entryList(QStringList("main"), QDir::Files);
+ const QStringList matching_main = dir.entryList({QStringLiteral("main")}, QDir::Files);
if (matching_main.size() == 1) {
- BootGame(dir.path() + DIR_SEP + matching_main[0]);
+ BootGame(dir.path() + QDir::separator() + matching_main[0]);
} else {
QMessageBox::warning(this, tr("Invalid Directory Selected"),
tr("The directory you have selected does not contain a 'main' file."));
@@ -1376,6 +1396,8 @@ void GMainWindow::OnMenuInstallToNAND() {
tr("The file was successfully installed."));
game_list->PopulateAsync(UISettings::values.game_directory_path,
UISettings::values.game_directory_deepscan);
+ FileUtil::DeleteDirRecursively(FileUtil::GetUserPath(FileUtil::UserPath::CacheDir) +
+ DIR_SEP + "game_list");
};
const auto failed = [this]() {
@@ -1393,11 +1415,10 @@ void GMainWindow::OnMenuInstallToNAND() {
QMessageBox::Yes;
};
- if (filename.endsWith("xci", Qt::CaseInsensitive) ||
- filename.endsWith("nsp", Qt::CaseInsensitive)) {
-
+ if (filename.endsWith(QStringLiteral("xci"), Qt::CaseInsensitive) ||
+ filename.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) {
std::shared_ptr<FileSys::NSP> nsp;
- if (filename.endsWith("nsp", Qt::CaseInsensitive)) {
+ if (filename.endsWith(QStringLiteral("nsp"), Qt::CaseInsensitive)) {
nsp = std::make_shared<FileSys::NSP>(
vfs->OpenFile(filename.toStdString(), FileSys::Mode::Read));
if (nsp->IsExtractedType())
@@ -1692,9 +1713,9 @@ void GMainWindow::OnConfigure() {
}
void GMainWindow::OnLoadAmiibo() {
- const QString extensions{"*.bin"};
+ const QString extensions{QStringLiteral("*.bin")};
const QString file_filter = tr("Amiibo File (%1);; All Files (*.*)").arg(extensions);
- const QString filename = QFileDialog::getOpenFileName(this, tr("Load Amiibo"), "", file_filter);
+ const QString filename = QFileDialog::getOpenFileName(this, tr("Load Amiibo"), {}, file_filter);
if (filename.isEmpty()) {
return;
@@ -1756,7 +1777,7 @@ void GMainWindow::OnCaptureScreenshot() {
QFileDialog png_dialog(this, tr("Capture Screenshot"), UISettings::values.screenshot_path,
tr("PNG Image (*.png)"));
png_dialog.setAcceptMode(QFileDialog::AcceptSave);
- png_dialog.setDefaultSuffix("png");
+ png_dialog.setDefaultSuffix(QStringLiteral("png"));
if (png_dialog.exec()) {
const QString path = png_dialog.selectedFiles().first();
if (!path.isEmpty()) {
@@ -1767,6 +1788,19 @@ void GMainWindow::OnCaptureScreenshot() {
OnStartGame();
}
+void GMainWindow::UpdateWindowTitle(const QString& title_name) {
+ const QString full_name = QString::fromUtf8(Common::g_build_fullname);
+ const QString branch_name = QString::fromUtf8(Common::g_scm_branch);
+ const QString description = QString::fromUtf8(Common::g_scm_desc);
+
+ if (title_name.isEmpty()) {
+ setWindowTitle(QStringLiteral("yuzu %1| %2-%3").arg(full_name, branch_name, description));
+ } else {
+ setWindowTitle(QStringLiteral("yuzu %1| %4 | %2-%3")
+ .arg(full_name, branch_name, description, title_name));
+ }
+}
+
void GMainWindow::UpdateStatusBar() {
if (emu_thread == nullptr) {
status_bar_update_timer.stop();
@@ -1806,17 +1840,17 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
"data, or other bugs.");
switch (result) {
case Core::System::ResultStatus::ErrorSystemFiles: {
- QString message = "yuzu was unable to locate a Switch system archive";
+ QString message = tr("yuzu was unable to locate a Switch system archive");
if (!details.empty()) {
- message.append(tr(": %1. ").arg(details.c_str()));
+ message.append(tr(": %1. ").arg(QString::fromStdString(details)));
} else {
- message.append(". ");
+ message.append(tr(". "));
}
message.append(common_message);
answer = QMessageBox::question(this, tr("System Archive Not Found"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
- status_message = "System Archive Missing";
+ status_message = tr("System Archive Missing");
break;
}
@@ -1825,7 +1859,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
message.append(common_message);
answer = QMessageBox::question(this, tr("Shared Fonts Not Found"), message,
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
- status_message = "Shared Font Missing";
+ status_message = tr("Shared Font Missing");
break;
}
@@ -1841,7 +1875,7 @@ void GMainWindow::OnCoreError(Core::System::ResultStatus result, std::string det
"Continuing emulation may result in crashes, corrupted save data, or other "
"bugs."),
QMessageBox::Yes | QMessageBox::No, QMessageBox::No);
- status_message = "Fatal Error encountered";
+ status_message = tr("Fatal Error encountered");
break;
}
@@ -1892,18 +1926,19 @@ void GMainWindow::OnReinitializeKeys(ReinitializeKeyBehavior behavior) {
};
QString errors;
-
- if (!pdm.HasFuses())
+ if (!pdm.HasFuses()) {
errors += tr("- Missing fuses - Cannot derive SBK\n");
- if (!pdm.HasBoot0())
+ }
+ if (!pdm.HasBoot0()) {
errors += tr("- Missing BOOT0 - Cannot derive master keys\n");
- if (!pdm.HasPackage2())
+ }
+ if (!pdm.HasPackage2()) {
errors += tr("- Missing BCPKG2-1-Normal-Main - Cannot derive general keys\n");
- if (!pdm.HasProdInfo())
+ }
+ if (!pdm.HasProdInfo()) {
errors += tr("- Missing PRODINFO - Cannot derive title keys\n");
-
+ }
if (!errors.isEmpty()) {
-
QMessageBox::warning(
this, tr("Warning Missing Derivation Components"),
tr("The following are missing from your configuration that may hinder key "
@@ -1953,13 +1988,15 @@ std::optional<u64> GMainWindow::SelectRomFSDumpTarget(const FileSys::ContentProv
std::vector<u64> romfs_tids;
romfs_tids.push_back(program_id);
- for (const auto& entry : dlc_match)
+ for (const auto& entry : dlc_match) {
romfs_tids.push_back(entry.title_id);
+ }
if (romfs_tids.size() > 1) {
- QStringList list{"Base"};
- for (std::size_t i = 1; i < romfs_tids.size(); ++i)
+ QStringList list{QStringLiteral("Base")};
+ for (std::size_t i = 1; i < romfs_tids.size(); ++i) {
list.push_back(QStringLiteral("DLC %1").arg(romfs_tids[i] & 0x7FF));
+ }
bool ok;
const auto res = QInputDialog::getItem(
@@ -2071,26 +2108,32 @@ void GMainWindow::filterBarSetChecked(bool state) {
}
void GMainWindow::UpdateUITheme() {
+ const QString default_icons = QStringLiteral(":/icons/default");
+ const QString& current_theme = UISettings::values.theme;
+ const bool is_default_theme = current_theme == QString::fromUtf8(UISettings::themes[0].second);
QStringList theme_paths(default_theme_paths);
- if (UISettings::values.theme != UISettings::themes[0].second &&
- !UISettings::values.theme.isEmpty()) {
- const QString theme_uri(":" + UISettings::values.theme + "/style.qss");
+
+ if (is_default_theme || current_theme.isEmpty()) {
+ qApp->setStyleSheet({});
+ setStyleSheet({});
+ theme_paths.append(default_icons);
+ QIcon::setThemeName(default_icons);
+ } else {
+ const QString theme_uri(QLatin1Char{':'} + current_theme + QStringLiteral("/style.qss"));
QFile f(theme_uri);
if (f.open(QFile::ReadOnly | QFile::Text)) {
QTextStream ts(&f);
qApp->setStyleSheet(ts.readAll());
- GMainWindow::setStyleSheet(ts.readAll());
+ setStyleSheet(ts.readAll());
} else {
LOG_ERROR(Frontend, "Unable to set style, stylesheet file not found");
}
- theme_paths.append(QStringList{":/icons/default", ":/icons/" + UISettings::values.theme});
- QIcon::setThemeName(":/icons/" + UISettings::values.theme);
- } else {
- qApp->setStyleSheet("");
- GMainWindow::setStyleSheet("");
- theme_paths.append(QStringList{":/icons/default"});
- QIcon::setThemeName(":/icons/default");
+
+ const QString theme_name = QStringLiteral(":/icons/") + current_theme;
+ theme_paths.append({default_icons, theme_name});
+ QIcon::setThemeName(theme_name);
}
+
QIcon::setThemeSearchPaths(theme_paths);
emit UpdateThemedIcons();
}
@@ -2118,8 +2161,8 @@ int main(int argc, char* argv[]) {
SCOPE_EXIT({ MicroProfileShutdown(); });
// Init settings params
- QCoreApplication::setOrganizationName("yuzu team");
- QCoreApplication::setApplicationName("yuzu");
+ QCoreApplication::setOrganizationName(QStringLiteral("yuzu team"));
+ QCoreApplication::setApplicationName(QStringLiteral("yuzu"));
// Enables the core to make the qt created contexts current on std::threads
QCoreApplication::setAttribute(Qt::AA_DontCheckOpenGLContextThreadAffinity);
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index c4566ed2c..1137bbc7a 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -209,6 +209,7 @@ private slots:
private:
std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
+ void UpdateWindowTitle(const QString& title_name = {});
void UpdateStatusBar();
Ui::MainWindow ui;
diff --git a/src/yuzu/ui_settings.h b/src/yuzu/ui_settings.h
index dbd318e20..a62cd6911 100644
--- a/src/yuzu/ui_settings.h
+++ b/src/yuzu/ui_settings.h
@@ -79,6 +79,7 @@ struct Values {
uint8_t row_1_text_id;
uint8_t row_2_text_id;
std::atomic_bool is_game_list_reload_pending{false};
+ bool cache_game_list;
};
extern Values values;
diff --git a/src/yuzu/util/sequence_dialog/sequence_dialog.cpp b/src/yuzu/util/sequence_dialog/sequence_dialog.cpp
index d3edf6ec3..bb5f74ec4 100644
--- a/src/yuzu/util/sequence_dialog/sequence_dialog.cpp
+++ b/src/yuzu/util/sequence_dialog/sequence_dialog.cpp
@@ -9,16 +9,19 @@
SequenceDialog::SequenceDialog(QWidget* parent) : QDialog(parent) {
setWindowTitle(tr("Enter a hotkey"));
- auto* layout = new QVBoxLayout(this);
+ setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
+
key_sequence = new QKeySequenceEdit;
- layout->addWidget(key_sequence);
- auto* buttons =
- new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, Qt::Horizontal);
+
+ auto* const buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
buttons->setCenterButtons(true);
+
+ auto* const layout = new QVBoxLayout(this);
+ layout->addWidget(key_sequence);
layout->addWidget(buttons);
+
connect(buttons, &QDialogButtonBox::accepted, this, &QDialog::accept);
connect(buttons, &QDialogButtonBox::rejected, this, &QDialog::reject);
- setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
}
SequenceDialog::~SequenceDialog() = default;
diff --git a/src/yuzu/util/spinbox.cpp b/src/yuzu/util/spinbox.cpp
deleted file mode 100644
index 14ef1e884..000000000
--- a/src/yuzu/util/spinbox.cpp
+++ /dev/null
@@ -1,278 +0,0 @@
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-// Copyright 2014 Tony Wasserka
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// * Neither the name of the owner nor the names of its contributors may
-// be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <cstdlib>
-#include <QLineEdit>
-#include <QRegExpValidator>
-#include "common/assert.h"
-#include "yuzu/util/spinbox.h"
-
-CSpinBox::CSpinBox(QWidget* parent)
- : QAbstractSpinBox(parent), min_value(-100), max_value(100), value(0), base(10), num_digits(0) {
- // TODO: Might be nice to not immediately call the slot.
- // Think of an address that is being replaced by a different one, in which case a lot
- // invalid intermediate addresses would be read from during editing.
- connect(lineEdit(), &QLineEdit::textEdited, this, &CSpinBox::OnEditingFinished);
-
- UpdateText();
-}
-
-void CSpinBox::SetValue(qint64 val) {
- auto old_value = value;
- value = std::max(std::min(val, max_value), min_value);
-
- if (old_value != value) {
- UpdateText();
- emit ValueChanged(value);
- }
-}
-
-void CSpinBox::SetRange(qint64 min, qint64 max) {
- min_value = min;
- max_value = max;
-
- SetValue(value);
- UpdateText();
-}
-
-void CSpinBox::stepBy(int steps) {
- auto new_value = value;
- // Scale number of steps by the currently selected digit
- // TODO: Move this code elsewhere and enable it.
- // TODO: Support for num_digits==0, too
- // TODO: Support base!=16, too
- // TODO: Make the cursor not jump back to the end of the line...
- /*if (base == 16 && num_digits > 0) {
- int digit = num_digits - (lineEdit()->cursorPosition() - prefix.length()) - 1;
- digit = std::max(0, std::min(digit, num_digits - 1));
- steps <<= digit * 4;
- }*/
-
- // Increment "new_value" by "steps", and perform annoying overflow checks, too.
- if (steps < 0 && new_value + steps > new_value) {
- new_value = std::numeric_limits<qint64>::min();
- } else if (steps > 0 && new_value + steps < new_value) {
- new_value = std::numeric_limits<qint64>::max();
- } else {
- new_value += steps;
- }
-
- SetValue(new_value);
- UpdateText();
-}
-
-QAbstractSpinBox::StepEnabled CSpinBox::stepEnabled() const {
- StepEnabled ret = StepNone;
-
- if (value > min_value)
- ret |= StepDownEnabled;
-
- if (value < max_value)
- ret |= StepUpEnabled;
-
- return ret;
-}
-
-void CSpinBox::SetBase(int base) {
- this->base = base;
-
- UpdateText();
-}
-
-void CSpinBox::SetNumDigits(int num_digits) {
- this->num_digits = num_digits;
-
- UpdateText();
-}
-
-void CSpinBox::SetPrefix(const QString& prefix) {
- this->prefix = prefix;
-
- UpdateText();
-}
-
-void CSpinBox::SetSuffix(const QString& suffix) {
- this->suffix = suffix;
-
- UpdateText();
-}
-
-static QString StringToInputMask(const QString& input) {
- QString mask = input;
-
- // ... replace any special characters by their escaped counterparts ...
- mask.replace("\\", "\\\\");
- mask.replace("A", "\\A");
- mask.replace("a", "\\a");
- mask.replace("N", "\\N");
- mask.replace("n", "\\n");
- mask.replace("X", "\\X");
- mask.replace("x", "\\x");
- mask.replace("9", "\\9");
- mask.replace("0", "\\0");
- mask.replace("D", "\\D");
- mask.replace("d", "\\d");
- mask.replace("#", "\\#");
- mask.replace("H", "\\H");
- mask.replace("h", "\\h");
- mask.replace("B", "\\B");
- mask.replace("b", "\\b");
- mask.replace(">", "\\>");
- mask.replace("<", "\\<");
- mask.replace("!", "\\!");
-
- return mask;
-}
-
-void CSpinBox::UpdateText() {
- // If a fixed number of digits is used, we put the line edit in insertion mode by setting an
- // input mask.
- QString mask;
- if (num_digits != 0) {
- mask += StringToInputMask(prefix);
-
- // For base 10 and negative range, demand a single sign character
- if (HasSign())
- mask += "X"; // identified as "-" or "+" in the validator
-
- // Uppercase digits greater than 9.
- mask += ">";
-
- // Match num_digits digits
- // Digits irrelevant to the chosen number base are filtered in the validator
- mask += QString("H").repeated(std::max(num_digits, 1));
-
- // Switch off case conversion
- mask += "!";
-
- mask += StringToInputMask(suffix);
- }
- lineEdit()->setInputMask(mask);
-
- // Set new text without changing the cursor position. This will cause the cursor to briefly
- // appear at the end of the line and then to jump back to its original position. That's
- // a bit ugly, but better than having setText() move the cursor permanently all the time.
- int cursor_position = lineEdit()->cursorPosition();
- lineEdit()->setText(TextFromValue());
- lineEdit()->setCursorPosition(cursor_position);
-}
-
-QString CSpinBox::TextFromValue() {
- return prefix + QString(HasSign() ? ((value < 0) ? "-" : "+") : "") +
- QString("%1").arg(std::abs(value), num_digits, base, QLatin1Char('0')).toUpper() +
- suffix;
-}
-
-qint64 CSpinBox::ValueFromText() {
- unsigned strpos = prefix.length();
-
- QString num_string = text().mid(strpos, text().length() - strpos - suffix.length());
- return num_string.toLongLong(nullptr, base);
-}
-
-bool CSpinBox::HasSign() const {
- return base == 10 && min_value < 0;
-}
-
-void CSpinBox::OnEditingFinished() {
- // Only update for valid input
- QString input = lineEdit()->text();
- int pos = 0;
- if (QValidator::Acceptable == validate(input, pos))
- SetValue(ValueFromText());
-}
-
-QValidator::State CSpinBox::validate(QString& input, int& pos) const {
- if (!prefix.isEmpty() && input.left(prefix.length()) != prefix)
- return QValidator::Invalid;
-
- int strpos = prefix.length();
-
- // Empty "numbers" allowed as intermediate values
- if (strpos >= input.length() - HasSign() - suffix.length())
- return QValidator::Intermediate;
-
- DEBUG_ASSERT(base <= 10 || base == 16);
- QString regexp;
-
- // Demand sign character for negative ranges
- if (HasSign())
- regexp += "[+\\-]";
-
- // Match digits corresponding to the chosen number base.
- regexp += QString("[0-%1").arg(std::min(base, 9));
- if (base == 16) {
- regexp += "a-fA-F";
- }
- regexp += "]";
-
- // Specify number of digits
- if (num_digits > 0) {
- regexp += QString("{%1}").arg(num_digits);
- } else {
- regexp += "+";
- }
-
- // Match string
- QRegExp num_regexp(regexp);
- int num_pos = strpos;
- QString sub_input = input.mid(strpos, input.length() - strpos - suffix.length());
-
- if (!num_regexp.exactMatch(sub_input) && num_regexp.matchedLength() == 0)
- return QValidator::Invalid;
-
- sub_input = sub_input.left(num_regexp.matchedLength());
- bool ok;
- qint64 val = sub_input.toLongLong(&ok, base);
-
- if (!ok)
- return QValidator::Invalid;
-
- // Outside boundaries => don't accept
- if (val < min_value || val > max_value)
- return QValidator::Invalid;
-
- // Make sure we are actually at the end of this string...
- strpos += num_regexp.matchedLength();
-
- if (!suffix.isEmpty() && input.mid(strpos) != suffix) {
- return QValidator::Invalid;
- } else {
- strpos += suffix.length();
- }
-
- if (strpos != input.length())
- return QValidator::Invalid;
-
- // At this point we can say for sure that the input is fine. Let's fix it up a bit though
- input.replace(num_pos, sub_input.length(), sub_input.toUpper());
-
- return QValidator::Acceptable;
-}
diff --git a/src/yuzu/util/spinbox.h b/src/yuzu/util/spinbox.h
deleted file mode 100644
index 2fa1db3a4..000000000
--- a/src/yuzu/util/spinbox.h
+++ /dev/null
@@ -1,86 +0,0 @@
-// Licensed under GPLv2 or any later version
-// Refer to the license.txt file included.
-
-// Copyright 2014 Tony Wasserka
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-// * Neither the name of the owner nor the names of its contributors may
-// be used to endorse or promote products derived from this software
-// without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#pragma once
-
-#include <QAbstractSpinBox>
-#include <QtGlobal>
-
-class QVariant;
-
-/**
- * A custom spin box widget with enhanced functionality over Qt's QSpinBox
- */
-class CSpinBox : public QAbstractSpinBox {
- Q_OBJECT
-
-public:
- explicit CSpinBox(QWidget* parent = nullptr);
-
- void stepBy(int steps) override;
- StepEnabled stepEnabled() const override;
-
- void SetValue(qint64 val);
-
- void SetRange(qint64 min, qint64 max);
-
- void SetBase(int base);
-
- void SetPrefix(const QString& prefix);
- void SetSuffix(const QString& suffix);
-
- void SetNumDigits(int num_digits);
-
- QValidator::State validate(QString& input, int& pos) const override;
-
-signals:
- void ValueChanged(qint64 val);
-
-private slots:
- void OnEditingFinished();
-
-private:
- void UpdateText();
-
- bool HasSign() const;
-
- QString TextFromValue();
- qint64 ValueFromText();
-
- qint64 min_value, max_value;
-
- qint64 value;
-
- QString prefix, suffix;
-
- int base;
-
- int num_digits;
-};
diff --git a/src/yuzu/util/util.cpp b/src/yuzu/util/util.cpp
index 62c080aff..ef31bc2d2 100644
--- a/src/yuzu/util/util.cpp
+++ b/src/yuzu/util/util.cpp
@@ -8,7 +8,7 @@
#include "yuzu/util/util.h"
QFont GetMonospaceFont() {
- QFont font("monospace");
+ QFont font(QStringLiteral("monospace"));
// Automatic fallback to a monospace font on on platforms without a font called "monospace"
font.setStyleHint(QFont::Monospace);
font.setFixedPitch(true);
@@ -16,14 +16,16 @@ QFont GetMonospaceFont() {
}
QString ReadableByteSize(qulonglong size) {
- static const std::array<const char*, 6> units = {"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
- if (size == 0)
- return "0";
- int digit_groups = std::min<int>(static_cast<int>(std::log10(size) / std::log10(1024)),
- static_cast<int>(units.size()));
- return QString("%L1 %2")
+ static constexpr std::array units{"B", "KiB", "MiB", "GiB", "TiB", "PiB"};
+ if (size == 0) {
+ return QStringLiteral("0");
+ }
+
+ const int digit_groups = std::min(static_cast<int>(std::log10(size) / std::log10(1024)),
+ static_cast<int>(units.size()));
+ return QStringLiteral("%L1 %2")
.arg(size / std::pow(1024, digit_groups), 0, 'f', 1)
- .arg(units[digit_groups]);
+ .arg(QString::fromUtf8(units[digit_groups]));
}
QPixmap CreateCirclePixmapFromColor(const QColor& color) {