summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/core/file_sys/control_metadata.cpp3
-rw-r--r--src/core/file_sys/control_metadata.h3
-rw-r--r--src/core/hle/kernel/k_scheduler.h5
-rw-r--r--src/core/hle/kernel/svc.cpp17
-rw-r--r--src/core/hle/result.h28
-rw-r--r--src/core/hle/service/ns/language.cpp26
-rw-r--r--src/core/hle/service/ns/language.h1
-rw-r--r--src/shader_recompiler/backend/spirv/emit_spirv_image.cpp21
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp15
-rw-r--r--src/yuzu/CMakeLists.txt5
-rw-r--r--src/yuzu/configuration/configure_dialog.cpp7
-rw-r--r--src/yuzu/configuration/configure_per_game.cpp2
-rw-r--r--src/yuzu/configuration/configure_per_game.ui8
-rw-r--r--src/yuzu/main.cpp19
15 files changed, 142 insertions, 24 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 6e66dc1df..63dd9febf 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -32,6 +32,7 @@ if (MSVC)
32 # /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates 32 # /Zc:externConstexpr - Allow extern constexpr variables to have external linkage, like the standard mandates
33 # /Zc:inline - Let codegen omit inline functions in object files 33 # /Zc:inline - Let codegen omit inline functions in object files
34 # /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null 34 # /Zc:throwingNew - Let codegen assume `operator new` (without std::nothrow) will never return null
35 # /GT - Supports fiber safety for data allocated using static thread-local storage
35 add_compile_options( 36 add_compile_options(
36 /MP 37 /MP
37 /Zi 38 /Zi
@@ -44,6 +45,7 @@ if (MSVC)
44 /Zc:externConstexpr 45 /Zc:externConstexpr
45 /Zc:inline 46 /Zc:inline
46 /Zc:throwingNew 47 /Zc:throwingNew
48 /GT
47 49
48 # External headers diagnostics 50 # External headers diagnostics
49 /experimental:external # Enables the external headers options. This option isn't required in Visual Studio 2019 version 16.10 and later 51 /experimental:external # Enables the external headers options. This option isn't required in Visual Studio 2019 version 16.10 and later
@@ -69,6 +71,10 @@ if (MSVC)
69 /we5038 # data member 'member1' will be initialized after data member 'member2' 71 /we5038 # data member 'member1' will be initialized after data member 'member2'
70 ) 72 )
71 73
74 if (ARCHITECTURE_x86_64)
75 add_compile_options(/QIntel-jcc-erratum)
76 endif()
77
72 # /GS- - No stack buffer overflow checks 78 # /GS- - No stack buffer overflow checks
73 add_compile_options("$<$<CONFIG:Release>:/GS->") 79 add_compile_options("$<$<CONFIG:Release>:/GS->")
74 80
diff --git a/src/core/file_sys/control_metadata.cpp b/src/core/file_sys/control_metadata.cpp
index f66759815..05936f3c3 100644
--- a/src/core/file_sys/control_metadata.cpp
+++ b/src/core/file_sys/control_metadata.cpp
@@ -9,7 +9,7 @@
9 9
10namespace FileSys { 10namespace FileSys {
11 11
12const std::array<const char*, 15> LANGUAGE_NAMES{{ 12const std::array<const char*, 16> LANGUAGE_NAMES{{
13 "AmericanEnglish", 13 "AmericanEnglish",
14 "BritishEnglish", 14 "BritishEnglish",
15 "Japanese", 15 "Japanese",
@@ -25,6 +25,7 @@ const std::array<const char*, 15> LANGUAGE_NAMES{{
25 "Korean", 25 "Korean",
26 "Taiwanese", 26 "Taiwanese",
27 "Chinese", 27 "Chinese",
28 "BrazilianPortuguese",
28}}; 29}};
29 30
30std::string LanguageEntry::GetApplicationName() const { 31std::string LanguageEntry::GetApplicationName() const {
diff --git a/src/core/file_sys/control_metadata.h b/src/core/file_sys/control_metadata.h
index dd9837cf5..af2b723df 100644
--- a/src/core/file_sys/control_metadata.h
+++ b/src/core/file_sys/control_metadata.h
@@ -88,11 +88,12 @@ enum class Language : u8 {
88 Korean = 12, 88 Korean = 12,
89 Taiwanese = 13, 89 Taiwanese = 13,
90 Chinese = 14, 90 Chinese = 14,
91 BrazilianPortuguese = 15,
91 92
92 Default = 255, 93 Default = 255,
93}; 94};
94 95
95extern const std::array<const char*, 15> LANGUAGE_NAMES; 96extern const std::array<const char*, 16> LANGUAGE_NAMES;
96 97
97// A class representing the format used by NX metadata files, typically named Control.nacp. 98// A class representing the format used by NX metadata files, typically named Control.nacp.
98// These store application name, dev name, title id, and other miscellaneous data. 99// These store application name, dev name, title id, and other miscellaneous data.
diff --git a/src/core/hle/kernel/k_scheduler.h b/src/core/hle/kernel/k_scheduler.h
index c8ccc1ae4..7df288438 100644
--- a/src/core/hle/kernel/k_scheduler.h
+++ b/src/core/hle/kernel/k_scheduler.h
@@ -49,6 +49,11 @@ public:
49 /// Gets the current running thread 49 /// Gets the current running thread
50 [[nodiscard]] KThread* GetCurrentThread() const; 50 [[nodiscard]] KThread* GetCurrentThread() const;
51 51
52 /// Gets the idle thread
53 [[nodiscard]] KThread* GetIdleThread() const {
54 return idle_thread;
55 }
56
52 /// Returns true if the scheduler is idle 57 /// Returns true if the scheduler is idle
53 [[nodiscard]] bool IsIdle() const { 58 [[nodiscard]] bool IsIdle() const {
54 return GetCurrentThread() == idle_thread; 59 return GetCurrentThread() == idle_thread;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index f98f24a60..7f38ade1c 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -886,7 +886,24 @@ static ResultCode GetInfo(Core::System& system, u64* result, u64 info_id, Handle
886 *result = out_ticks; 886 *result = out_ticks;
887 return ResultSuccess; 887 return ResultSuccess;
888 } 888 }
889 case GetInfoType::IdleTickCount: {
890 if (handle == 0) {
891 LOG_ERROR(Kernel_SVC, "Thread handle does not exist, handle=0x{:08X}",
892 static_cast<Handle>(handle));
893 return ResultInvalidHandle;
894 }
889 895
896 if (info_sub_id != 0xFFFFFFFFFFFFFFFF && info_sub_id != system.CurrentCoreIndex()) {
897 LOG_ERROR(Kernel_SVC, "Core is not the current core, got {}", info_sub_id);
898 return ResultInvalidCombination;
899 }
900
901 const auto& scheduler = *system.Kernel().CurrentScheduler();
902 const auto* const idle_thread = scheduler.GetIdleThread();
903
904 *result = idle_thread->GetCpuTime();
905 return ResultSuccess;
906 }
890 default: 907 default:
891 LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id); 908 LOG_ERROR(Kernel_SVC, "Unimplemented svcGetInfo id=0x{:016X}", info_id);
892 return ResultInvalidEnumValue; 909 return ResultInvalidEnumValue;
diff --git a/src/core/hle/result.h b/src/core/hle/result.h
index a755008d5..2c6b24848 100644
--- a/src/core/hle/result.h
+++ b/src/core/hle/result.h
@@ -206,7 +206,7 @@ public:
206 return result; 206 return result;
207 } 207 }
208 208
209 ResultVal(const ResultVal& o) : result_code(o.result_code) { 209 ResultVal(const ResultVal& o) noexcept : result_code(o.result_code) {
210 if (!o.empty()) { 210 if (!o.empty()) {
211 new (&object) T(o.object); 211 new (&object) T(o.object);
212 } 212 }
@@ -224,7 +224,7 @@ public:
224 } 224 }
225 } 225 }
226 226
227 ResultVal& operator=(const ResultVal& o) { 227 ResultVal& operator=(const ResultVal& o) noexcept {
228 if (this == &o) { 228 if (this == &o) {
229 return *this; 229 return *this;
230 } 230 }
@@ -244,6 +244,26 @@ public:
244 return *this; 244 return *this;
245 } 245 }
246 246
247 ResultVal& operator=(ResultVal&& o) noexcept {
248 if (this == &o) {
249 return *this;
250 }
251 if (!empty()) {
252 if (!o.empty()) {
253 object = std::move(o.object);
254 } else {
255 object.~T();
256 }
257 } else {
258 if (!o.empty()) {
259 new (&object) T(std::move(o.object));
260 }
261 }
262 result_code = o.result_code;
263
264 return *this;
265 }
266
247 /** 267 /**
248 * Replaces the current result with a new constructed result value in-place. The code must not 268 * Replaces the current result with a new constructed result value in-place. The code must not
249 * be an error code. 269 * be an error code.
@@ -329,8 +349,8 @@ template <typename T, typename... Args>
329 * copy or move constructing. 349 * copy or move constructing.
330 */ 350 */
331template <typename Arg> 351template <typename Arg>
332[[nodiscard]] ResultVal<std::remove_reference_t<Arg>> MakeResult(Arg&& arg) { 352[[nodiscard]] ResultVal<std::remove_cvref_t<Arg>> MakeResult(Arg&& arg) {
333 return ResultVal<std::remove_reference_t<Arg>>::WithCode(ResultSuccess, std::forward<Arg>(arg)); 353 return ResultVal<std::remove_cvref_t<Arg>>::WithCode(ResultSuccess, std::forward<Arg>(arg));
334} 354}
335 355
336/** 356/**
diff --git a/src/core/hle/service/ns/language.cpp b/src/core/hle/service/ns/language.cpp
index 7d9e4a20b..e01c6be47 100644
--- a/src/core/hle/service/ns/language.cpp
+++ b/src/core/hle/service/ns/language.cpp
@@ -277,6 +277,25 @@ constexpr ApplicationLanguagePriorityList priority_list_simplified_chinese = {{
277 ApplicationLanguage::Korean, 277 ApplicationLanguage::Korean,
278}}; 278}};
279 279
280constexpr ApplicationLanguagePriorityList priority_list_brazilian_portuguese = {{
281 ApplicationLanguage::BrazilianPortuguese,
282 ApplicationLanguage::Portuguese,
283 ApplicationLanguage::LatinAmericanSpanish,
284 ApplicationLanguage::AmericanEnglish,
285 ApplicationLanguage::BritishEnglish,
286 ApplicationLanguage::Japanese,
287 ApplicationLanguage::French,
288 ApplicationLanguage::German,
289 ApplicationLanguage::Spanish,
290 ApplicationLanguage::Italian,
291 ApplicationLanguage::Dutch,
292 ApplicationLanguage::CanadianFrench,
293 ApplicationLanguage::Russian,
294 ApplicationLanguage::Korean,
295 ApplicationLanguage::SimplifiedChinese,
296 ApplicationLanguage::TraditionalChinese,
297}};
298
280const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList( 299const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
281 const ApplicationLanguage lang) { 300 const ApplicationLanguage lang) {
282 switch (lang) { 301 switch (lang) {
@@ -310,6 +329,8 @@ const ApplicationLanguagePriorityList* GetApplicationLanguagePriorityList(
310 return &priority_list_traditional_chinese; 329 return &priority_list_traditional_chinese;
311 case ApplicationLanguage::SimplifiedChinese: 330 case ApplicationLanguage::SimplifiedChinese:
312 return &priority_list_simplified_chinese; 331 return &priority_list_simplified_chinese;
332 case ApplicationLanguage::BrazilianPortuguese:
333 return &priority_list_brazilian_portuguese;
313 default: 334 default:
314 return nullptr; 335 return nullptr;
315 } 336 }
@@ -339,7 +360,6 @@ std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
339 case Set::LanguageCode::FR_CA: 360 case Set::LanguageCode::FR_CA:
340 return ApplicationLanguage::CanadianFrench; 361 return ApplicationLanguage::CanadianFrench;
341 case Set::LanguageCode::PT: 362 case Set::LanguageCode::PT:
342 case Set::LanguageCode::PT_BR:
343 return ApplicationLanguage::Portuguese; 363 return ApplicationLanguage::Portuguese;
344 case Set::LanguageCode::RU: 364 case Set::LanguageCode::RU:
345 return ApplicationLanguage::Russian; 365 return ApplicationLanguage::Russian;
@@ -351,6 +371,8 @@ std::optional<ApplicationLanguage> ConvertToApplicationLanguage(
351 case Set::LanguageCode::ZH_CN: 371 case Set::LanguageCode::ZH_CN:
352 case Set::LanguageCode::ZH_HANS: 372 case Set::LanguageCode::ZH_HANS:
353 return ApplicationLanguage::SimplifiedChinese; 373 return ApplicationLanguage::SimplifiedChinese;
374 case Set::LanguageCode::PT_BR:
375 return ApplicationLanguage::BrazilianPortuguese;
354 default: 376 default:
355 return std::nullopt; 377 return std::nullopt;
356 } 378 }
@@ -388,6 +410,8 @@ std::optional<Set::LanguageCode> ConvertToLanguageCode(const ApplicationLanguage
388 return Set::LanguageCode::ZH_HANT; 410 return Set::LanguageCode::ZH_HANT;
389 case ApplicationLanguage::SimplifiedChinese: 411 case ApplicationLanguage::SimplifiedChinese:
390 return Set::LanguageCode::ZH_HANS; 412 return Set::LanguageCode::ZH_HANS;
413 case ApplicationLanguage::BrazilianPortuguese:
414 return Set::LanguageCode::PT_BR;
391 default: 415 default:
392 return std::nullopt; 416 return std::nullopt;
393 } 417 }
diff --git a/src/core/hle/service/ns/language.h b/src/core/hle/service/ns/language.h
index e9829f9d2..d84c3f277 100644
--- a/src/core/hle/service/ns/language.h
+++ b/src/core/hle/service/ns/language.h
@@ -30,6 +30,7 @@ enum class ApplicationLanguage : u8 {
30 Korean, 30 Korean,
31 TraditionalChinese, 31 TraditionalChinese,
32 SimplifiedChinese, 32 SimplifiedChinese,
33 BrazilianPortuguese,
33 Count 34 Count
34}; 35};
35using ApplicationLanguagePriorityList = 36using ApplicationLanguagePriorityList =
diff --git a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
index 3588f052b..1d5364309 100644
--- a/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
+++ b/src/shader_recompiler/backend/spirv/emit_spirv_image.cpp
@@ -355,11 +355,22 @@ Id EmitImageSampleExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value&
355Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, 355Id EmitImageSampleDrefImplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
356 Id coords, Id dref, Id bias_lc, const IR::Value& offset) { 356 Id coords, Id dref, Id bias_lc, const IR::Value& offset) {
357 const auto info{inst->Flags<IR::TextureInstInfo>()}; 357 const auto info{inst->Flags<IR::TextureInstInfo>()};
358 const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0, bias_lc, 358 if (ctx.stage == Stage::Fragment) {
359 offset); 359 const ImageOperands operands(ctx, info.has_bias != 0, false, info.has_lod_clamp != 0,
360 return Emit(&EmitContext::OpImageSparseSampleDrefImplicitLod, 360 bias_lc, offset);
361 &EmitContext::OpImageSampleDrefImplicitLod, ctx, inst, ctx.F32[1], 361 return Emit(&EmitContext::OpImageSparseSampleDrefImplicitLod,
362 Texture(ctx, info, index), coords, dref, operands.MaskOptional(), operands.Span()); 362 &EmitContext::OpImageSampleDrefImplicitLod, ctx, inst, ctx.F32[1],
363 Texture(ctx, info, index), coords, dref, operands.MaskOptional(),
364 operands.Span());
365 } else {
366 // Implicit lods in compute behave on hardware as if sampling from LOD 0.
367 // This check is to ensure all drivers behave this way.
368 const Id lod{ctx.Const(0.0f)};
369 const ImageOperands operands(ctx, false, true, false, lod, offset);
370 return Emit(&EmitContext::OpImageSparseSampleDrefExplicitLod,
371 &EmitContext::OpImageSampleDrefExplicitLod, ctx, inst, ctx.F32[1],
372 Texture(ctx, info, index), coords, dref, operands.Mask(), operands.Span());
373 }
363} 374}
364 375
365Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index, 376Id EmitImageSampleDrefExplicitLod(EmitContext& ctx, IR::Inst* inst, const IR::Value& index,
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 1e1d1d020..0764ea6e0 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -181,6 +181,21 @@ Device::Device() {
181 LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported"); 181 LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported");
182 shader_backend = Settings::ShaderBackend::GLSL; 182 shader_backend = Settings::ShaderBackend::GLSL;
183 } 183 }
184
185 if (shader_backend == Settings::ShaderBackend::GLSL && is_nvidia &&
186 !Settings::values.renderer_debug) {
187 const std::string_view driver_version = version.substr(13);
188 const int version_major =
189 std::atoi(driver_version.substr(0, driver_version.find(".")).data());
190
191 if (version_major >= 495) {
192 LOG_WARNING(Render_OpenGL, "NVIDIA drivers 495 and later causes significant problems "
193 "with yuzu. Forcing GLASM as a mitigation.");
194 shader_backend = Settings::ShaderBackend::GLASM;
195 use_assembly_shaders = true;
196 }
197 }
198
184 // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation. 199 // Blocks AMD and Intel OpenGL drivers on Windows from using asynchronous shader compilation.
185 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() && 200 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() &&
186 !(is_amd || (is_intel && !is_linux)); 201 !(is_amd || (is_intel && !is_linux));
diff --git a/src/yuzu/CMakeLists.txt b/src/yuzu/CMakeLists.txt
index 402be6a78..d62fd566f 100644
--- a/src/yuzu/CMakeLists.txt
+++ b/src/yuzu/CMakeLists.txt
@@ -299,6 +299,11 @@ if (YUZU_USE_BUNDLED_QT)
299 copy_yuzu_Qt5_deps(yuzu) 299 copy_yuzu_Qt5_deps(yuzu)
300endif() 300endif()
301 301
302if (ENABLE_SDL2)
303 target_link_libraries(yuzu PRIVATE SDL2)
304 target_compile_definitions(yuzu PRIVATE HAVE_SDL2)
305endif()
306
302if (MSVC) 307if (MSVC)
303 include(CopyYuzuSDLDeps) 308 include(CopyYuzuSDLDeps)
304 include(CopyYuzuFFmpegDeps) 309 include(CopyYuzuFFmpegDeps)
diff --git a/src/yuzu/configuration/configure_dialog.cpp b/src/yuzu/configuration/configure_dialog.cpp
index 4fa0c4a43..642a5f966 100644
--- a/src/yuzu/configuration/configure_dialog.cpp
+++ b/src/yuzu/configuration/configure_dialog.cpp
@@ -81,8 +81,11 @@ ConfigureDialog::ConfigureDialog(QWidget* parent, HotkeyRegistry& registry,
81 SetConfiguration(); 81 SetConfiguration();
82 PopulateSelectionList(); 82 PopulateSelectionList();
83 83
84 connect(ui->tabWidget, &QTabWidget::currentChanged, this, 84 connect(ui->tabWidget, &QTabWidget::currentChanged, this, [this](int index) {
85 [this]() { debug_tab_tab->SetCurrentIndex(0); }); 85 if (index != -1) {
86 debug_tab_tab->SetCurrentIndex(0);
87 }
88 });
86 connect(ui_tab.get(), &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged); 89 connect(ui_tab.get(), &ConfigureUi::LanguageChanged, this, &ConfigureDialog::OnLanguageChanged);
87 connect(ui->selectorList, &QListWidget::itemSelectionChanged, this, 90 connect(ui->selectorList, &QListWidget::itemSelectionChanged, this,
88 &ConfigureDialog::UpdateVisibleTabs); 91 &ConfigureDialog::UpdateVisibleTabs);
diff --git a/src/yuzu/configuration/configure_per_game.cpp b/src/yuzu/configuration/configure_per_game.cpp
index 1031399e1..12699c126 100644
--- a/src/yuzu/configuration/configure_per_game.cpp
+++ b/src/yuzu/configuration/configure_per_game.cpp
@@ -66,7 +66,7 @@ ConfigurePerGame::ConfigurePerGame(QWidget* parent, u64 title_id, const std::str
66 ui->tabWidget->addTab(system_tab.get(), tr("System")); 66 ui->tabWidget->addTab(system_tab.get(), tr("System"));
67 ui->tabWidget->addTab(cpu_tab.get(), tr("CPU")); 67 ui->tabWidget->addTab(cpu_tab.get(), tr("CPU"));
68 ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics")); 68 ui->tabWidget->addTab(graphics_tab.get(), tr("Graphics"));
69 ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("GraphicsAdvanced")); 69 ui->tabWidget->addTab(graphics_advanced_tab.get(), tr("Adv. Graphics"));
70 ui->tabWidget->addTab(audio_tab.get(), tr("Audio")); 70 ui->tabWidget->addTab(audio_tab.get(), tr("Audio"));
71 71
72 setFocusPolicy(Qt::ClickFocus); 72 setFocusPolicy(Qt::ClickFocus);
diff --git a/src/yuzu/configuration/configure_per_game.ui b/src/yuzu/configuration/configure_per_game.ui
index 60efdbf21..85c86e107 100644
--- a/src/yuzu/configuration/configure_per_game.ui
+++ b/src/yuzu/configuration/configure_per_game.ui
@@ -2,14 +2,6 @@
2<ui version="4.0"> 2<ui version="4.0">
3 <class>ConfigurePerGame</class> 3 <class>ConfigurePerGame</class>
4 <widget class="QDialog" name="ConfigurePerGame"> 4 <widget class="QDialog" name="ConfigurePerGame">
5 <property name="geometry">
6 <rect>
7 <x>0</x>
8 <y>0</y>
9 <width>900</width>
10 <height>630</height>
11 </rect>
12 </property>
13 <property name="minimumSize"> 5 <property name="minimumSize">
14 <size> 6 <size>
15 <width>900</width> 7 <width>900</width>
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index 2af582fe5..e871fee36 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -66,6 +66,10 @@ static FileSys::VirtualFile VfsDirectoryCreateFileWrapper(const FileSys::Virtual
66#include <QUrl> 66#include <QUrl>
67#include <QtConcurrent/QtConcurrent> 67#include <QtConcurrent/QtConcurrent>
68 68
69#ifdef HAVE_SDL2
70#include <SDL.h> // For SDL ScreenSaver functions
71#endif
72
69#include <fmt/format.h> 73#include <fmt/format.h>
70#include "common/detached_tasks.h" 74#include "common/detached_tasks.h"
71#include "common/fs/fs.h" 75#include "common/fs/fs.h"
@@ -287,6 +291,14 @@ GMainWindow::GMainWindow()
287 291
288 ui->action_Fullscreen->setChecked(false); 292 ui->action_Fullscreen->setChecked(false);
289 293
294#if defined(HAVE_SDL2) && !defined(_WIN32)
295 SDL_InitSubSystem(SDL_INIT_VIDEO);
296 // SDL disables the screen saver by default, and setting the hint
297 // SDL_HINT_VIDEO_ALLOW_SCREENSAVER doesn't seem to work, so we just enable the screen saver
298 // for now.
299 SDL_EnableScreenSaver();
300#endif
301
290 QStringList args = QApplication::arguments(); 302 QStringList args = QApplication::arguments();
291 303
292 if (args.size() < 2) { 304 if (args.size() < 2) {
@@ -357,8 +369,9 @@ GMainWindow::GMainWindow()
357 369
358GMainWindow::~GMainWindow() { 370GMainWindow::~GMainWindow() {
359 // will get automatically deleted otherwise 371 // will get automatically deleted otherwise
360 if (render_window->parent() == nullptr) 372 if (render_window->parent() == nullptr) {
361 delete render_window; 373 delete render_window;
374 }
362} 375}
363 376
364void GMainWindow::RegisterMetaTypes() { 377void GMainWindow::RegisterMetaTypes() {
@@ -1223,12 +1236,16 @@ void GMainWindow::OnDisplayTitleBars(bool show) {
1223void GMainWindow::PreventOSSleep() { 1236void GMainWindow::PreventOSSleep() {
1224#ifdef _WIN32 1237#ifdef _WIN32
1225 SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED); 1238 SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED | ES_DISPLAY_REQUIRED);
1239#elif defined(HAVE_SDL2)
1240 SDL_DisableScreenSaver();
1226#endif 1241#endif
1227} 1242}
1228 1243
1229void GMainWindow::AllowOSSleep() { 1244void GMainWindow::AllowOSSleep() {
1230#ifdef _WIN32 1245#ifdef _WIN32
1231 SetThreadExecutionState(ES_CONTINUOUS); 1246 SetThreadExecutionState(ES_CONTINUOUS);
1247#elif defined(HAVE_SDL2)
1248 SDL_EnableScreenSaver();
1232#endif 1249#endif
1233} 1250}
1234 1251