diff options
| -rw-r--r-- | CMakeModules/CopyYuzuFFmpegDeps.cmake | 2 | ||||
| -rw-r--r-- | src/core/hle/service/nvdrv/core/syncpoint_manager.cpp | 2 | ||||
| -rw-r--r-- | src/video_core/buffer_cache/buffer_cache.h | 6 | ||||
| -rw-r--r-- | src/video_core/renderer_vulkan/vk_master_semaphore.cpp | 11 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.cpp | 36 | ||||
| -rw-r--r-- | src/yuzu/configuration/config.h | 6 | ||||
| -rw-r--r-- | src/yuzu/main.cpp | 185 |
7 files changed, 165 insertions, 83 deletions
diff --git a/CMakeModules/CopyYuzuFFmpegDeps.cmake b/CMakeModules/CopyYuzuFFmpegDeps.cmake index 7aaa073ee..e50696cc0 100644 --- a/CMakeModules/CopyYuzuFFmpegDeps.cmake +++ b/CMakeModules/CopyYuzuFFmpegDeps.cmake | |||
| @@ -6,5 +6,5 @@ function(copy_yuzu_FFmpeg_deps target_dir) | |||
| 6 | set(DLL_DEST "$<TARGET_FILE_DIR:${target_dir}>/") | 6 | set(DLL_DEST "$<TARGET_FILE_DIR:${target_dir}>/") |
| 7 | file(READ "${FFmpeg_PATH}/requirements.txt" FFmpeg_REQUIRED_DLLS) | 7 | file(READ "${FFmpeg_PATH}/requirements.txt" FFmpeg_REQUIRED_DLLS) |
| 8 | string(STRIP "${FFmpeg_REQUIRED_DLLS}" FFmpeg_REQUIRED_DLLS) | 8 | string(STRIP "${FFmpeg_REQUIRED_DLLS}" FFmpeg_REQUIRED_DLLS) |
| 9 | windows_copy_files(${target_dir} ${FFmpeg_DLL_DIR} ${DLL_DEST} ${FFmpeg_REQUIRED_DLLS}) | 9 | windows_copy_files(${target_dir} ${FFmpeg_LIBRARY_DIR} ${DLL_DEST} ${FFmpeg_REQUIRED_DLLS}) |
| 10 | endfunction(copy_yuzu_FFmpeg_deps) | 10 | endfunction(copy_yuzu_FFmpeg_deps) |
diff --git a/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp b/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp index aba51d280..c4c4c2593 100644 --- a/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp +++ b/src/core/hle/service/nvdrv/core/syncpoint_manager.cpp | |||
| @@ -64,7 +64,7 @@ void SyncpointManager::FreeSyncpoint(u32 id) { | |||
| 64 | } | 64 | } |
| 65 | 65 | ||
| 66 | bool SyncpointManager::IsSyncpointAllocated(u32 id) const { | 66 | bool SyncpointManager::IsSyncpointAllocated(u32 id) const { |
| 67 | return (id <= SyncpointCount) && syncpoints[id].reserved; | 67 | return (id < SyncpointCount) && syncpoints[id].reserved; |
| 68 | } | 68 | } |
| 69 | 69 | ||
| 70 | bool SyncpointManager::HasSyncpointExpired(u32 id, u32 threshold) const { | 70 | bool SyncpointManager::HasSyncpointExpired(u32 id, u32 threshold) const { |
diff --git a/src/video_core/buffer_cache/buffer_cache.h b/src/video_core/buffer_cache/buffer_cache.h index 427afd5fc..f1ad5f7cb 100644 --- a/src/video_core/buffer_cache/buffer_cache.h +++ b/src/video_core/buffer_cache/buffer_cache.h | |||
| @@ -1278,7 +1278,7 @@ typename BufferCache<P>::OverlapResult BufferCache<P>::ResolveOverlaps(VAddr cpu | |||
| 1278 | const VAddr overlap_cpu_addr = overlap.CpuAddr(); | 1278 | const VAddr overlap_cpu_addr = overlap.CpuAddr(); |
| 1279 | const bool expands_left = overlap_cpu_addr < begin; | 1279 | const bool expands_left = overlap_cpu_addr < begin; |
| 1280 | if (expands_left) { | 1280 | if (expands_left) { |
| 1281 | cpu_addr = begin = overlap_cpu_addr; | 1281 | begin = overlap_cpu_addr; |
| 1282 | } | 1282 | } |
| 1283 | const VAddr overlap_end = overlap_cpu_addr + overlap.SizeBytes(); | 1283 | const VAddr overlap_end = overlap_cpu_addr + overlap.SizeBytes(); |
| 1284 | const bool expands_right = overlap_end > end; | 1284 | const bool expands_right = overlap_end > end; |
| @@ -1292,7 +1292,7 @@ typename BufferCache<P>::OverlapResult BufferCache<P>::ResolveOverlaps(VAddr cpu | |||
| 1292 | has_stream_leap = true; | 1292 | has_stream_leap = true; |
| 1293 | if (expands_right) { | 1293 | if (expands_right) { |
| 1294 | begin -= CACHING_PAGESIZE * 256; | 1294 | begin -= CACHING_PAGESIZE * 256; |
| 1295 | cpu_addr = begin; | 1295 | cpu_addr = begin - CACHING_PAGESIZE; |
| 1296 | } | 1296 | } |
| 1297 | if (expands_left) { | 1297 | if (expands_left) { |
| 1298 | end += CACHING_PAGESIZE * 256; | 1298 | end += CACHING_PAGESIZE * 256; |
| @@ -1315,7 +1315,7 @@ void BufferCache<P>::JoinOverlap(BufferId new_buffer_id, BufferId overlap_id, | |||
| 1315 | if (accumulate_stream_score) { | 1315 | if (accumulate_stream_score) { |
| 1316 | new_buffer.IncreaseStreamScore(overlap.StreamScore() + 1); | 1316 | new_buffer.IncreaseStreamScore(overlap.StreamScore() + 1); |
| 1317 | } | 1317 | } |
| 1318 | boost::container::small_vector<BufferCopy, 1> copies; | 1318 | boost::container::small_vector<BufferCopy, 10> copies; |
| 1319 | const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr(); | 1319 | const size_t dst_base_offset = overlap.CpuAddr() - new_buffer.CpuAddr(); |
| 1320 | copies.push_back(BufferCopy{ | 1320 | copies.push_back(BufferCopy{ |
| 1321 | .src_offset = 0, | 1321 | .src_offset = 0, |
diff --git a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp index 8b65aeaeb..b128c4f6e 100644 --- a/src/video_core/renderer_vulkan/vk_master_semaphore.cpp +++ b/src/video_core/renderer_vulkan/vk_master_semaphore.cpp | |||
| @@ -128,15 +128,12 @@ VkResult MasterSemaphore::SubmitQueueTimeline(vk::CommandBuffer& cmdbuf, | |||
| 128 | const std::array signal_values{host_tick, u64(0)}; | 128 | const std::array signal_values{host_tick, u64(0)}; |
| 129 | const std::array signal_semaphores{timeline_semaphore, signal_semaphore}; | 129 | const std::array signal_semaphores{timeline_semaphore, signal_semaphore}; |
| 130 | 130 | ||
| 131 | const u32 num_wait_semaphores = wait_semaphore ? 2 : 1; | 131 | const u32 num_wait_semaphores = wait_semaphore ? 1 : 0; |
| 132 | const std::array wait_values{host_tick - 1, u64(1)}; | ||
| 133 | const std::array wait_semaphores{timeline_semaphore, wait_semaphore}; | ||
| 134 | |||
| 135 | const VkTimelineSemaphoreSubmitInfo timeline_si{ | 132 | const VkTimelineSemaphoreSubmitInfo timeline_si{ |
| 136 | .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, | 133 | .sType = VK_STRUCTURE_TYPE_TIMELINE_SEMAPHORE_SUBMIT_INFO, |
| 137 | .pNext = nullptr, | 134 | .pNext = nullptr, |
| 138 | .waitSemaphoreValueCount = num_wait_semaphores, | 135 | .waitSemaphoreValueCount = 0, |
| 139 | .pWaitSemaphoreValues = wait_values.data(), | 136 | .pWaitSemaphoreValues = nullptr, |
| 140 | .signalSemaphoreValueCount = num_signal_semaphores, | 137 | .signalSemaphoreValueCount = num_signal_semaphores, |
| 141 | .pSignalSemaphoreValues = signal_values.data(), | 138 | .pSignalSemaphoreValues = signal_values.data(), |
| 142 | }; | 139 | }; |
| @@ -144,7 +141,7 @@ VkResult MasterSemaphore::SubmitQueueTimeline(vk::CommandBuffer& cmdbuf, | |||
| 144 | .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, | 141 | .sType = VK_STRUCTURE_TYPE_SUBMIT_INFO, |
| 145 | .pNext = &timeline_si, | 142 | .pNext = &timeline_si, |
| 146 | .waitSemaphoreCount = num_wait_semaphores, | 143 | .waitSemaphoreCount = num_wait_semaphores, |
| 147 | .pWaitSemaphores = wait_semaphores.data(), | 144 | .pWaitSemaphores = &wait_semaphore, |
| 148 | .pWaitDstStageMask = wait_stage_masks.data(), | 145 | .pWaitDstStageMask = wait_stage_masks.data(), |
| 149 | .commandBufferCount = 1, | 146 | .commandBufferCount = 1, |
| 150 | .pCommandBuffers = cmdbuf.address(), | 147 | .pCommandBuffers = cmdbuf.address(), |
diff --git a/src/yuzu/configuration/config.cpp b/src/yuzu/configuration/config.cpp index 662651196..6288fef62 100644 --- a/src/yuzu/configuration/config.cpp +++ b/src/yuzu/configuration/config.cpp | |||
| @@ -65,6 +65,42 @@ const std::array<int, 2> Config::default_ringcon_analogs{{ | |||
| 65 | Qt::Key_D, | 65 | Qt::Key_D, |
| 66 | }}; | 66 | }}; |
| 67 | 67 | ||
| 68 | const std::map<Settings::AntiAliasing, QString> Config::anti_aliasing_texts_map = { | ||
| 69 | {Settings::AntiAliasing::None, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "None"))}, | ||
| 70 | {Settings::AntiAliasing::Fxaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FXAA"))}, | ||
| 71 | {Settings::AntiAliasing::Smaa, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "SMAA"))}, | ||
| 72 | }; | ||
| 73 | |||
| 74 | const std::map<Settings::ScalingFilter, QString> Config::scaling_filter_texts_map = { | ||
| 75 | {Settings::ScalingFilter::NearestNeighbor, | ||
| 76 | QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Nearest"))}, | ||
| 77 | {Settings::ScalingFilter::Bilinear, | ||
| 78 | QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bilinear"))}, | ||
| 79 | {Settings::ScalingFilter::Bicubic, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Bicubic"))}, | ||
| 80 | {Settings::ScalingFilter::Gaussian, | ||
| 81 | QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Gaussian"))}, | ||
| 82 | {Settings::ScalingFilter::ScaleForce, | ||
| 83 | QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "ScaleForce"))}, | ||
| 84 | {Settings::ScalingFilter::Fsr, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "FSR"))}, | ||
| 85 | }; | ||
| 86 | |||
| 87 | const std::map<bool, QString> Config::use_docked_mode_texts_map = { | ||
| 88 | {true, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Docked"))}, | ||
| 89 | {false, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Handheld"))}, | ||
| 90 | }; | ||
| 91 | |||
| 92 | const std::map<Settings::GPUAccuracy, QString> Config::gpu_accuracy_texts_map = { | ||
| 93 | {Settings::GPUAccuracy::Normal, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Normal"))}, | ||
| 94 | {Settings::GPUAccuracy::High, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "High"))}, | ||
| 95 | {Settings::GPUAccuracy::Extreme, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Extreme"))}, | ||
| 96 | }; | ||
| 97 | |||
| 98 | const std::map<Settings::RendererBackend, QString> Config::renderer_backend_texts_map = { | ||
| 99 | {Settings::RendererBackend::Vulkan, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Vulkan"))}, | ||
| 100 | {Settings::RendererBackend::OpenGL, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "OpenGL"))}, | ||
| 101 | {Settings::RendererBackend::Null, QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "Null"))}, | ||
| 102 | }; | ||
| 103 | |||
| 68 | // This shouldn't have anything except static initializers (no functions). So | 104 | // This shouldn't have anything except static initializers (no functions). So |
| 69 | // QKeySequence(...).toString() is NOT ALLOWED HERE. | 105 | // QKeySequence(...).toString() is NOT ALLOWED HERE. |
| 70 | // This must be in alphabetical order according to action name as it must have the same order as | 106 | // This must be in alphabetical order according to action name as it must have the same order as |
diff --git a/src/yuzu/configuration/config.h b/src/yuzu/configuration/config.h index 9cb9db6cf..ad590ea9e 100644 --- a/src/yuzu/configuration/config.h +++ b/src/yuzu/configuration/config.h | |||
| @@ -49,6 +49,12 @@ public: | |||
| 49 | static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods; | 49 | static const std::array<int, Settings::NativeKeyboard::NumKeyboardMods> default_keyboard_mods; |
| 50 | static const std::array<UISettings::Shortcut, 22> default_hotkeys; | 50 | static const std::array<UISettings::Shortcut, 22> default_hotkeys; |
| 51 | 51 | ||
| 52 | static const std::map<Settings::AntiAliasing, QString> anti_aliasing_texts_map; | ||
| 53 | static const std::map<Settings::ScalingFilter, QString> scaling_filter_texts_map; | ||
| 54 | static const std::map<bool, QString> use_docked_mode_texts_map; | ||
| 55 | static const std::map<Settings::GPUAccuracy, QString> gpu_accuracy_texts_map; | ||
| 56 | static const std::map<Settings::RendererBackend, QString> renderer_backend_texts_map; | ||
| 57 | |||
| 52 | static constexpr UISettings::Theme default_theme{ | 58 | static constexpr UISettings::Theme default_theme{ |
| 53 | #ifdef _WIN32 | 59 | #ifdef _WIN32 |
| 54 | UISettings::Theme::DarkColorful | 60 | UISettings::Theme::DarkColorful |
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp index 25cfef6d5..82bce9a3a 100644 --- a/src/yuzu/main.cpp +++ b/src/yuzu/main.cpp | |||
| @@ -1054,6 +1054,24 @@ void GMainWindow::InitializeWidgets() { | |||
| 1054 | bottomLeft.setY(bottomLeft.y() - volume_popup->geometry().height()); | 1054 | bottomLeft.setY(bottomLeft.y() - volume_popup->geometry().height()); |
| 1055 | volume_popup->setGeometry(QRect(bottomLeft, QSize(rect.width(), rect.height()))); | 1055 | volume_popup->setGeometry(QRect(bottomLeft, QSize(rect.width(), rect.height()))); |
| 1056 | }); | 1056 | }); |
| 1057 | volume_button->setContextMenuPolicy(Qt::CustomContextMenu); | ||
| 1058 | connect(volume_button, &QPushButton::customContextMenuRequested, | ||
| 1059 | [this](const QPoint& menu_location) { | ||
| 1060 | QMenu context_menu; | ||
| 1061 | context_menu.addAction( | ||
| 1062 | Settings::values.audio_muted ? tr("Unmute") : tr("Mute"), [this] { | ||
| 1063 | Settings::values.audio_muted = !Settings::values.audio_muted; | ||
| 1064 | UpdateVolumeUI(); | ||
| 1065 | }); | ||
| 1066 | |||
| 1067 | context_menu.addAction(tr("Reset Volume"), [this] { | ||
| 1068 | Settings::values.volume.SetValue(100); | ||
| 1069 | UpdateVolumeUI(); | ||
| 1070 | }); | ||
| 1071 | |||
| 1072 | context_menu.exec(volume_button->mapToGlobal(menu_location)); | ||
| 1073 | volume_button->repaint(); | ||
| 1074 | }); | ||
| 1057 | statusBar()->insertPermanentWidget(0, volume_button); | 1075 | statusBar()->insertPermanentWidget(0, volume_button); |
| 1058 | 1076 | ||
| 1059 | // setup AA button | 1077 | // setup AA button |
| @@ -1074,6 +1092,19 @@ void GMainWindow::InitializeWidgets() { | |||
| 1074 | UpdateAAText(); | 1092 | UpdateAAText(); |
| 1075 | aa_status_button->setCheckable(true); | 1093 | aa_status_button->setCheckable(true); |
| 1076 | aa_status_button->setChecked(true); | 1094 | aa_status_button->setChecked(true); |
| 1095 | aa_status_button->setContextMenuPolicy(Qt::CustomContextMenu); | ||
| 1096 | connect(aa_status_button, &QPushButton::customContextMenuRequested, | ||
| 1097 | [this](const QPoint& menu_location) { | ||
| 1098 | QMenu context_menu; | ||
| 1099 | for (auto const& aa_text_pair : Config::anti_aliasing_texts_map) { | ||
| 1100 | context_menu.addAction(aa_text_pair.second, [this, aa_text_pair] { | ||
| 1101 | Settings::values.anti_aliasing.SetValue(aa_text_pair.first); | ||
| 1102 | UpdateAAText(); | ||
| 1103 | }); | ||
| 1104 | } | ||
| 1105 | context_menu.exec(aa_status_button->mapToGlobal(menu_location)); | ||
| 1106 | aa_status_button->repaint(); | ||
| 1107 | }); | ||
| 1077 | statusBar()->insertPermanentWidget(0, aa_status_button); | 1108 | statusBar()->insertPermanentWidget(0, aa_status_button); |
| 1078 | 1109 | ||
| 1079 | // Setup Filter button | 1110 | // Setup Filter button |
| @@ -1085,6 +1116,19 @@ void GMainWindow::InitializeWidgets() { | |||
| 1085 | UpdateFilterText(); | 1116 | UpdateFilterText(); |
| 1086 | filter_status_button->setCheckable(true); | 1117 | filter_status_button->setCheckable(true); |
| 1087 | filter_status_button->setChecked(true); | 1118 | filter_status_button->setChecked(true); |
| 1119 | filter_status_button->setContextMenuPolicy(Qt::CustomContextMenu); | ||
| 1120 | connect(filter_status_button, &QPushButton::customContextMenuRequested, | ||
| 1121 | [this](const QPoint& menu_location) { | ||
| 1122 | QMenu context_menu; | ||
| 1123 | for (auto const& filter_text_pair : Config::scaling_filter_texts_map) { | ||
| 1124 | context_menu.addAction(filter_text_pair.second, [this, filter_text_pair] { | ||
| 1125 | Settings::values.scaling_filter.SetValue(filter_text_pair.first); | ||
| 1126 | UpdateFilterText(); | ||
| 1127 | }); | ||
| 1128 | } | ||
| 1129 | context_menu.exec(filter_status_button->mapToGlobal(menu_location)); | ||
| 1130 | filter_status_button->repaint(); | ||
| 1131 | }); | ||
| 1088 | statusBar()->insertPermanentWidget(0, filter_status_button); | 1132 | statusBar()->insertPermanentWidget(0, filter_status_button); |
| 1089 | 1133 | ||
| 1090 | // Setup Dock button | 1134 | // Setup Dock button |
| @@ -1094,14 +1138,47 @@ void GMainWindow::InitializeWidgets() { | |||
| 1094 | connect(dock_status_button, &QPushButton::clicked, this, &GMainWindow::OnToggleDockedMode); | 1138 | connect(dock_status_button, &QPushButton::clicked, this, &GMainWindow::OnToggleDockedMode); |
| 1095 | dock_status_button->setCheckable(true); | 1139 | dock_status_button->setCheckable(true); |
| 1096 | UpdateDockedButton(); | 1140 | UpdateDockedButton(); |
| 1141 | dock_status_button->setContextMenuPolicy(Qt::CustomContextMenu); | ||
| 1142 | connect(dock_status_button, &QPushButton::customContextMenuRequested, | ||
| 1143 | [this](const QPoint& menu_location) { | ||
| 1144 | QMenu context_menu; | ||
| 1145 | |||
| 1146 | for (auto const& docked_mode_pair : Config::use_docked_mode_texts_map) { | ||
| 1147 | context_menu.addAction(docked_mode_pair.second, [this, docked_mode_pair] { | ||
| 1148 | if (docked_mode_pair.first != Settings::values.use_docked_mode.GetValue()) { | ||
| 1149 | OnToggleDockedMode(); | ||
| 1150 | } | ||
| 1151 | }); | ||
| 1152 | } | ||
| 1153 | context_menu.exec(dock_status_button->mapToGlobal(menu_location)); | ||
| 1154 | dock_status_button->repaint(); | ||
| 1155 | }); | ||
| 1097 | statusBar()->insertPermanentWidget(0, dock_status_button); | 1156 | statusBar()->insertPermanentWidget(0, dock_status_button); |
| 1098 | 1157 | ||
| 1158 | // Setup GPU Accuracy button | ||
| 1099 | gpu_accuracy_button = new QPushButton(); | 1159 | gpu_accuracy_button = new QPushButton(); |
| 1100 | gpu_accuracy_button->setObjectName(QStringLiteral("GPUStatusBarButton")); | 1160 | gpu_accuracy_button->setObjectName(QStringLiteral("GPUStatusBarButton")); |
| 1101 | gpu_accuracy_button->setCheckable(true); | 1161 | gpu_accuracy_button->setCheckable(true); |
| 1102 | gpu_accuracy_button->setFocusPolicy(Qt::NoFocus); | 1162 | gpu_accuracy_button->setFocusPolicy(Qt::NoFocus); |
| 1103 | connect(gpu_accuracy_button, &QPushButton::clicked, this, &GMainWindow::OnToggleGpuAccuracy); | 1163 | connect(gpu_accuracy_button, &QPushButton::clicked, this, &GMainWindow::OnToggleGpuAccuracy); |
| 1104 | UpdateGPUAccuracyButton(); | 1164 | UpdateGPUAccuracyButton(); |
| 1165 | gpu_accuracy_button->setContextMenuPolicy(Qt::CustomContextMenu); | ||
| 1166 | connect(gpu_accuracy_button, &QPushButton::customContextMenuRequested, | ||
| 1167 | [this](const QPoint& menu_location) { | ||
| 1168 | QMenu context_menu; | ||
| 1169 | |||
| 1170 | for (auto const& gpu_accuracy_pair : Config::gpu_accuracy_texts_map) { | ||
| 1171 | if (gpu_accuracy_pair.first == Settings::GPUAccuracy::Extreme) { | ||
| 1172 | continue; | ||
| 1173 | } | ||
| 1174 | context_menu.addAction(gpu_accuracy_pair.second, [this, gpu_accuracy_pair] { | ||
| 1175 | Settings::values.gpu_accuracy.SetValue(gpu_accuracy_pair.first); | ||
| 1176 | UpdateGPUAccuracyButton(); | ||
| 1177 | }); | ||
| 1178 | } | ||
| 1179 | context_menu.exec(gpu_accuracy_button->mapToGlobal(menu_location)); | ||
| 1180 | gpu_accuracy_button->repaint(); | ||
| 1181 | }); | ||
| 1105 | statusBar()->insertPermanentWidget(0, gpu_accuracy_button); | 1182 | statusBar()->insertPermanentWidget(0, gpu_accuracy_button); |
| 1106 | 1183 | ||
| 1107 | // Setup Renderer API button | 1184 | // Setup Renderer API button |
| @@ -1114,6 +1191,24 @@ void GMainWindow::InitializeWidgets() { | |||
| 1114 | renderer_status_button->setCheckable(true); | 1191 | renderer_status_button->setCheckable(true); |
| 1115 | renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() == | 1192 | renderer_status_button->setChecked(Settings::values.renderer_backend.GetValue() == |
| 1116 | Settings::RendererBackend::Vulkan); | 1193 | Settings::RendererBackend::Vulkan); |
| 1194 | renderer_status_button->setContextMenuPolicy(Qt::CustomContextMenu); | ||
| 1195 | connect(renderer_status_button, &QPushButton::customContextMenuRequested, | ||
| 1196 | [this](const QPoint& menu_location) { | ||
| 1197 | QMenu context_menu; | ||
| 1198 | |||
| 1199 | for (auto const& renderer_backend_pair : Config::renderer_backend_texts_map) { | ||
| 1200 | if (renderer_backend_pair.first == Settings::RendererBackend::Null) { | ||
| 1201 | continue; | ||
| 1202 | } | ||
| 1203 | context_menu.addAction( | ||
| 1204 | renderer_backend_pair.second, [this, renderer_backend_pair] { | ||
| 1205 | Settings::values.renderer_backend.SetValue(renderer_backend_pair.first); | ||
| 1206 | UpdateAPIText(); | ||
| 1207 | }); | ||
| 1208 | } | ||
| 1209 | context_menu.exec(renderer_status_button->mapToGlobal(menu_location)); | ||
| 1210 | renderer_status_button->repaint(); | ||
| 1211 | }); | ||
| 1117 | statusBar()->insertPermanentWidget(0, renderer_status_button); | 1212 | statusBar()->insertPermanentWidget(0, renderer_status_button); |
| 1118 | 1213 | ||
| 1119 | statusBar()->setVisible(true); | 1214 | statusBar()->setVisible(true); |
| @@ -1798,6 +1893,7 @@ void GMainWindow::BootGame(const QString& filename, u64 program_id, std::size_t | |||
| 1798 | } | 1893 | } |
| 1799 | 1894 | ||
| 1800 | system->SetShuttingDown(false); | 1895 | system->SetShuttingDown(false); |
| 1896 | game_list->setDisabled(true); | ||
| 1801 | 1897 | ||
| 1802 | // Create and start the emulation thread | 1898 | // Create and start the emulation thread |
| 1803 | emu_thread = std::make_unique<EmuThread>(*system); | 1899 | emu_thread = std::make_unique<EmuThread>(*system); |
| @@ -1993,6 +2089,9 @@ void GMainWindow::OnEmulationStopped() { | |||
| 1993 | // When closing the game, destroy the GLWindow to clear the context after the game is closed | 2089 | // When closing the game, destroy the GLWindow to clear the context after the game is closed |
| 1994 | render_window->ReleaseRenderTarget(); | 2090 | render_window->ReleaseRenderTarget(); |
| 1995 | 2091 | ||
| 2092 | // Enable game list | ||
| 2093 | game_list->setEnabled(true); | ||
| 2094 | |||
| 1996 | Settings::RestoreGlobalState(system->IsPoweredOn()); | 2095 | Settings::RestoreGlobalState(system->IsPoweredOn()); |
| 1997 | system->HIDCore().ReloadInputDevices(); | 2096 | system->HIDCore().ReloadInputDevices(); |
| 1998 | UpdateStatusButtons(); | 2097 | UpdateStatusButtons(); |
| @@ -4000,94 +4099,38 @@ void GMainWindow::UpdateStatusBar() { | |||
| 4000 | } | 4099 | } |
| 4001 | 4100 | ||
| 4002 | void GMainWindow::UpdateGPUAccuracyButton() { | 4101 | void GMainWindow::UpdateGPUAccuracyButton() { |
| 4003 | switch (Settings::values.gpu_accuracy.GetValue()) { | 4102 | const auto gpu_accuracy = Settings::values.gpu_accuracy.GetValue(); |
| 4004 | case Settings::GPUAccuracy::Normal: { | 4103 | const auto gpu_accuracy_text = Config::gpu_accuracy_texts_map.find(gpu_accuracy)->second; |
| 4005 | gpu_accuracy_button->setText(tr("GPU NORMAL")); | 4104 | gpu_accuracy_button->setText(gpu_accuracy_text.toUpper()); |
| 4006 | gpu_accuracy_button->setChecked(false); | 4105 | gpu_accuracy_button->setChecked(gpu_accuracy != Settings::GPUAccuracy::Normal); |
| 4007 | break; | ||
| 4008 | } | ||
| 4009 | case Settings::GPUAccuracy::High: { | ||
| 4010 | gpu_accuracy_button->setText(tr("GPU HIGH")); | ||
| 4011 | gpu_accuracy_button->setChecked(true); | ||
| 4012 | break; | ||
| 4013 | } | ||
| 4014 | case Settings::GPUAccuracy::Extreme: { | ||
| 4015 | gpu_accuracy_button->setText(tr("GPU EXTREME")); | ||
| 4016 | gpu_accuracy_button->setChecked(true); | ||
| 4017 | break; | ||
| 4018 | } | ||
| 4019 | default: { | ||
| 4020 | gpu_accuracy_button->setText(tr("GPU ERROR")); | ||
| 4021 | gpu_accuracy_button->setChecked(true); | ||
| 4022 | break; | ||
| 4023 | } | ||
| 4024 | } | ||
| 4025 | } | 4106 | } |
| 4026 | 4107 | ||
| 4027 | void GMainWindow::UpdateDockedButton() { | 4108 | void GMainWindow::UpdateDockedButton() { |
| 4028 | const bool is_docked = Settings::values.use_docked_mode.GetValue(); | 4109 | const bool is_docked = Settings::values.use_docked_mode.GetValue(); |
| 4029 | dock_status_button->setChecked(is_docked); | 4110 | dock_status_button->setChecked(is_docked); |
| 4030 | dock_status_button->setText(is_docked ? tr("DOCKED") : tr("HANDHELD")); | 4111 | dock_status_button->setText( |
| 4112 | Config::use_docked_mode_texts_map.find(is_docked)->second.toUpper()); | ||
| 4031 | } | 4113 | } |
| 4032 | 4114 | ||
| 4033 | void GMainWindow::UpdateAPIText() { | 4115 | void GMainWindow::UpdateAPIText() { |
| 4034 | const auto api = Settings::values.renderer_backend.GetValue(); | 4116 | const auto api = Settings::values.renderer_backend.GetValue(); |
| 4035 | switch (api) { | 4117 | const auto renderer_status_text = Config::renderer_backend_texts_map.find(api)->second; |
| 4036 | case Settings::RendererBackend::OpenGL: | 4118 | renderer_status_button->setText(renderer_status_text.toUpper()); |
| 4037 | renderer_status_button->setText(tr("OPENGL")); | ||
| 4038 | break; | ||
| 4039 | case Settings::RendererBackend::Vulkan: | ||
| 4040 | renderer_status_button->setText(tr("VULKAN")); | ||
| 4041 | break; | ||
| 4042 | case Settings::RendererBackend::Null: | ||
| 4043 | renderer_status_button->setText(tr("NULL")); | ||
| 4044 | break; | ||
| 4045 | } | ||
| 4046 | } | 4119 | } |
| 4047 | 4120 | ||
| 4048 | void GMainWindow::UpdateFilterText() { | 4121 | void GMainWindow::UpdateFilterText() { |
| 4049 | const auto filter = Settings::values.scaling_filter.GetValue(); | 4122 | const auto filter = Settings::values.scaling_filter.GetValue(); |
| 4050 | switch (filter) { | 4123 | const auto filter_text = Config::scaling_filter_texts_map.find(filter)->second; |
| 4051 | case Settings::ScalingFilter::NearestNeighbor: | 4124 | filter_status_button->setText(filter == Settings::ScalingFilter::Fsr ? tr("FSR") |
| 4052 | filter_status_button->setText(tr("NEAREST")); | 4125 | : filter_text.toUpper()); |
| 4053 | break; | ||
| 4054 | case Settings::ScalingFilter::Bilinear: | ||
| 4055 | filter_status_button->setText(tr("BILINEAR")); | ||
| 4056 | break; | ||
| 4057 | case Settings::ScalingFilter::Bicubic: | ||
| 4058 | filter_status_button->setText(tr("BICUBIC")); | ||
| 4059 | break; | ||
| 4060 | case Settings::ScalingFilter::Gaussian: | ||
| 4061 | filter_status_button->setText(tr("GAUSSIAN")); | ||
| 4062 | break; | ||
| 4063 | case Settings::ScalingFilter::ScaleForce: | ||
| 4064 | filter_status_button->setText(tr("SCALEFORCE")); | ||
| 4065 | break; | ||
| 4066 | case Settings::ScalingFilter::Fsr: | ||
| 4067 | filter_status_button->setText(tr("FSR")); | ||
| 4068 | break; | ||
| 4069 | default: | ||
| 4070 | filter_status_button->setText(tr("BILINEAR")); | ||
| 4071 | break; | ||
| 4072 | } | ||
| 4073 | } | 4126 | } |
| 4074 | 4127 | ||
| 4075 | void GMainWindow::UpdateAAText() { | 4128 | void GMainWindow::UpdateAAText() { |
| 4076 | const auto aa_mode = Settings::values.anti_aliasing.GetValue(); | 4129 | const auto aa_mode = Settings::values.anti_aliasing.GetValue(); |
| 4077 | switch (aa_mode) { | 4130 | const auto aa_text = Config::anti_aliasing_texts_map.find(aa_mode)->second; |
| 4078 | case Settings::AntiAliasing::None: | 4131 | aa_status_button->setText(aa_mode == Settings::AntiAliasing::None |
| 4079 | aa_status_button->setText(tr("NO AA")); | 4132 | ? QStringLiteral(QT_TRANSLATE_NOOP("GMainWindow", "NO AA")) |
| 4080 | break; | 4133 | : aa_text.toUpper()); |
| 4081 | case Settings::AntiAliasing::Fxaa: | ||
| 4082 | aa_status_button->setText(tr("FXAA")); | ||
| 4083 | break; | ||
| 4084 | case Settings::AntiAliasing::Smaa: | ||
| 4085 | aa_status_button->setText(tr("SMAA")); | ||
| 4086 | break; | ||
| 4087 | default: | ||
| 4088 | aa_status_button->setText(tr("NO AA")); | ||
| 4089 | break; | ||
| 4090 | } | ||
| 4091 | } | 4134 | } |
| 4092 | 4135 | ||
| 4093 | void GMainWindow::UpdateVolumeUI() { | 4136 | void GMainWindow::UpdateVolumeUI() { |