diff options
Diffstat (limited to 'src/yuzu')
-rw-r--r-- | src/yuzu/Info.plist | 2 | ||||
-rw-r--r-- | src/yuzu/bootmanager.cpp | 19 | ||||
-rw-r--r-- | src/yuzu/bootmanager.h | 4 | ||||
-rw-r--r-- | src/yuzu/configuration/config.cpp | 55 | ||||
-rw-r--r-- | src/yuzu/configuration/configuration_shared.cpp | 10 | ||||
-rw-r--r-- | src/yuzu/configuration/configuration_shared.h | 3 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_graphics.ui | 15 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_graphics_advanced.cpp | 22 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_graphics_advanced.h | 2 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_graphics_advanced.ui | 20 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_input_player.cpp | 6 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_input_player.h | 3 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_system.cpp | 10 | ||||
-rw-r--r-- | src/yuzu/configuration/configure_system.h | 6 | ||||
-rw-r--r-- | src/yuzu/hotkeys.cpp | 6 | ||||
-rw-r--r-- | src/yuzu/hotkeys.h | 1 | ||||
-rw-r--r-- | src/yuzu/main.cpp | 57 | ||||
-rw-r--r-- | src/yuzu/main.h | 5 | ||||
-rw-r--r-- | src/yuzu/uisettings.h | 1 |
19 files changed, 203 insertions, 44 deletions
diff --git a/src/yuzu/Info.plist b/src/yuzu/Info.plist index 0eb377926..f05f3186c 100644 --- a/src/yuzu/Info.plist +++ b/src/yuzu/Info.plist @@ -34,6 +34,8 @@ SPDX-License-Identifier: GPL-2.0-or-later <string></string> <key>CSResourcesFileMapped</key> <true/> + <key>LSApplicationCategoryType</key> + <string>public.app-category.games</string> <key>LSRequiresCarbon</key> <true/> <key>NSHumanReadableCopyright</key> diff --git a/src/yuzu/bootmanager.cpp b/src/yuzu/bootmanager.cpp index 3d560f303..d65991734 100644 --- a/src/yuzu/bootmanager.cpp +++ b/src/yuzu/bootmanager.cpp @@ -96,9 +96,9 @@ void EmuThread::run() { m_is_running.store(false); m_is_running.notify_all(); - emit DebugModeEntered(); + EmulationPaused(lk); Common::CondvarWait(m_should_run_cv, lk, stop_token, [&] { return m_should_run; }); - emit DebugModeLeft(); + EmulationResumed(lk); } } @@ -111,6 +111,21 @@ void EmuThread::run() { #endif } +// Unlock while emitting signals so that the main thread can +// continue pumping events. + +void EmuThread::EmulationPaused(std::unique_lock<std::mutex>& lk) { + lk.unlock(); + emit DebugModeEntered(); + lk.lock(); +} + +void EmuThread::EmulationResumed(std::unique_lock<std::mutex>& lk) { + lk.unlock(); + emit DebugModeLeft(); + lk.lock(); +} + #ifdef HAS_OPENGL class OpenGLSharedContext : public Core::Frontend::GraphicsContext { public: diff --git a/src/yuzu/bootmanager.h b/src/yuzu/bootmanager.h index eca16b313..092c6206f 100644 --- a/src/yuzu/bootmanager.h +++ b/src/yuzu/bootmanager.h @@ -92,6 +92,10 @@ public: } private: + void EmulationPaused(std::unique_lock<std::mutex>& lk); + void EmulationResumed(std::unique_lock<std::mutex>& lk); + +private: Core::System& m_system; std::stop_source m_stop_source; diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index e9425b5bd..fd3bb30e1 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp @@ -70,28 +70,28 @@ const std::array<int, 2> Config::default_ringcon_analogs{{ // UISetting::values.shortcuts, which is alphabetically ordered. // clang-format off const std::array<UISettings::Shortcut, 22> Config::default_hotkeys{{ - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("="), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change GPU Accuracy")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F9"), QStringLiteral("Home+R"), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Continue/Pause Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F4"), QStringLiteral("Home+Plus"), Qt::WindowShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Esc"), QStringLiteral(""), Qt::WindowShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit yuzu")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+Q"), QStringLiteral("Home+Minus"), Qt::WindowShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F6"), QStringLiteral(""), Qt::WindowShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F5"), QStringLiteral(""), Qt::WindowShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Filter Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F"), QStringLiteral(""), Qt::WindowShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Framerate Limit")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+U"), QStringLiteral("Home+Y"), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Mouse Panning")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F9"), QStringLiteral(""), Qt::ApplicationShortcut}}, - {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Status Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+S"), QStringLiteral(""), Qt::WindowShortcut}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Mute/Unmute")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+M"), QStringLiteral("Home+Dpad_Right"), Qt::WindowShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Down")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("-"), QStringLiteral("Home+Dpad_Down"), Qt::ApplicationShortcut, true}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Audio Volume Up")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("="), QStringLiteral("Home+Dpad_Up"), Qt::ApplicationShortcut, true}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Capture Screenshot")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+P"), QStringLiteral("Screenshot"), Qt::WidgetWithChildrenShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Adapting Filter")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F8"), QStringLiteral("Home+L"), Qt::ApplicationShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change Docked Mode")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F10"), QStringLiteral("Home+X"), Qt::ApplicationShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Change GPU Accuracy")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F9"), QStringLiteral("Home+R"), Qt::ApplicationShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Continue/Pause Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F4"), QStringLiteral("Home+Plus"), Qt::WindowShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Esc"), QStringLiteral(""), Qt::WindowShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Exit yuzu")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+Q"), QStringLiteral("Home+Minus"), Qt::WindowShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Fullscreen")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F11"), QStringLiteral("Home+B"), Qt::WindowShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load File")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+O"), QStringLiteral(""), Qt::WidgetWithChildrenShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Load/Remove Amiibo")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F2"), QStringLiteral("Home+A"), Qt::WidgetWithChildrenShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Restart Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F6"), QStringLiteral(""), Qt::WindowShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Stop Emulation")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("F5"), QStringLiteral(""), Qt::WindowShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Record")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F7"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Reset")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F6"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "TAS Start/Stop")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F5"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Filter Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F"), QStringLiteral(""), Qt::WindowShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Framerate Limit")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+U"), QStringLiteral("Home+Y"), Qt::ApplicationShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Mouse Panning")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+F9"), QStringLiteral(""), Qt::ApplicationShortcut, false}}, + {QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Toggle Status Bar")), QStringLiteral(QT_TRANSLATE_NOOP("Hotkeys", "Main Window")), {QStringLiteral("Ctrl+S"), QStringLiteral(""), Qt::WindowShortcut, false}}, }}; // clang-format on @@ -690,6 +690,7 @@ void Config::ReadRendererValues() { qt_config->beginGroup(QStringLiteral("Renderer")); ReadGlobalSetting(Settings::values.renderer_backend); + ReadGlobalSetting(Settings::values.renderer_force_max_clock); ReadGlobalSetting(Settings::values.vulkan_device); ReadGlobalSetting(Settings::values.fullscreen_mode); ReadGlobalSetting(Settings::values.aspect_ratio); @@ -709,6 +710,7 @@ void Config::ReadRendererValues() { ReadGlobalSetting(Settings::values.use_asynchronous_shaders); ReadGlobalSetting(Settings::values.use_fast_gpu_time); ReadGlobalSetting(Settings::values.use_pessimistic_flushes); + ReadGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); ReadGlobalSetting(Settings::values.bg_red); ReadGlobalSetting(Settings::values.bg_green); ReadGlobalSetting(Settings::values.bg_blue); @@ -745,7 +747,7 @@ void Config::ReadShortcutValues() { for (const auto& [name, group, shortcut] : default_hotkeys) { qt_config->beginGroup(group); qt_config->beginGroup(name); - // No longer using ReadSetting for shortcut.second as it innacurately returns a value of 1 + // No longer using ReadSetting for shortcut.second as it inaccurately returns a value of 1 // for WidgetWithChildrenShortcut which is a value of 3. Needed to fix shortcuts the open // a file dialog in windowed mode UISettings::values.shortcuts.push_back( @@ -754,7 +756,7 @@ void Config::ReadShortcutValues() { {ReadSetting(QStringLiteral("KeySeq"), shortcut.keyseq).toString(), ReadSetting(QStringLiteral("Controller_KeySeq"), shortcut.controller_keyseq) .toString(), - shortcut.context}}); + shortcut.context, ReadSetting(QStringLiteral("Repeat"), shortcut.repeat).toBool()}}); qt_config->endGroup(); qt_config->endGroup(); } @@ -1305,6 +1307,9 @@ void Config::SaveRendererValues() { static_cast<u32>(Settings::values.renderer_backend.GetValue(global)), static_cast<u32>(Settings::values.renderer_backend.GetDefault()), Settings::values.renderer_backend.UsingGlobal()); + WriteSetting(QString::fromStdString(Settings::values.renderer_force_max_clock.GetLabel()), + static_cast<u32>(Settings::values.renderer_force_max_clock.GetValue(global)), + static_cast<u32>(Settings::values.renderer_force_max_clock.GetDefault())); WriteGlobalSetting(Settings::values.vulkan_device); WriteSetting(QString::fromStdString(Settings::values.fullscreen_mode.GetLabel()), static_cast<u32>(Settings::values.fullscreen_mode.GetValue(global)), @@ -1348,6 +1353,7 @@ void Config::SaveRendererValues() { WriteGlobalSetting(Settings::values.use_asynchronous_shaders); WriteGlobalSetting(Settings::values.use_fast_gpu_time); WriteGlobalSetting(Settings::values.use_pessimistic_flushes); + WriteGlobalSetting(Settings::values.use_vulkan_driver_pipeline_cache); WriteGlobalSetting(Settings::values.bg_red); WriteGlobalSetting(Settings::values.bg_green); WriteGlobalSetting(Settings::values.bg_blue); @@ -1387,6 +1393,7 @@ void Config::SaveShortcutValues() { WriteSetting(QStringLiteral("Controller_KeySeq"), shortcut.controller_keyseq, default_hotkey.controller_keyseq); WriteSetting(QStringLiteral("Context"), shortcut.context, default_hotkey.context); + WriteSetting(QStringLiteral("Repeat"), shortcut.repeat, default_hotkey.repeat); qt_config->endGroup(); qt_config->endGroup(); } diff --git a/src/yuzu/configuration/configuration_shared.cpp b/src/yuzu/configuration/configuration_shared.cpp index 97fb664bf..ac42cc7fc 100644 --- a/src/yuzu/configuration/configuration_shared.cpp +++ b/src/yuzu/configuration/configuration_shared.cpp @@ -92,3 +92,13 @@ void ConfigurationShared::InsertGlobalItem(QComboBox* combobox, int global_index combobox->insertItem(ConfigurationShared::USE_GLOBAL_INDEX, use_global_text); combobox->insertSeparator(ConfigurationShared::USE_GLOBAL_SEPARATOR_INDEX); } + +int ConfigurationShared::GetComboboxIndex(int global_setting_index, const QComboBox* combobox) { + if (Settings::IsConfiguringGlobal()) { + return combobox->currentIndex(); + } + if (combobox->currentIndex() == ConfigurationShared::USE_GLOBAL_INDEX) { + return global_setting_index; + } + return combobox->currentIndex() - ConfigurationShared::USE_GLOBAL_OFFSET; +} diff --git a/src/yuzu/configuration/configuration_shared.h b/src/yuzu/configuration/configuration_shared.h index e597dcdb5..04c88758c 100644 --- a/src/yuzu/configuration/configuration_shared.h +++ b/src/yuzu/configuration/configuration_shared.h @@ -69,4 +69,7 @@ void SetColoredComboBox(QComboBox* combobox, QWidget* target, int global); // Adds the "Use Global Configuration" selection and separator to the beginning of a QComboBox void InsertGlobalItem(QComboBox* combobox, int global_index); +// Returns the correct index of a QComboBox taking into account global configuration +int GetComboboxIndex(int global_setting_index, const QComboBox* combobox); + } // namespace ConfigurationShared diff --git a/src/yuzu/configuration/configure_graphics.ui b/src/yuzu/configuration/configure_graphics.ui index aa02cc63c..bb9910a53 100644 --- a/src/yuzu/configuration/configure_graphics.ui +++ b/src/yuzu/configuration/configure_graphics.ui @@ -366,6 +366,11 @@ </item> <item> <property name="text"> + <string>1.5X (1080p/1620p) [EXPERIMENTAL]</string> + </property> + </item> + <item> + <property name="text"> <string>2X (1440p/2160p)</string> </property> </item> @@ -389,6 +394,16 @@ <string>6X (4320p/6480p)</string> </property> </item> + <item> + <property name="text"> + <string>7X (5040p/7560p)</string> + </property> + </item> + <item> + <property name="text"> + <string>8X (5760p/8640p)</string> + </property> + </item> </widget> </item> </layout> diff --git a/src/yuzu/configuration/configure_graphics_advanced.cpp b/src/yuzu/configuration/configure_graphics_advanced.cpp index 01f074699..cc0155a2c 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.cpp +++ b/src/yuzu/configuration/configure_graphics_advanced.cpp @@ -22,13 +22,17 @@ ConfigureGraphicsAdvanced::~ConfigureGraphicsAdvanced() = default; void ConfigureGraphicsAdvanced::SetConfiguration() { const bool runtime_lock = !system.IsPoweredOn(); ui->use_vsync->setEnabled(runtime_lock); + ui->renderer_force_max_clock->setEnabled(runtime_lock); ui->use_asynchronous_shaders->setEnabled(runtime_lock); ui->anisotropic_filtering_combobox->setEnabled(runtime_lock); + ui->renderer_force_max_clock->setChecked(Settings::values.renderer_force_max_clock.GetValue()); ui->use_vsync->setChecked(Settings::values.use_vsync.GetValue()); ui->use_asynchronous_shaders->setChecked(Settings::values.use_asynchronous_shaders.GetValue()); ui->use_fast_gpu_time->setChecked(Settings::values.use_fast_gpu_time.GetValue()); ui->use_pessimistic_flushes->setChecked(Settings::values.use_pessimistic_flushes.GetValue()); + ui->use_vulkan_driver_pipeline_cache->setChecked( + Settings::values.use_vulkan_driver_pipeline_cache.GetValue()); if (Settings::IsConfiguringGlobal()) { ui->gpu_accuracy->setCurrentIndex( @@ -41,6 +45,8 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { &Settings::values.max_anisotropy); ConfigurationShared::SetHighlight(ui->label_gpu_accuracy, !Settings::values.gpu_accuracy.UsingGlobal()); + ConfigurationShared::SetHighlight(ui->renderer_force_max_clock, + !Settings::values.renderer_force_max_clock.UsingGlobal()); ConfigurationShared::SetHighlight(ui->af_label, !Settings::values.max_anisotropy.UsingGlobal()); } @@ -48,6 +54,9 @@ void ConfigureGraphicsAdvanced::SetConfiguration() { void ConfigureGraphicsAdvanced::ApplyConfiguration() { ConfigurationShared::ApplyPerGameSetting(&Settings::values.gpu_accuracy, ui->gpu_accuracy); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.renderer_force_max_clock, + ui->renderer_force_max_clock, + renderer_force_max_clock); ConfigurationShared::ApplyPerGameSetting(&Settings::values.max_anisotropy, ui->anisotropic_filtering_combobox); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vsync, ui->use_vsync, use_vsync); @@ -58,6 +67,9 @@ void ConfigureGraphicsAdvanced::ApplyConfiguration() { ui->use_fast_gpu_time, use_fast_gpu_time); ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_pessimistic_flushes, ui->use_pessimistic_flushes, use_pessimistic_flushes); + ConfigurationShared::ApplyPerGameSetting(&Settings::values.use_vulkan_driver_pipeline_cache, + ui->use_vulkan_driver_pipeline_cache, + use_vulkan_driver_pipeline_cache); } void ConfigureGraphicsAdvanced::changeEvent(QEvent* event) { @@ -76,18 +88,25 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { // Disable if not global (only happens during game) if (Settings::IsConfiguringGlobal()) { ui->gpu_accuracy->setEnabled(Settings::values.gpu_accuracy.UsingGlobal()); + ui->renderer_force_max_clock->setEnabled( + Settings::values.renderer_force_max_clock.UsingGlobal()); ui->use_vsync->setEnabled(Settings::values.use_vsync.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()); ui->use_pessimistic_flushes->setEnabled( Settings::values.use_pessimistic_flushes.UsingGlobal()); + ui->use_vulkan_driver_pipeline_cache->setEnabled( + Settings::values.use_vulkan_driver_pipeline_cache.UsingGlobal()); ui->anisotropic_filtering_combobox->setEnabled( Settings::values.max_anisotropy.UsingGlobal()); return; } + ConfigurationShared::SetColoredTristate(ui->renderer_force_max_clock, + Settings::values.renderer_force_max_clock, + renderer_force_max_clock); ConfigurationShared::SetColoredTristate(ui->use_vsync, Settings::values.use_vsync, use_vsync); ConfigurationShared::SetColoredTristate(ui->use_asynchronous_shaders, Settings::values.use_asynchronous_shaders, @@ -97,6 +116,9 @@ void ConfigureGraphicsAdvanced::SetupPerGameUI() { ConfigurationShared::SetColoredTristate(ui->use_pessimistic_flushes, Settings::values.use_pessimistic_flushes, use_pessimistic_flushes); + ConfigurationShared::SetColoredTristate(ui->use_vulkan_driver_pipeline_cache, + Settings::values.use_vulkan_driver_pipeline_cache, + use_vulkan_driver_pipeline_cache); ConfigurationShared::SetColoredComboBox( ui->gpu_accuracy, ui->label_gpu_accuracy, static_cast<int>(Settings::values.gpu_accuracy.GetValue(true))); diff --git a/src/yuzu/configuration/configure_graphics_advanced.h b/src/yuzu/configuration/configure_graphics_advanced.h index 12e816905..df557d585 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.h +++ b/src/yuzu/configuration/configure_graphics_advanced.h @@ -36,10 +36,12 @@ private: std::unique_ptr<Ui::ConfigureGraphicsAdvanced> ui; + ConfigurationShared::CheckState renderer_force_max_clock; ConfigurationShared::CheckState use_vsync; ConfigurationShared::CheckState use_asynchronous_shaders; ConfigurationShared::CheckState use_fast_gpu_time; ConfigurationShared::CheckState use_pessimistic_flushes; + ConfigurationShared::CheckState use_vulkan_driver_pipeline_cache; const Core::System& system; }; diff --git a/src/yuzu/configuration/configure_graphics_advanced.ui b/src/yuzu/configuration/configure_graphics_advanced.ui index 87a121471..061885e30 100644 --- a/src/yuzu/configuration/configure_graphics_advanced.ui +++ b/src/yuzu/configuration/configure_graphics_advanced.ui @@ -70,6 +70,16 @@ </widget> </item> <item> + <widget class="QCheckBox" name="renderer_force_max_clock"> + <property name="toolTip"> + <string>Runs work in the background while waiting for graphics commands to keep the GPU from lowering its clock speed.</string> + </property> + <property name="text"> + <string>Force maximum clocks (Vulkan only)</string> + </property> + </widget> + </item> + <item> <widget class="QCheckBox" name="use_vsync"> <property name="toolTip"> <string>VSync prevents the screen from tearing, but some graphics cards have lower performance with VSync enabled. Keep it enabled if you don't notice a performance difference.</string> @@ -110,6 +120,16 @@ </widget> </item> <item> + <widget class="QCheckBox" name="use_vulkan_driver_pipeline_cache"> + <property name="toolTip"> + <string>Enables GPU vendor-specific pipeline cache. This option can improve shader loading time significantly in cases where the Vulkan driver does not store pipeline cache files internally.</string> + </property> + <property name="text"> + <string>Use Vulkan pipeline cache</string> + </property> + </widget> + </item> + <item> <widget class="QWidget" name="af_layout" native="true"> <layout class="QHBoxLayout" name="horizontalLayout_1"> <property name="leftMargin"> diff --git a/src/yuzu/configuration/configure_input_player.cpp b/src/yuzu/configuration/configure_input_player.cpp index 183cbe562..c40d980c9 100644 --- a/src/yuzu/configuration/configure_input_player.cpp +++ b/src/yuzu/configuration/configure_input_player.cpp @@ -1466,6 +1466,12 @@ void ConfigureInputPlayer::mousePressEvent(QMouseEvent* event) { input_subsystem->GetMouse()->PressButton(0, 0, 0, 0, button); } +void ConfigureInputPlayer::wheelEvent(QWheelEvent* event) { + const int x = event->angleDelta().x(); + const int y = event->angleDelta().y(); + input_subsystem->GetMouse()->MouseWheelChange(x, y); +} + void ConfigureInputPlayer::keyPressEvent(QKeyEvent* event) { if (!input_setter || !event) { return; diff --git a/src/yuzu/configuration/configure_input_player.h b/src/yuzu/configuration/configure_input_player.h index 6d1876f2b..99a9c875d 100644 --- a/src/yuzu/configuration/configure_input_player.h +++ b/src/yuzu/configuration/configure_input_player.h @@ -116,6 +116,9 @@ private: /// Handle mouse button press events. void mousePressEvent(QMouseEvent* event) override; + /// Handle mouse wheel move events. + void wheelEvent(QWheelEvent* event) override; + /// Handle key press events. void keyPressEvent(QKeyEvent* event) override; diff --git a/src/yuzu/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp index 94049f2f4..9ea4c02da 100644 --- a/src/yuzu/configuration/configure_system.cpp +++ b/src/yuzu/configuration/configure_system.cpp @@ -31,6 +31,9 @@ constexpr std::array<u32, 7> LOCALE_BLOCKLIST{ }; static bool IsValidLocale(u32 region_index, u32 language_index) { + if (region_index >= LOCALE_BLOCKLIST.size()) { + return false; + } return ((LOCALE_BLOCKLIST.at(region_index) >> language_index) & 1) == 0; } @@ -55,8 +58,11 @@ ConfigureSystem::ConfigureSystem(Core::System& system_, QWidget* parent) }); const auto locale_check = [this](int index) { - const bool valid_locale = - IsValidLocale(ui->combo_region->currentIndex(), ui->combo_language->currentIndex()); + const auto region_index = ConfigurationShared::GetComboboxIndex( + Settings::values.region_index.GetValue(true), ui->combo_region); + const auto language_index = ConfigurationShared::GetComboboxIndex( + Settings::values.language_index.GetValue(true), ui->combo_language); + const bool valid_locale = IsValidLocale(region_index, language_index); ui->label_warn_invalid_locale->setVisible(!valid_locale); if (!valid_locale) { ui->label_warn_invalid_locale->setText( diff --git a/src/yuzu/configuration/configure_system.h b/src/yuzu/configuration/configure_system.h index 8f02880a7..a7f086258 100644 --- a/src/yuzu/configuration/configure_system.h +++ b/src/yuzu/configuration/configure_system.h @@ -42,13 +42,7 @@ private: std::unique_ptr<Ui::ConfigureSystem> ui; bool enabled = false; - int language_index = 0; - int region_index = 0; - int time_zone_index = 0; - int sound_index = 0; - ConfigurationShared::CheckState use_rng_seed; - ConfigurationShared::CheckState use_custom_rtc; Core::System& system; }; diff --git a/src/yuzu/hotkeys.cpp b/src/yuzu/hotkeys.cpp index 13723f6e5..6530186c1 100644 --- a/src/yuzu/hotkeys.cpp +++ b/src/yuzu/hotkeys.cpp @@ -21,7 +21,7 @@ void HotkeyRegistry::SaveHotkeys() { {hotkey.first, group.first, UISettings::ContextualShortcut({hotkey.second.keyseq.toString(), hotkey.second.controller_keyseq, - hotkey.second.context})}); + hotkey.second.context, hotkey.second.repeat})}); } } } @@ -47,6 +47,7 @@ void HotkeyRegistry::LoadHotkeys() { hk.controller_shortcut->disconnect(); hk.controller_shortcut->SetKey(hk.controller_keyseq); } + hk.repeat = shortcut.shortcut.repeat; } } @@ -57,8 +58,7 @@ QShortcut* HotkeyRegistry::GetHotkey(const QString& group, const QString& action hk.shortcut = new QShortcut(hk.keyseq, widget, nullptr, nullptr, hk.context); } - hk.shortcut->setAutoRepeat(false); - + hk.shortcut->setAutoRepeat(hk.repeat); return hk.shortcut; } diff --git a/src/yuzu/hotkeys.h b/src/yuzu/hotkeys.h index dc5b7f628..848239c35 100644 --- a/src/yuzu/hotkeys.h +++ b/src/yuzu/hotkeys.h @@ -115,6 +115,7 @@ private: QShortcut* shortcut = nullptr; ControllerShortcut* controller_shortcut = nullptr; Qt::ShortcutContext context = Qt::WindowShortcut; + bool repeat; }; using HotkeyMap = std::map<QString, Hotkey>; diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 524650144..571eacf9f 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp @@ -1839,9 +1839,11 @@ void GMainWindow::OnEmulationStopTimeExpired() { void GMainWindow::OnEmulationStopped() { shutdown_timer.stop(); - emu_thread->disconnect(); - emu_thread->wait(); - emu_thread = nullptr; + if (emu_thread) { + emu_thread->disconnect(); + emu_thread->wait(); + emu_thread.reset(); + } if (shutdown_dialog) { shutdown_dialog->deleteLater(); @@ -2229,8 +2231,10 @@ void GMainWindow::OnGameListRemoveFile(u64 program_id, GameListRemoveTarget targ } switch (target) { - case GameListRemoveTarget::GlShaderCache: case GameListRemoveTarget::VkShaderCache: + RemoveVulkanDriverPipelineCache(program_id); + [[fallthrough]]; + case GameListRemoveTarget::GlShaderCache: RemoveTransferableShaderCache(program_id, target); break; case GameListRemoveTarget::AllShaderCache: @@ -2271,6 +2275,22 @@ void GMainWindow::RemoveTransferableShaderCache(u64 program_id, GameListRemoveTa } } +void GMainWindow::RemoveVulkanDriverPipelineCache(u64 program_id) { + static constexpr std::string_view target_file_name = "vulkan_pipelines.bin"; + + const auto shader_cache_dir = Common::FS::GetYuzuPath(Common::FS::YuzuPath::ShaderDir); + 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(target_file)) { + return; + } + if (!Common::FS::RemoveFile(target_file)) { + QMessageBox::warning(this, tr("Error Removing Vulkan Driver Pipeline Cache"), + tr("Failed to remove the driver pipeline cache.")); + } +} + 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); @@ -3011,6 +3031,8 @@ void GMainWindow::OnStopGame() { if (OnShutdownBegin()) { OnShutdownBeginDialog(); + } else { + OnEmulationStopped(); } } @@ -3708,15 +3730,36 @@ void GMainWindow::UpdateWindowTitle(std::string_view title_name, std::string_vie } } +std::string GMainWindow::CreateTASFramesString( + std::array<size_t, InputCommon::TasInput::PLAYER_NUMBER> frames) const { + std::string string = ""; + size_t maxPlayerIndex = 0; + for (size_t i = 0; i < frames.size(); i++) { + if (frames[i] != 0) { + if (maxPlayerIndex != 0) + string += ", "; + while (maxPlayerIndex++ != i) + string += "0, "; + string += std::to_string(frames[i]); + } + } + return string; +} + QString GMainWindow::GetTasStateDescription() const { auto [tas_status, current_tas_frame, total_tas_frames] = input_subsystem->GetTas()->GetStatus(); + std::string tas_frames_string = CreateTASFramesString(total_tas_frames); switch (tas_status) { case InputCommon::TasInput::TasState::Running: - return tr("TAS state: Running %1/%2").arg(current_tas_frame).arg(total_tas_frames); + return tr("TAS state: Running %1/%2") + .arg(current_tas_frame) + .arg(QString::fromStdString(tas_frames_string)); case InputCommon::TasInput::TasState::Recording: - return tr("TAS state: Recording %1").arg(total_tas_frames); + return tr("TAS state: Recording %1").arg(total_tas_frames[0]); case InputCommon::TasInput::TasState::Stopped: - return tr("TAS state: Idle %1/%2").arg(current_tas_frame).arg(total_tas_frames); + return tr("TAS state: Idle %1/%2") + .arg(current_tas_frame) + .arg(QString::fromStdString(tas_frames_string)); default: return tr("TAS State: Invalid"); } diff --git a/src/yuzu/main.h b/src/yuzu/main.h index db318485d..0f61abc7a 100644 --- a/src/yuzu/main.h +++ b/src/yuzu/main.h @@ -12,6 +12,7 @@ #include "common/announce_multiplayer_room.h" #include "common/common_types.h" +#include "input_common/drivers/tas_input.h" #include "yuzu/compatibility_list.h" #include "yuzu/hotkeys.h" @@ -266,6 +267,9 @@ private: void changeEvent(QEvent* event) override; void closeEvent(QCloseEvent* event) override; + std::string CreateTASFramesString( + std::array<size_t, InputCommon::TasInput::PLAYER_NUMBER> frames) const; + #ifdef __unix__ void SetupSigInterrupts(); static void HandleSigInterrupt(int); @@ -347,6 +351,7 @@ private: void RemoveUpdateContent(u64 program_id, InstalledEntryType type); void RemoveAddOnContent(u64 program_id, InstalledEntryType type); void RemoveTransferableShaderCache(u64 program_id, GameListRemoveTarget target); + void RemoveVulkanDriverPipelineCache(u64 program_id); 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); diff --git a/src/yuzu/uisettings.h b/src/yuzu/uisettings.h index 2006b883e..db43b7033 100644 --- a/src/yuzu/uisettings.h +++ b/src/yuzu/uisettings.h @@ -22,6 +22,7 @@ struct ContextualShortcut { QString keyseq; QString controller_keyseq; int context; + bool repeat; }; struct Shortcut { |