summaryrefslogtreecommitdiff
path: root/src/yuzu
diff options
context:
space:
mode:
Diffstat (limited to 'src/yuzu')
-rw-r--r--src/yuzu/CMakeLists.txt28
-rw-r--r--src/yuzu/applets/qt_controller.cpp (renamed from src/yuzu/applets/controller.cpp)4
-rw-r--r--src/yuzu/applets/qt_controller.h (renamed from src/yuzu/applets/controller.h)0
-rw-r--r--src/yuzu/applets/qt_controller.ui (renamed from src/yuzu/applets/controller.ui)0
-rw-r--r--src/yuzu/applets/qt_error.cpp (renamed from src/yuzu/applets/error.cpp)2
-rw-r--r--src/yuzu/applets/qt_error.h (renamed from src/yuzu/applets/error.h)0
-rw-r--r--src/yuzu/applets/qt_profile_select.cpp (renamed from src/yuzu/applets/profile_select.cpp)2
-rw-r--r--src/yuzu/applets/qt_profile_select.h (renamed from src/yuzu/applets/profile_select.h)0
-rw-r--r--src/yuzu/applets/qt_software_keyboard.cpp (renamed from src/yuzu/applets/software_keyboard.cpp)4
-rw-r--r--src/yuzu/applets/qt_software_keyboard.h (renamed from src/yuzu/applets/software_keyboard.h)0
-rw-r--r--src/yuzu/applets/qt_software_keyboard.ui (renamed from src/yuzu/applets/software_keyboard.ui)0
-rw-r--r--src/yuzu/applets/qt_web_browser.cpp (renamed from src/yuzu/applets/web_browser.cpp)19
-rw-r--r--src/yuzu/applets/qt_web_browser.h (renamed from src/yuzu/applets/web_browser.h)3
-rw-r--r--src/yuzu/applets/qt_web_browser_scripts.h (renamed from src/yuzu/applets/web_browser_scripts.h)6
-rw-r--r--src/yuzu/bootmanager.cpp28
-rw-r--r--src/yuzu/configuration/config.cpp723
-rw-r--r--src/yuzu/configuration/config.h79
-rw-r--r--src/yuzu/configuration/configuration_shared.cpp14
-rw-r--r--src/yuzu/configuration/configuration_shared.h15
-rw-r--r--src/yuzu/configuration/configure.ui50
-rw-r--r--src/yuzu/configuration/configure_audio.cpp21
-rw-r--r--src/yuzu/configuration/configure_cpu.cpp35
-rw-r--r--src/yuzu/configuration/configure_cpu.h1
-rw-r--r--src/yuzu/configuration/configure_cpu.ui14
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.cpp21
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.h1
-rw-r--r--src/yuzu/configuration/configure_cpu_debug.ui94
-rw-r--r--src/yuzu/configuration/configure_debug.cpp39
-rw-r--r--src/yuzu/configuration/configure_debug.ui108
-rw-r--r--src/yuzu/configuration/configure_debug_tab.cpp38
-rw-r--r--src/yuzu/configuration/configure_debug_tab.h32
-rw-r--r--src/yuzu/configuration/configure_debug_tab.ui52
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp6
-rw-r--r--src/yuzu/configuration/configure_filesystem.cpp13
-rw-r--r--src/yuzu/configuration/configure_general.cpp58
-rw-r--r--src/yuzu/configuration/configure_general.h2
-rw-r--r--src/yuzu/configuration/configure_general.ui34
-rw-r--r--src/yuzu/configuration/configure_graphics.cpp102
-rw-r--r--src/yuzu/configuration/configure_graphics.h4
-rw-r--r--src/yuzu/configuration/configure_graphics.ui118
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.cpp33
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.h2
-rw-r--r--src/yuzu/configuration/configure_graphics_advanced.ui38
-rw-r--r--src/yuzu/configuration/configure_input_advanced.cpp12
-rw-r--r--src/yuzu/configuration/configure_input_advanced.ui15
-rw-r--r--src/yuzu/configuration/configure_input_player.cpp47
-rw-r--r--src/yuzu/configuration/configure_input_player.ui44
-rw-r--r--src/yuzu/configuration/configure_motion_touch.cpp11
-rw-r--r--src/yuzu/configuration/configure_profile_manager.cpp11
-rw-r--r--src/yuzu/configuration/configure_service.cpp2
-rw-r--r--src/yuzu/configuration/configure_system.ui5
-rw-r--r--src/yuzu/configuration/configure_ui.cpp11
-rw-r--r--src/yuzu/configuration/configure_web.cpp12
-rw-r--r--src/yuzu/debugger/console.cpp4
-rw-r--r--src/yuzu/game_list.cpp25
-rw-r--r--src/yuzu/game_list.h9
-rw-r--r--src/yuzu/game_list_p.h15
-rw-r--r--src/yuzu/game_list_worker.cpp44
-rw-r--r--src/yuzu/main.cpp292
-rw-r--r--src/yuzu/main.h13
-rw-r--r--src/yuzu/uisettings.h43
61 files changed, 1431 insertions, 1027 deletions
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 634fe66a5..cb4bdcc7e 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -15,18 +15,19 @@ add_executable(yuzu
about_dialog.cpp
about_dialog.h
aboutdialog.ui
- applets/controller.cpp
- applets/controller.h
- applets/controller.ui
- applets/error.cpp
- applets/error.h
- applets/profile_select.cpp
- applets/profile_select.h
- applets/software_keyboard.cpp
- applets/software_keyboard.h
- applets/software_keyboard.ui
- applets/web_browser.cpp
- applets/web_browser.h
+ applets/qt_controller.cpp
+ applets/qt_controller.h
+ applets/qt_controller.ui
+ applets/qt_error.cpp
+ applets/qt_error.h
+ applets/qt_profile_select.cpp
+ applets/qt_profile_select.h
+ applets/qt_software_keyboard.cpp
+ applets/qt_software_keyboard.h
+ applets/qt_software_keyboard.ui
+ applets/qt_web_browser.cpp
+ applets/qt_web_browser.h
+ applets/qt_web_browser_scripts.h
bootmanager.cpp
bootmanager.h
compatdb.ui
@@ -52,6 +53,9 @@ add_executable(yuzu
configuration/configure_debug_controller.cpp
configuration/configure_debug_controller.h
configuration/configure_debug_controller.ui
+ configuration/configure_debug_tab.cpp
+ configuration/configure_debug_tab.h
+ configuration/configure_debug_tab.ui
configuration/configure_dialog.cpp
configuration/configure_dialog.h
configuration/configure_filesystem.cpp
diff --git a/src/yuzu/applets/controller.cpp b/src/yuzu/applets/qt_controller.cpp
index 836d90fda..97106d2cc 100644
--- a/src/yuzu/applets/controller.cpp
+++ b/src/yuzu/applets/qt_controller.cpp
@@ -12,8 +12,8 @@
#include "core/hle/service/hid/controllers/npad.h"
#include "core/hle/service/hid/hid.h"
#include "core/hle/service/sm/sm.h"
-#include "ui_controller.h"
-#include "yuzu/applets/controller.h"
+#include "ui_qt_controller.h"
+#include "yuzu/applets/qt_controller.h"
#include "yuzu/configuration/configure_input.h"
#include "yuzu/configuration/configure_input_profile_dialog.h"
#include "yuzu/configuration/configure_motion_touch.h"
diff --git a/src/yuzu/applets/controller.h b/src/yuzu/applets/qt_controller.h
index 9b57aea1a..9b57aea1a 100644
--- a/src/yuzu/applets/controller.h
+++ b/src/yuzu/applets/qt_controller.h
diff --git a/src/yuzu/applets/controller.ui b/src/yuzu/applets/qt_controller.ui
index c8cb6bcf3..c8cb6bcf3 100644
--- a/src/yuzu/applets/controller.ui
+++ b/src/yuzu/applets/qt_controller.ui
diff --git a/src/yuzu/applets/error.cpp b/src/yuzu/applets/qt_error.cpp
index 085688cd4..45cf64603 100644
--- a/src/yuzu/applets/error.cpp
+++ b/src/yuzu/applets/qt_error.cpp
@@ -4,7 +4,7 @@
#include <QDateTime>
#include "core/hle/lock.h"
-#include "yuzu/applets/error.h"
+#include "yuzu/applets/qt_error.h"
#include "yuzu/main.h"
QtErrorDisplay::QtErrorDisplay(GMainWindow& parent) {
diff --git a/src/yuzu/applets/error.h b/src/yuzu/applets/qt_error.h
index 8bd895a32..8bd895a32 100644
--- a/src/yuzu/applets/error.h
+++ b/src/yuzu/applets/qt_error.h
diff --git a/src/yuzu/applets/profile_select.cpp b/src/yuzu/applets/qt_profile_select.cpp
index 62fd1141c..a56638e21 100644
--- a/src/yuzu/applets/profile_select.cpp
+++ b/src/yuzu/applets/qt_profile_select.cpp
@@ -14,7 +14,7 @@
#include "common/string_util.h"
#include "core/constants.h"
#include "core/hle/lock.h"
-#include "yuzu/applets/profile_select.h"
+#include "yuzu/applets/qt_profile_select.h"
#include "yuzu/main.h"
namespace {
diff --git a/src/yuzu/applets/profile_select.h b/src/yuzu/applets/qt_profile_select.h
index 4e9037488..4e9037488 100644
--- a/src/yuzu/applets/profile_select.h
+++ b/src/yuzu/applets/qt_profile_select.h
diff --git a/src/yuzu/applets/software_keyboard.cpp b/src/yuzu/applets/qt_software_keyboard.cpp
index aa453a79f..848801cec 100644
--- a/src/yuzu/applets/software_keyboard.cpp
+++ b/src/yuzu/applets/qt_software_keyboard.cpp
@@ -11,8 +11,8 @@
#include "common/string_util.h"
#include "core/core.h"
#include "core/frontend/input_interpreter.h"
-#include "ui_software_keyboard.h"
-#include "yuzu/applets/software_keyboard.h"
+#include "ui_qt_software_keyboard.h"
+#include "yuzu/applets/qt_software_keyboard.h"
#include "yuzu/main.h"
#include "yuzu/util/overlay_dialog.h"
diff --git a/src/yuzu/applets/software_keyboard.h b/src/yuzu/applets/qt_software_keyboard.h
index 1a03c098c..1a03c098c 100644
--- a/src/yuzu/applets/software_keyboard.h
+++ b/src/yuzu/applets/qt_software_keyboard.h
diff --git a/src/yuzu/applets/software_keyboard.ui b/src/yuzu/applets/qt_software_keyboard.ui
index b0a1fcde9..b0a1fcde9 100644
--- a/src/yuzu/applets/software_keyboard.ui
+++ b/src/yuzu/applets/qt_software_keyboard.ui
diff --git a/src/yuzu/applets/web_browser.cpp b/src/yuzu/applets/qt_web_browser.cpp
index 34d3feb55..652d99570 100644
--- a/src/yuzu/applets/web_browser.cpp
+++ b/src/yuzu/applets/qt_web_browser.cpp
@@ -17,8 +17,8 @@
#include "core/frontend/input_interpreter.h"
#include "input_common/keyboard.h"
#include "input_common/main.h"
-#include "yuzu/applets/web_browser.h"
-#include "yuzu/applets/web_browser_scripts.h"
+#include "yuzu/applets/qt_web_browser.h"
+#include "yuzu/applets/qt_web_browser_scripts.h"
#include "yuzu/main.h"
#include "yuzu/util/url_request_interceptor.h"
@@ -107,6 +107,7 @@ void QtNXWebEngineView::LoadLocalWebPage(const std::string& main_url,
is_local = true;
LoadExtractedFonts();
+ FocusFirstLinkElement();
SetUserAgent(UserAgent::WebApplet);
SetFinished(false);
SetExitReason(Service::AM::Applets::WebExitReason::EndButtonPressed);
@@ -121,6 +122,7 @@ void QtNXWebEngineView::LoadExternalWebPage(const std::string& main_url,
const std::string& additional_args) {
is_local = false;
+ FocusFirstLinkElement();
SetUserAgent(UserAgent::WebApplet);
SetFinished(false);
SetExitReason(Service::AM::Applets::WebExitReason::EndButtonPressed);
@@ -208,7 +210,7 @@ void QtNXWebEngineView::HandleWindowFooterButtonPressedOnce() {
if (input_interpreter->IsButtonPressedOnce(button)) {
page()->runJavaScript(
QStringLiteral("yuzu_key_callbacks[%1] == null;").arg(static_cast<u8>(button)),
- [&](const QVariant& variant) {
+ [this, button](const QVariant& variant) {
if (variant.toBool()) {
switch (button) {
case HIDButton::A:
@@ -364,6 +366,17 @@ void QtNXWebEngineView::LoadExtractedFonts() {
Qt::QueuedConnection);
}
+void QtNXWebEngineView::FocusFirstLinkElement() {
+ QWebEngineScript focus_link_element;
+
+ focus_link_element.setName(QStringLiteral("focus_link_element.js"));
+ focus_link_element.setSourceCode(QString::fromStdString(FOCUS_LINK_ELEMENT_SCRIPT));
+ focus_link_element.setWorldId(QWebEngineScript::MainWorld);
+ focus_link_element.setInjectionPoint(QWebEngineScript::Deferred);
+ focus_link_element.setRunsOnSubFrames(true);
+ default_profile->scripts()->insert(focus_link_element);
+}
+
#endif
QtWebBrowser::QtWebBrowser(GMainWindow& main_window) {
diff --git a/src/yuzu/applets/web_browser.h b/src/yuzu/applets/qt_web_browser.h
index 7ad07409f..7e9f703fc 100644
--- a/src/yuzu/applets/web_browser.h
+++ b/src/yuzu/applets/qt_web_browser.h
@@ -161,6 +161,9 @@ private:
/// Loads the extracted fonts using JavaScript.
void LoadExtractedFonts();
+ /// Brings focus to the first available link element.
+ void FocusFirstLinkElement();
+
InputCommon::InputSubsystem* input_subsystem;
std::unique_ptr<UrlRequestInterceptor> url_interceptor;
diff --git a/src/yuzu/applets/web_browser_scripts.h b/src/yuzu/applets/qt_web_browser_scripts.h
index 992837a85..c4ba8d40f 100644
--- a/src/yuzu/applets/web_browser_scripts.h
+++ b/src/yuzu/applets/qt_web_browser_scripts.h
@@ -73,6 +73,12 @@ constexpr char LOAD_NX_FONT[] = R"(
})();
)";
+constexpr char FOCUS_LINK_ELEMENT_SCRIPT[] = R"(
+if (document.getElementsByTagName("a").length > 0) {
+ document.getElementsByTagName("a")[0].focus();
+}
+)";
+
constexpr char GAMEPAD_SCRIPT[] = R"(
window.addEventListener("gamepadconnected", function(e) {
console.log("Gamepad connected at index %d: %s. %d buttons, %d axes.",
diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp
index 7524e3c40..25b658b2a 100644
--- a/src/yuzu/bootmanager.cpp
+++ b/src/yuzu/bootmanager.cpp
@@ -64,12 +64,13 @@ void EmuThread::run() {
emit LoadProgress(VideoCore::LoadCallbackStage::Prepare, 0, 0);
- system.Renderer().ReadRasterizer()->LoadDiskResources(
- system.CurrentProcess()->GetTitleID(), stop_token,
- [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
- emit LoadProgress(stage, value, total);
- });
-
+ if (Settings::values.use_disk_shader_cache.GetValue()) {
+ system.Renderer().ReadRasterizer()->LoadDiskResources(
+ system.CurrentProcess()->GetTitleID(), stop_token,
+ [this](VideoCore::LoadCallbackStage stage, std::size_t value, std::size_t total) {
+ emit LoadProgress(stage, value, total);
+ });
+ }
emit LoadProgress(VideoCore::LoadCallbackStage::Complete, 0, 0);
gpu.ReleaseContext();
@@ -411,8 +412,9 @@ void GRenderWindow::mousePressEvent(QMouseEvent* event) {
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
-
- auto pos = event->pos();
+ // Qt sometimes returns the parent coordinates. To avoid this we read the global mouse
+ // coordinates and map them to the current render area
+ const auto pos = mapFromGlobal(QCursor::pos());
const auto [x, y] = ScaleTouch(pos);
const auto button = QtButtonToMouseButton(event->button());
input_subsystem->GetMouse()->PressButton(x, y, button);
@@ -429,7 +431,9 @@ void GRenderWindow::mouseMoveEvent(QMouseEvent* event) {
if (event->source() == Qt::MouseEventSynthesizedBySystem) {
return;
}
- auto pos = event->pos();
+ // Qt sometimes returns the parent coordinates. To avoid this we read the global mouse
+ // coordinates and map them to the current render area
+ const auto pos = mapFromGlobal(QCursor::pos());
const auto [x, y] = ScaleTouch(pos);
const int center_x = width() / 2;
const int center_y = height() / 2;
@@ -564,6 +568,12 @@ std::unique_ptr<Core::Frontend::GraphicsContext> GRenderWindow::CreateSharedCont
bool GRenderWindow::InitRenderTarget() {
ReleaseRenderTarget();
+ {
+ // Create a dummy render widget so that Qt
+ // places the render window at the correct position.
+ const RenderWidget dummy_widget{this};
+ }
+
first_frame = false;
switch (Settings::values.renderer_backend.GetValue()) {
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp
index 62bafc453..f3b8787f5 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -272,6 +272,66 @@ void Config::Initialize(const std::string& config_name) {
}
}
+/* {Read,Write}BasicSetting and WriteGlobalSetting templates must be defined here before their
+ * usages later in this file. This allows explicit definition of some types that don't work
+ * nicely with the general version.
+ */
+
+// Explicit std::string definition: Qt can't implicitly convert a std::string to a QVariant, nor
+// can it implicitly convert a QVariant back to a {std::,Q}string
+template <>
+void Config::ReadBasicSetting(Settings::BasicSetting<std::string>& setting) {
+ const QString name = QString::fromStdString(setting.GetLabel());
+ const auto default_value = QString::fromStdString(setting.GetDefault());
+ if (qt_config->value(name + QStringLiteral("/default"), false).toBool()) {
+ setting.SetValue(default_value.toStdString());
+ } else {
+ setting.SetValue(qt_config->value(name, default_value).toString().toStdString());
+ }
+}
+
+template <typename Type>
+void Config::ReadBasicSetting(Settings::BasicSetting<Type>& setting) {
+ const QString name = QString::fromStdString(setting.GetLabel());
+ const Type default_value = setting.GetDefault();
+ if (qt_config->value(name + QStringLiteral("/default"), false).toBool()) {
+ setting.SetValue(default_value);
+ } else {
+ setting.SetValue(
+ static_cast<QVariant>(qt_config->value(name, default_value)).value<Type>());
+ }
+}
+
+// Explicit std::string definition: Qt can't implicitly convert a std::string to a QVariant
+template <>
+void Config::WriteBasicSetting(const Settings::BasicSetting<std::string>& setting) {
+ const QString name = QString::fromStdString(setting.GetLabel());
+ const std::string& value = setting.GetValue();
+ qt_config->setValue(name + QStringLiteral("/default"), value == setting.GetDefault());
+ qt_config->setValue(name, QString::fromStdString(value));
+}
+
+template <typename Type>
+void Config::WriteBasicSetting(const Settings::BasicSetting<Type>& setting) {
+ const QString name = QString::fromStdString(setting.GetLabel());
+ const Type value = setting.GetValue();
+ qt_config->setValue(name + QStringLiteral("/default"), value == setting.GetDefault());
+ qt_config->setValue(name, value);
+}
+
+template <typename Type>
+void Config::WriteGlobalSetting(const Settings::Setting<Type>& setting) {
+ const QString name = QString::fromStdString(setting.GetLabel());
+ const Type& value = setting.GetValue(global);
+ if (!global) {
+ qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal());
+ }
+ if (global || !setting.UsingGlobal()) {
+ qt_config->setValue(name + QStringLiteral("/default"), value == setting.GetDefault());
+ qt_config->setValue(name, value);
+ }
+}
+
void Config::ReadPlayerValue(std::size_t player_index) {
const QString player_prefix = [this, player_index] {
if (type == ConfigType::InputProfile) {
@@ -395,8 +455,7 @@ void Config::ReadPlayerValue(std::size_t player_index) {
}
void Config::ReadDebugValues() {
- Settings::values.debug_pad_enabled =
- ReadSetting(QStringLiteral("debug_pad_enabled"), false).toBool();
+ ReadBasicSetting(Settings::values.debug_pad_enabled);
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
@@ -432,8 +491,7 @@ void Config::ReadDebugValues() {
}
void Config::ReadKeyboardValues() {
- Settings::values.keyboard_enabled =
- ReadSetting(QStringLiteral("keyboard_enabled"), false).toBool();
+ ReadBasicSetting(Settings::values.keyboard_enabled);
std::transform(default_keyboard_keys.begin(), default_keyboard_keys.end(),
Settings::values.keyboard_keys.begin(), InputCommon::GenerateKeyboardParam);
@@ -446,7 +504,7 @@ void Config::ReadKeyboardValues() {
}
void Config::ReadMouseValues() {
- Settings::values.mouse_enabled = ReadSetting(QStringLiteral("mouse_enabled"), false).toBool();
+ ReadBasicSetting(Settings::values.mouse_enabled);
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
const std::string default_param =
@@ -481,18 +539,11 @@ void Config::ReadAudioValues() {
qt_config->beginGroup(QStringLiteral("Audio"));
if (global) {
- Settings::values.sink_id =
- ReadSetting(QStringLiteral("output_engine"), QStringLiteral("auto"))
- .toString()
- .toStdString();
- Settings::values.audio_device_id =
- ReadSetting(QStringLiteral("output_device"), QStringLiteral("auto"))
- .toString()
- .toStdString();
+ ReadBasicSetting(Settings::values.audio_device_id);
+ ReadBasicSetting(Settings::values.sink_id);
}
- ReadSettingGlobal(Settings::values.enable_audio_stretching,
- QStringLiteral("enable_audio_stretching"), true);
- ReadSettingGlobal(Settings::values.volume, QStringLiteral("volume"), 1);
+ ReadGlobalSetting(Settings::values.enable_audio_stretching);
+ ReadGlobalSetting(Settings::values.volume);
qt_config->endGroup();
}
@@ -509,13 +560,11 @@ void Config::ReadControlValues() {
ReadTouchscreenValues();
ReadMotionTouchValues();
- Settings::values.emulate_analog_keyboard =
- ReadSetting(QStringLiteral("emulate_analog_keyboard"), false).toBool();
+ ReadBasicSetting(Settings::values.emulate_analog_keyboard);
Settings::values.mouse_panning = false;
- Settings::values.mouse_panning_sensitivity =
- ReadSetting(QStringLiteral("mouse_panning_sensitivity"), 1).toFloat();
+ ReadBasicSetting(Settings::values.mouse_panning_sensitivity);
- ReadSettingGlobal(Settings::values.use_docked_mode, QStringLiteral("use_docked_mode"), true);
+ ReadGlobalSetting(Settings::values.use_docked_mode);
// Disable docked mode if handheld is selected
const auto controller_type = Settings::values.players.GetValue()[0].controller_type;
@@ -523,11 +572,9 @@ void Config::ReadControlValues() {
Settings::values.use_docked_mode.SetValue(false);
}
- ReadSettingGlobal(Settings::values.vibration_enabled, QStringLiteral("vibration_enabled"),
- true);
- ReadSettingGlobal(Settings::values.enable_accurate_vibrations,
- QStringLiteral("enable_accurate_vibrations"), false);
- ReadSettingGlobal(Settings::values.motion_enabled, QStringLiteral("motion_enabled"), true);
+ ReadGlobalSetting(Settings::values.vibration_enabled);
+ ReadGlobalSetting(Settings::values.enable_accurate_vibrations);
+ ReadGlobalSetting(Settings::values.motion_enabled);
qt_config->endGroup();
}
@@ -565,33 +612,19 @@ void Config::ReadMotionTouchValues() {
}
qt_config->endArray();
- Settings::values.motion_device =
- ReadSetting(QStringLiteral("motion_device"),
- QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01"))
- .toString()
- .toStdString();
- Settings::values.touch_device =
- ReadSetting(QStringLiteral("touch_device"),
- QStringLiteral("min_x:100,min_y:50,max_x:1800,max_y:850"))
- .toString()
- .toStdString();
- Settings::values.use_touch_from_button =
- ReadSetting(QStringLiteral("use_touch_from_button"), false).toBool();
- Settings::values.touch_from_button_map_index =
- ReadSetting(QStringLiteral("touch_from_button_map"), 0).toInt();
- Settings::values.touch_from_button_map_index =
- std::clamp(Settings::values.touch_from_button_map_index, 0, num_touch_from_button_maps - 1);
- Settings::values.udp_input_servers =
- ReadSetting(QStringLiteral("udp_input_servers"),
- QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV))
- .toString()
- .toStdString();
+ ReadBasicSetting(Settings::values.motion_device);
+ ReadBasicSetting(Settings::values.touch_device);
+ ReadBasicSetting(Settings::values.use_touch_from_button);
+ ReadBasicSetting(Settings::values.touch_from_button_map_index);
+ Settings::values.touch_from_button_map_index = std::clamp(
+ Settings::values.touch_from_button_map_index.GetValue(), 0, num_touch_from_button_maps - 1);
+ ReadBasicSetting(Settings::values.udp_input_servers);
}
void Config::ReadCoreValues() {
qt_config->beginGroup(QStringLiteral("Core"));
- ReadSettingGlobal(Settings::values.use_multi_core, QStringLiteral("use_multi_core"), true);
+ ReadGlobalSetting(Settings::values.use_multi_core);
qt_config->endGroup();
}
@@ -599,7 +632,7 @@ void Config::ReadCoreValues() {
void Config::ReadDataStorageValues() {
qt_config->beginGroup(QStringLiteral("Data Storage"));
- Settings::values.use_virtual_sd = ReadSetting(QStringLiteral("use_virtual_sd"), true).toBool();
+ ReadBasicSetting(Settings::values.use_virtual_sd);
FS::SetYuzuPath(
FS::YuzuPath::NANDDir,
qt_config
@@ -628,12 +661,9 @@ void Config::ReadDataStorageValues() {
QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)))
.toString()
.toStdString());
- Settings::values.gamecard_inserted =
- ReadSetting(QStringLiteral("gamecard_inserted"), false).toBool();
- Settings::values.gamecard_current_game =
- ReadSetting(QStringLiteral("gamecard_current_game"), false).toBool();
- Settings::values.gamecard_path =
- ReadSetting(QStringLiteral("gamecard_path"), QString{}).toString().toStdString();
+ ReadBasicSetting(Settings::values.gamecard_inserted);
+ ReadBasicSetting(Settings::values.gamecard_current_game);
+ ReadBasicSetting(Settings::values.gamecard_path);
qt_config->endGroup();
}
@@ -644,34 +674,24 @@ void Config::ReadDebuggingValues() {
// Intentionally not using the QT default setting as this is intended to be changed in the ini
Settings::values.record_frame_times =
qt_config->value(QStringLiteral("record_frame_times"), false).toBool();
- Settings::values.program_args =
- ReadSetting(QStringLiteral("program_args"), QString{}).toString().toStdString();
- Settings::values.dump_exefs = ReadSetting(QStringLiteral("dump_exefs"), false).toBool();
- Settings::values.dump_nso = ReadSetting(QStringLiteral("dump_nso"), false).toBool();
- Settings::values.enable_fs_access_log =
- ReadSetting(QStringLiteral("enable_fs_access_log"), false).toBool();
- Settings::values.reporting_services =
- ReadSetting(QStringLiteral("reporting_services"), false).toBool();
- Settings::values.quest_flag = ReadSetting(QStringLiteral("quest_flag"), false).toBool();
- Settings::values.disable_macro_jit =
- ReadSetting(QStringLiteral("disable_macro_jit"), false).toBool();
- Settings::values.extended_logging =
- ReadSetting(QStringLiteral("extended_logging"), false).toBool();
- Settings::values.use_debug_asserts =
- ReadSetting(QStringLiteral("use_debug_asserts"), false).toBool();
- Settings::values.use_auto_stub = ReadSetting(QStringLiteral("use_auto_stub"), false).toBool();
+ ReadBasicSetting(Settings::values.program_args);
+ ReadBasicSetting(Settings::values.dump_exefs);
+ ReadBasicSetting(Settings::values.dump_nso);
+ ReadBasicSetting(Settings::values.enable_fs_access_log);
+ ReadBasicSetting(Settings::values.reporting_services);
+ ReadBasicSetting(Settings::values.quest_flag);
+ ReadBasicSetting(Settings::values.disable_macro_jit);
+ ReadBasicSetting(Settings::values.extended_logging);
+ ReadBasicSetting(Settings::values.use_debug_asserts);
+ ReadBasicSetting(Settings::values.use_auto_stub);
qt_config->endGroup();
}
void Config::ReadServiceValues() {
qt_config->beginGroup(QStringLiteral("Services"));
- Settings::values.bcat_backend =
- ReadSetting(QStringLiteral("bcat_backend"), QStringLiteral("none"))
- .toString()
- .toStdString();
- Settings::values.bcat_boxcat_local =
- ReadSetting(QStringLiteral("bcat_boxcat_local"), false).toBool();
+ ReadBasicSetting(Settings::values.bcat_backend);
+ ReadBasicSetting(Settings::values.bcat_boxcat_local);
qt_config->endGroup();
}
@@ -697,11 +717,8 @@ void Config::ReadDisabledAddOnValues() {
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();
+ ReadBasicSetting(Settings::values.log_filter);
+ ReadBasicSetting(Settings::values.use_dev_keys);
qt_config->endGroup();
}
@@ -751,38 +768,31 @@ void Config::ReadPathValues() {
void Config::ReadCpuValues() {
qt_config->beginGroup(QStringLiteral("Cpu"));
- ReadSettingGlobal(Settings::values.cpu_accuracy, QStringLiteral("cpu_accuracy"), 0);
+ ReadBasicSetting(Settings::values.cpu_accuracy_first_time);
+ if (Settings::values.cpu_accuracy_first_time) {
+ Settings::values.cpu_accuracy.SetValue(Settings::values.cpu_accuracy.GetDefault());
+ Settings::values.cpu_accuracy_first_time.SetValue(false);
+ } else {
+ ReadGlobalSetting(Settings::values.cpu_accuracy);
+ }
- ReadSettingGlobal(Settings::values.cpuopt_unsafe_unfuse_fma,
- QStringLiteral("cpuopt_unsafe_unfuse_fma"), true);
- ReadSettingGlobal(Settings::values.cpuopt_unsafe_reduce_fp_error,
- QStringLiteral("cpuopt_unsafe_reduce_fp_error"), true);
- ReadSettingGlobal(Settings::values.cpuopt_unsafe_ignore_standard_fpcr,
- QStringLiteral("cpuopt_unsafe_ignore_standard_fpcr"), true);
- ReadSettingGlobal(Settings::values.cpuopt_unsafe_inaccurate_nan,
- QStringLiteral("cpuopt_unsafe_inaccurate_nan"), true);
- ReadSettingGlobal(Settings::values.cpuopt_unsafe_fastmem_check,
- QStringLiteral("cpuopt_unsafe_fastmem_check"), true);
+ ReadGlobalSetting(Settings::values.cpuopt_unsafe_unfuse_fma);
+ ReadGlobalSetting(Settings::values.cpuopt_unsafe_reduce_fp_error);
+ ReadGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
+ ReadGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan);
+ ReadGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
if (global) {
- Settings::values.cpuopt_page_tables =
- ReadSetting(QStringLiteral("cpuopt_page_tables"), true).toBool();
- Settings::values.cpuopt_block_linking =
- ReadSetting(QStringLiteral("cpuopt_block_linking"), true).toBool();
- Settings::values.cpuopt_return_stack_buffer =
- ReadSetting(QStringLiteral("cpuopt_return_stack_buffer"), true).toBool();
- Settings::values.cpuopt_fast_dispatcher =
- ReadSetting(QStringLiteral("cpuopt_fast_dispatcher"), true).toBool();
- Settings::values.cpuopt_context_elimination =
- ReadSetting(QStringLiteral("cpuopt_context_elimination"), true).toBool();
- Settings::values.cpuopt_const_prop =
- ReadSetting(QStringLiteral("cpuopt_const_prop"), true).toBool();
- Settings::values.cpuopt_misc_ir =
- ReadSetting(QStringLiteral("cpuopt_misc_ir"), true).toBool();
- Settings::values.cpuopt_reduce_misalign_checks =
- ReadSetting(QStringLiteral("cpuopt_reduce_misalign_checks"), true).toBool();
- Settings::values.cpuopt_fastmem =
- ReadSetting(QStringLiteral("cpuopt_fastmem"), true).toBool();
+ ReadBasicSetting(Settings::values.cpu_debug_mode);
+ ReadBasicSetting(Settings::values.cpuopt_page_tables);
+ ReadBasicSetting(Settings::values.cpuopt_block_linking);
+ ReadBasicSetting(Settings::values.cpuopt_return_stack_buffer);
+ ReadBasicSetting(Settings::values.cpuopt_fast_dispatcher);
+ ReadBasicSetting(Settings::values.cpuopt_context_elimination);
+ ReadBasicSetting(Settings::values.cpuopt_const_prop);
+ ReadBasicSetting(Settings::values.cpuopt_misc_ir);
+ ReadBasicSetting(Settings::values.cpuopt_reduce_misalign_checks);
+ ReadBasicSetting(Settings::values.cpuopt_fastmem);
}
qt_config->endGroup();
@@ -791,41 +801,34 @@ void Config::ReadCpuValues() {
void Config::ReadRendererValues() {
qt_config->beginGroup(QStringLiteral("Renderer"));
- ReadSettingGlobal(Settings::values.renderer_backend, QStringLiteral("backend"), 0);
- ReadSettingGlobal(Settings::values.renderer_debug, QStringLiteral("debug"), false);
- ReadSettingGlobal(Settings::values.vulkan_device, QStringLiteral("vulkan_device"), 0);
-#ifdef _WIN32
- ReadSettingGlobal(Settings::values.fullscreen_mode, QStringLiteral("fullscreen_mode"), 0);
-#else
- // *nix platforms may have issues with the borderless windowed fullscreen mode.
- // Default to exclusive fullscreen on these platforms for now.
- ReadSettingGlobal(Settings::values.fullscreen_mode, QStringLiteral("fullscreen_mode"), 1);
-#endif
- ReadSettingGlobal(Settings::values.aspect_ratio, QStringLiteral("aspect_ratio"), 0);
- ReadSettingGlobal(Settings::values.max_anisotropy, QStringLiteral("max_anisotropy"), 0);
- ReadSettingGlobal(Settings::values.use_frame_limit, QStringLiteral("use_frame_limit"), true);
- ReadSettingGlobal(Settings::values.frame_limit, QStringLiteral("frame_limit"), 100);
- ReadSettingGlobal(Settings::values.use_disk_shader_cache,
- QStringLiteral("use_disk_shader_cache"), true);
- ReadSettingGlobal(Settings::values.gpu_accuracy, QStringLiteral("gpu_accuracy"), 1);
- ReadSettingGlobal(Settings::values.use_asynchronous_gpu_emulation,
- QStringLiteral("use_asynchronous_gpu_emulation"), true);
- ReadSettingGlobal(Settings::values.use_nvdec_emulation, QStringLiteral("use_nvdec_emulation"),
- true);
- ReadSettingGlobal(Settings::values.accelerate_astc, QStringLiteral("accelerate_astc"), true);
- ReadSettingGlobal(Settings::values.use_vsync, QStringLiteral("use_vsync"), true);
- ReadSettingGlobal(Settings::values.disable_fps_limit, QStringLiteral("disable_fps_limit"),
- false);
- ReadSettingGlobal(Settings::values.use_assembly_shaders, QStringLiteral("use_assembly_shaders"),
- false);
- ReadSettingGlobal(Settings::values.use_asynchronous_shaders,
- QStringLiteral("use_asynchronous_shaders"), false);
- ReadSettingGlobal(Settings::values.use_fast_gpu_time, QStringLiteral("use_fast_gpu_time"),
- true);
- ReadSettingGlobal(Settings::values.use_caches_gc, QStringLiteral("use_caches_gc"), false);
- ReadSettingGlobal(Settings::values.bg_red, QStringLiteral("bg_red"), 0.0);
- ReadSettingGlobal(Settings::values.bg_green, QStringLiteral("bg_green"), 0.0);
- ReadSettingGlobal(Settings::values.bg_blue, QStringLiteral("bg_blue"), 0.0);
+ ReadGlobalSetting(Settings::values.renderer_backend);
+ ReadGlobalSetting(Settings::values.vulkan_device);
+ ReadGlobalSetting(Settings::values.fullscreen_mode);
+ ReadGlobalSetting(Settings::values.aspect_ratio);
+ ReadGlobalSetting(Settings::values.max_anisotropy);
+ ReadGlobalSetting(Settings::values.use_speed_limit);
+ ReadGlobalSetting(Settings::values.speed_limit);
+ ReadGlobalSetting(Settings::values.use_disk_shader_cache);
+ ReadGlobalSetting(Settings::values.gpu_accuracy);
+ ReadGlobalSetting(Settings::values.use_asynchronous_gpu_emulation);
+ ReadGlobalSetting(Settings::values.use_nvdec_emulation);
+ ReadGlobalSetting(Settings::values.accelerate_astc);
+ ReadGlobalSetting(Settings::values.use_vsync);
+ ReadGlobalSetting(Settings::values.shader_backend);
+ ReadGlobalSetting(Settings::values.use_asynchronous_shaders);
+ ReadGlobalSetting(Settings::values.use_fast_gpu_time);
+ ReadGlobalSetting(Settings::values.use_caches_gc);
+ ReadGlobalSetting(Settings::values.bg_red);
+ ReadGlobalSetting(Settings::values.bg_green);
+ ReadGlobalSetting(Settings::values.bg_blue);
+
+ if (global) {
+ ReadBasicSetting(Settings::values.fps_cap);
+ ReadBasicSetting(Settings::values.renderer_debug);
+ ReadBasicSetting(Settings::values.renderer_shader_feedback);
+ ReadBasicSetting(Settings::values.enable_nsight_aftermath);
+ ReadBasicSetting(Settings::values.disable_shader_loop_safety_checks);
+ }
qt_config->endGroup();
}
@@ -870,15 +873,15 @@ void Config::ReadShortcutValues() {
void Config::ReadSystemValues() {
qt_config->beginGroup(QStringLiteral("System"));
- ReadSettingGlobal(Settings::values.current_user, QStringLiteral("current_user"), 0);
- Settings::values.current_user =
- std::clamp<int>(Settings::values.current_user, 0, Service::Account::MAX_USERS - 1);
+ ReadBasicSetting(Settings::values.current_user);
+ Settings::values.current_user = std::clamp<int>(Settings::values.current_user.GetValue(), 0,
+ Service::Account::MAX_USERS - 1);
- ReadSettingGlobal(Settings::values.language_index, QStringLiteral("language_index"), 1);
+ ReadGlobalSetting(Settings::values.language_index);
- ReadSettingGlobal(Settings::values.region_index, QStringLiteral("region_index"), 1);
+ ReadGlobalSetting(Settings::values.region_index);
- ReadSettingGlobal(Settings::values.time_zone_index, QStringLiteral("time_zone_index"), 0);
+ ReadGlobalSetting(Settings::values.time_zone_index);
bool rng_seed_enabled;
ReadSettingGlobal(rng_seed_enabled, QStringLiteral("rng_seed_enabled"), false);
@@ -904,7 +907,7 @@ void Config::ReadSystemValues() {
}
}
- ReadSettingGlobal(Settings::values.sound_index, QStringLiteral("sound_index"), 1);
+ ReadGlobalSetting(Settings::values.sound_index);
qt_config->endGroup();
}
@@ -915,10 +918,8 @@ void Config::ReadUIValues() {
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.select_user_on_boot =
- ReadSetting(QStringLiteral("select_user_on_boot"), false).toBool();
+ ReadBasicSetting(UISettings::values.enable_discord_presence);
+ ReadBasicSetting(UISettings::values.select_user_on_boot);
ReadUIGamelistValues();
ReadUILayoutValues();
@@ -926,24 +927,17 @@ void Config::ReadUIValues() {
ReadScreenshotValues();
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.pause_when_in_background =
- ReadSetting(QStringLiteral("pauseWhenInBackground"), false).toBool();
- UISettings::values.hide_mouse =
- ReadSetting(QStringLiteral("hideInactiveMouse"), false).toBool();
+ ReadBasicSetting(UISettings::values.single_window_mode);
+ ReadBasicSetting(UISettings::values.fullscreen);
+ ReadBasicSetting(UISettings::values.display_titlebar);
+ ReadBasicSetting(UISettings::values.show_filter_bar);
+ ReadBasicSetting(UISettings::values.show_status_bar);
+ ReadBasicSetting(UISettings::values.confirm_before_closing);
+ ReadBasicSetting(UISettings::values.first_start);
+ ReadBasicSetting(UISettings::values.callout_flags);
+ ReadBasicSetting(UISettings::values.show_console);
+ ReadBasicSetting(UISettings::values.pause_when_in_background);
+ ReadBasicSetting(UISettings::values.hide_mouse);
qt_config->endGroup();
}
@@ -951,12 +945,11 @@ void Config::ReadUIValues() {
void Config::ReadUIGamelistValues() {
qt_config->beginGroup(QStringLiteral("UIGameList"));
- 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();
+ ReadBasicSetting(UISettings::values.show_add_ons);
+ ReadBasicSetting(UISettings::values.icon_size);
+ ReadBasicSetting(UISettings::values.row_1_text_id);
+ ReadBasicSetting(UISettings::values.row_2_text_id);
+ ReadBasicSetting(UISettings::values.cache_game_list);
const int favorites_size = qt_config->beginReadArray(QStringLiteral("favorites"));
for (int i = 0; i < favorites_size; i++) {
qt_config->setArrayIndex(i);
@@ -979,8 +972,7 @@ void Config::ReadUILayoutValues() {
ReadSetting(QStringLiteral("gameListHeaderState")).toByteArray();
UISettings::values.microprofile_geometry =
ReadSetting(QStringLiteral("microProfileDialogGeometry")).toByteArray();
- UISettings::values.microprofile_visible =
- ReadSetting(QStringLiteral("microProfileDialogVisible"), false).toBool();
+ ReadBasicSetting(UISettings::values.microprofile_visible);
qt_config->endGroup();
}
@@ -988,16 +980,10 @@ void Config::ReadUILayoutValues() {
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();
+ ReadBasicSetting(Settings::values.enable_telemetry);
+ ReadBasicSetting(Settings::values.web_api_url);
+ ReadBasicSetting(Settings::values.yuzu_username);
+ ReadBasicSetting(Settings::values.yuzu_token);
qt_config->endGroup();
}
@@ -1083,7 +1069,7 @@ void Config::SavePlayerValue(std::size_t player_index) {
}
void Config::SaveDebugValues() {
- WriteSetting(QStringLiteral("debug_pad_enabled"), Settings::values.debug_pad_enabled, false);
+ WriteBasicSetting(Settings::values.debug_pad_enabled);
for (int i = 0; i < Settings::NativeButton::NumButtons; ++i) {
const std::string default_param = InputCommon::GenerateKeyboardParam(default_buttons[i]);
WriteSetting(QStringLiteral("debug_pad_") +
@@ -1103,7 +1089,7 @@ void Config::SaveDebugValues() {
}
void Config::SaveMouseValues() {
- WriteSetting(QStringLiteral("mouse_enabled"), Settings::values.mouse_enabled, false);
+ WriteBasicSetting(Settings::values.mouse_enabled);
for (int i = 0; i < Settings::NativeMouseButton::NumMouseButtons; ++i) {
const std::string default_param =
@@ -1126,19 +1112,11 @@ void Config::SaveTouchscreenValues() {
}
void Config::SaveMotionTouchValues() {
- WriteSetting(QStringLiteral("motion_device"),
- QString::fromStdString(Settings::values.motion_device),
- QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01"));
- WriteSetting(QStringLiteral("touch_device"),
- QString::fromStdString(Settings::values.touch_device),
- QStringLiteral("engine:emu_window"));
- WriteSetting(QStringLiteral("use_touch_from_button"), Settings::values.use_touch_from_button,
- false);
- WriteSetting(QStringLiteral("touch_from_button_map"),
- Settings::values.touch_from_button_map_index, 0);
- WriteSetting(QStringLiteral("udp_input_servers"),
- QString::fromStdString(Settings::values.udp_input_servers),
- QString::fromUtf8(InputCommon::CemuhookUDP::DEFAULT_SRV));
+ WriteBasicSetting(Settings::values.motion_device);
+ WriteBasicSetting(Settings::values.touch_device);
+ WriteBasicSetting(Settings::values.use_touch_from_button);
+ WriteBasicSetting(Settings::values.touch_from_button_map_index);
+ WriteBasicSetting(Settings::values.udp_input_servers);
qt_config->beginWriteArray(QStringLiteral("touch_from_button_maps"));
for (std::size_t p = 0; p < Settings::values.touch_from_button_maps.size(); ++p) {
@@ -1181,15 +1159,11 @@ void Config::SaveAudioValues() {
qt_config->beginGroup(QStringLiteral("Audio"));
if (global) {
- WriteSetting(QStringLiteral("output_engine"),
- QString::fromStdString(Settings::values.sink_id), QStringLiteral("auto"));
- WriteSetting(QStringLiteral("output_device"),
- QString::fromStdString(Settings::values.audio_device_id),
- QStringLiteral("auto"));
+ WriteBasicSetting(Settings::values.sink_id);
+ WriteBasicSetting(Settings::values.audio_device_id);
}
- WriteSettingGlobal(QStringLiteral("enable_audio_stretching"),
- Settings::values.enable_audio_stretching, true);
- WriteSettingGlobal(QStringLiteral("volume"), Settings::values.volume, 1.0f);
+ WriteGlobalSetting(Settings::values.enable_audio_stretching);
+ WriteGlobalSetting(Settings::values.volume);
qt_config->endGroup();
}
@@ -1205,30 +1179,21 @@ void Config::SaveControlValues() {
SaveTouchscreenValues();
SaveMotionTouchValues();
- WriteSettingGlobal(QStringLiteral("use_docked_mode"), Settings::values.use_docked_mode, true);
- WriteSettingGlobal(QStringLiteral("vibration_enabled"), Settings::values.vibration_enabled,
- true);
- WriteSettingGlobal(QStringLiteral("enable_accurate_vibrations"),
- Settings::values.enable_accurate_vibrations, false);
- WriteSettingGlobal(QStringLiteral("motion_enabled"), Settings::values.motion_enabled, true);
- WriteSetting(QStringLiteral("motion_device"),
- QString::fromStdString(Settings::values.motion_device),
- QStringLiteral("engine:motion_emu,update_period:100,sensitivity:0.01"));
- WriteSetting(QStringLiteral("touch_device"),
- QString::fromStdString(Settings::values.touch_device),
- QStringLiteral("engine:emu_window"));
- WriteSetting(QStringLiteral("keyboard_enabled"), Settings::values.keyboard_enabled, false);
- WriteSetting(QStringLiteral("emulate_analog_keyboard"),
- Settings::values.emulate_analog_keyboard, false);
- WriteSetting(QStringLiteral("mouse_panning_sensitivity"),
- Settings::values.mouse_panning_sensitivity, 1.0f);
+ WriteGlobalSetting(Settings::values.use_docked_mode);
+ WriteGlobalSetting(Settings::values.vibration_enabled);
+ WriteGlobalSetting(Settings::values.enable_accurate_vibrations);
+ WriteGlobalSetting(Settings::values.motion_enabled);
+ WriteBasicSetting(Settings::values.keyboard_enabled);
+ WriteBasicSetting(Settings::values.emulate_analog_keyboard);
+ WriteBasicSetting(Settings::values.mouse_panning_sensitivity);
+
qt_config->endGroup();
}
void Config::SaveCoreValues() {
qt_config->beginGroup(QStringLiteral("Core"));
- WriteSettingGlobal(QStringLiteral("use_multi_core"), Settings::values.use_multi_core, true);
+ WriteGlobalSetting(Settings::values.use_multi_core);
qt_config->endGroup();
}
@@ -1236,7 +1201,7 @@ void Config::SaveCoreValues() {
void Config::SaveDataStorageValues() {
qt_config->beginGroup(QStringLiteral("Data Storage"));
- WriteSetting(QStringLiteral("use_virtual_sd"), Settings::values.use_virtual_sd, true);
+ WriteBasicSetting(Settings::values.use_virtual_sd);
WriteSetting(QStringLiteral("nand_directory"),
QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)),
QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::NANDDir)));
@@ -1249,11 +1214,9 @@ void Config::SaveDataStorageValues() {
WriteSetting(QStringLiteral("dump_directory"),
QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)),
QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::DumpDir)));
- WriteSetting(QStringLiteral("gamecard_inserted"), Settings::values.gamecard_inserted, false);
- WriteSetting(QStringLiteral("gamecard_current_game"), Settings::values.gamecard_current_game,
- false);
- WriteSetting(QStringLiteral("gamecard_path"),
- QString::fromStdString(Settings::values.gamecard_path), QString{});
+ WriteBasicSetting(Settings::values.gamecard_inserted);
+ WriteBasicSetting(Settings::values.gamecard_current_game);
+ WriteBasicSetting(Settings::values.gamecard_path);
qt_config->endGroup();
}
@@ -1263,24 +1226,23 @@ void Config::SaveDebuggingValues() {
// Intentionally not using the QT default setting as this is intended to be changed in the ini
qt_config->setValue(QStringLiteral("record_frame_times"), Settings::values.record_frame_times);
- WriteSetting(QStringLiteral("program_args"),
- QString::fromStdString(Settings::values.program_args), QString{});
- WriteSetting(QStringLiteral("dump_exefs"), Settings::values.dump_exefs, false);
- WriteSetting(QStringLiteral("dump_nso"), Settings::values.dump_nso, false);
- WriteSetting(QStringLiteral("enable_fs_access_log"), Settings::values.enable_fs_access_log,
- false);
- WriteSetting(QStringLiteral("quest_flag"), Settings::values.quest_flag, false);
- WriteSetting(QStringLiteral("use_debug_asserts"), Settings::values.use_debug_asserts, false);
- WriteSetting(QStringLiteral("disable_macro_jit"), Settings::values.disable_macro_jit, false);
+ WriteBasicSetting(Settings::values.program_args);
+ WriteBasicSetting(Settings::values.dump_exefs);
+ WriteBasicSetting(Settings::values.dump_nso);
+ WriteBasicSetting(Settings::values.enable_fs_access_log);
+ WriteBasicSetting(Settings::values.quest_flag);
+ WriteBasicSetting(Settings::values.use_debug_asserts);
+ WriteBasicSetting(Settings::values.disable_macro_jit);
qt_config->endGroup();
}
void Config::SaveServiceValues() {
qt_config->beginGroup(QStringLiteral("Services"));
- WriteSetting(QStringLiteral("bcat_backend"),
- QString::fromStdString(Settings::values.bcat_backend), QStringLiteral("none"));
- WriteSetting(QStringLiteral("bcat_boxcat_local"), Settings::values.bcat_boxcat_local, false);
+
+ WriteBasicSetting(Settings::values.bcat_backend);
+ WriteBasicSetting(Settings::values.bcat_boxcat_local);
+
qt_config->endGroup();
}
@@ -1306,9 +1268,8 @@ void Config::SaveDisabledAddOnValues() {
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);
+ WriteBasicSetting(Settings::values.log_filter);
+ WriteBasicSetting(Settings::values.use_dev_keys);
qt_config->endGroup();
}
@@ -1336,38 +1297,29 @@ void Config::SavePathValues() {
void Config::SaveCpuValues() {
qt_config->beginGroup(QStringLiteral("Cpu"));
- WriteSettingGlobal(QStringLiteral("cpu_accuracy"),
- static_cast<u32>(Settings::values.cpu_accuracy.GetValue(global)),
- Settings::values.cpu_accuracy.UsingGlobal(),
- static_cast<u32>(Settings::CPUAccuracy::Accurate));
-
- WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_unfuse_fma"),
- Settings::values.cpuopt_unsafe_unfuse_fma, true);
- WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_reduce_fp_error"),
- Settings::values.cpuopt_unsafe_reduce_fp_error, true);
- WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_ignore_standard_fpcr"),
- Settings::values.cpuopt_unsafe_ignore_standard_fpcr, true);
- WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_inaccurate_nan"),
- Settings::values.cpuopt_unsafe_inaccurate_nan, true);
- WriteSettingGlobal(QStringLiteral("cpuopt_unsafe_fastmem_check"),
- Settings::values.cpuopt_unsafe_fastmem_check, true);
+ WriteBasicSetting(Settings::values.cpu_accuracy_first_time);
+ WriteSetting(QStringLiteral("cpu_accuracy"),
+ static_cast<u32>(Settings::values.cpu_accuracy.GetValue(global)),
+ static_cast<u32>(Settings::values.cpu_accuracy.GetDefault()),
+ Settings::values.cpu_accuracy.UsingGlobal());
+
+ WriteGlobalSetting(Settings::values.cpuopt_unsafe_unfuse_fma);
+ WriteGlobalSetting(Settings::values.cpuopt_unsafe_reduce_fp_error);
+ WriteGlobalSetting(Settings::values.cpuopt_unsafe_ignore_standard_fpcr);
+ WriteGlobalSetting(Settings::values.cpuopt_unsafe_inaccurate_nan);
+ WriteGlobalSetting(Settings::values.cpuopt_unsafe_fastmem_check);
if (global) {
- WriteSetting(QStringLiteral("cpuopt_page_tables"), Settings::values.cpuopt_page_tables,
- true);
- WriteSetting(QStringLiteral("cpuopt_block_linking"), Settings::values.cpuopt_block_linking,
- true);
- WriteSetting(QStringLiteral("cpuopt_return_stack_buffer"),
- Settings::values.cpuopt_return_stack_buffer, true);
- WriteSetting(QStringLiteral("cpuopt_fast_dispatcher"),
- Settings::values.cpuopt_fast_dispatcher, true);
- WriteSetting(QStringLiteral("cpuopt_context_elimination"),
- Settings::values.cpuopt_context_elimination, true);
- WriteSetting(QStringLiteral("cpuopt_const_prop"), Settings::values.cpuopt_const_prop, true);
- WriteSetting(QStringLiteral("cpuopt_misc_ir"), Settings::values.cpuopt_misc_ir, true);
- WriteSetting(QStringLiteral("cpuopt_reduce_misalign_checks"),
- Settings::values.cpuopt_reduce_misalign_checks, true);
- WriteSetting(QStringLiteral("cpuopt_fastmem"), Settings::values.cpuopt_fastmem, true);
+ WriteBasicSetting(Settings::values.cpu_debug_mode);
+ WriteBasicSetting(Settings::values.cpuopt_page_tables);
+ WriteBasicSetting(Settings::values.cpuopt_block_linking);
+ WriteBasicSetting(Settings::values.cpuopt_return_stack_buffer);
+ WriteBasicSetting(Settings::values.cpuopt_fast_dispatcher);
+ WriteBasicSetting(Settings::values.cpuopt_context_elimination);
+ WriteBasicSetting(Settings::values.cpuopt_const_prop);
+ WriteBasicSetting(Settings::values.cpuopt_misc_ir);
+ WriteBasicSetting(Settings::values.cpuopt_reduce_misalign_checks);
+ WriteBasicSetting(Settings::values.cpuopt_fastmem);
}
qt_config->endGroup();
@@ -1376,46 +1328,46 @@ void Config::SaveCpuValues() {
void Config::SaveRendererValues() {
qt_config->beginGroup(QStringLiteral("Renderer"));
- WriteSettingGlobal(QStringLiteral("backend"),
- static_cast<int>(Settings::values.renderer_backend.GetValue(global)),
- Settings::values.renderer_backend.UsingGlobal(), 0);
- WriteSetting(QStringLiteral("debug"), Settings::values.renderer_debug, false);
- WriteSettingGlobal(QStringLiteral("vulkan_device"), Settings::values.vulkan_device, 0);
-#ifdef _WIN32
- WriteSettingGlobal(QStringLiteral("fullscreen_mode"), Settings::values.fullscreen_mode, 0);
-#else
- // *nix platforms may have issues with the borderless windowed fullscreen mode.
- // Default to exclusive fullscreen on these platforms for now.
- WriteSettingGlobal(QStringLiteral("fullscreen_mode"), Settings::values.fullscreen_mode, 1);
-#endif
- WriteSettingGlobal(QStringLiteral("aspect_ratio"), Settings::values.aspect_ratio, 0);
- WriteSettingGlobal(QStringLiteral("max_anisotropy"), Settings::values.max_anisotropy, 0);
- WriteSettingGlobal(QStringLiteral("use_frame_limit"), Settings::values.use_frame_limit, true);
- WriteSettingGlobal(QStringLiteral("frame_limit"), Settings::values.frame_limit, 100);
- WriteSettingGlobal(QStringLiteral("use_disk_shader_cache"),
- Settings::values.use_disk_shader_cache, true);
- WriteSettingGlobal(QStringLiteral("gpu_accuracy"),
- static_cast<int>(Settings::values.gpu_accuracy.GetValue(global)),
- Settings::values.gpu_accuracy.UsingGlobal(), 1);
- WriteSettingGlobal(QStringLiteral("use_asynchronous_gpu_emulation"),
- Settings::values.use_asynchronous_gpu_emulation, true);
- WriteSettingGlobal(QStringLiteral("use_nvdec_emulation"), Settings::values.use_nvdec_emulation,
- true);
- WriteSettingGlobal(QStringLiteral("accelerate_astc"), Settings::values.accelerate_astc, true);
- WriteSettingGlobal(QStringLiteral("use_vsync"), Settings::values.use_vsync, true);
- WriteSettingGlobal(QStringLiteral("disable_fps_limit"), Settings::values.disable_fps_limit,
- false);
- WriteSettingGlobal(QStringLiteral("use_assembly_shaders"),
- Settings::values.use_assembly_shaders, false);
- WriteSettingGlobal(QStringLiteral("use_asynchronous_shaders"),
- Settings::values.use_asynchronous_shaders, false);
- WriteSettingGlobal(QStringLiteral("use_fast_gpu_time"), Settings::values.use_fast_gpu_time,
- true);
- WriteSettingGlobal(QStringLiteral("use_caches_gc"), Settings::values.use_caches_gc, false);
- // Cast to double because Qt's written float values are not human-readable
- WriteSettingGlobal(QStringLiteral("bg_red"), Settings::values.bg_red, 0.0);
- WriteSettingGlobal(QStringLiteral("bg_green"), Settings::values.bg_green, 0.0);
- WriteSettingGlobal(QStringLiteral("bg_blue"), Settings::values.bg_blue, 0.0);
+ WriteSetting(QString::fromStdString(Settings::values.renderer_backend.GetLabel()),
+ static_cast<u32>(Settings::values.renderer_backend.GetValue(global)),
+ static_cast<u32>(Settings::values.renderer_backend.GetDefault()),
+ Settings::values.renderer_backend.UsingGlobal());
+ WriteGlobalSetting(Settings::values.vulkan_device);
+ WriteSetting(QString::fromStdString(Settings::values.fullscreen_mode.GetLabel()),
+ static_cast<u32>(Settings::values.fullscreen_mode.GetValue(global)),
+ static_cast<u32>(Settings::values.fullscreen_mode.GetDefault()),
+ Settings::values.fullscreen_mode.UsingGlobal());
+ WriteGlobalSetting(Settings::values.aspect_ratio);
+ WriteGlobalSetting(Settings::values.max_anisotropy);
+ WriteGlobalSetting(Settings::values.use_speed_limit);
+ WriteGlobalSetting(Settings::values.speed_limit);
+ WriteGlobalSetting(Settings::values.use_disk_shader_cache);
+ WriteSetting(QString::fromStdString(Settings::values.gpu_accuracy.GetLabel()),
+ static_cast<u32>(Settings::values.gpu_accuracy.GetValue(global)),
+ static_cast<u32>(Settings::values.gpu_accuracy.GetDefault()),
+ Settings::values.gpu_accuracy.UsingGlobal());
+ WriteGlobalSetting(Settings::values.use_asynchronous_gpu_emulation);
+ WriteGlobalSetting(Settings::values.use_nvdec_emulation);
+ WriteGlobalSetting(Settings::values.accelerate_astc);
+ WriteGlobalSetting(Settings::values.use_vsync);
+ WriteSetting(QString::fromStdString(Settings::values.shader_backend.GetLabel()),
+ static_cast<u32>(Settings::values.shader_backend.GetValue(global)),
+ static_cast<u32>(Settings::values.shader_backend.GetDefault()),
+ Settings::values.shader_backend.UsingGlobal());
+ WriteGlobalSetting(Settings::values.use_asynchronous_shaders);
+ WriteGlobalSetting(Settings::values.use_fast_gpu_time);
+ WriteGlobalSetting(Settings::values.use_caches_gc);
+ WriteGlobalSetting(Settings::values.bg_red);
+ WriteGlobalSetting(Settings::values.bg_green);
+ WriteGlobalSetting(Settings::values.bg_blue);
+
+ if (global) {
+ WriteBasicSetting(Settings::values.fps_cap);
+ WriteBasicSetting(Settings::values.renderer_debug);
+ WriteBasicSetting(Settings::values.renderer_shader_feedback);
+ WriteBasicSetting(Settings::values.enable_nsight_aftermath);
+ WriteBasicSetting(Settings::values.disable_shader_loop_safety_checks);
+ }
qt_config->endGroup();
}
@@ -1423,8 +1375,7 @@ void Config::SaveRendererValues() {
void Config::SaveScreenshotValues() {
qt_config->beginGroup(QStringLiteral("Screenshots"));
- WriteSetting(QStringLiteral("enable_screenshot_save_as"),
- UISettings::values.enable_screenshot_save_as);
+ WriteBasicSetting(UISettings::values.enable_screenshot_save_as);
WriteSetting(QStringLiteral("screenshot_path"),
QString::fromStdString(FS::GetYuzuPathString(FS::YuzuPath::ScreenshotsDir)));
@@ -1454,17 +1405,16 @@ void Config::SaveShortcutValues() {
void Config::SaveSystemValues() {
qt_config->beginGroup(QStringLiteral("System"));
- WriteSetting(QStringLiteral("current_user"), Settings::values.current_user, 0);
- WriteSettingGlobal(QStringLiteral("language_index"), Settings::values.language_index, 1);
- WriteSettingGlobal(QStringLiteral("region_index"), Settings::values.region_index, 1);
- WriteSettingGlobal(QStringLiteral("time_zone_index"), Settings::values.time_zone_index, 0);
+ WriteBasicSetting(Settings::values.current_user);
+ WriteGlobalSetting(Settings::values.language_index);
+ WriteGlobalSetting(Settings::values.region_index);
+ WriteGlobalSetting(Settings::values.time_zone_index);
- WriteSettingGlobal(QStringLiteral("rng_seed_enabled"),
- Settings::values.rng_seed.GetValue(global).has_value(),
- Settings::values.rng_seed.UsingGlobal(), false);
- WriteSettingGlobal(QStringLiteral("rng_seed"),
- Settings::values.rng_seed.GetValue(global).value_or(0),
- Settings::values.rng_seed.UsingGlobal(), 0);
+ WriteSetting(QStringLiteral("rng_seed_enabled"),
+ Settings::values.rng_seed.GetValue(global).has_value(), false,
+ Settings::values.rng_seed.UsingGlobal());
+ WriteSetting(QStringLiteral("rng_seed"), Settings::values.rng_seed.GetValue(global).value_or(0),
+ 0, Settings::values.rng_seed.UsingGlobal());
if (global) {
WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(),
@@ -1475,7 +1425,7 @@ void Config::SaveSystemValues() {
0);
}
- WriteSettingGlobal(QStringLiteral("sound_index"), Settings::values.sound_index, 1);
+ WriteGlobalSetting(Settings::values.sound_index);
qt_config->endGroup();
}
@@ -1485,10 +1435,8 @@ void Config::SaveUIValues() {
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("select_user_on_boot"), UISettings::values.select_user_on_boot,
- false);
+ WriteBasicSetting(UISettings::values.enable_discord_presence);
+ WriteBasicSetting(UISettings::values.select_user_on_boot);
SaveUIGamelistValues();
SaveUILayoutValues();
@@ -1496,18 +1444,17 @@ void Config::SaveUIValues() {
SaveScreenshotValues();
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("pauseWhenInBackground"),
- UISettings::values.pause_when_in_background, false);
- WriteSetting(QStringLiteral("hideInactiveMouse"), UISettings::values.hide_mouse, false);
+ WriteBasicSetting(UISettings::values.single_window_mode);
+ WriteBasicSetting(UISettings::values.fullscreen);
+ WriteBasicSetting(UISettings::values.display_titlebar);
+ WriteBasicSetting(UISettings::values.show_filter_bar);
+ WriteBasicSetting(UISettings::values.show_status_bar);
+ WriteBasicSetting(UISettings::values.confirm_before_closing);
+ WriteBasicSetting(UISettings::values.first_start);
+ WriteBasicSetting(UISettings::values.callout_flags);
+ WriteBasicSetting(UISettings::values.show_console);
+ WriteBasicSetting(UISettings::values.pause_when_in_background);
+ WriteBasicSetting(UISettings::values.hide_mouse);
qt_config->endGroup();
}
@@ -1515,11 +1462,11 @@ void Config::SaveUIValues() {
void Config::SaveUIGamelistValues() {
qt_config->beginGroup(QStringLiteral("UIGameList"));
- 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);
+ WriteBasicSetting(UISettings::values.show_add_ons);
+ WriteBasicSetting(UISettings::values.icon_size);
+ WriteBasicSetting(UISettings::values.row_1_text_id);
+ WriteBasicSetting(UISettings::values.row_2_text_id);
+ WriteBasicSetting(UISettings::values.cache_game_list);
qt_config->beginWriteArray(QStringLiteral("favorites"));
for (int i = 0; i < UISettings::values.favorited_ids.size(); i++) {
qt_config->setArrayIndex(i);
@@ -1540,8 +1487,7 @@ void Config::SaveUILayoutValues() {
WriteSetting(QStringLiteral("gameListHeaderState"), UISettings::values.gamelist_header_state);
WriteSetting(QStringLiteral("microProfileDialogGeometry"),
UISettings::values.microprofile_geometry);
- WriteSetting(QStringLiteral("microProfileDialogVisible"),
- UISettings::values.microprofile_visible, false);
+ WriteBasicSetting(UISettings::values.microprofile_visible);
qt_config->endGroup();
}
@@ -1549,13 +1495,10 @@ void Config::SaveUILayoutValues() {
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));
+ WriteBasicSetting(Settings::values.enable_telemetry);
+ WriteBasicSetting(Settings::values.web_api_url);
+ WriteBasicSetting(Settings::values.yuzu_username);
+ WriteBasicSetting(Settings::values.yuzu_token);
qt_config->endGroup();
}
@@ -1575,21 +1518,14 @@ QVariant Config::ReadSetting(const QString& name, const QVariant& default_value)
}
template <typename Type>
-void Config::ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name) {
+void Config::ReadGlobalSetting(Settings::Setting<Type>& setting) {
+ QString name = QString::fromStdString(setting.GetLabel());
const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool();
setting.SetGlobal(use_global);
if (global || !use_global) {
- setting.SetValue(ReadSetting(name).value<Type>());
- }
-}
-
-template <typename Type>
-void Config::ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name,
- const QVariant& default_value) {
- const bool use_global = qt_config->value(name + QStringLiteral("/use_global"), true).toBool();
- setting.SetGlobal(use_global);
- if (global || !use_global) {
- setting.SetValue(ReadSetting(name, default_value).value<Type>());
+ setting.SetValue(static_cast<QVariant>(
+ ReadSetting(name, QVariant::fromValue<Type>(setting.GetDefault())))
+ .value<Type>());
}
}
@@ -1612,31 +1548,8 @@ void Config::WriteSetting(const QString& name, const QVariant& value,
qt_config->setValue(name, value);
}
-template <typename Type>
-void Config::WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting) {
- if (!global) {
- qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal());
- }
- if (global || !setting.UsingGlobal()) {
- qt_config->setValue(name, setting.GetValue(global));
- }
-}
-
-template <typename Type>
-void Config::WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting,
- const QVariant& default_value) {
- if (!global) {
- qt_config->setValue(name + QStringLiteral("/use_global"), setting.UsingGlobal());
- }
- if (global || !setting.UsingGlobal()) {
- qt_config->setValue(name + QStringLiteral("/default"),
- setting.GetValue(global) == default_value.value<Type>());
- qt_config->setValue(name, setting.GetValue(global));
- }
-}
-
-void Config::WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global,
- const QVariant& default_value) {
+void Config::WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
+ bool use_global) {
if (!global) {
qt_config->setValue(name + QStringLiteral("/use_global"), use_global);
}
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h
index 3c1de0ac9..c1d7feb9f 100644
--- a/src/yuzu/configuration/config.h
+++ b/src/yuzu/configuration/config.h
@@ -102,28 +102,75 @@ private:
void SaveUILayoutValues();
void SaveWebServiceValues();
+ /**
+ * Reads a setting from the qt_config.
+ *
+ * @param name The setting's identifier
+ * @param default_value The value to use when the setting is not already present in the config
+ */
QVariant ReadSetting(const QString& name) const;
QVariant ReadSetting(const QString& name, const QVariant& default_value) const;
- // Templated ReadSettingGlobal functions will also look for the use_global setting and set
- // both the value and the global state properly
- template <typename Type>
- void ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name);
- template <typename Type>
- void ReadSettingGlobal(Settings::Setting<Type>& setting, const QString& name,
- const QVariant& default_value);
+
+ /**
+ * Only reads a setting from the qt_config if the current config is a global config, or if the
+ * current config is a custom config and the setting is overriding the global setting. Otherwise
+ * it does nothing.
+ *
+ * @param setting The variable to be modified
+ * @param name The setting's identifier
+ * @param default_value The value to use when the setting is not already present in the config
+ */
template <typename Type>
void ReadSettingGlobal(Type& setting, const QString& name, const QVariant& default_value) const;
- // Templated WriteSettingGlobal functions will also write the global state if needed and will
- // skip writing the actual setting if it defers to the global value
+
+ /**
+ * Writes a setting to the qt_config.
+ *
+ * @param name The setting's idetentifier
+ * @param value Value of the setting
+ * @param default_value Default of the setting if not present in qt_config
+ * @param use_global Specifies if the custom or global config should be in use, for custom
+ * configs
+ */
void WriteSetting(const QString& name, const QVariant& value);
void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value);
+ void WriteSetting(const QString& name, const QVariant& value, const QVariant& default_value,
+ bool use_global);
+
+ /**
+ * Reads a value from the qt_config and applies it to the setting, using its label and default
+ * value. If the config is a custom config, this will also read the global state of the setting
+ * and apply that information to it.
+ *
+ * @param The setting
+ */
+ template <typename Type>
+ void ReadGlobalSetting(Settings::Setting<Type>& setting);
+
+ /**
+ * Sets a value to the qt_config using the setting's label and default value. If the config is a
+ * custom config, it will apply the global state, and the custom value if needed.
+ *
+ * @param The setting
+ */
template <typename Type>
- void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting);
+ void WriteGlobalSetting(const Settings::Setting<Type>& setting);
+
+ /**
+ * Reads a value from the qt_config using the setting's label and default value and applies the
+ * value to the setting.
+ *
+ * @param The setting
+ */
template <typename Type>
- void WriteSettingGlobal(const QString& name, const Settings::Setting<Type>& setting,
- const QVariant& default_value);
- void WriteSettingGlobal(const QString& name, const QVariant& value, bool use_global,
- const QVariant& default_value);
+ void ReadBasicSetting(Settings::BasicSetting<Type>& setting);
+
+ /** Sets a value from the setting in the qt_config using the setting's label and default value.
+ *
+ * @param The setting
+ */
+ template <typename Type>
+ void WriteBasicSetting(const Settings::BasicSetting<Type>& setting);
ConfigType type;
std::unique_ptr<QSettings> qt_config;
@@ -133,5 +180,7 @@ private:
// These metatype declarations cannot be in common/settings.h because core is devoid of QT
Q_DECLARE_METATYPE(Settings::CPUAccuracy);
-Q_DECLARE_METATYPE(Settings::RendererBackend);
Q_DECLARE_METATYPE(Settings::GPUAccuracy);
+Q_DECLARE_METATYPE(Settings::FullscreenMode);
+Q_DECLARE_METATYPE(Settings::RendererBackend);
+Q_DECLARE_METATYPE(Settings::ShaderBackend);
diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp
index 096e42e94..251aab912 100644
--- a/src/yuzu/configuration/configuration_shared.cpp
+++ b/src/yuzu/configuration/configuration_shared.cpp
@@ -25,20 +25,6 @@ void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<bool>* setting,
}
}
-void ConfigurationShared::ApplyPerGameSetting(Settings::Setting<int>* setting,
- const QComboBox* combobox) {
- if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
- setting->SetValue(combobox->currentIndex());
- } else if (!Settings::IsConfiguringGlobal()) {
- if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
- setting->SetGlobal(true);
- } else {
- setting->SetGlobal(false);
- setting->SetValue(combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET);
- }
- }
-}
-
void ConfigurationShared::SetPerGameSetting(QCheckBox* checkbox,
const Settings::Setting<bool>* setting) {
if (setting->UsingGlobal()) {
diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h
index 1e0ef01ca..5423dbc92 100644
--- a/src/yuzu/configuration/configuration_shared.h
+++ b/src/yuzu/configuration/configuration_shared.h
@@ -28,7 +28,20 @@ enum class CheckState {
// ApplyPerGameSetting, given a Settings::Setting and a Qt UI element, properly applies a Setting
void ApplyPerGameSetting(Settings::Setting<bool>* setting, const QCheckBox* checkbox,
const CheckState& tracker);
-void ApplyPerGameSetting(Settings::Setting<int>* setting, const QComboBox* combobox);
+template <typename Type>
+void ApplyPerGameSetting(Settings::Setting<Type>* setting, const QComboBox* combobox) {
+ if (Settings::IsConfiguringGlobal() && setting->UsingGlobal()) {
+ setting->SetValue(static_cast<Type>(combobox->currentIndex()));
+ } else if (!Settings::IsConfiguringGlobal()) {
+ if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
+ setting->SetGlobal(true);
+ } else {
+ setting->SetGlobal(false);
+ setting->SetValue(static_cast<Type>(combobox->currentIndex() -
+ ConfigurationShared::USE_GLOBAL_OFFSET));
+ }
+ }
+}
// Sets a Qt UI element given a Settings::Setting
void SetPerGameSetting(QCheckBox* checkbox, const Settings::Setting<bool>* setting);
diff --git a/src/yuzu/configuration/configure.ui b/src/yuzu/configuration/configure.ui
index f92c3aff3..fca9aed5f 100644
--- a/src/yuzu/configuration/configure.ui
+++ b/src/yuzu/configuration/configure.ui
@@ -41,7 +41,7 @@
<item>
<widget class="QTabWidget" name="tabWidget">
<property name="currentIndex">
- <number>0</number>
+ <number>11</number>
</property>
<widget class="ConfigureGeneral" name="generalTab">
<property name="accessibleName">
@@ -107,14 +107,6 @@
<string>CPU</string>
</attribute>
</widget>
- <widget class="ConfigureCpuDebug" name="cpuDebugTab">
- <property name="accessibleName">
- <string>Debug</string>
- </property>
- <attribute name="title">
- <string>Debug</string>
- </attribute>
- </widget>
<widget class="ConfigureGraphics" name="graphicsTab">
<property name="accessibleName">
<string>Graphics</string>
@@ -139,7 +131,7 @@
<string>Audio</string>
</attribute>
</widget>
- <widget class="ConfigureDebug" name="debugTab">
+ <widget class="ConfigureDebugTab" name="debugTab">
<property name="accessibleName">
<string>Debug</string>
</property>
@@ -208,24 +200,12 @@
<container>1</container>
</customwidget>
<customwidget>
- <class>ConfigureDebug</class>
- <extends>QWidget</extends>
- <header>configuration/configure_debug.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
<class>ConfigureCpu</class>
<extends>QWidget</extends>
<header>configuration/configure_cpu.h</header>
<container>1</container>
</customwidget>
<customwidget>
- <class>ConfigureCpuDebug</class>
- <extends>QWidget</extends>
- <header>configuration/configure_cpu_debug.h</header>
- <container>1</container>
- </customwidget>
- <customwidget>
<class>ConfigureGraphics</class>
<extends>QWidget</extends>
<header>configuration/configure_graphics.h</header>
@@ -267,6 +247,12 @@
<header>configuration/configure_service.h</header>
<container>1</container>
</customwidget>
+ <customwidget>
+ <class>ConfigureDebugTab</class>
+ <extends>QWidget</extends>
+ <header>configuration/configure_debug_tab.h</header>
+ <container>1</container>
+ </customwidget>
</customwidgets>
<resources/>
<connections>
@@ -275,12 +261,32 @@
<signal>accepted()</signal>
<receiver>ConfigureDialog</receiver>
<slot>accept()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
</connection>
<connection>
<sender>buttonBox</sender>
<signal>rejected()</signal>
<receiver>ConfigureDialog</receiver>
<slot>reject()</slot>
+ <hints>
+ <hint type="sourcelabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ <hint type="destinationlabel">
+ <x>20</x>
+ <y>20</y>
+ </hint>
+ </hints>
</connection>
</connections>
</ui>
diff --git a/src/yuzu/configuration/configure_audio.cpp b/src/yuzu/configuration/configure_audio.cpp
index fc0191432..1d84bf4ed 100644
--- a/src/yuzu/configuration/configure_audio.cpp
+++ b/src/yuzu/configuration/configure_audio.cpp
@@ -47,7 +47,8 @@ void ConfigureAudio::SetConfiguration() {
SetAudioDeviceFromDeviceID();
- ui->volume_slider->setValue(Settings::values.volume.GetValue() * ui->volume_slider->maximum());
+ const auto volume_value = static_cast<int>(Settings::values.volume.GetValue());
+ ui->volume_slider->setValue(volume_value);
ui->toggle_audio_stretching->setChecked(Settings::values.enable_audio_stretching.GetValue());
@@ -69,7 +70,7 @@ void ConfigureAudio::SetOutputSinkFromSinkID() {
[[maybe_unused]] const QSignalBlocker blocker(ui->output_sink_combo_box);
int new_sink_index = 0;
- const QString sink_id = QString::fromStdString(Settings::values.sink_id);
+ const QString sink_id = QString::fromStdString(Settings::values.sink_id.GetValue());
for (int index = 0; index < ui->output_sink_combo_box->count(); index++) {
if (ui->output_sink_combo_box->itemText(index) == sink_id) {
new_sink_index = index;
@@ -83,7 +84,7 @@ void ConfigureAudio::SetOutputSinkFromSinkID() {
void ConfigureAudio::SetAudioDeviceFromDeviceID() {
int new_device_index = -1;
- const QString device_id = QString::fromStdString(Settings::values.audio_device_id);
+ const QString device_id = QString::fromStdString(Settings::values.audio_device_id.GetValue());
for (int index = 0; index < ui->audio_device_combo_box->count(); index++) {
if (ui->audio_device_combo_box->itemText(index) == device_id) {
new_device_index = index;
@@ -106,24 +107,22 @@ void ConfigureAudio::ApplyConfiguration() {
Settings::values.sink_id =
ui->output_sink_combo_box->itemText(ui->output_sink_combo_box->currentIndex())
.toStdString();
- Settings::values.audio_device_id =
+ Settings::values.audio_device_id.SetValue(
ui->audio_device_combo_box->itemText(ui->audio_device_combo_box->currentIndex())
- .toStdString();
+ .toStdString());
// Guard if during game and set to game-specific value
if (Settings::values.volume.UsingGlobal()) {
- Settings::values.volume.SetValue(
- static_cast<float>(ui->volume_slider->sliderPosition()) /
- ui->volume_slider->maximum());
+ const auto volume = static_cast<u8>(ui->volume_slider->value());
+ Settings::values.volume.SetValue(volume);
}
} else {
if (ui->volume_combo_box->currentIndex() == 0) {
Settings::values.volume.SetGlobal(true);
} else {
Settings::values.volume.SetGlobal(false);
- Settings::values.volume.SetValue(
- static_cast<float>(ui->volume_slider->sliderPosition()) /
- ui->volume_slider->maximum());
+ const auto volume = static_cast<u8>(ui->volume_slider->value());
+ Settings::values.volume.SetValue(volume);
}
}
}
diff --git a/src/yuzu/configuration/configure_cpu.cpp b/src/yuzu/configuration/configure_cpu.cpp
index 13db2ba98..784b6484e 100644
--- a/src/yuzu/configuration/configure_cpu.cpp
+++ b/src/yuzu/configuration/configure_cpu.cpp
@@ -20,8 +20,6 @@ ConfigureCpu::ConfigureCpu(QWidget* parent) : QWidget(parent), ui(new Ui::Config
SetConfiguration();
- connect(ui->accuracy, qOverload<int>(&QComboBox::activated), this,
- &ConfigureCpu::AccuracyUpdated);
connect(ui->accuracy, qOverload<int>(&QComboBox::currentIndexChanged), this,
&ConfigureCpu::UpdateGroup);
}
@@ -58,20 +56,6 @@ void ConfigureCpu::SetConfiguration() {
UpdateGroup(ui->accuracy->currentIndex());
}
-void ConfigureCpu::AccuracyUpdated(int index) {
- if (Settings::IsConfiguringGlobal() &&
- static_cast<Settings::CPUAccuracy>(index) == Settings::CPUAccuracy::DebugMode) {
- const auto result = QMessageBox::warning(this, tr("Setting CPU to Debug Mode"),
- tr("CPU Debug Mode is only intended for developer "
- "use. Are you sure you want to enable this?"),
- QMessageBox::Yes | QMessageBox::No);
- if (result == QMessageBox::No) {
- ui->accuracy->setCurrentIndex(static_cast<int>(Settings::CPUAccuracy::Accurate));
- UpdateGroup(static_cast<int>(Settings::CPUAccuracy::Accurate));
- }
- }
-}
-
void ConfigureCpu::UpdateGroup(int index) {
if (!Settings::IsConfiguringGlobal()) {
index -= ConfigurationShared::USE_GLOBAL_OFFSET;
@@ -81,6 +65,7 @@ void ConfigureCpu::UpdateGroup(int index) {
}
void ConfigureCpu::ApplyConfiguration() {
+ ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpu_accuracy, ui->accuracy);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_unfuse_fma,
ui->cpuopt_unsafe_unfuse_fma,
cpuopt_unsafe_unfuse_fma);
@@ -96,22 +81,6 @@ void ConfigureCpu::ApplyConfiguration() {
ConfigurationShared::ApplyPerGameSetting(&Settings::values.cpuopt_unsafe_fastmem_check,
ui->cpuopt_unsafe_fastmem_check,
cpuopt_unsafe_fastmem_check);
-
- if (Settings::IsConfiguringGlobal()) {
- // Guard if during game and set to game-specific value
- if (Settings::values.cpu_accuracy.UsingGlobal()) {
- Settings::values.cpu_accuracy.SetValue(
- static_cast<Settings::CPUAccuracy>(ui->accuracy->currentIndex()));
- }
- } else {
- if (ui->accuracy->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
- Settings::values.cpu_accuracy.SetGlobal(true);
- } else {
- Settings::values.cpu_accuracy.SetGlobal(false);
- Settings::values.cpu_accuracy.SetValue(static_cast<Settings::CPUAccuracy>(
- ui->accuracy->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET));
- }
- }
}
void ConfigureCpu::changeEvent(QEvent* event) {
@@ -134,8 +103,6 @@ void ConfigureCpu::SetupPerGameUI() {
ConfigurationShared::SetColoredComboBox(
ui->accuracy, ui->widget_accuracy,
static_cast<u32>(Settings::values.cpu_accuracy.GetValue(true)));
- ui->accuracy->removeItem(static_cast<u32>(Settings::CPUAccuracy::DebugMode) +
- ConfigurationShared::USE_GLOBAL_OFFSET);
ConfigurationShared::SetColoredTristate(ui->cpuopt_unsafe_unfuse_fma,
Settings::values.cpuopt_unsafe_unfuse_fma,
diff --git a/src/yuzu/configuration/configure_cpu.h b/src/yuzu/configuration/configure_cpu.h
index b2b5f1671..154931482 100644
--- a/src/yuzu/configuration/configure_cpu.h
+++ b/src/yuzu/configuration/configure_cpu.h
@@ -29,7 +29,6 @@ private:
void changeEvent(QEvent* event) override;
void RetranslateUI();
- void AccuracyUpdated(int index);
void UpdateGroup(int index);
void SetConfiguration();
diff --git a/src/yuzu/configuration/configure_cpu.ui b/src/yuzu/configuration/configure_cpu.ui
index 0e296d4e5..5b9457faf 100644
--- a/src/yuzu/configuration/configure_cpu.ui
+++ b/src/yuzu/configuration/configure_cpu.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>400</width>
- <height>321</height>
+ <width>448</width>
+ <height>433</height>
</rect>
</property>
<property name="windowTitle">
@@ -17,7 +17,7 @@
<item>
<layout class="QVBoxLayout">
<item>
- <widget class="QGroupBox">
+ <widget class="QGroupBox" name="groupBox">
<property name="title">
<string>General</string>
</property>
@@ -36,17 +36,17 @@
<widget class="QComboBox" name="accuracy">
<item>
<property name="text">
- <string>Accurate</string>
+ <string>Auto</string>
</property>
</item>
<item>
<property name="text">
- <string>Unsafe</string>
+ <string>Accurate</string>
</property>
</item>
<item>
<property name="text">
- <string>Enable Debug Mode</string>
+ <string>Unsafe</string>
</property>
</item>
</widget>
@@ -57,7 +57,7 @@
<item>
<widget class="QLabel" name="label_recommended_accuracy">
<property name="text">
- <string>We recommend setting accuracy to &quot;Accurate&quot;.</string>
+ <string>We recommend setting accuracy to &quot;Auto&quot;.</string>
</property>
<property name="wordWrap">
<bool>false</bool>
diff --git a/src/yuzu/configuration/configure_cpu_debug.cpp b/src/yuzu/configuration/configure_cpu_debug.cpp
index e25c52baf..98e2d2be5 100644
--- a/src/yuzu/configuration/configure_cpu_debug.cpp
+++ b/src/yuzu/configuration/configure_cpu_debug.cpp
@@ -24,23 +24,26 @@ void ConfigureCpuDebug::SetConfiguration() {
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
ui->cpuopt_page_tables->setEnabled(runtime_lock);
- ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables);
+ ui->cpuopt_page_tables->setChecked(Settings::values.cpuopt_page_tables.GetValue());
ui->cpuopt_block_linking->setEnabled(runtime_lock);
- ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking);
+ ui->cpuopt_block_linking->setChecked(Settings::values.cpuopt_block_linking.GetValue());
ui->cpuopt_return_stack_buffer->setEnabled(runtime_lock);
- ui->cpuopt_return_stack_buffer->setChecked(Settings::values.cpuopt_return_stack_buffer);
+ ui->cpuopt_return_stack_buffer->setChecked(
+ Settings::values.cpuopt_return_stack_buffer.GetValue());
ui->cpuopt_fast_dispatcher->setEnabled(runtime_lock);
- ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher);
+ ui->cpuopt_fast_dispatcher->setChecked(Settings::values.cpuopt_fast_dispatcher.GetValue());
ui->cpuopt_context_elimination->setEnabled(runtime_lock);
- ui->cpuopt_context_elimination->setChecked(Settings::values.cpuopt_context_elimination);
+ ui->cpuopt_context_elimination->setChecked(
+ Settings::values.cpuopt_context_elimination.GetValue());
ui->cpuopt_const_prop->setEnabled(runtime_lock);
- ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop);
+ ui->cpuopt_const_prop->setChecked(Settings::values.cpuopt_const_prop.GetValue());
ui->cpuopt_misc_ir->setEnabled(runtime_lock);
- ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir);
+ ui->cpuopt_misc_ir->setChecked(Settings::values.cpuopt_misc_ir.GetValue());
ui->cpuopt_reduce_misalign_checks->setEnabled(runtime_lock);
- ui->cpuopt_reduce_misalign_checks->setChecked(Settings::values.cpuopt_reduce_misalign_checks);
+ ui->cpuopt_reduce_misalign_checks->setChecked(
+ Settings::values.cpuopt_reduce_misalign_checks.GetValue());
ui->cpuopt_fastmem->setEnabled(runtime_lock);
- ui->cpuopt_fastmem->setChecked(Settings::values.cpuopt_fastmem);
+ ui->cpuopt_fastmem->setChecked(Settings::values.cpuopt_fastmem.GetValue());
}
void ConfigureCpuDebug::ApplyConfiguration() {
diff --git a/src/yuzu/configuration/configure_cpu_debug.h b/src/yuzu/configuration/configure_cpu_debug.h
index 10de55099..1b0d8050c 100644
--- a/src/yuzu/configuration/configure_cpu_debug.h
+++ b/src/yuzu/configuration/configure_cpu_debug.h
@@ -6,7 +6,6 @@
#include <memory>
#include <QWidget>
-#include "common/settings.h"
namespace Ui {
class ConfigureCpuDebug;
diff --git a/src/yuzu/configuration/configure_cpu_debug.ui b/src/yuzu/configuration/configure_cpu_debug.ui
index c43f89a5a..abf469b55 100644
--- a/src/yuzu/configuration/configure_cpu_debug.ui
+++ b/src/yuzu/configuration/configure_cpu_debug.ui
@@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
- <width>400</width>
- <height>321</height>
+ <width>592</width>
+ <height>503</height>
</rect>
</property>
<property name="windowTitle">
@@ -17,140 +17,132 @@
<item>
<layout class="QVBoxLayout">
<item>
- <widget class="QGroupBox">
+ <widget class="QGroupBox" name="groupBox">
<property name="title">
<string>Toggle CPU Optimizations</string>
</property>
<layout class="QVBoxLayout">
<item>
- <widget class="QLabel">
- <property name="wordWrap">
- <bool>1</bool>
- </property>
+ <widget class="QLabel" name="label">
<property name="text">
- <string>
- &lt;div&gt;
- &lt;b&gt;For debugging only.&lt;/b&gt;
- &lt;br&gt;
- If you're not sure what these do, keep all of these enabled.
- &lt;br&gt;
- These settings, when disabled, only take effect when CPU Accuracy is "Debug Mode".
- &lt;/div&gt;
- </string>
+ <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;For debugging only.&lt;/span&gt;&lt;br/&gt;If you're not sure what these do, keep all of these enabled. &lt;br/&gt;These settings, when disabled, only take effect when CPU Debugging is enabled. &lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
+ </property>
+ <property name="wordWrap">
+ <bool>false</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_page_tables">
- <property name="text">
- <string>Enable inline page tables</string>
- </property>
<property name="toolTip">
<string>
- &lt;div style="white-space: nowrap"&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
- &lt;div style="white-space: nowrap"&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt;
- &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it inlines accesses to PageTable::pointers into emitted code.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all memory accesses to go through the Memory::Read/Memory::Write functions.&lt;/div&gt;
</string>
</property>
+ <property name="text">
+ <string>Enable inline page tables</string>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_block_linking">
- <property name="text">
- <string>Enable block linking</string>
- </property>
<property name="toolTip">
<string>
&lt;div&gt;This optimization avoids dispatcher lookups by allowing emitted basic blocks to jump directly to other basic blocks if the destination PC is static.&lt;/div&gt;
</string>
</property>
+ <property name="text">
+ <string>Enable block linking</string>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_return_stack_buffer">
- <property name="text">
- <string>Enable return stack buffer</string>
- </property>
<property name="toolTip">
<string>
&lt;div&gt;This optimization avoids dispatcher lookups by keeping track potential return addresses of BL instructions. This approximates what happens with a return stack buffer on a real CPU.&lt;/div&gt;
</string>
</property>
+ <property name="text">
+ <string>Enable return stack buffer</string>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_fast_dispatcher">
- <property name="text">
- <string>Enable fast dispatcher</string>
- </property>
<property name="toolTip">
<string>
&lt;div&gt;Enable a two-tiered dispatch system. A faster dispatcher written in assembly has a small MRU cache of jump destinations is used first. If that fails, dispatch falls back to the slower C++ dispatcher.&lt;/div&gt;
</string>
</property>
+ <property name="text">
+ <string>Enable fast dispatcher</string>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_context_elimination">
- <property name="text">
- <string>Enable context elimination</string>
- </property>
<property name="toolTip">
<string>
&lt;div&gt;Enables an IR optimization that reduces unnecessary accesses to the CPU context structure.&lt;/div&gt;
</string>
</property>
+ <property name="text">
+ <string>Enable context elimination</string>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_const_prop">
- <property name="text">
- <string>Enable constant propagation</string>
- </property>
<property name="toolTip">
<string>
&lt;div&gt;Enables IR optimizations that involve constant propagation.&lt;/div&gt;
</string>
</property>
+ <property name="text">
+ <string>Enable constant propagation</string>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_misc_ir">
- <property name="text">
- <string>Enable miscellaneous optimizations</string>
- </property>
<property name="toolTip">
<string>
&lt;div&gt;Enables miscellaneous IR optimizations.&lt;/div&gt;
</string>
</property>
+ <property name="text">
+ <string>Enable miscellaneous optimizations</string>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_reduce_misalign_checks">
- <property name="text">
- <string>Enable misalignment check reduction</string>
- </property>
<property name="toolTip">
<string>
- &lt;div style="white-space: nowrap"&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt;
- &lt;div style="white-space: nowrap"&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;When enabled, a misalignment is only triggered when an access crosses a page boundary.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;When disabled, a misalignment is triggered on all misaligned accesses.&lt;/div&gt;
</string>
</property>
+ <property name="text">
+ <string>Enable misalignment check reduction</string>
+ </property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="cpuopt_fastmem">
- <property name="text">
- <string>Enable Host MMU Emulation</string>
- </property>
<property name="toolTip">
<string>
- &lt;div style="white-space: nowrap"&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
- &lt;div style="white-space: nowrap"&gt;Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt;
- &lt;div style="white-space: nowrap"&gt;Disabling this forces all memory accesses to use Software MMU Emulation.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;This optimization speeds up memory accesses by the guest program.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Enabling it causes guest memory reads/writes to be done directly into memory and make use of Host's MMU.&lt;/div&gt;
+ &lt;div style=&quot;white-space: nowrap&quot;&gt;Disabling this forces all memory accesses to use Software MMU Emulation.&lt;/div&gt;
</string>
</property>
+ <property name="text">
+ <string>Enable Host MMU Emulation</string>
+ </property>
</widget>
</item>
</layout>
diff --git a/src/yuzu/configuration/configure_debug.cpp b/src/yuzu/configuration/configure_debug.cpp
index 15d6a5ad7..c0b240c1e 100644
--- a/src/yuzu/configuration/configure_debug.cpp
+++ b/src/yuzu/configuration/configure_debug.cpp
@@ -31,20 +31,30 @@ void ConfigureDebug::SetConfiguration() {
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
ui->toggle_console->setEnabled(runtime_lock);
- ui->toggle_console->setChecked(UISettings::values.show_console);
- ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter));
- ui->homebrew_args_edit->setText(QString::fromStdString(Settings::values.program_args));
+ ui->toggle_console->setChecked(UISettings::values.show_console.GetValue());
+ ui->log_filter_edit->setText(QString::fromStdString(Settings::values.log_filter.GetValue()));
+ ui->homebrew_args_edit->setText(
+ QString::fromStdString(Settings::values.program_args.GetValue()));
ui->fs_access_log->setEnabled(runtime_lock);
- ui->fs_access_log->setChecked(Settings::values.enable_fs_access_log);
- ui->reporting_services->setChecked(Settings::values.reporting_services);
- ui->quest_flag->setChecked(Settings::values.quest_flag);
- ui->use_debug_asserts->setChecked(Settings::values.use_debug_asserts);
- ui->use_auto_stub->setChecked(Settings::values.use_auto_stub);
+ ui->fs_access_log->setChecked(Settings::values.enable_fs_access_log.GetValue());
+ ui->reporting_services->setChecked(Settings::values.reporting_services.GetValue());
+ ui->quest_flag->setChecked(Settings::values.quest_flag.GetValue());
+ ui->use_debug_asserts->setChecked(Settings::values.use_debug_asserts.GetValue());
+ ui->use_auto_stub->setChecked(Settings::values.use_auto_stub.GetValue());
ui->enable_graphics_debugging->setEnabled(runtime_lock);
- ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug);
+ ui->enable_graphics_debugging->setChecked(Settings::values.renderer_debug.GetValue());
+ ui->enable_shader_feedback->setEnabled(runtime_lock);
+ ui->enable_shader_feedback->setChecked(Settings::values.renderer_shader_feedback.GetValue());
+ ui->enable_cpu_debugging->setEnabled(runtime_lock);
+ ui->enable_cpu_debugging->setChecked(Settings::values.cpu_debug_mode.GetValue());
+ ui->enable_nsight_aftermath->setEnabled(runtime_lock);
+ ui->enable_nsight_aftermath->setChecked(Settings::values.enable_nsight_aftermath.GetValue());
ui->disable_macro_jit->setEnabled(runtime_lock);
- ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit);
- ui->extended_logging->setChecked(Settings::values.extended_logging);
+ ui->disable_macro_jit->setChecked(Settings::values.disable_macro_jit.GetValue());
+ ui->disable_loop_safety_checks->setEnabled(runtime_lock);
+ ui->disable_loop_safety_checks->setChecked(
+ Settings::values.disable_shader_loop_safety_checks.GetValue());
+ ui->extended_logging->setChecked(Settings::values.extended_logging.GetValue());
}
void ConfigureDebug::ApplyConfiguration() {
@@ -57,11 +67,16 @@ void ConfigureDebug::ApplyConfiguration() {
Settings::values.use_debug_asserts = ui->use_debug_asserts->isChecked();
Settings::values.use_auto_stub = ui->use_auto_stub->isChecked();
Settings::values.renderer_debug = ui->enable_graphics_debugging->isChecked();
+ Settings::values.renderer_shader_feedback = ui->enable_shader_feedback->isChecked();
+ Settings::values.cpu_debug_mode = ui->enable_cpu_debugging->isChecked();
+ Settings::values.enable_nsight_aftermath = ui->enable_nsight_aftermath->isChecked();
+ Settings::values.disable_shader_loop_safety_checks =
+ ui->disable_loop_safety_checks->isChecked();
Settings::values.disable_macro_jit = ui->disable_macro_jit->isChecked();
Settings::values.extended_logging = ui->extended_logging->isChecked();
Debugger::ToggleConsole();
Common::Log::Filter filter;
- filter.ParseFilterString(Settings::values.log_filter);
+ filter.ParseFilterString(Settings::values.log_filter.GetValue());
Common::Log::SetGlobalFilter(filter);
}
diff --git a/src/yuzu/configuration/configure_debug.ui b/src/yuzu/configuration/configure_debug.ui
index c8087542f..3fe9ff7de 100644
--- a/src/yuzu/configuration/configure_debug.ui
+++ b/src/yuzu/configuration/configure_debug.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>400</width>
- <height>486</height>
+ <height>777</height>
</rect>
</property>
<property name="windowTitle">
@@ -111,8 +111,8 @@
<property name="title">
<string>Graphics</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout_6">
- <item>
+ <layout class="QGridLayout" name="gridLayout_3">
+ <item row="0" column="0">
<widget class="QCheckBox" name="enable_graphics_debugging">
<property name="enabled">
<bool>true</bool>
@@ -125,7 +125,17 @@
</property>
</widget>
</item>
- <item>
+ <item row="2" column="0">
+ <widget class="QCheckBox" name="enable_nsight_aftermath">
+ <property name="toolTip">
+ <string>When checked, it enables Nsight Aftermath crash dumps</string>
+ </property>
+ <property name="text">
+ <string>Enable Nsight Aftermath</string>
+ </property>
+ </widget>
+ </item>
+ <item row="0" column="1">
<widget class="QCheckBox" name="disable_macro_jit">
<property name="enabled">
<bool>true</bool>
@@ -138,6 +148,26 @@
</property>
</widget>
</item>
+ <item row="1" column="0">
+ <widget class="QCheckBox" name="enable_shader_feedback">
+ <property name="toolTip">
+ <string>When checked, yuzu will log statistics about the compiled pipeline cache</string>
+ </property>
+ <property name="text">
+ <string>Enable Shader Feedback</string>
+ </property>
+ </widget>
+ </item>
+ <item row="1" column="1">
+ <widget class="QCheckBox" name="disable_loop_safety_checks">
+ <property name="toolTip">
+ <string>When checked, it executes shaders without loop logic changes</string>
+ </property>
+ <property name="text">
+ <string>Disable Loop safety checks</string>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -192,34 +222,41 @@
</property>
</widget>
</item>
- <item>
- <widget class="QCheckBox" name="use_debug_asserts">
- <property name="text">
- <string>Enable Debug Asserts</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="use_auto_stub">
- <property name="text">
- <string>Enable Auto-Stub</string>
- </property>
- </widget>
- </item>
<item>
- <widget class="QLabel" name="label_5">
- <property name="font">
- <font>
- <italic>true</italic>
- </font>
- </property>
- <property name="text">
- <string>This will be reset automatically when yuzu closes.</string>
- </property>
- <property name="indent">
- <number>20</number>
- </property>
- </widget>
+ <widget class="QCheckBox" name="enable_cpu_debugging">
+ <property name="text">
+ <string>Enable CPU Debugging</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="use_debug_asserts">
+ <property name="text">
+ <string>Enable Debug Asserts</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QCheckBox" name="use_auto_stub">
+ <property name="text">
+ <string>Enable Auto-Stub</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLabel" name="label_5">
+ <property name="font">
+ <font>
+ <italic>true</italic>
+ </font>
+ </property>
+ <property name="text">
+ <string>This will be reset automatically when yuzu closes.</string>
+ </property>
+ <property name="indent">
+ <number>20</number>
+ </property>
+ </widget>
</item>
</layout>
</widget>
@@ -245,11 +282,20 @@
<tabstops>
<tabstop>log_filter_edit</tabstop>
<tabstop>toggle_console</tabstop>
+ <tabstop>extended_logging</tabstop>
<tabstop>open_log_button</tabstop>
<tabstop>homebrew_args_edit</tabstop>
<tabstop>enable_graphics_debugging</tabstop>
+ <tabstop>enable_shader_feedback</tabstop>
+ <tabstop>enable_nsight_aftermath</tabstop>
+ <tabstop>disable_macro_jit</tabstop>
+ <tabstop>disable_loop_safety_checks</tabstop>
+ <tabstop>fs_access_log</tabstop>
<tabstop>reporting_services</tabstop>
<tabstop>quest_flag</tabstop>
+ <tabstop>enable_cpu_debugging</tabstop>
+ <tabstop>use_debug_asserts</tabstop>
+ <tabstop>use_auto_stub</tabstop>
</tabstops>
<resources/>
<connections/>
diff --git a/src/yuzu/configuration/configure_debug_tab.cpp b/src/yuzu/configuration/configure_debug_tab.cpp
new file mode 100644
index 000000000..67d369249
--- /dev/null
+++ b/src/yuzu/configuration/configure_debug_tab.cpp
@@ -0,0 +1,38 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#include "ui_configure_debug_tab.h"
+#include "yuzu/configuration/configure_debug_tab.h"
+
+ConfigureDebugTab::ConfigureDebugTab(QWidget* parent)
+ : QWidget(parent), ui(new Ui::ConfigureDebugTab) {
+ ui->setupUi(this);
+
+ SetConfiguration();
+}
+
+ConfigureDebugTab::~ConfigureDebugTab() = default;
+
+void ConfigureDebugTab::ApplyConfiguration() {
+ ui->debugTab->ApplyConfiguration();
+ ui->cpuDebugTab->ApplyConfiguration();
+}
+
+void ConfigureDebugTab::SetCurrentIndex(int index) {
+ ui->tabWidget->setCurrentIndex(index);
+}
+
+void ConfigureDebugTab::changeEvent(QEvent* event) {
+ if (event->type() == QEvent::LanguageChange) {
+ RetranslateUI();
+ }
+
+ QWidget::changeEvent(event);
+}
+
+void ConfigureDebugTab::RetranslateUI() {
+ ui->retranslateUi(this);
+}
+
+void ConfigureDebugTab::SetConfiguration() {}
diff --git a/src/yuzu/configuration/configure_debug_tab.h b/src/yuzu/configuration/configure_debug_tab.h
new file mode 100644
index 000000000..0a96d43d0
--- /dev/null
+++ b/src/yuzu/configuration/configure_debug_tab.h
@@ -0,0 +1,32 @@
+// Copyright 2021 yuzu Emulator Project
+// Licensed under GPLv2 or any later version
+// Refer to the license.txt file included.
+
+#pragma once
+
+#include <memory>
+#include <QWidget>
+
+namespace Ui {
+class ConfigureDebugTab;
+}
+
+class ConfigureDebugTab : public QWidget {
+ Q_OBJECT
+
+public:
+ explicit ConfigureDebugTab(QWidget* parent = nullptr);
+ ~ConfigureDebugTab() override;
+
+ void ApplyConfiguration();
+
+ void SetCurrentIndex(int index);
+
+private:
+ void changeEvent(QEvent* event) override;
+ void RetranslateUI();
+
+ void SetConfiguration();
+
+ std::unique_ptr<Ui::ConfigureDebugTab> ui;
+};
diff --git a/src/yuzu/configuration/configure_debug_tab.ui b/src/yuzu/configuration/configure_debug_tab.ui
new file mode 100644
index 000000000..7dc6dd704
--- /dev/null
+++ b/src/yuzu/configuration/configure_debug_tab.ui
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>ConfigureDebugTab</class>
+ <widget class="QWidget" name="ConfigureDebugTab">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>320</width>
+ <height>240</height>
+ </rect>
+ </property>
+ <property name="windowTitle">
+ <string>Form</string>
+ </property>
+ <layout class="QVBoxLayout" name="verticalLayout">
+ <item>
+ <widget class="QTabWidget" name="tabWidget">
+ <property name="currentIndex">
+ <number>1</number>
+ </property>
+ <widget class="ConfigureDebug" name="debugTab">
+ <attribute name="title">
+ <string>General</string>
+ </attribute>
+ </widget>
+ <widget class="ConfigureCpuDebug" name="cpuDebugTab">
+ <attribute name="title">
+ <string>CPU</string>
+ </attribute>
+ </widget>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <customwidgets>
+ <customwidget>
+ <class>ConfigureDebug</class>
+ <extends>QWidget</extends>
+ <header>configuration/configure_debug.h</header>
+ <container>1</container>
+ </customwidget>
+ <customwidget>
+ <class>ConfigureCpuDebug</class>
+ <extends>QWidget</extends>
+ <header>configuration/configure_cpu_debug.h</header>
+ <container>1</container>
+ </customwidget>
+ </customwidgets>
+ <resources/>
+ <connections/>
+</ui>
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 371bc01b1..bc009b6b3 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -8,6 +8,7 @@
#include <QListWidgetItem>
#include <QPushButton>
#include <QSignalBlocker>
+#include <QTabWidget>
#include "common/settings.h"
#include "core/core.h"
#include "ui_configure.h"
@@ -32,6 +33,8 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry,
SetConfiguration();
PopulateSelectionList();
+ connect(ui->tabWidget, &QTabWidget::currentChanged, this,
+ [this]() { ui->debugTab->SetCurrentIndex(0); });
connect(ui->uiTab, &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
&ConfigureDialog::UpdateVisibleTabs);
@@ -59,7 +62,6 @@ void ConfigureDialog::ApplyConfiguration() {
ui->inputTab->ApplyConfiguration();
ui->hotkeysTab->ApplyConfiguration(registry);
ui->cpuTab->ApplyConfiguration();
- ui->cpuDebugTab->ApplyConfiguration();
ui->graphicsTab->ApplyConfiguration();
ui->graphicsAdvancedTab->ApplyConfiguration();
ui->audioTab->ApplyConfiguration();
@@ -102,7 +104,7 @@ void ConfigureDialog::PopulateSelectionList() {
const std::array<std::pair<QString, QList<QWidget*>>, 6> items{
{{tr("General"), {ui->generalTab, ui->hotkeysTab, ui->uiTab, ui->webTab, ui->debugTab}},
{tr("System"), {ui->systemTab, ui->profileManagerTab, ui->serviceTab, ui->filesystemTab}},
- {tr("CPU"), {ui->cpuTab, ui->cpuDebugTab}},
+ {tr("CPU"), {ui->cpuTab}},
{tr("Graphics"), {ui->graphicsTab, ui->graphicsAdvancedTab}},
{tr("Audio"), {ui->audioTab}},
{tr("Controls"), ui->inputTab->GetSubTabs()}},
diff --git a/src/yuzu/configuration/configure_filesystem.cpp b/src/yuzu/configuration/configure_filesystem.cpp
index d223c40ea..9cb317822 100644
--- a/src/yuzu/configuration/configure_filesystem.cpp
+++ b/src/yuzu/configuration/configure_filesystem.cpp
@@ -43,18 +43,19 @@ void ConfigureFilesystem::setConfiguration() {
QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::NANDDir)));
ui->sdmc_directory_edit->setText(
QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::SDMCDir)));
- ui->gamecard_path_edit->setText(QString::fromStdString(Settings::values.gamecard_path));
+ ui->gamecard_path_edit->setText(
+ QString::fromStdString(Settings::values.gamecard_path.GetValue()));
ui->dump_path_edit->setText(
QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::DumpDir)));
ui->load_path_edit->setText(
QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::LoadDir)));
- ui->gamecard_inserted->setChecked(Settings::values.gamecard_inserted);
- ui->gamecard_current_game->setChecked(Settings::values.gamecard_current_game);
- ui->dump_exefs->setChecked(Settings::values.dump_exefs);
- ui->dump_nso->setChecked(Settings::values.dump_nso);
+ ui->gamecard_inserted->setChecked(Settings::values.gamecard_inserted.GetValue());
+ ui->gamecard_current_game->setChecked(Settings::values.gamecard_current_game.GetValue());
+ ui->dump_exefs->setChecked(Settings::values.dump_exefs.GetValue());
+ ui->dump_nso->setChecked(Settings::values.dump_nso.GetValue());
- ui->cache_game_list->setChecked(UISettings::values.cache_game_list);
+ ui->cache_game_list->setChecked(UISettings::values.cache_game_list.GetValue());
UpdateEnabledControls();
}
diff --git a/src/yuzu/configuration/configure_general.cpp b/src/yuzu/configuration/configure_general.cpp
index 38edb4d8d..1f647a0d1 100644
--- a/src/yuzu/configuration/configure_general.cpp
+++ b/src/yuzu/configuration/configure_general.cpp
@@ -24,8 +24,8 @@ ConfigureGeneral::ConfigureGeneral(QWidget* parent)
SetConfiguration();
if (Settings::IsConfiguringGlobal()) {
- connect(ui->toggle_frame_limit, &QCheckBox::clicked, ui->frame_limit,
- [this]() { ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked()); });
+ connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit,
+ [this]() { ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked()); });
}
connect(ui->button_reset_defaults, &QPushButton::clicked, this,
@@ -40,21 +40,23 @@ void ConfigureGeneral::SetConfiguration() {
ui->use_multi_core->setEnabled(runtime_lock);
ui->use_multi_core->setChecked(Settings::values.use_multi_core.GetValue());
- ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing);
- ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot);
- ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background);
- ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse);
+ ui->toggle_check_exit->setChecked(UISettings::values.confirm_before_closing.GetValue());
+ ui->toggle_user_on_boot->setChecked(UISettings::values.select_user_on_boot.GetValue());
+ ui->toggle_background_pause->setChecked(UISettings::values.pause_when_in_background.GetValue());
+ ui->toggle_hide_mouse->setChecked(UISettings::values.hide_mouse.GetValue());
- ui->toggle_frame_limit->setChecked(Settings::values.use_frame_limit.GetValue());
- ui->frame_limit->setValue(Settings::values.frame_limit.GetValue());
+ ui->toggle_speed_limit->setChecked(Settings::values.use_speed_limit.GetValue());
+ ui->speed_limit->setValue(Settings::values.speed_limit.GetValue());
+
+ ui->fps_cap->setValue(Settings::values.fps_cap.GetValue());
ui->button_reset_defaults->setEnabled(runtime_lock);
if (Settings::IsConfiguringGlobal()) {
- ui->frame_limit->setEnabled(Settings::values.use_frame_limit.GetValue());
+ ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue());
} else {
- ui->frame_limit->setEnabled(Settings::values.use_frame_limit.GetValue() &&
- use_frame_limit != ConfigurationShared::CheckState::Global);
+ ui->speed_limit->setEnabled(Settings::values.use_speed_limit.GetValue() &&
+ use_speed_limit != ConfigurationShared::CheckState::Global);
}
}
@@ -87,20 +89,22 @@ void ConfigureGeneral::ApplyConfiguration() {
UISettings::values.pause_when_in_background = ui->toggle_background_pause->isChecked();
UISettings::values.hide_mouse = ui->toggle_hide_mouse->isChecked();
+ Settings::values.fps_cap.SetValue(ui->fps_cap->value());
+
// Guard if during game and set to game-specific value
- if (Settings::values.use_frame_limit.UsingGlobal()) {
- Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() ==
+ if (Settings::values.use_speed_limit.UsingGlobal()) {
+ Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
Qt::Checked);
- Settings::values.frame_limit.SetValue(ui->frame_limit->value());
+ Settings::values.speed_limit.SetValue(ui->speed_limit->value());
}
} else {
- bool global_frame_limit = use_frame_limit == ConfigurationShared::CheckState::Global;
- Settings::values.use_frame_limit.SetGlobal(global_frame_limit);
- Settings::values.frame_limit.SetGlobal(global_frame_limit);
- if (!global_frame_limit) {
- Settings::values.use_frame_limit.SetValue(ui->toggle_frame_limit->checkState() ==
+ bool global_speed_limit = use_speed_limit == ConfigurationShared::CheckState::Global;
+ Settings::values.use_speed_limit.SetGlobal(global_speed_limit);
+ Settings::values.speed_limit.SetGlobal(global_speed_limit);
+ if (!global_speed_limit) {
+ Settings::values.use_speed_limit.SetValue(ui->toggle_speed_limit->checkState() ==
Qt::Checked);
- Settings::values.frame_limit.SetValue(ui->frame_limit->value());
+ Settings::values.speed_limit.SetValue(ui->speed_limit->value());
}
}
}
@@ -122,8 +126,8 @@ void ConfigureGeneral::SetupPerGameUI() {
// Disables each setting if:
// - A game is running (thus settings in use), and
// - A non-global setting is applied.
- ui->toggle_frame_limit->setEnabled(Settings::values.use_frame_limit.UsingGlobal());
- ui->frame_limit->setEnabled(Settings::values.frame_limit.UsingGlobal());
+ ui->toggle_speed_limit->setEnabled(Settings::values.use_speed_limit.UsingGlobal());
+ ui->speed_limit->setEnabled(Settings::values.speed_limit.UsingGlobal());
return;
}
@@ -135,13 +139,13 @@ void ConfigureGeneral::SetupPerGameUI() {
ui->button_reset_defaults->setVisible(false);
- ConfigurationShared::SetColoredTristate(ui->toggle_frame_limit,
- Settings::values.use_frame_limit, use_frame_limit);
+ ConfigurationShared::SetColoredTristate(ui->toggle_speed_limit,
+ Settings::values.use_speed_limit, use_speed_limit);
ConfigurationShared::SetColoredTristate(ui->use_multi_core, Settings::values.use_multi_core,
use_multi_core);
- connect(ui->toggle_frame_limit, &QCheckBox::clicked, ui->frame_limit, [this]() {
- ui->frame_limit->setEnabled(ui->toggle_frame_limit->isChecked() &&
- (use_frame_limit != ConfigurationShared::CheckState::Global));
+ connect(ui->toggle_speed_limit, &QCheckBox::clicked, ui->speed_limit, [this]() {
+ ui->speed_limit->setEnabled(ui->toggle_speed_limit->isChecked() &&
+ (use_speed_limit != ConfigurationShared::CheckState::Global));
});
}
diff --git a/src/yuzu/configuration/configure_general.h b/src/yuzu/configuration/configure_general.h
index a0fd52492..c9df37d73 100644
--- a/src/yuzu/configuration/configure_general.h
+++ b/src/yuzu/configuration/configure_general.h
@@ -43,6 +43,6 @@ private:
std::unique_ptr<Ui::ConfigureGeneral> ui;
- ConfigurationShared::CheckState use_frame_limit;
+ ConfigurationShared::CheckState use_speed_limit;
ConfigurationShared::CheckState use_multi_core;
};
diff --git a/src/yuzu/configuration/configure_general.ui b/src/yuzu/configuration/configure_general.ui
index bc7041090..8ce97edec 100644
--- a/src/yuzu/configuration/configure_general.ui
+++ b/src/yuzu/configuration/configure_general.ui
@@ -27,14 +27,14 @@
<item>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<item>
- <widget class="QCheckBox" name="toggle_frame_limit">
+ <widget class="QCheckBox" name="toggle_speed_limit">
<property name="text">
<string>Limit Speed Percent</string>
</property>
</widget>
</item>
<item>
- <widget class="QSpinBox" name="frame_limit">
+ <widget class="QSpinBox" name="speed_limit">
<property name="suffix">
<string>%</string>
</property>
@@ -52,6 +52,36 @@
</layout>
</item>
<item>
+ <layout class="QHBoxLayout" name="horizontalLayout_2">
+ <item>
+ <widget class="QLabel" name="fps_cap_label">
+ <property name="text">
+ <string>Framerate Cap</string>
+ </property>
+ <property name="toolTip">
+ <string>Requires the use of the FPS Limiter Toggle hotkey to take effect.</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QSpinBox" name="fps_cap">
+ <property name="suffix">
+ <string>x</string>
+ </property>
+ <property name="minimum">
+ <number>1</number>
+ </property>
+ <property name="maximum">
+ <number>1000</number>
+ </property>
+ <property name="value">
+ <number>500</number>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item>
<widget class="QCheckBox" name="use_multi_core">
<property name="text">
<string>Multicore CPU Emulation</string>
diff --git a/src/yuzu/configuration/configure_graphics.cpp b/src/yuzu/configuration/configure_graphics.cpp
index 41a69d9b8..37e896258 100644
--- a/src/yuzu/configuration/configure_graphics.cpp
+++ b/src/yuzu/configuration/configure_graphics.cpp
@@ -26,19 +26,29 @@ ConfigureGraphics::ConfigureGraphics(QWidget* parent)
ui->setupUi(this);
+ for (const auto& device : vulkan_devices) {
+ ui->device->addItem(device);
+ }
+
+ ui->backend->addItem(QStringLiteral("GLSL"));
+ ui->backend->addItem(tr("GLASM (Assembly Shaders, NVIDIA Only)"));
+ ui->backend->addItem(QStringLiteral("SPIR-V (Experimental, Mesa Only)"));
+
SetupPerGameUI();
SetConfiguration();
connect(ui->api, qOverload<int>(&QComboBox::currentIndexChanged), this, [this] {
- UpdateDeviceComboBox();
+ UpdateAPILayout();
if (!Settings::IsConfiguringGlobal()) {
ConfigurationShared::SetHighlight(
- ui->api_layout, ui->api->currentIndex() != ConfigurationShared::USE_GLOBAL_INDEX);
+ ui->api_widget, ui->api->currentIndex() != ConfigurationShared::USE_GLOBAL_INDEX);
}
});
connect(ui->device, qOverload<int>(&QComboBox::activated), this,
[this](int device) { UpdateDeviceSelection(device); });
+ connect(ui->backend, qOverload<int>(&QComboBox::activated), this,
+ [this](int backend) { UpdateShaderBackendSelection(backend); });
connect(ui->bg_button, &QPushButton::clicked, this, [this] {
const QColor new_bg_color = QColorDialog::getColor(bg_color);
@@ -61,12 +71,21 @@ void ConfigureGraphics::UpdateDeviceSelection(int device) {
}
}
+void ConfigureGraphics::UpdateShaderBackendSelection(int backend) {
+ if (backend == -1) {
+ return;
+ }
+ if (GetCurrentGraphicsBackend() == Settings::RendererBackend::OpenGL) {
+ shader_backend = static_cast<Settings::ShaderBackend>(backend);
+ }
+}
+
ConfigureGraphics::~ConfigureGraphics() = default;
void ConfigureGraphics::SetConfiguration() {
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
- ui->api->setEnabled(runtime_lock);
+ ui->api_widget->setEnabled(runtime_lock);
ui->use_asynchronous_gpu_emulation->setEnabled(runtime_lock);
ui->use_disk_shader_cache->setEnabled(runtime_lock);
ui->use_nvdec_emulation->setEnabled(runtime_lock);
@@ -79,11 +98,12 @@ void ConfigureGraphics::SetConfiguration() {
if (Settings::IsConfiguringGlobal()) {
ui->api->setCurrentIndex(static_cast<int>(Settings::values.renderer_backend.GetValue()));
- ui->fullscreen_mode_combobox->setCurrentIndex(Settings::values.fullscreen_mode.GetValue());
+ ui->fullscreen_mode_combobox->setCurrentIndex(
+ static_cast<int>(Settings::values.fullscreen_mode.GetValue()));
ui->aspect_ratio_combobox->setCurrentIndex(Settings::values.aspect_ratio.GetValue());
} else {
ConfigurationShared::SetPerGameSetting(ui->api, &Settings::values.renderer_backend);
- ConfigurationShared::SetHighlight(ui->api_layout,
+ ConfigurationShared::SetHighlight(ui->api_widget,
!Settings::values.renderer_backend.UsingGlobal());
ConfigurationShared::SetPerGameSetting(ui->fullscreen_mode_combobox,
@@ -100,11 +120,10 @@ void ConfigureGraphics::SetConfiguration() {
ui->bg_button->setEnabled(!Settings::values.bg_red.UsingGlobal());
ConfigurationShared::SetHighlight(ui->bg_layout, !Settings::values.bg_red.UsingGlobal());
}
-
- UpdateBackgroundColorButton(QColor::fromRgbF(Settings::values.bg_red.GetValue(),
- Settings::values.bg_green.GetValue(),
- Settings::values.bg_blue.GetValue()));
- UpdateDeviceComboBox();
+ UpdateBackgroundColorButton(QColor::fromRgb(Settings::values.bg_red.GetValue(),
+ Settings::values.bg_green.GetValue(),
+ Settings::values.bg_blue.GetValue()));
+ UpdateAPILayout();
}
void ConfigureGraphics::ApplyConfiguration() {
@@ -128,26 +147,36 @@ void ConfigureGraphics::ApplyConfiguration() {
if (Settings::values.renderer_backend.UsingGlobal()) {
Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
}
+ if (Settings::values.shader_backend.UsingGlobal()) {
+ Settings::values.shader_backend.SetValue(shader_backend);
+ }
if (Settings::values.vulkan_device.UsingGlobal()) {
Settings::values.vulkan_device.SetValue(vulkan_device);
}
if (Settings::values.bg_red.UsingGlobal()) {
- Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF()));
- Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF()));
- Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF()));
+ Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
+ Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
+ Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
}
} else {
if (ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
Settings::values.renderer_backend.SetGlobal(true);
+ Settings::values.shader_backend.SetGlobal(true);
Settings::values.vulkan_device.SetGlobal(true);
} else {
Settings::values.renderer_backend.SetGlobal(false);
Settings::values.renderer_backend.SetValue(GetCurrentGraphicsBackend());
- if (GetCurrentGraphicsBackend() == Settings::RendererBackend::Vulkan) {
+ switch (GetCurrentGraphicsBackend()) {
+ case Settings::RendererBackend::OpenGL:
+ Settings::values.shader_backend.SetGlobal(false);
+ Settings::values.vulkan_device.SetGlobal(true);
+ Settings::values.shader_backend.SetValue(shader_backend);
+ break;
+ case Settings::RendererBackend::Vulkan:
+ Settings::values.shader_backend.SetGlobal(true);
Settings::values.vulkan_device.SetGlobal(false);
Settings::values.vulkan_device.SetValue(vulkan_device);
- } else {
- Settings::values.vulkan_device.SetGlobal(true);
+ break;
}
}
@@ -159,9 +188,9 @@ void ConfigureGraphics::ApplyConfiguration() {
Settings::values.bg_red.SetGlobal(false);
Settings::values.bg_green.SetGlobal(false);
Settings::values.bg_blue.SetGlobal(false);
- Settings::values.bg_red.SetValue(static_cast<float>(bg_color.redF()));
- Settings::values.bg_green.SetValue(static_cast<float>(bg_color.greenF()));
- Settings::values.bg_blue.SetValue(static_cast<float>(bg_color.blueF()));
+ Settings::values.bg_red.SetValue(static_cast<u8>(bg_color.red()));
+ Settings::values.bg_green.SetValue(static_cast<u8>(bg_color.green()));
+ Settings::values.bg_blue.SetValue(static_cast<u8>(bg_color.blue()));
}
}
}
@@ -188,32 +217,32 @@ void ConfigureGraphics::UpdateBackgroundColorButton(QColor color) {
ui->bg_button->setIcon(color_icon);
}
-void ConfigureGraphics::UpdateDeviceComboBox() {
- ui->device->clear();
-
- bool enabled = false;
-
+void ConfigureGraphics::UpdateAPILayout() {
if (!Settings::IsConfiguringGlobal() &&
ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
+ vulkan_device = Settings::values.vulkan_device.GetValue(true);
+ shader_backend = Settings::values.shader_backend.GetValue(true);
+ ui->device_widget->setEnabled(false);
+ ui->backend_widget->setEnabled(false);
+ } else {
vulkan_device = Settings::values.vulkan_device.GetValue();
+ shader_backend = Settings::values.shader_backend.GetValue();
+ ui->device_widget->setEnabled(true);
+ ui->backend_widget->setEnabled(true);
}
+
switch (GetCurrentGraphicsBackend()) {
case Settings::RendererBackend::OpenGL:
- ui->device->addItem(tr("OpenGL Graphics Device"));
- enabled = false;
+ ui->backend->setCurrentIndex(static_cast<u32>(shader_backend));
+ ui->device_widget->setVisible(false);
+ ui->backend_widget->setVisible(true);
break;
case Settings::RendererBackend::Vulkan:
- for (const auto& device : vulkan_devices) {
- ui->device->addItem(device);
- }
ui->device->setCurrentIndex(vulkan_device);
- enabled = !vulkan_devices.empty();
+ ui->device_widget->setVisible(true);
+ ui->backend_widget->setVisible(false);
break;
}
- // If in per-game config and use global is selected, don't enable.
- enabled &= !(!Settings::IsConfiguringGlobal() &&
- ui->api->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX);
- ui->device->setEnabled(enabled && !Core::System::GetInstance().IsPoweredOn());
}
void ConfigureGraphics::RetrieveVulkanDevices() try {
@@ -282,8 +311,9 @@ void ConfigureGraphics::SetupPerGameUI() {
ConfigurationShared::SetColoredComboBox(ui->aspect_ratio_combobox, ui->ar_label,
Settings::values.aspect_ratio.GetValue(true));
- ConfigurationShared::SetColoredComboBox(ui->fullscreen_mode_combobox, ui->fullscreen_mode_label,
- Settings::values.fullscreen_mode.GetValue(true));
+ ConfigurationShared::SetColoredComboBox(
+ ui->fullscreen_mode_combobox, ui->fullscreen_mode_label,
+ static_cast<int>(Settings::values.fullscreen_mode.GetValue(true)));
ConfigurationShared::InsertGlobalItem(
ui->api, static_cast<int>(Settings::values.renderer_backend.GetValue(true)));
}
diff --git a/src/yuzu/configuration/configure_graphics.h b/src/yuzu/configuration/configure_graphics.h
index 6418115cf..c866b911b 100644
--- a/src/yuzu/configuration/configure_graphics.h
+++ b/src/yuzu/configuration/configure_graphics.h
@@ -34,8 +34,9 @@ private:
void SetConfiguration();
void UpdateBackgroundColorButton(QColor color);
- void UpdateDeviceComboBox();
+ void UpdateAPILayout();
void UpdateDeviceSelection(int device);
+ void UpdateShaderBackendSelection(int backend);
void RetrieveVulkanDevices();
@@ -53,4 +54,5 @@ private:
std::vector<QString> vulkan_devices;
u32 vulkan_device{};
+ Settings::ShaderBackend shader_backend{};
};
diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui
index 5b999d84d..099ddbb7c 100644
--- a/src/yuzu/configuration/configure_graphics.ui
+++ b/src/yuzu/configuration/configure_graphics.ui
@@ -23,7 +23,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<item>
- <widget class="QWidget" name="api_layout" native="true">
+ <widget class="QWidget" name="api_widget" native="true">
<layout class="QGridLayout" name="gridLayout">
<property name="leftMargin">
<number>0</number>
@@ -40,37 +40,107 @@
<property name="horizontalSpacing">
<number>6</number>
</property>
- <item row="0" column="0">
- <widget class="QLabel" name="api_label">
- <property name="text">
- <string>API:</string>
- </property>
+ <item row="4" column="0">
+ <widget class="QWidget" name="backend_widget" native="true">
+ <layout class="QHBoxLayout" name="backend_layout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="backend_label">
+ <property name="text">
+ <string>Shader Backend:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="backend"/>
+ </item>
+ </layout>
</widget>
</item>
- <item row="0" column="1">
- <widget class="QComboBox" name="api">
- <item>
- <property name="text">
- <string notr="true">OpenGL</string>
+ <item row="2" column="0">
+ <widget class="QWidget" name="device_widget" native="true">
+ <layout class="QHBoxLayout" name="device_layout">
+ <property name="leftMargin">
+ <number>0</number>
</property>
- </item>
- <item>
- <property name="text">
- <string notr="true">Vulkan</string>
+ <property name="topMargin">
+ <number>0</number>
</property>
- </item>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="device_label">
+ <property name="text">
+ <string>Device:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="device"/>
+ </item>
+ </layout>
</widget>
</item>
- <item row="1" column="0">
- <widget class="QLabel" name="device_label">
- <property name="text">
- <string>Device:</string>
- </property>
+ <item row="0" column="0">
+ <widget class="QWidget" name="api_layout_2" native="true">
+ <layout class="QHBoxLayout" name="api_layout">
+ <property name="leftMargin">
+ <number>0</number>
+ </property>
+ <property name="topMargin">
+ <number>0</number>
+ </property>
+ <property name="rightMargin">
+ <number>0</number>
+ </property>
+ <property name="bottomMargin">
+ <number>0</number>
+ </property>
+ <item>
+ <widget class="QLabel" name="api_label">
+ <property name="text">
+ <string>API:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QComboBox" name="api">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
+ <item>
+ <property name="text">
+ <string notr="true">OpenGL</string>
+ </property>
+ </item>
+ <item>
+ <property name="text">
+ <string notr="true">Vulkan</string>
+ </property>
+ </item>
+ </widget>
+ </item>
+ </layout>
</widget>
</item>
- <item row="1" column="1">
- <widget class="QComboBox" name="device"/>
- </item>
</layout>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp
index 8d13c9857..a31b8e192 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.cpp
+++ b/src/yuzu/configuration/configure_graphics_advanced.cpp
@@ -23,13 +23,10 @@ ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default;
void ConfigureGraphicsAdvanced::SetConfiguration() {
const bool runtime_lock = !Core::System::GetInstance().IsPoweredOn();
ui->use_vsync->setEnabled(runtime_lock);
- ui->use_assembly_shaders->setEnabled(runtime_lock);
ui->use_asynchronous_shaders->setEnabled(runtime_lock);
ui->anisotropic_filtering_combobox->setEnabled(runtime_lock);
ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue());
- ui->disable_fps_limit->setChecked(Settings::values.disable_fps_limit.GetValue());
- ui->use_assembly_shaders->setChecked(Settings::values.use_assembly_shaders.GetValue());
ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue());
ui->use_caches_gc->setChecked(Settings::values.use_caches_gc.GetValue());
ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue());
@@ -51,18 +48,10 @@ void ConfigureGraphicsAdvanced::SetConfiguration() {
}
void ConfigureGraphicsAdvanced::ApplyConfiguration() {
- // Subtract 2 if configuring per-game (separator and "use global configuration" take 2 slots)
- const auto gpu_accuracy = static_cast<Settings::GPUAccuracy>(
- ui->gpu_accuracy->currentIndex() -
- ((Settings::IsConfiguringGlobal()) ? 0 : ConfigurationShared::USE_GLOBAL_OFFSET));
-
+ ConfigurationShared::ApplyPerGameSetting(&Settings::values.gpu_accuracy, ui->gpu_accuracy);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy,
ui->anisotropic_filtering_combobox);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync);
- ConfigurationShared::ApplyPerGameSetting(&Settings::values.disable_fps_limit,
- ui->disable_fps_limit, disable_fps_limit);
- ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_assembly_shaders,
- ui->use_assembly_shaders, use_assembly_shaders);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_asynchronous_shaders,
ui->use_asynchronous_shaders,
use_asynchronous_shaders);
@@ -70,20 +59,6 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() {
use_caches_gc);
ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_fast_gpu_time,
ui->use_fast_gpu_time, use_fast_gpu_time);
-
- if (Settings::IsConfiguringGlobal()) {
- // Must guard in case of a during-game configuration when set to be game-specific.
- if (Settings::values.gpu_accuracy.UsingGlobal()) {
- Settings::values.gpu_accuracy.SetValue(gpu_accuracy);
- }
- } else {
- if (ui->gpu_accuracy->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) {
- Settings::values.gpu_accuracy.SetGlobal(true);
- } else {
- Settings::values.gpu_accuracy.SetGlobal(false);
- Settings::values.gpu_accuracy.SetValue(gpu_accuracy);
- }
- }
}
void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) {
@@ -103,8 +78,6 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
if (Settings::IsConfiguringGlobal()) {
ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal());
ui->use_vsync->setEnabled(Settings::values.use_vsync.UsingGlobal());
- ui->disable_fps_limit->setEnabled(Settings::values.disable_fps_limit.UsingGlobal());
- ui->use_assembly_shaders->setEnabled(Settings::values.use_assembly_shaders.UsingGlobal());
ui->use_asynchronous_shaders->setEnabled(
Settings::values.use_asynchronous_shaders.UsingGlobal());
ui->use_fast_gpu_time->setEnabled(Settings::values.use_fast_gpu_time.UsingGlobal());
@@ -116,10 +89,6 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() {
}
ConfigurationShared::SetColoredTristate(ui->use_vsync, Settings::values.use_vsync, use_vsync);
- ConfigurationShared::SetColoredTristate(ui->disable_fps_limit,
- Settings::values.disable_fps_limit, disable_fps_limit);
- ConfigurationShared::SetColoredTristate(
- ui->use_assembly_shaders, Settings::values.use_assembly_shaders, use_assembly_shaders);
ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders,
Settings::values.use_asynchronous_shaders,
use_asynchronous_shaders);
diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h
index 6ac5f20ec..7356e6916 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.h
+++ b/src/yuzu/configuration/configure_graphics_advanced.h
@@ -35,8 +35,6 @@ private:
std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui;
ConfigurationShared::CheckState use_vsync;
- ConfigurationShared::CheckState disable_fps_limit;
- ConfigurationShared::CheckState use_assembly_shaders;
ConfigurationShared::CheckState use_asynchronous_shaders;
ConfigurationShared::CheckState use_fast_gpu_time;
ConfigurationShared::CheckState use_caches_gc;
diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui
index 18c43629e..379dc5d2e 100644
--- a/src/yuzu/configuration/configure_graphics_advanced.ui
+++ b/src/yuzu/configuration/configure_graphics_advanced.ui
@@ -77,40 +77,12 @@
</widget>
</item>
<item>
- <widget class="QCheckBox" name="disable_fps_limit">
- <property name="enabled">
- <bool>true</bool>
- </property>
- <property name="toolTip">
- <string>
- &lt;html&gt;&lt;head/&gt;&lt;body&gt;
- &lt;p&gt;Presents guest frames as they become available, disabling the FPS limit in most titles.&lt;/p&gt;
- &lt;p&gt;NOTE: Will cause instabilities.&lt;/p&gt;
- &lt;/body&gt;&lt;/html&gt;
- </string>
- </property>
- <property name="text">
- <string>Disable framerate limit (experimental)</string>
- </property>
- </widget>
- </item>
- <item>
- <widget class="QCheckBox" name="use_assembly_shaders">
- <property name="toolTip">
- <string>Enabling this reduces shader stutter. Enables OpenGL assembly shaders on supported Nvidia devices (NV_gpu_program5 is required). This feature is experimental.</string>
- </property>
- <property name="text">
- <string>Use assembly shaders (experimental, Nvidia OpenGL only)</string>
- </property>
- </widget>
- </item>
- <item>
<widget class="QCheckBox" name="use_asynchronous_shaders">
<property name="toolTip">
<string>Enables asynchronous shader compilation, which may reduce shader stutter. This feature is experimental.</string>
</property>
<property name="text">
- <string>Use asynchronous shader building (experimental)</string>
+ <string>Use asynchronous shader building</string>
</property>
</widget>
</item>
@@ -162,22 +134,22 @@
</item>
<item>
<property name="text">
- <string>2x</string>
+ <string>2x (WILL BREAK THINGS)</string>
</property>
</item>
<item>
<property name="text">
- <string>4x</string>
+ <string>4x (WILL BREAK THINGS)</string>
</property>
</item>
<item>
<property name="text">
- <string>8x</string>
+ <string>8x (WILL BREAK THINGS)</string>
</property>
</item>
<item>
<property name="text">
- <string>16x</string>
+ <string>16x (WILL BREAK THINGS)</string>
</property>
</item>
</widget>
diff --git a/src/yuzu/configuration/configure_input_advanced.cpp b/src/yuzu/configuration/configure_input_advanced.cpp
index d8d3b83dc..2f1419b5b 100644
--- a/src/yuzu/configuration/configure_input_advanced.cpp
+++ b/src/yuzu/configuration/configure_input_advanced.cpp
@@ -148,12 +148,12 @@ void ConfigureInputAdvanced::LoadConfiguration() {
}
}
- ui->debug_enabled->setChecked(Settings::values.debug_pad_enabled);
- ui->mouse_enabled->setChecked(Settings::values.mouse_enabled);
- ui->keyboard_enabled->setChecked(Settings::values.keyboard_enabled);
- ui->emulate_analog_keyboard->setChecked(Settings::values.emulate_analog_keyboard);
- ui->mouse_panning->setChecked(Settings::values.mouse_panning);
- ui->mouse_panning_sensitivity->setValue(Settings::values.mouse_panning_sensitivity);
+ ui->debug_enabled->setChecked(Settings::values.debug_pad_enabled.GetValue());
+ ui->mouse_enabled->setChecked(Settings::values.mouse_enabled.GetValue());
+ ui->keyboard_enabled->setChecked(Settings::values.keyboard_enabled.GetValue());
+ ui->emulate_analog_keyboard->setChecked(Settings::values.emulate_analog_keyboard.GetValue());
+ ui->mouse_panning->setChecked(Settings::values.mouse_panning.GetValue());
+ ui->mouse_panning_sensitivity->setValue(Settings::values.mouse_panning_sensitivity.GetValue());
ui->touchscreen_enabled->setChecked(Settings::values.touchscreen.enabled);
UpdateUIEnabled();
diff --git a/src/yuzu/configuration/configure_input_advanced.ui b/src/yuzu/configuration/configure_input_advanced.ui
index 173130d8d..d3ef5bd06 100644
--- a/src/yuzu/configuration/configure_input_advanced.ui
+++ b/src/yuzu/configuration/configure_input_advanced.ui
@@ -2573,27 +2573,24 @@
</widget>
</item>
<item row="2" column="2">
- <widget class="QDoubleSpinBox" name="mouse_panning_sensitivity">
+ <widget class="QSpinBox" name="mouse_panning_sensitivity">
<property name="toolTip">
<string>Mouse sensitivity</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
- <property name="decimals">
- <number>2</number>
+ <property name="suffix">
+ <string>%</string>
</property>
<property name="minimum">
- <double>0.100000000000000</double>
+ <number>1</number>
</property>
<property name="maximum">
- <double>16.000000000000000</double>
- </property>
- <property name="singleStep">
- <double>0.010000000000000</double>
+ <number>100</number>
</property>
<property name="value">
- <double>1.000000000000000</double>
+ <number>100</number>
</property>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp
index d5d624b96..6b9bd05f1 100644
--- a/src/yuzu/configuration/configure_input_player.cpp
+++ b/src/yuzu/configuration/configure_input_player.cpp
@@ -149,8 +149,9 @@ QString ButtonToText(const Common::ParamPackage& param) {
if (param.Has("button")) {
const QString button_str = QString::fromStdString(param.Get("button", ""));
+ const QString toggle = QString::fromStdString(param.Get("toggle", false) ? "~" : "");
- return QObject::tr("Button %1").arg(button_str);
+ return QObject::tr("%1Button %2").arg(toggle, button_str);
}
if (param.Has("motion")) {
@@ -313,6 +314,24 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
buttons_param[button_id].Set("toggle", toggle_value);
button_map[button_id]->setText(ButtonToText(buttons_param[button_id]));
});
+ if (buttons_param[button_id].Has("threshold")) {
+ context_menu.addAction(tr("Set threshold"), [&] {
+ const int button_threshold = static_cast<int>(
+ buttons_param[button_id].Get("threshold", 0.5f) * 100.0f);
+ const int new_threshold = QInputDialog::getInt(
+ this, tr("Set threshold"), tr("Choose a value between 0% and 100%"),
+ button_threshold, 0, 100);
+ buttons_param[button_id].Set("threshold", new_threshold / 100.0f);
+
+ if (button_id == Settings::NativeButton::ZL) {
+ ui->sliderZLThreshold->setValue(new_threshold);
+ }
+ if (button_id == Settings::NativeButton::ZR) {
+ ui->sliderZRThreshold->setValue(new_threshold);
+ }
+ });
+ }
+
context_menu.exec(button_map[button_id]->mapToGlobal(menu_location));
ui->controllerFrame->SetPlayerInput(player_index, buttons_param, analogs_param);
});
@@ -341,6 +360,20 @@ ConfigureInputPlayer::ConfigureInputPlayer(QWidget* parent, std::size_t player_i
});
}
+ connect(ui->sliderZLThreshold, &QSlider::valueChanged, [=, this] {
+ if (buttons_param[Settings::NativeButton::ZL].Has("threshold")) {
+ const auto slider_value = ui->sliderZLThreshold->value();
+ buttons_param[Settings::NativeButton::ZL].Set("threshold", slider_value / 100.0f);
+ }
+ });
+
+ connect(ui->sliderZRThreshold, &QSlider::valueChanged, [=, this] {
+ if (buttons_param[Settings::NativeButton::ZR].Has("threshold")) {
+ const auto slider_value = ui->sliderZRThreshold->value();
+ buttons_param[Settings::NativeButton::ZR].Set("threshold", slider_value / 100.0f);
+ }
+ });
+
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) {
auto* const analog_button = analog_map_buttons[analog_id][sub_button_id];
@@ -849,6 +882,18 @@ void ConfigureInputPlayer::UpdateUI() {
button_map[button]->setText(ButtonToText(buttons_param[button]));
}
+ if (buttons_param[Settings::NativeButton::ZL].Has("threshold")) {
+ const int button_threshold = static_cast<int>(
+ buttons_param[Settings::NativeButton::ZL].Get("threshold", 0.5f) * 100.0f);
+ ui->sliderZLThreshold->setValue(button_threshold);
+ }
+
+ if (buttons_param[Settings::NativeButton::ZR].Has("threshold")) {
+ const int button_threshold = static_cast<int>(
+ buttons_param[Settings::NativeButton::ZR].Get("threshold", 0.5f) * 100.0f);
+ ui->sliderZRThreshold->setValue(button_threshold);
+ }
+
for (int motion_id = 0; motion_id < Settings::NativeMotion::NumMotions; ++motion_id) {
motion_map[motion_id]->setText(ButtonToText(motions_param[motion_id]));
}
diff --git a/src/yuzu/configuration/configure_input_player.ui b/src/yuzu/configuration/configure_input_player.ui
index e76aa484f..e7433912b 100644
--- a/src/yuzu/configuration/configure_input_player.ui
+++ b/src/yuzu/configuration/configure_input_player.ui
@@ -1334,6 +1334,12 @@
</item>
<item>
<widget class="QGroupBox" name="buttonShoulderButtonsButtonZLGroup">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="title">
<string>ZL</string>
</property>
@@ -1378,6 +1384,22 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QSlider" name="sliderZLThreshold">
+ <property name="maximumSize">
+ <size>
+ <width>70</width>
+ <height>15</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
@@ -1759,6 +1781,12 @@
</item>
<item>
<widget class="QGroupBox" name="buttonShoulderButtonsZRGroup">
+ <property name="sizePolicy">
+ <sizepolicy hsizetype="Maximum" vsizetype="Preferred">
+ <horstretch>0</horstretch>
+ <verstretch>0</verstretch>
+ </sizepolicy>
+ </property>
<property name="title">
<string>ZR</string>
</property>
@@ -1803,6 +1831,22 @@
</property>
</widget>
</item>
+ <item>
+ <widget class="QSlider" name="sliderZRThreshold">
+ <property name="maximumSize">
+ <size>
+ <width>70</width>
+ <height>15</height>
+ </size>
+ </property>
+ <property name="maximum">
+ <number>100</number>
+ </property>
+ <property name="orientation">
+ <enum>Qt::Horizontal</enum>
+ </property>
+ </widget>
+ </item>
</layout>
</widget>
</item>
diff --git a/src/yuzu/configuration/configure_motion_touch.cpp b/src/yuzu/configuration/configure_motion_touch.cpp
index 6a5d625df..f8e08c422 100644
--- a/src/yuzu/configuration/configure_motion_touch.cpp
+++ b/src/yuzu/configuration/configure_motion_touch.cpp
@@ -101,15 +101,16 @@ ConfigureMotionTouch::ConfigureMotionTouch(QWidget* parent,
ConfigureMotionTouch::~ConfigureMotionTouch() = default;
void ConfigureMotionTouch::SetConfiguration() {
- const Common::ParamPackage motion_param(Settings::values.motion_device);
- const Common::ParamPackage touch_param(Settings::values.touch_device);
+ const Common::ParamPackage motion_param(Settings::values.motion_device.GetValue());
+ const Common::ParamPackage touch_param(Settings::values.touch_device.GetValue());
- ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button);
+ ui->touch_from_button_checkbox->setChecked(Settings::values.use_touch_from_button.GetValue());
touch_from_button_maps = Settings::values.touch_from_button_maps;
for (const auto& touch_map : touch_from_button_maps) {
ui->touch_from_button_map->addItem(QString::fromStdString(touch_map.name));
}
- ui->touch_from_button_map->setCurrentIndex(Settings::values.touch_from_button_map_index);
+ ui->touch_from_button_map->setCurrentIndex(
+ Settings::values.touch_from_button_map_index.GetValue());
ui->motion_sensitivity->setValue(motion_param.Get("sensitivity", 0.01f));
min_x = touch_param.Get("min_x", 100);
@@ -124,7 +125,7 @@ void ConfigureMotionTouch::SetConfiguration() {
udp_server_list_model->setStringList({});
ui->udp_server_list->setModel(udp_server_list_model);
- std::stringstream ss(Settings::values.udp_input_servers);
+ std::stringstream ss(Settings::values.udp_input_servers.GetValue());
std::string token;
while (std::getline(ss, token, ',')) {
diff --git a/src/yuzu/configuration/configure_profile_manager.cpp b/src/yuzu/configuration/configure_profile_manager.cpp
index f5881e58d..ac849b01d 100644
--- a/src/yuzu/configuration/configure_profile_manager.cpp
+++ b/src/yuzu/configuration/configure_profile_manager.cpp
@@ -166,7 +166,7 @@ void ConfigureProfileManager::PopulateUserList() {
void ConfigureProfileManager::UpdateCurrentUser() {
ui->pm_add->setEnabled(profile_manager->GetUserCount() < Service::Account::MAX_USERS);
- const auto& current_user = profile_manager->GetUser(Settings::values.current_user);
+ const auto& current_user = profile_manager->GetUser(Settings::values.current_user.GetValue());
ASSERT(current_user);
const auto username = GetAccountUsername(*profile_manager, *current_user);
@@ -245,15 +245,18 @@ void ConfigureProfileManager::DeleteUser() {
this, tr("Confirm Delete"),
tr("You are about to delete user with name \"%1\". Are you sure?").arg(username));
- if (confirm == QMessageBox::No)
+ if (confirm == QMessageBox::No) {
return;
+ }
- if (Settings::values.current_user == tree_view->currentIndex().row())
+ if (Settings::values.current_user.GetValue() == tree_view->currentIndex().row()) {
Settings::values.current_user = 0;
+ }
UpdateCurrentUser();
- if (!profile_manager->RemoveUser(*uuid))
+ if (!profile_manager->RemoveUser(*uuid)) {
return;
+ }
item_model->removeRows(tree_view->currentIndex().row(), 1);
tree_view->clearSelection();
diff --git a/src/yuzu/configuration/configure_service.cpp b/src/yuzu/configuration/configure_service.cpp
index 6d954a67f..4aa424803 100644
--- a/src/yuzu/configuration/configure_service.cpp
+++ b/src/yuzu/configuration/configure_service.cpp
@@ -65,7 +65,7 @@ void ConfigureService::RetranslateUi() {
void ConfigureService::SetConfiguration() {
const int index =
- ui->bcat_source->findData(QString::fromStdString(Settings::values.bcat_backend));
+ ui->bcat_source->findData(QString::fromStdString(Settings::values.bcat_backend.GetValue()));
ui->bcat_source->setCurrentIndex(index == -1 ? 0 : index);
}
diff --git a/src/yuzu/configuration/configure_system.ui b/src/yuzu/configuration/configure_system.ui
index 53b95658b..27f552f59 100644
--- a/src/yuzu/configuration/configure_system.ui
+++ b/src/yuzu/configuration/configure_system.ui
@@ -401,6 +401,11 @@
<string>Traditional Chinese (正體中文)</string>
</property>
</item>
+ <item>
+ <property name="text">
+ <string>Brazilian Portuguese (português do Brasil)</string>
+ </property>
+ </item>
</widget>
</item>
<item row="5" column="0">
diff --git a/src/yuzu/configuration/configure_ui.cpp b/src/yuzu/configuration/configure_ui.cpp
index 9674119e1..e8f41bf65 100644
--- a/src/yuzu/configuration/configure_ui.cpp
+++ b/src/yuzu/configuration/configure_ui.cpp
@@ -113,11 +113,12 @@ void ConfigureUi::SetConfiguration() {
ui->theme_combobox->setCurrentIndex(ui->theme_combobox->findData(UISettings::values.theme));
ui->language_combobox->setCurrentIndex(
ui->language_combobox->findData(UISettings::values.language));
- ui->show_add_ons->setChecked(UISettings::values.show_add_ons);
+ ui->show_add_ons->setChecked(UISettings::values.show_add_ons.GetValue());
ui->icon_size_combobox->setCurrentIndex(
- ui->icon_size_combobox->findData(UISettings::values.icon_size));
+ ui->icon_size_combobox->findData(UISettings::values.icon_size.GetValue()));
- ui->enable_screenshot_save_as->setChecked(UISettings::values.enable_screenshot_save_as);
+ ui->enable_screenshot_save_as->setChecked(
+ UISettings::values.enable_screenshot_save_as.GetValue());
ui->screenshot_path_edit->setText(QString::fromStdString(
Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir)));
}
@@ -178,7 +179,7 @@ void ConfigureUi::InitializeRowComboBoxes() {
void ConfigureUi::UpdateFirstRowComboBox(bool init) {
const int currentIndex =
- init ? UISettings::values.row_1_text_id
+ init ? UISettings::values.row_1_text_id.GetValue()
: ui->row_1_text_combobox->findData(ui->row_1_text_combobox->currentData());
ui->row_1_text_combobox->clear();
@@ -197,7 +198,7 @@ void ConfigureUi::UpdateFirstRowComboBox(bool init) {
void ConfigureUi::UpdateSecondRowComboBox(bool init) {
const int currentIndex =
- init ? UISettings::values.row_2_text_id
+ init ? UISettings::values.row_2_text_id.GetValue()
: ui->row_2_text_combobox->findData(ui->row_2_text_combobox->currentData());
ui->row_2_text_combobox->clear();
diff --git a/src/yuzu/configuration/configure_web.cpp b/src/yuzu/configuration/configure_web.cpp
index f3f3b54d6..d779251b4 100644
--- a/src/yuzu/configuration/configure_web.cpp
+++ b/src/yuzu/configuration/configure_web.cpp
@@ -88,22 +88,22 @@ void ConfigureWeb::SetConfiguration() {
ui->web_signup_link->setOpenExternalLinks(true);
ui->web_token_info_link->setOpenExternalLinks(true);
- if (Settings::values.yuzu_username.empty()) {
+ if (Settings::values.yuzu_username.GetValue().empty()) {
ui->username->setText(tr("Unspecified"));
} else {
- ui->username->setText(QString::fromStdString(Settings::values.yuzu_username));
+ ui->username->setText(QString::fromStdString(Settings::values.yuzu_username.GetValue()));
}
- ui->toggle_telemetry->setChecked(Settings::values.enable_telemetry);
- ui->edit_token->setText(QString::fromStdString(
- GenerateDisplayToken(Settings::values.yuzu_username, Settings::values.yuzu_token)));
+ ui->toggle_telemetry->setChecked(Settings::values.enable_telemetry.GetValue());
+ ui->edit_token->setText(QString::fromStdString(GenerateDisplayToken(
+ Settings::values.yuzu_username.GetValue(), Settings::values.yuzu_token.GetValue())));
// Connect after setting the values, to avoid calling OnLoginChanged now
connect(ui->edit_token, &QLineEdit::textChanged, this, &ConfigureWeb::OnLoginChanged);
user_verified = true;
- ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence);
+ ui->toggle_discordrpc->setChecked(UISettings::values.enable_discord_presence.GetValue());
}
void ConfigureWeb::ApplyConfiguration() {
diff --git a/src/yuzu/debugger/console.cpp b/src/yuzu/debugger/console.cpp
index c11a326ac..22ca1285d 100644
--- a/src/yuzu/debugger/console.cpp
+++ b/src/yuzu/debugger/console.cpp
@@ -15,10 +15,10 @@
namespace Debugger {
void ToggleConsole() {
static bool console_shown = false;
- if (console_shown == UISettings::values.show_console) {
+ if (console_shown == UISettings::values.show_console.GetValue()) {
return;
} else {
- console_shown = UISettings::values.show_console;
+ console_shown = UISettings::values.show_console.GetValue();
}
#if defined(_WIN32) && !defined(_DEBUG)
diff --git a/src/yuzu/game_list.cpp b/src/yuzu/game_list.cpp
index e44907be8..f746bd85d 100644
--- a/src/yuzu/game_list.cpp
+++ b/src/yuzu/game_list.cpp
@@ -244,7 +244,8 @@ void GameList::OnUpdateThemedIcons() {
for (int i = 0; i < item_model->invisibleRootItem()->rowCount(); i++) {
QStandardItem* child = item_model->invisibleRootItem()->child(i);
- const int icon_size = std::min(static_cast<int>(UISettings::values.icon_size), 64);
+ const int icon_size =
+ std::min(static_cast<int>(UISettings::values.icon_size.GetValue()), 64);
switch (child->data(GameListItem::TypeRole).value<GameListItemType>()) {
case GameListItemType::SdmcDir:
child->setData(
@@ -403,9 +404,11 @@ void GameList::ValidateEntry(const QModelIndex& item) {
return;
}
+ const auto title_id = selected.data(GameListItemPath::ProgramIdRole).toULongLong();
+
// Users usually want to run a different game after closing one
search_field->clear();
- emit GameChosen(file_path);
+ emit GameChosen(file_path, title_id);
break;
}
case GameListItemType::AddDir:
@@ -517,9 +520,11 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
QMenu* remove_menu = context_menu.addMenu(tr("Remove"));
QAction* remove_update = remove_menu->addAction(tr("Remove Installed Update"));
QAction* remove_dlc = remove_menu->addAction(tr("Remove All Installed DLC"));
- QAction* remove_shader_cache = remove_menu->addAction(tr("Remove Shader Cache"));
QAction* remove_custom_config = remove_menu->addAction(tr("Remove Custom Configuration"));
+ QAction* remove_gl_shader_cache = remove_menu->addAction(tr("Remove OpenGL Shader Cache"));
+ QAction* remove_vk_shader_cache = remove_menu->addAction(tr("Remove Vulkan Shader Cache"));
remove_menu->addSeparator();
+ QAction* remove_shader_cache = remove_menu->addAction(tr("Remove All Shader Caches"));
QAction* remove_all_content = remove_menu->addAction(tr("Remove All Installed Contents"));
QMenu* dump_romfs_menu = context_menu.addMenu(tr("Dump RomFS"));
QAction* dump_romfs = dump_romfs_menu->addAction(tr("Dump RomFS"));
@@ -537,6 +542,8 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
open_transferable_shader_cache->setVisible(program_id != 0);
remove_update->setVisible(program_id != 0);
remove_dlc->setVisible(program_id != 0);
+ remove_gl_shader_cache->setVisible(program_id != 0);
+ remove_vk_shader_cache->setVisible(program_id != 0);
remove_shader_cache->setVisible(program_id != 0);
remove_all_content->setVisible(program_id != 0);
auto it = FindMatchingCompatibilityEntry(compatibility_list, program_id);
@@ -547,10 +554,10 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
emit OpenFolderRequested(program_id, GameListOpenTarget::SaveData, path);
});
connect(start_game, &QAction::triggered, [this, path]() {
- emit BootGame(QString::fromStdString(path), 0, StartGameType::Normal);
+ emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Normal);
});
connect(start_game_global, &QAction::triggered, [this, path]() {
- emit BootGame(QString::fromStdString(path), 0, StartGameType::Global);
+ emit BootGame(QString::fromStdString(path), 0, 0, StartGameType::Global);
});
connect(open_mod_location, &QAction::triggered, [this, program_id, path]() {
emit OpenFolderRequested(program_id, GameListOpenTarget::ModData, path);
@@ -566,8 +573,14 @@ void GameList::AddGamePopup(QMenu& context_menu, u64 program_id, const std::stri
connect(remove_dlc, &QAction::triggered, [this, program_id]() {
emit RemoveInstalledEntryRequested(program_id, InstalledEntryType::AddOnContent);
});
+ connect(remove_gl_shader_cache, &QAction::triggered, [this, program_id, path]() {
+ emit RemoveFileRequested(program_id, GameListRemoveTarget::GlShaderCache, path);
+ });
+ connect(remove_vk_shader_cache, &QAction::triggered, [this, program_id, path]() {
+ emit RemoveFileRequested(program_id, GameListRemoveTarget::VkShaderCache, path);
+ });
connect(remove_shader_cache, &QAction::triggered, [this, program_id, path]() {
- emit RemoveFileRequested(program_id, GameListRemoveTarget::ShaderCache, path);
+ emit RemoveFileRequested(program_id, GameListRemoveTarget::AllShaderCache, path);
});
connect(remove_custom_config, &QAction::triggered, [this, program_id, path]() {
emit RemoveFileRequested(program_id, GameListRemoveTarget::CustomConfiguration, path);
diff --git a/src/yuzu/game_list.h b/src/yuzu/game_list.h
index 50402da51..10339dcca 100644
--- a/src/yuzu/game_list.h
+++ b/src/yuzu/game_list.h
@@ -41,7 +41,9 @@ enum class GameListOpenTarget {
};
enum class GameListRemoveTarget {
- ShaderCache,
+ GlShaderCache,
+ VkShaderCache,
+ AllShaderCache,
CustomConfiguration,
};
@@ -88,8 +90,9 @@ public:
static const QStringList supported_file_extensions;
signals:
- void BootGame(const QString& game_path, std::size_t program_index, StartGameType type);
- void GameChosen(const QString& game_path);
+ void BootGame(const QString& game_path, u64 program_id, std::size_t program_index,
+ StartGameType type);
+ void GameChosen(const QString& game_path, const u64 title_id = 0);
void ShouldCancelWorker();
void OpenFolderRequested(u64 program_id, GameListOpenTarget target,
const std::string& game_path);
diff --git a/src/yuzu/game_list_p.h b/src/yuzu/game_list_p.h
index 978d27325..982c0789d 100644
--- a/src/yuzu/game_list_p.h
+++ b/src/yuzu/game_list_p.h
@@ -80,7 +80,7 @@ public:
setData(qulonglong(program_id), ProgramIdRole);
setData(game_type, FileTypeRole);
- const u32 size = UISettings::values.icon_size;
+ const u32 size = UISettings::values.icon_size.GetValue();
QPixmap picture;
if (!picture.loadFromData(picture_data.data(), static_cast<u32>(picture_data.size()))) {
@@ -108,8 +108,8 @@ public:
data(TitleRole).toString(),
}};
- const auto& row1 = row_data.at(UISettings::values.row_1_text_id);
- const int row2_id = UISettings::values.row_2_text_id;
+ const auto& row1 = row_data.at(UISettings::values.row_1_text_id.GetValue());
+ const int row2_id = UISettings::values.row_2_text_id.GetValue();
if (role == SortRole) {
return row1.toLower();
@@ -233,7 +233,8 @@ public:
UISettings::GameDir* game_dir = &directory;
setData(QVariant(UISettings::values.game_dirs.indexOf(directory)), GameDirRole);
- const int icon_size = std::min(static_cast<int>(UISettings::values.icon_size), 64);
+ const int icon_size =
+ std::min(static_cast<int>(UISettings::values.icon_size.GetValue()), 64);
switch (dir_type) {
case GameListItemType::SdmcDir:
setData(
@@ -294,7 +295,8 @@ public:
explicit GameListAddDir() {
setData(type(), TypeRole);
- const int icon_size = std::min(static_cast<int>(UISettings::values.icon_size), 64);
+ const int icon_size =
+ std::min(static_cast<int>(UISettings::values.icon_size.GetValue()), 64);
setData(QIcon::fromTheme(QStringLiteral("plus"))
.pixmap(icon_size)
.scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
@@ -316,7 +318,8 @@ public:
explicit GameListFavorites() {
setData(type(), TypeRole);
- const int icon_size = std::min(static_cast<int>(UISettings::values.icon_size), 64);
+ const int icon_size =
+ std::min(static_cast<int>(UISettings::values.icon_size.GetValue()), 64);
setData(QIcon::fromTheme(QStringLiteral("star"))
.pixmap(icon_size)
.scaled(icon_size, icon_size, Qt::IgnoreAspectRatio, Qt::SmoothTransformation),
diff --git a/src/yuzu/game_list_worker.cpp b/src/yuzu/game_list_worker.cpp
index 33cc90d5a..2d5492157 100644
--- a/src/yuzu/game_list_worker.cpp
+++ b/src/yuzu/game_list_worker.cpp
@@ -336,18 +336,44 @@ void GameListWorker::ScanFileSystem(ScanTarget target, const std::string& dir_pa
}
}
} else {
- std::vector<u8> icon;
- [[maybe_unused]] const auto res1 = loader->ReadIcon(icon);
+ std::vector<u64> program_ids;
+ loader->ReadProgramIds(program_ids);
+
+ if (res2 == Loader::ResultStatus::Success && program_ids.size() > 1 &&
+ (file_type == Loader::FileType::XCI || file_type == Loader::FileType::NSP)) {
+ for (const auto id : program_ids) {
+ loader = Loader::GetLoader(system, file, id);
+ if (!loader) {
+ continue;
+ }
+
+ std::vector<u8> icon;
+ [[maybe_unused]] const auto res1 = loader->ReadIcon(icon);
- std::string name = " ";
- [[maybe_unused]] const auto res3 = loader->ReadTitle(name);
+ std::string name = " ";
+ [[maybe_unused]] const auto res3 = loader->ReadTitle(name);
- const FileSys::PatchManager patch{program_id, system.GetFileSystemController(),
- system.GetContentProvider()};
+ const FileSys::PatchManager patch{id, system.GetFileSystemController(),
+ system.GetContentProvider()};
+
+ emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, id,
+ compatibility_list, patch),
+ parent_dir);
+ }
+ } else {
+ std::vector<u8> icon;
+ [[maybe_unused]] const auto res1 = loader->ReadIcon(icon);
- emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader, program_id,
- compatibility_list, patch),
- parent_dir);
+ std::string name = " ";
+ [[maybe_unused]] const auto res3 = loader->ReadTitle(name);
+
+ const FileSys::PatchManager patch{program_id, system.GetFileSystemController(),
+ system.GetContentProvider()};
+
+ emit EntryReady(MakeGameListEntry(physical_name, name, icon, *loader,
+ program_id, compatibility_list, patch),
+ parent_dir);
+ }
}
} else if (is_dir) {
watch_list.append(QString::fromStdString(physical_name));
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f462cd072..9544f0fb0 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -11,11 +11,11 @@
#endif
// VFS includes must be before glad as they will conflict with Windows file api, which uses defines.
-#include "applets/controller.h"
-#include "applets/error.h"
-#include "applets/profile_select.h"
-#include "applets/software_keyboard.h"
-#include "applets/web_browser.h"
+#include "applets/qt_controller.h"
+#include "applets/qt_error.h"
+#include "applets/qt_profile_select.h"
+#include "applets/qt_software_keyboard.h"
+#include "applets/qt_web_browser.h"
#include "common/nvidia_flags.h"
#include "configuration/configure_input.h"
#include "configuration/configure_per_game.h"
@@ -156,11 +156,13 @@ enum class CalloutFlag : uint32_t {
};
void GMainWindow::ShowTelemetryCallout() {
- if (UISettings::values.callout_flags & static_cast<uint32_t>(CalloutFlag::Telemetry)) {
+ if (UISettings::values.callout_flags.GetValue() &
+ static_cast<uint32_t>(CalloutFlag::Telemetry)) {
return;
}
- UISettings::values.callout_flags |= static_cast<uint32_t>(CalloutFlag::Telemetry);
+ UISettings::values.callout_flags =
+ UISettings::values.callout_flags.GetValue() | static_cast<uint32_t>(CalloutFlag::Telemetry);
const QString telemetry_message =
tr("<a href='https://yuzu-emu.org/help/feature/telemetry/'>Anonymous "
"data is collected</a> to help improve yuzu. "
@@ -177,7 +179,7 @@ static void InitializeLogging() {
using namespace Common;
Log::Filter log_filter;
- log_filter.ParseFilterString(Settings::values.log_filter);
+ log_filter.ParseFilterString(Settings::values.log_filter.GetValue());
Log::SetGlobalFilter(log_filter);
const auto log_dir = FS::GetYuzuPath(FS::YuzuPath::LogDir);
@@ -216,7 +218,7 @@ GMainWindow::GMainWindow()
default_theme_paths = QIcon::themeSearchPaths();
UpdateUITheme();
- SetDiscordEnabled(UISettings::values.enable_discord_presence);
+ SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue());
discord_rpc->Update();
RegisterMetaTypes();
@@ -787,41 +789,28 @@ void GMainWindow::InitializeWidgets() {
dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
statusBar()->insertPermanentWidget(0, dock_status_button);
- // Setup ASync button
- async_status_button = new QPushButton();
- async_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
- async_status_button->setFocusPolicy(Qt::NoFocus);
- connect(async_status_button, &QPushButton::clicked, [&] {
- if (emulation_running) {
- return;
+ gpu_accuracy_button = new QPushButton();
+ gpu_accuracy_button->setObjectName(QStringLiteral("GPUStatusBarButton"));
+ gpu_accuracy_button->setCheckable(true);
+ gpu_accuracy_button->setFocusPolicy(Qt::NoFocus);
+ connect(gpu_accuracy_button, &QPushButton::clicked, [this] {
+ switch (Settings::values.gpu_accuracy.GetValue()) {
+ case Settings::GPUAccuracy::High: {
+ Settings::values.gpu_accuracy.SetValue(Settings::GPUAccuracy::Normal);
+ break;
+ }
+ case Settings::GPUAccuracy::Normal:
+ case Settings::GPUAccuracy::Extreme:
+ default: {
+ Settings::values.gpu_accuracy.SetValue(Settings::GPUAccuracy::High);
}
- Settings::values.use_asynchronous_gpu_emulation.SetValue(
- !Settings::values.use_asynchronous_gpu_emulation.GetValue());
- async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
- Core::System::GetInstance().ApplySettings();
- });
- async_status_button->setText(tr("ASYNC"));
- async_status_button->setCheckable(true);
- async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
-
- // Setup Multicore button
- multicore_status_button = new QPushButton();
- multicore_status_button->setObjectName(QStringLiteral("TogglableStatusBarButton"));
- multicore_status_button->setFocusPolicy(Qt::NoFocus);
- connect(multicore_status_button, &QPushButton::clicked, [&] {
- if (emulation_running) {
- return;
}
- Settings::values.use_multi_core.SetValue(!Settings::values.use_multi_core.GetValue());
- multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
+
Core::System::GetInstance().ApplySettings();
+ UpdateGPUAccuracyButton();
});
- multicore_status_button->setText(tr("MULTICORE"));
- multicore_status_button->setCheckable(true);
- multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
-
- statusBar()->insertPermanentWidget(0, multicore_status_button);
- statusBar()->insertPermanentWidget(0, async_status_button);
+ UpdateGPUAccuracyButton();
+ statusBar()->insertPermanentWidget(0, gpu_accuracy_button);
// Setup Renderer API button
renderer_status_button = new QPushButton();
@@ -983,23 +972,23 @@ void GMainWindow::InitializeHotkeys() {
});
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Toggle Speed Limit"), this),
&QShortcut::activated, this, [&] {
- Settings::values.use_frame_limit.SetValue(
- !Settings::values.use_frame_limit.GetValue());
+ Settings::values.use_speed_limit.SetValue(
+ !Settings::values.use_speed_limit.GetValue());
UpdateStatusBar();
});
constexpr u16 SPEED_LIMIT_STEP = 5;
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Increase Speed Limit"), this),
&QShortcut::activated, this, [&] {
- if (Settings::values.frame_limit.GetValue() < 9999 - SPEED_LIMIT_STEP) {
- Settings::values.frame_limit.SetValue(SPEED_LIMIT_STEP +
- Settings::values.frame_limit.GetValue());
+ if (Settings::values.speed_limit.GetValue() < 9999 - SPEED_LIMIT_STEP) {
+ Settings::values.speed_limit.SetValue(SPEED_LIMIT_STEP +
+ Settings::values.speed_limit.GetValue());
UpdateStatusBar();
}
});
connect(hotkey_registry.GetHotkey(main_window, QStringLiteral("Decrease Speed Limit"), this),
&QShortcut::activated, this, [&] {
- if (Settings::values.frame_limit.GetValue() > SPEED_LIMIT_STEP) {
- Settings::values.frame_limit.SetValue(Settings::values.frame_limit.GetValue() -
+ if (Settings::values.speed_limit.GetValue() > SPEED_LIMIT_STEP) {
+ Settings::values.speed_limit.SetValue(Settings::values.speed_limit.GetValue() -
SPEED_LIMIT_STEP);
UpdateStatusBar();
}
@@ -1060,23 +1049,24 @@ void GMainWindow::RestoreUIState() {
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
#if MICROPROFILE_ENABLED
microProfileDialog->restoreGeometry(UISettings::values.microprofile_geometry);
- microProfileDialog->setVisible(UISettings::values.microprofile_visible);
+ microProfileDialog->setVisible(UISettings::values.microprofile_visible.GetValue());
#endif
game_list->LoadInterfaceLayout();
- ui.action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode);
+ ui.action_Single_Window_Mode->setChecked(UISettings::values.single_window_mode.GetValue());
ToggleWindowMode();
- ui.action_Fullscreen->setChecked(UISettings::values.fullscreen);
+ ui.action_Fullscreen->setChecked(UISettings::values.fullscreen.GetValue());
- ui.action_Display_Dock_Widget_Headers->setChecked(UISettings::values.display_titlebar);
+ ui.action_Display_Dock_Widget_Headers->setChecked(
+ UISettings::values.display_titlebar.GetValue());
OnDisplayTitleBars(ui.action_Display_Dock_Widget_Headers->isChecked());
- ui.action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar);
+ ui.action_Show_Filter_Bar->setChecked(UISettings::values.show_filter_bar.GetValue());
game_list->SetFilterVisible(ui.action_Show_Filter_Bar->isChecked());
- ui.action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar);
+ ui.action_Show_Status_Bar->setChecked(UISettings::values.show_status_bar.GetValue());
statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked());
Debugger::ToggleConsole();
}
@@ -1218,7 +1208,7 @@ void GMainWindow::AllowOSSleep() {
#endif
}
-bool GMainWindow::LoadROM(const QString& filename, std::size_t program_index) {
+bool GMainWindow::LoadROM(const QString& filename, u64 program_id, std::size_t program_index) {
// Shutdown previous session if the emu thread is still active...
if (emu_thread != nullptr)
ShutdownGame();
@@ -1241,15 +1231,16 @@ bool GMainWindow::LoadROM(const QString& filename, std::size_t program_index) {
});
const Core::System::ResultStatus result{
- system.Load(*render_window, filename.toStdString(), program_index)};
+ system.Load(*render_window, filename.toStdString(), program_id, program_index)};
- const auto drd_callout =
- (UISettings::values.callout_flags & static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0;
+ const auto drd_callout = (UISettings::values.callout_flags.GetValue() &
+ static_cast<u32>(CalloutFlag::DRDDeprecation)) == 0;
if (result == Core::System::ResultStatus::Success &&
system.GetAppLoader().GetFileType() == Loader::FileType::DeconstructedRomDirectory &&
drd_callout) {
- UISettings::values.callout_flags |= static_cast<u32>(CalloutFlag::DRDDeprecation);
+ UISettings::values.callout_flags = UISettings::values.callout_flags.GetValue() |
+ static_cast<u32>(CalloutFlag::DRDDeprecation);
QMessageBox::warning(
this, tr("Warning Outdated Game Format"),
tr("You are using the deconstructed ROM directory format for this game, which is an "
@@ -1327,7 +1318,8 @@ void GMainWindow::SelectAndSetCurrentUser() {
Settings::values.current_user = dialog.GetIndex();
}
-void GMainWindow::BootGame(const QString& filename, std::size_t program_index, StartGameType type) {
+void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t program_index,
+ StartGameType type) {
LOG_INFO(Frontend, "yuzu starting...");
StoreRecentFile(filename); // Put the filename on top of the list
@@ -1337,7 +1329,7 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
auto& system = Core::System::GetInstance();
const auto v_file = Core::GetGameFileFromPath(vfs, filename.toUtf8().constData());
- const auto loader = Loader::GetLoader(system, v_file, program_index);
+ const auto loader = Loader::GetLoader(system, v_file, program_id, program_index);
if (loader != nullptr && loader->ReadProgramId(title_id) == Loader::ResultStatus::Success &&
type == StartGameType::Normal) {
@@ -1351,6 +1343,9 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
ConfigureVibration::SetAllVibrationDevices();
+ // Disable fps limit toggle when booting a new title
+ Settings::values.disable_fps_limit.SetValue(false);
+
// Save configurations
UpdateUISettings();
game_list->SaveInterfaceLayout();
@@ -1362,7 +1357,7 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
SelectAndSetCurrentUser();
}
- if (!LoadROM(filename, program_index))
+ if (!LoadROM(filename, program_id, program_index))
return;
// Create and start the emulation thread
@@ -1393,8 +1388,6 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
game_list_placeholder->hide();
}
status_bar_update_timer.start(500);
- async_status_button->setDisabled(true);
- multicore_status_button->setDisabled(true);
renderer_status_button->setDisabled(true);
if (UISettings::values.hide_mouse || Settings::values.mouse_panning) {
@@ -1424,8 +1417,10 @@ void GMainWindow::BootGame(const QString& filename, std::size_t program_index, S
std::filesystem::path{filename.toStdU16String()}.filename());
}
const bool is_64bit = system.Kernel().CurrentProcess()->Is64BitProcess();
- const auto instruction_set_suffix = is_64bit ? " (64-bit)" : " (32-bit)";
- title_name += instruction_set_suffix;
+ const auto instruction_set_suffix = is_64bit ? tr("(64-bit)") : tr("(32-bit)");
+ title_name = tr("%1 %2", "%1 is the title name. %2 indicates if the title is 64-bit or 32-bit")
+ .arg(QString::fromStdString(title_name), instruction_set_suffix)
+ .toStdString();
LOG_INFO(Frontend, "Booting game: {:016X} | {} | {}", title_id, title_name, title_version);
const auto gpu_vendor = system.GPU().Renderer().GetDeviceVendor();
UpdateWindowTitle(title_name, title_version, gpu_vendor);
@@ -1496,8 +1491,6 @@ void GMainWindow::ShutdownGame() {
emu_speed_label->setVisible(false);
game_fps_label->setVisible(false);
emu_frametime_label->setVisible(false);
- async_status_button->setEnabled(true);
- multicore_status_button->setEnabled(true);
renderer_status_button->setEnabled(true);
emulation_running = false;
@@ -1539,8 +1532,8 @@ void GMainWindow::UpdateRecentFiles() {
ui.menu_recent_files->setEnabled(num_recent_files != 0);
}
-void GMainWindow::OnGameListLoadFile(QString game_path) {
- BootGame(game_path);
+void GMainWindow::OnGameListLoadFile(QString game_path, u64 program_id) {
+ BootGame(game_path, program_id);
}
void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target,
@@ -1644,35 +1637,15 @@ void GMainWindow::OnGameListOpenFolder(u64 program_id, GameListOpenTarget target
void GMainWindow::OnTransferableShaderCacheOpenFile(u64 program_id) {
const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir);
- const auto transferable_shader_cache_folder_path = shader_cache_dir / "opengl" / "transferable";
- const auto transferable_shader_cache_file_path =
- transferable_shader_cache_folder_path / fmt::format("{:016X}.bin", program_id);
-
- if (!Common::FS::Exists(transferable_shader_cache_file_path)) {
+ const auto shader_cache_folder_path{shader_cache_dir / fmt::format("{:016x}", program_id)};
+ if (!Common::FS::CreateDirs(shader_cache_folder_path)) {
QMessageBox::warning(this, tr("Error Opening Transferable Shader Cache"),
- tr("A shader cache for this title does not exist."));
+ tr("Filed to create the shader cache directory for this title."));
return;
}
-
- const auto qt_shader_cache_folder_path =
- QString::fromStdString(Common::FS::PathToUTF8String(transferable_shader_cache_folder_path));
- const auto qt_shader_cache_file_path =
- QString::fromStdString(Common::FS::PathToUTF8String(transferable_shader_cache_file_path));
-
- // Windows supports opening a folder with selecting a specified file in explorer. On every other
- // OS we just open the transferable shader cache folder without preselecting the transferable
- // shader cache file for the selected game.
-#if defined(Q_OS_WIN)
- const QString explorer = QStringLiteral("explorer");
- QStringList param;
- if (!QFileInfo(qt_shader_cache_file_path).isDir()) {
- param << QStringLiteral("/select,");
- }
- param << QDir::toNativeSeparators(qt_shader_cache_file_path);
- QProcess::startDetached(explorer, param);
-#else
- QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_folder_path));
-#endif
+ const auto shader_path_string{Common::FS::PathToUTF8String(shader_cache_folder_path)};
+ const auto qt_shader_cache_path = QString::fromStdString(shader_path_string);
+ QDesktopServices::openUrl(QUrl::fromLocalFile(qt_shader_cache_path));
}
static std::size_t CalculateRomFSEntrySize(const FileSys::VirtualDir& dir, bool full) {
@@ -1815,8 +1788,12 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ
const std::string& game_path) {
const QString question = [this, target] {
switch (target) {
- case GameListRemoveTarget::ShaderCache:
- return tr("Delete Transferable Shader Cache?");
+ case GameListRemoveTarget::GlShaderCache:
+ return tr("Delete OpenGL Transferable Shader Cache?");
+ case GameListRemoveTarget::VkShaderCache:
+ return tr("Delete Vulkan Transferable Shader Cache?");
+ case GameListRemoveTarget::AllShaderCache:
+ return tr("Delete All Transferable Shader Caches?");
case GameListRemoveTarget::CustomConfiguration:
return tr("Remove Custom Game Configuration?");
default:
@@ -1830,8 +1807,12 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ
}
switch (target) {
- case GameListRemoveTarget::ShaderCache:
- RemoveTransferableShaderCache(program_id);
+ case GameListRemoveTarget::GlShaderCache:
+ case GameListRemoveTarget::VkShaderCache:
+ RemoveTransferableShaderCache(program_id, target);
+ break;
+ case GameListRemoveTarget::AllShaderCache:
+ RemoveAllTransferableShaderCaches(program_id);
break;
case GameListRemoveTarget::CustomConfiguration:
RemoveCustomConfiguration(program_id, game_path);
@@ -1839,18 +1820,27 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ
}
}
-void GMainWindow::RemoveTransferableShaderCache(u64 program_id) {
+void GMainWindow::RemoveTransferableShaderCache(u64 program_id, GameListRemoveTarget target) {
+ const auto target_file_name = [target] {
+ switch (target) {
+ case GameListRemoveTarget::GlShaderCache:
+ return "opengl.bin";
+ case GameListRemoveTarget::VkShaderCache:
+ return "vulkan.bin";
+ default:
+ return "";
+ }
+ }();
const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir);
- const auto transferable_shader_cache_file_path =
- shader_cache_dir / "opengl" / "transferable" / fmt::format("{:016X}.bin", program_id);
+ const auto shader_cache_folder_path = shader_cache_dir / fmt::format("{:016x}", program_id);
+ const auto target_file = shader_cache_folder_path / target_file_name;
- if (!Common::FS::Exists(transferable_shader_cache_file_path)) {
+ if (!Common::FS::Exists(target_file)) {
QMessageBox::warning(this, tr("Error Removing Transferable Shader Cache"),
tr("A shader cache for this title does not exist."));
return;
}
-
- if (Common::FS::RemoveFile(transferable_shader_cache_file_path)) {
+ if (Common::FS::RemoveFile(target_file)) {
QMessageBox::information(this, tr("Successfully Removed"),
tr("Successfully removed the transferable shader cache."));
} else {
@@ -1859,6 +1849,24 @@ void GMainWindow::RemoveTransferableShaderCache(u64 program_id) {
}
}
+void GMainWindow::RemoveAllTransferableShaderCaches(u64 program_id) {
+ const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir);
+ const auto program_shader_cache_dir = shader_cache_dir / fmt::format("{:016x}", program_id);
+
+ if (!Common::FS::Exists(program_shader_cache_dir)) {
+ QMessageBox::warning(this, tr("Error Removing Transferable Shader Caches"),
+ tr("A shader cache for this title does not exist."));
+ return;
+ }
+ if (Common::FS::RemoveDirRecursively(program_shader_cache_dir)) {
+ QMessageBox::information(this, tr("Successfully Removed"),
+ tr("Successfully removed the transferable shader caches."));
+ } else {
+ QMessageBox::warning(this, tr("Error Removing Transferable Shader Caches"),
+ tr("Failed to remove the transferable shader cache directory."));
+ }
+}
+
void GMainWindow::RemoveCustomConfiguration(u64 program_id, const std::string& game_path) {
const auto file_path = std::filesystem::path(Common::FS::ToU8String(game_path));
const auto config_file_name =
@@ -2441,7 +2449,7 @@ void GMainWindow::OnLoadComplete() {
void GMainWindow::OnExecuteProgram(std::size_t program_index) {
ShutdownGame();
- BootGame(last_filename_booted, program_index);
+ BootGame(last_filename_booted, 0, program_index);
}
void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_text) {
@@ -2453,7 +2461,8 @@ void GMainWindow::ErrorDisplayDisplayError(QString error_code, QString error_tex
}
void GMainWindow::OnMenuReportCompatibility() {
- if (!Settings::values.yuzu_token.empty() && !Settings::values.yuzu_username.empty()) {
+ if (!Settings::values.yuzu_token.GetValue().empty() &&
+ !Settings::values.yuzu_username.GetValue().empty()) {
CompatDB compatdb{this};
compatdb.exec();
} else {
@@ -2504,7 +2513,7 @@ void GMainWindow::ShowFullscreen() {
ui.menubar->hide();
statusBar()->hide();
- if (Settings::values.fullscreen_mode.GetValue() == 1) {
+ if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) {
showFullScreen();
return;
}
@@ -2519,7 +2528,7 @@ void GMainWindow::ShowFullscreen() {
} else {
UISettings::values.renderwindow_geometry = render_window->saveGeometry();
- if (Settings::values.fullscreen_mode.GetValue() == 1) {
+ if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) {
render_window->showFullScreen();
return;
}
@@ -2536,7 +2545,7 @@ void GMainWindow::ShowFullscreen() {
void GMainWindow::HideFullscreen() {
if (ui.action_Single_Window_Mode->isChecked()) {
- if (Settings::values.fullscreen_mode.GetValue() == 1) {
+ if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) {
showNormal();
restoreGeometry(UISettings::values.geometry);
} else {
@@ -2550,7 +2559,7 @@ void GMainWindow::HideFullscreen() {
statusBar()->setVisible(ui.action_Show_Status_Bar->isChecked());
ui.menubar->show();
} else {
- if (Settings::values.fullscreen_mode.GetValue() == 1) {
+ if (Settings::values.fullscreen_mode.GetValue() == Settings::FullscreenMode::Exclusive) {
render_window->showNormal();
render_window->restoreGeometry(UISettings::values.renderwindow_geometry);
} else {
@@ -2618,7 +2627,7 @@ void GMainWindow::ResetWindowSize1080() {
void GMainWindow::OnConfigure() {
const auto old_theme = UISettings::values.theme;
- const bool old_discord_presence = UISettings::values.enable_discord_presence;
+ const bool old_discord_presence = UISettings::values.enable_discord_presence.GetValue();
ConfigureDialog configure_dialog(this, hotkey_registry, input_subsystem.get());
connect(&configure_dialog, &ConfigureDialog::LanguageChanged, this,
@@ -2675,8 +2684,8 @@ void GMainWindow::OnConfigure() {
if (UISettings::values.theme != old_theme) {
UpdateUITheme();
}
- if (UISettings::values.enable_discord_presence != old_discord_presence) {
- SetDiscordEnabled(UISettings::values.enable_discord_presence);
+ if (UISettings::values.enable_discord_presence.GetValue() != old_discord_presence) {
+ SetDiscordEnabled(UISettings::values.enable_discord_presence.GetValue());
}
emit UpdateThemedIcons();
@@ -2812,7 +2821,7 @@ void GMainWindow::OnCaptureScreenshot() {
QString::fromStdString(Common::FS::GetYuzuPathString(Common::FS::YuzuPath::ScreenshotsDir));
const auto date =
QDateTime::currentDateTime().toString(QStringLiteral("yyyy-MM-dd_hh-mm-ss-zzz"));
- QString filename = QStringLiteral("%1%2_%3.png")
+ QString filename = QStringLiteral("%1/%2_%3.png")
.arg(screenshot_path)
.arg(title_id, 16, 16, QLatin1Char{'0'})
.arg(date);
@@ -2832,7 +2841,8 @@ void GMainWindow::OnCaptureScreenshot() {
}
}
#endif
- render_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor, filename);
+ render_window->CaptureScreenshot(UISettings::values.screenshot_resolution_factor.GetValue(),
+ filename);
OnStartGame();
}
@@ -2888,26 +2898,31 @@ void GMainWindow::UpdateStatusBar() {
return;
}
- auto results = Core::System::GetInstance().GetAndResetPerfStats();
- auto& shader_notify = Core::System::GetInstance().GPU().ShaderNotify();
- const auto shaders_building = shader_notify.GetShadersBuilding();
+ auto& system = Core::System::GetInstance();
+ auto results = system.GetAndResetPerfStats();
+ auto& shader_notify = system.GPU().ShaderNotify();
+ const int shaders_building = shader_notify.ShadersBuilding();
- if (shaders_building != 0) {
- shader_building_label->setText(
- tr("Building: %n shader(s)", "", static_cast<int>(shaders_building)));
+ if (shaders_building > 0) {
+ shader_building_label->setText(tr("Building: %n shader(s)", "", shaders_building));
shader_building_label->setVisible(true);
} else {
shader_building_label->setVisible(false);
}
- if (Settings::values.use_frame_limit.GetValue()) {
+ if (Settings::values.use_speed_limit.GetValue()) {
emu_speed_label->setText(tr("Speed: %1% / %2%")
.arg(results.emulation_speed * 100.0, 0, 'f', 0)
- .arg(Settings::values.frame_limit.GetValue()));
+ .arg(Settings::values.speed_limit.GetValue()));
} else {
emu_speed_label->setText(tr("Speed: %1%").arg(results.emulation_speed * 100.0, 0, 'f', 0));
}
- game_fps_label->setText(tr("Game: %1 FPS").arg(results.average_game_fps, 0, 'f', 0));
+ if (Settings::values.disable_fps_limit) {
+ game_fps_label->setText(
+ tr("Game: %1 FPS (Unlocked)").arg(results.average_game_fps, 0, 'f', 0));
+ } else {
+ game_fps_label->setText(tr("Game: %1 FPS").arg(results.average_game_fps, 0, 'f', 0));
+ }
emu_frametime_label->setText(tr("Frame: %1 ms").arg(results.frametime * 1000.0, 0, 'f', 2));
emu_speed_label->setVisible(!Settings::values.use_multi_core.GetValue());
@@ -2915,12 +2930,35 @@ void GMainWindow::UpdateStatusBar() {
emu_frametime_label->setVisible(true);
}
+void GMainWindow::UpdateGPUAccuracyButton() {
+ switch (Settings::values.gpu_accuracy.GetValue()) {
+ case Settings::GPUAccuracy::Normal: {
+ gpu_accuracy_button->setText(tr("GPU NORMAL"));
+ gpu_accuracy_button->setChecked(false);
+ break;
+ }
+ case Settings::GPUAccuracy::High: {
+ gpu_accuracy_button->setText(tr("GPU HIGH"));
+ gpu_accuracy_button->setChecked(true);
+ break;
+ }
+ case Settings::GPUAccuracy::Extreme: {
+ gpu_accuracy_button->setText(tr("GPU EXTREME"));
+ gpu_accuracy_button->setChecked(true);
+ break;
+ }
+ default: {
+ gpu_accuracy_button->setText(tr("GPU ERROR"));
+ gpu_accuracy_button->setChecked(true);
+ }
+ }
+}
+
void GMainWindow::UpdateStatusButtons() {
dock_status_button->setChecked(Settings::values.use_docked_mode.GetValue());
- multicore_status_button->setChecked(Settings::values.use_multi_core.GetValue());
- async_status_button->setChecked(Settings::values.use_asynchronous_gpu_emulation.GetValue());
renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() ==
Settings::RendererBackend::Vulkan);
+ UpdateGPUAccuracyButton();
}
void GMainWindow::UpdateUISettings() {
diff --git a/src/yuzu/main.h b/src/yuzu/main.h
index 45c8310e1..38e66ccd0 100644
--- a/src/yuzu/main.h
+++ b/src/yuzu/main.h
@@ -186,8 +186,8 @@ private:
void PreventOSSleep();
void AllowOSSleep();
- bool LoadROM(const QString& filename, std::size_t program_index);
- void BootGame(const QString& filename, std::size_t program_index = 0,
+ bool LoadROM(const QString& filename, u64 program_id, std::size_t program_index);
+ void BootGame(const QString& filename, u64 program_id = 0, std::size_t program_index = 0,
StartGameType with_config = StartGameType::Normal);
void ShutdownGame();
@@ -238,7 +238,7 @@ private slots:
void OnOpenQuickstartGuide();
void OnOpenFAQ();
/// Called whenever a user selects a game in the game list widget.
- void OnGameListLoadFile(QString game_path);
+ void OnGameListLoadFile(QString game_path, u64 program_id);
void OnGameListOpenFolder(u64 program_id, GameListOpenTarget target,
const std::string& game_path);
void OnTransferableShaderCacheOpenFile(u64 program_id);
@@ -282,7 +282,8 @@ private:
void RemoveBaseContent(u64 program_id, const QString& entry_type);
void RemoveUpdateContent(u64 program_id, const QString& entry_type);
void RemoveAddOnContent(u64 program_id, const QString& entry_type);
- void RemoveTransferableShaderCache(u64 program_id);
+ void RemoveTransferableShaderCache(u64 program_id, GameListRemoveTarget target);
+ void RemoveAllTransferableShaderCaches(u64 program_id);
void RemoveCustomConfiguration(u64 program_id, const std::string& game_path);
std::optional<u64> SelectRomFSDumpTarget(const FileSys::ContentProvider&, u64 program_id);
InstallResult InstallNSPXCI(const QString& filename);
@@ -291,6 +292,7 @@ private:
void UpdateWindowTitle(std::string_view title_name = {}, std::string_view title_version = {},
std::string_view gpu_vendor = {});
void UpdateStatusBar();
+ void UpdateGPUAccuracyButton();
void UpdateStatusButtons();
void UpdateUISettings();
void HideMouseCursor();
@@ -316,8 +318,7 @@ private:
QLabel* emu_speed_label = nullptr;
QLabel* game_fps_label = nullptr;
QLabel* emu_frametime_label = nullptr;
- QPushButton* async_status_button = nullptr;
- QPushButton* multicore_status_button = nullptr;
+ QPushButton* gpu_accuracy_button = nullptr;
QPushButton* renderer_status_button = nullptr;
QPushButton* dock_status_button = nullptr;
QTimer status_bar_update_timer;
diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h
index cdcb83f9f..7b9d2dd53 100644
--- a/src/yuzu/uisettings.h
+++ b/src/yuzu/uisettings.h
@@ -13,6 +13,7 @@
#include <QStringList>
#include <QVector>
#include "common/common_types.h"
+#include "common/settings.h"
namespace UISettings {
@@ -48,26 +49,26 @@ struct Values {
QByteArray gamelist_header_state;
QByteArray microprofile_geometry;
- bool microprofile_visible;
+ Settings::BasicSetting<bool> microprofile_visible{false, "microProfileDialogVisible"};
- bool single_window_mode;
- bool fullscreen;
- bool display_titlebar;
- bool show_filter_bar;
- bool show_status_bar;
+ Settings::BasicSetting<bool> single_window_mode{true, "singleWindowMode"};
+ Settings::BasicSetting<bool> fullscreen{false, "fullscreen"};
+ Settings::BasicSetting<bool> display_titlebar{true, "displayTitleBars"};
+ Settings::BasicSetting<bool> show_filter_bar{true, "showFilterBar"};
+ Settings::BasicSetting<bool> show_status_bar{true, "showStatusBar"};
- bool confirm_before_closing;
- bool first_start;
- bool pause_when_in_background;
- bool hide_mouse;
+ Settings::BasicSetting<bool> confirm_before_closing{true, "confirmClose"};
+ Settings::BasicSetting<bool> first_start{true, "firstStart"};
+ Settings::BasicSetting<bool> pause_when_in_background{false, "pauseWhenInBackground"};
+ Settings::BasicSetting<bool> hide_mouse{false, "hideInactiveMouse"};
- bool select_user_on_boot;
+ Settings::BasicSetting<bool> select_user_on_boot{false, "select_user_on_boot"};
// Discord RPC
- bool enable_discord_presence;
+ Settings::BasicSetting<bool> enable_discord_presence{true, "enable_discord_presence"};
- bool enable_screenshot_save_as;
- u16 screenshot_resolution_factor;
+ Settings::BasicSetting<bool> enable_screenshot_save_as{true, "enable_screenshot_save_as"};
+ Settings::BasicSetting<u16> screenshot_resolution_factor{0, "screenshot_resolution_factor"};
QString roms_path;
QString symbols_path;
@@ -83,18 +84,18 @@ struct Values {
// Shortcut name <Shortcut, context>
std::vector<Shortcut> shortcuts;
- uint32_t callout_flags;
+ Settings::BasicSetting<uint32_t> callout_flags{0, "calloutFlags"};
// logging
- bool show_console;
+ Settings::BasicSetting<bool> show_console{false, "showConsole"};
// Game List
- bool show_add_ons;
- uint32_t icon_size;
- uint8_t row_1_text_id;
- uint8_t row_2_text_id;
+ Settings::BasicSetting<bool> show_add_ons{true, "show_add_ons"};
+ Settings::BasicSetting<uint32_t> icon_size{64, "icon_size"};
+ Settings::BasicSetting<uint8_t> row_1_text_id{3, "row_1_text_id"};
+ Settings::BasicSetting<uint8_t> row_2_text_id{2, "row_2_text_id"};
std::atomic_bool is_game_list_reload_pending{false};
- bool cache_game_list;
+ Settings::BasicSetting<bool> cache_game_list{true, "cache_game_list"};
bool configuration_applied;
bool reset_to_defaults;