summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/CMakeLists.txt6
-rw-r--r--src/common/alignment.h7
-rw-r--r--src/common/settings.h5
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp2
-rw-r--r--src/core/core.cpp5
-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_page_table.cpp2
-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/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp17
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h13
-rw-r--r--src/core/hle/service/time/time_manager.cpp13
-rw-r--r--src/input_common/udp/client.cpp74
-rw-r--r--src/shader_recompiler/ir_opt/texture_pass.cpp2
-rw-r--r--src/video_core/dirty_flags.h3
-rw-r--r--src/video_core/renderer_opengl/gl_device.cpp16
-rw-r--r--src/video_core/renderer_vulkan/vk_rasterizer.cpp16
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.cpp1
-rw-r--r--src/video_core/renderer_vulkan/vk_state_tracker.h3
-rw-r--r--src/video_core/texture_cache/texture_cache.h3
-rw-r--r--src/video_core/vulkan_common/vulkan_device.cpp4
-rw-r--r--src/video_core/vulkan_common/vulkan_device.h5
-rw-r--r--src/yuzu/CMakeLists.txt5
-rw-r--r--src/yuzu/configuration/config.cpp7
-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/configuration/configure_system.cpp10
-rw-r--r--src/yuzu/configuration/configure_tas.ui4
-rw-r--r--src/yuzu/main.cpp19
-rw-r--r--src/yuzu_cmd/config.cpp3
35 files changed, 234 insertions, 111 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/common/alignment.h b/src/common/alignment.h
index 1b56569d1..8570c7d3c 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -64,7 +64,7 @@ public:
64 using propagate_on_container_copy_assignment = std::true_type; 64 using propagate_on_container_copy_assignment = std::true_type;
65 using propagate_on_container_move_assignment = std::true_type; 65 using propagate_on_container_move_assignment = std::true_type;
66 using propagate_on_container_swap = std::true_type; 66 using propagate_on_container_swap = std::true_type;
67 using is_always_equal = std::true_type; 67 using is_always_equal = std::false_type;
68 68
69 constexpr AlignmentAllocator() noexcept = default; 69 constexpr AlignmentAllocator() noexcept = default;
70 70
@@ -83,6 +83,11 @@ public:
83 struct rebind { 83 struct rebind {
84 using other = AlignmentAllocator<T2, Align>; 84 using other = AlignmentAllocator<T2, Align>;
85 }; 85 };
86
87 template <typename T2, size_t Align2>
88 constexpr bool operator==(const AlignmentAllocator<T2, Align2>&) const noexcept {
89 return std::is_same_v<T, T2> && Align == Align2;
90 }
86}; 91};
87 92
88} // namespace Common 93} // namespace Common
diff --git a/src/common/settings.h b/src/common/settings.h
index 402339443..9ff4cf85d 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -7,7 +7,6 @@
7#include <algorithm> 7#include <algorithm>
8#include <array> 8#include <array>
9#include <atomic> 9#include <atomic>
10#include <chrono>
11#include <map> 10#include <map>
12#include <optional> 11#include <optional>
13#include <string> 12#include <string>
@@ -487,9 +486,9 @@ struct Values {
487 // System 486 // System
488 Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"}; 487 Setting<std::optional<u32>> rng_seed{std::optional<u32>(), "rng_seed"};
489 // Measured in seconds since epoch 488 // Measured in seconds since epoch
490 std::optional<std::chrono::seconds> custom_rtc; 489 std::optional<s64> custom_rtc;
491 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc` 490 // Set on game boot, reset on stop. Seconds difference between current time and `custom_rtc`
492 std::chrono::seconds custom_rtc_differential; 491 s64 custom_rtc_differential;
493 492
494 BasicSetting<s32> current_user{0, "current_user"}; 493 BasicSetting<s32> current_user{0, "current_user"};
495 RangedSetting<s32> language_index{1, 0, 17, "language_index"}; 494 RangedSetting<s32> language_index{1, 0, 17, "language_index"};
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index bf27ffe71..4fd15f111 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -263,7 +263,7 @@ void ARM_Dynarmic_64::Run() {
263} 263}
264 264
265void ARM_Dynarmic_64::Step() { 265void ARM_Dynarmic_64::Step() {
266 cb->InterpreterFallback(jit->GetPC(), 1); 266 jit->Step();
267} 267}
268 268
269ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_, 269ARM_Dynarmic_64::ARM_Dynarmic_64(System& system_, CPUInterrupts& interrupt_handlers_,
diff --git a/src/core/core.cpp b/src/core/core.cpp
index 3042d611b..3c75f42ae 100644
--- a/src/core/core.cpp
+++ b/src/core/core.cpp
@@ -196,8 +196,9 @@ struct System::Impl {
196 cpu_manager.Initialize(); 196 cpu_manager.Initialize();
197 core_timing.Initialize([&system]() { system.RegisterHostThread(); }); 197 core_timing.Initialize([&system]() { system.RegisterHostThread(); });
198 198
199 const auto current_time = std::chrono::duration_cast<std::chrono::seconds>( 199 const auto posix_time = std::chrono::system_clock::now().time_since_epoch();
200 std::chrono::system_clock::now().time_since_epoch()); 200 const auto current_time =
201 std::chrono::duration_cast<std::chrono::seconds>(posix_time).count();
201 Settings::values.custom_rtc_differential = 202 Settings::values.custom_rtc_differential =
202 Settings::values.custom_rtc.value_or(current_time) - current_time; 203 Settings::values.custom_rtc.value_or(current_time) - current_time;
203 204
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_page_table.cpp b/src/core/hle/kernel/k_page_table.cpp
index 701268545..5e0b620c2 100644
--- a/src/core/hle/kernel/k_page_table.cpp
+++ b/src/core/hle/kernel/k_page_table.cpp
@@ -363,6 +363,8 @@ ResultCode KPageTable::UnmapProcessCodeMemory(VAddr dst_addr, VAddr src_addr, st
363 block_manager->Update(src_addr, num_pages, KMemoryState::Normal, 363 block_manager->Update(src_addr, num_pages, KMemoryState::Normal,
364 KMemoryPermission::ReadAndWrite); 364 KMemoryPermission::ReadAndWrite);
365 365
366 system.InvalidateCpuInstructionCacheRange(dst_addr, size);
367
366 return ResultSuccess; 368 return ResultSuccess;
367} 369}
368 370
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/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
index 845de724d..e61261f98 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.cpp
@@ -69,8 +69,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
69 std::vector<Reloc> relocs(params.relocation_count); 69 std::vector<Reloc> relocs(params.relocation_count);
70 std::vector<u32> reloc_shifts(params.relocation_count); 70 std::vector<u32> reloc_shifts(params.relocation_count);
71 std::vector<SyncptIncr> syncpt_increments(params.syncpoint_count); 71 std::vector<SyncptIncr> syncpt_increments(params.syncpoint_count);
72 std::vector<SyncptIncr> wait_checks(params.syncpoint_count); 72 std::vector<u32> fence_thresholds(params.fence_count);
73 std::vector<Fence> fences(params.fence_count);
74 73
75 // Slice input into their respective buffers 74 // Slice input into their respective buffers
76 std::size_t offset = sizeof(IoctlSubmit); 75 std::size_t offset = sizeof(IoctlSubmit);
@@ -78,15 +77,13 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
78 offset += SliceVectors(input, relocs, params.relocation_count, offset); 77 offset += SliceVectors(input, relocs, params.relocation_count, offset);
79 offset += SliceVectors(input, reloc_shifts, params.relocation_count, offset); 78 offset += SliceVectors(input, reloc_shifts, params.relocation_count, offset);
80 offset += SliceVectors(input, syncpt_increments, params.syncpoint_count, offset); 79 offset += SliceVectors(input, syncpt_increments, params.syncpoint_count, offset);
81 offset += SliceVectors(input, wait_checks, params.syncpoint_count, offset); 80 offset += SliceVectors(input, fence_thresholds, params.fence_count, offset);
82 offset += SliceVectors(input, fences, params.fence_count, offset);
83 81
84 auto& gpu = system.GPU(); 82 auto& gpu = system.GPU();
85 if (gpu.UseNvdec()) { 83 if (gpu.UseNvdec()) {
86 for (std::size_t i = 0; i < syncpt_increments.size(); i++) { 84 for (std::size_t i = 0; i < syncpt_increments.size(); i++) {
87 const SyncptIncr& syncpt_incr = syncpt_increments[i]; 85 const SyncptIncr& syncpt_incr = syncpt_increments[i];
88 fences[i].id = syncpt_incr.id; 86 fence_thresholds[i] =
89 fences[i].value =
90 syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments); 87 syncpoint_manager.IncreaseSyncpoint(syncpt_incr.id, syncpt_incr.increments);
91 } 88 }
92 } 89 }
@@ -98,11 +95,6 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
98 cmdlist.size() * sizeof(u32)); 95 cmdlist.size() * sizeof(u32));
99 gpu.PushCommandBuffer(cmdlist); 96 gpu.PushCommandBuffer(cmdlist);
100 } 97 }
101 if (gpu.UseNvdec()) {
102 fences[0].value = syncpoint_manager.IncreaseSyncpoint(fences[0].id, 1);
103 Tegra::ChCommandHeaderList cmdlist{{(4 << 28) | fences[0].id}};
104 gpu.PushCommandBuffer(cmdlist);
105 }
106 std::memcpy(output.data(), &params, sizeof(IoctlSubmit)); 98 std::memcpy(output.data(), &params, sizeof(IoctlSubmit));
107 // Some games expect command_buffers to be written back 99 // Some games expect command_buffers to be written back
108 offset = sizeof(IoctlSubmit); 100 offset = sizeof(IoctlSubmit);
@@ -110,8 +102,7 @@ NvResult nvhost_nvdec_common::Submit(const std::vector<u8>& input, std::vector<u
110 offset += WriteVectors(output, relocs, offset); 102 offset += WriteVectors(output, relocs, offset);
111 offset += WriteVectors(output, reloc_shifts, offset); 103 offset += WriteVectors(output, reloc_shifts, offset);
112 offset += WriteVectors(output, syncpt_increments, offset); 104 offset += WriteVectors(output, syncpt_increments, offset);
113 offset += WriteVectors(output, wait_checks, offset); 105 offset += WriteVectors(output, fence_thresholds, offset);
114 offset += WriteVectors(output, fences, offset);
115 106
116 return NvResult::Success; 107 return NvResult::Success;
117} 108}
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
index af59f00d2..ae4199b79 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
+++ b/src/core/hle/service/nvdrv/devices/nvhost_nvdec_common.h
@@ -56,19 +56,16 @@ protected:
56 s32 target{}; 56 s32 target{};
57 s32 target_offset{}; 57 s32 target_offset{};
58 }; 58 };
59 static_assert(sizeof(Reloc) == 0x10, "CommandBuffer has incorrect size"); 59 static_assert(sizeof(Reloc) == 0x10, "Reloc has incorrect size");
60 60
61 struct SyncptIncr { 61 struct SyncptIncr {
62 u32 id{}; 62 u32 id{};
63 u32 increments{}; 63 u32 increments{};
64 u32 unk0{};
65 u32 unk1{};
66 u32 unk2{};
64 }; 67 };
65 static_assert(sizeof(SyncptIncr) == 0x8, "CommandBuffer has incorrect size"); 68 static_assert(sizeof(SyncptIncr) == 0x14, "SyncptIncr has incorrect size");
66
67 struct Fence {
68 u32 id{};
69 u32 value{};
70 };
71 static_assert(sizeof(Fence) == 0x8, "CommandBuffer has incorrect size");
72 69
73 struct IoctlGetSyncpoint { 70 struct IoctlGetSyncpoint {
74 // Input 71 // Input
diff --git a/src/core/hle/service/time/time_manager.cpp b/src/core/hle/service/time/time_manager.cpp
index 4bbc606a1..9c4c960ef 100644
--- a/src/core/hle/service/time/time_manager.cpp
+++ b/src/core/hle/service/time/time_manager.cpp
@@ -13,18 +13,19 @@
13#include "core/hle/service/time/time_manager.h" 13#include "core/hle/service/time/time_manager.h"
14 14
15namespace Service::Time { 15namespace Service::Time {
16 16namespace {
17constexpr Clock::TimeSpanType standard_network_clock_accuracy{0x0009356907420000ULL}; 17constexpr Clock::TimeSpanType standard_network_clock_accuracy{0x0009356907420000ULL};
18 18
19static std::chrono::seconds GetSecondsSinceEpoch() { 19s64 GetSecondsSinceEpoch() {
20 return std::chrono::duration_cast<std::chrono::seconds>( 20 const auto time_since_epoch = std::chrono::system_clock::now().time_since_epoch();
21 std::chrono::system_clock::now().time_since_epoch()) + 21 return std::chrono::duration_cast<std::chrono::seconds>(time_since_epoch).count() +
22 Settings::values.custom_rtc_differential; 22 Settings::values.custom_rtc_differential;
23} 23}
24 24
25static s64 GetExternalRtcValue() { 25s64 GetExternalRtcValue() {
26 return GetSecondsSinceEpoch().count() + TimeManager::GetExternalTimeZoneOffset(); 26 return GetSecondsSinceEpoch() + TimeManager::GetExternalTimeZoneOffset();
27} 27}
28} // Anonymous namespace
28 29
29struct TimeManager::Impl final { 30struct TimeManager::Impl final {
30 explicit Impl(Core::System& system) 31 explicit Impl(Core::System& system)
diff --git a/src/input_common/udp/client.cpp b/src/input_common/udp/client.cpp
index 9b0aec797..b9512aa2e 100644
--- a/src/input_common/udp/client.cpp
+++ b/src/input_common/udp/client.cpp
@@ -471,46 +471,42 @@ CalibrationConfigurationJob::CalibrationConfigurationJob(
471 std::function<void(u16, u16, u16, u16)> data_callback) { 471 std::function<void(u16, u16, u16, u16)> data_callback) {
472 472
473 std::thread([=, this] { 473 std::thread([=, this] {
474 constexpr u16 CALIBRATION_THRESHOLD = 100;
475
476 u16 min_x{UINT16_MAX};
477 u16 min_y{UINT16_MAX};
478 u16 max_x{};
479 u16 max_y{};
480
481 Status current_status{Status::Initialized}; 474 Status current_status{Status::Initialized};
482 SocketCallback callback{[](Response::Version) {}, [](Response::PortInfo) {}, 475 SocketCallback callback{
483 [&](Response::PadData data) { 476 [](Response::Version) {}, [](Response::PortInfo) {},
484 if (current_status == Status::Initialized) { 477 [&](Response::PadData data) {
485 // Receiving data means the communication is ready now 478 static constexpr u16 CALIBRATION_THRESHOLD = 100;
486 current_status = Status::Ready; 479 static constexpr u16 MAX_VALUE = UINT16_MAX;
487 status_callback(current_status); 480
488 } 481 if (current_status == Status::Initialized) {
489 if (data.touch[0].is_active == 0) { 482 // Receiving data means the communication is ready now
490 return; 483 current_status = Status::Ready;
491 } 484 status_callback(current_status);
492 LOG_DEBUG(Input, "Current touch: {} {}", data.touch[0].x, 485 }
493 data.touch[0].y); 486 const auto& touchpad_0 = data.touch[0];
494 min_x = std::min(min_x, static_cast<u16>(data.touch[0].x)); 487 if (touchpad_0.is_active == 0) {
495 min_y = std::min(min_y, static_cast<u16>(data.touch[0].y)); 488 return;
496 if (current_status == Status::Ready) { 489 }
497 // First touch - min data (min_x/min_y) 490 LOG_DEBUG(Input, "Current touch: {} {}", touchpad_0.x, touchpad_0.y);
498 current_status = Status::Stage1Completed; 491 const u16 min_x = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.x));
499 status_callback(current_status); 492 const u16 min_y = std::min(MAX_VALUE, static_cast<u16>(touchpad_0.y));
500 } 493 if (current_status == Status::Ready) {
501 if (data.touch[0].x - min_x > CALIBRATION_THRESHOLD && 494 // First touch - min data (min_x/min_y)
502 data.touch[0].y - min_y > CALIBRATION_THRESHOLD) { 495 current_status = Status::Stage1Completed;
503 // Set the current position as max value and finishes 496 status_callback(current_status);
504 // configuration 497 }
505 max_x = data.touch[0].x; 498 if (touchpad_0.x - min_x > CALIBRATION_THRESHOLD &&
506 max_y = data.touch[0].y; 499 touchpad_0.y - min_y > CALIBRATION_THRESHOLD) {
507 current_status = Status::Completed; 500 // Set the current position as max value and finishes configuration
508 data_callback(min_x, min_y, max_x, max_y); 501 const u16 max_x = touchpad_0.x;
509 status_callback(current_status); 502 const u16 max_y = touchpad_0.y;
510 503 current_status = Status::Completed;
511 complete_event.Set(); 504 data_callback(min_x, min_y, max_x, max_y);
512 } 505 status_callback(current_status);
513 }}; 506
507 complete_event.Set();
508 }
509 }};
514 Socket socket{host, port, std::move(callback)}; 510 Socket socket{host, port, std::move(callback)};
515 std::thread worker_thread{SocketLoop, &socket}; 511 std::thread worker_thread{SocketLoop, &socket};
516 complete_event.Wait(); 512 complete_event.Wait();
diff --git a/src/shader_recompiler/ir_opt/texture_pass.cpp b/src/shader_recompiler/ir_opt/texture_pass.cpp
index 225c238fb..96c997a58 100644
--- a/src/shader_recompiler/ir_opt/texture_pass.cpp
+++ b/src/shader_recompiler/ir_opt/texture_pass.cpp
@@ -492,7 +492,7 @@ void TexturePass(Environment& env, IR::Program& program) {
492 const auto insert_point{IR::Block::InstructionList::s_iterator_to(*inst)}; 492 const auto insert_point{IR::Block::InstructionList::s_iterator_to(*inst)};
493 IR::IREmitter ir{*texture_inst.block, insert_point}; 493 IR::IREmitter ir{*texture_inst.block, insert_point};
494 const IR::U32 shift{ir.Imm32(std::countr_zero(DESCRIPTOR_SIZE))}; 494 const IR::U32 shift{ir.Imm32(std::countr_zero(DESCRIPTOR_SIZE))};
495 inst->SetArg(0, ir.SMin(ir.ShiftRightArithmetic(cbuf.dynamic_offset, shift), 495 inst->SetArg(0, ir.UMin(ir.ShiftRightArithmetic(cbuf.dynamic_offset, shift),
496 ir.Imm32(DESCRIPTOR_SIZE - 1))); 496 ir.Imm32(DESCRIPTOR_SIZE - 1)));
497 } else { 497 } else {
498 inst->SetArg(0, IR::Value{}); 498 inst->SetArg(0, IR::Value{});
diff --git a/src/video_core/dirty_flags.h b/src/video_core/dirty_flags.h
index 504465d3f..f0d545f90 100644
--- a/src/video_core/dirty_flags.h
+++ b/src/video_core/dirty_flags.h
@@ -38,6 +38,9 @@ enum : u8 {
38 38
39 Shaders, 39 Shaders,
40 40
41 // Special entries
42 DepthBiasGlobal,
43
41 LastCommonEntry, 44 LastCommonEntry,
42}; 45};
43 46
diff --git a/src/video_core/renderer_opengl/gl_device.cpp b/src/video_core/renderer_opengl/gl_device.cpp
index 9692b8e94..0764ea6e0 100644
--- a/src/video_core/renderer_opengl/gl_device.cpp
+++ b/src/video_core/renderer_opengl/gl_device.cpp
@@ -10,6 +10,7 @@
10#include <limits> 10#include <limits>
11#include <optional> 11#include <optional>
12#include <span> 12#include <span>
13#include <stdexcept>
13#include <vector> 14#include <vector>
14 15
15#include <glad/glad.h> 16#include <glad/glad.h>
@@ -180,6 +181,21 @@ Device::Device() {
180 LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported"); 181 LOG_ERROR(Render_OpenGL, "Assembly shaders enabled but not supported");
181 shader_backend = Settings::ShaderBackend::GLSL; 182 shader_backend = Settings::ShaderBackend::GLSL;
182 } 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
183 // 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.
184 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() && 200 use_asynchronous_shaders = Settings::values.use_asynchronous_shaders.GetValue() &&
185 !(is_amd || (is_intel && !is_linux)); 201 !(is_amd || (is_intel && !is_linux));
diff --git a/src/video_core/renderer_vulkan/vk_rasterizer.cpp b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
index 3bcd6d6cc..30b47a7a0 100644
--- a/src/video_core/renderer_vulkan/vk_rasterizer.cpp
+++ b/src/video_core/renderer_vulkan/vk_rasterizer.cpp
@@ -627,9 +627,21 @@ void RasterizerVulkan::UpdateDepthBias(Tegra::Engines::Maxwell3D::Regs& regs) {
627 if (!state_tracker.TouchDepthBias()) { 627 if (!state_tracker.TouchDepthBias()) {
628 return; 628 return;
629 } 629 }
630 scheduler.Record([constant = regs.polygon_offset_units, clamp = regs.polygon_offset_clamp, 630 float units = regs.polygon_offset_units / 2.0f;
631 const bool is_d24 = regs.zeta.format == Tegra::DepthFormat::S8_UINT_Z24_UNORM ||
632 regs.zeta.format == Tegra::DepthFormat::D24X8_UNORM ||
633 regs.zeta.format == Tegra::DepthFormat::D24S8_UNORM ||
634 regs.zeta.format == Tegra::DepthFormat::D24C8_UNORM;
635 if (is_d24 && !device.SupportsD24DepthBuffer()) {
636 // the base formulas can be obtained from here:
637 // https://docs.microsoft.com/en-us/windows/win32/direct3d11/d3d10-graphics-programming-guide-output-merger-stage-depth-bias
638 const double rescale_factor =
639 static_cast<double>(1ULL << (32 - 24)) / (static_cast<double>(0x1.ep+127));
640 units = static_cast<float>(static_cast<double>(units) * rescale_factor);
641 }
642 scheduler.Record([constant = units, clamp = regs.polygon_offset_clamp,
631 factor = regs.polygon_offset_factor](vk::CommandBuffer cmdbuf) { 643 factor = regs.polygon_offset_factor](vk::CommandBuffer cmdbuf) {
632 cmdbuf.SetDepthBias(constant, clamp, factor / 2.0f); 644 cmdbuf.SetDepthBias(constant, clamp, factor);
633 }); 645 });
634} 646}
635 647
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.cpp b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
index e3b7dd61c..c00913f55 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.cpp
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.cpp
@@ -54,6 +54,7 @@ void SetupDirtyViewports(Tables& tables) {
54 FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports); 54 FillBlock(tables[0], OFF(viewport_transform), NUM(viewport_transform), Viewports);
55 FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports); 55 FillBlock(tables[0], OFF(viewports), NUM(viewports), Viewports);
56 tables[0][OFF(viewport_transform_enabled)] = Viewports; 56 tables[0][OFF(viewport_transform_enabled)] = Viewports;
57 tables[1][OFF(screen_y_control)] = Viewports;
57} 58}
58 59
59void SetupDirtyScissors(Tables& tables) { 60void SetupDirtyScissors(Tables& tables) {
diff --git a/src/video_core/renderer_vulkan/vk_state_tracker.h b/src/video_core/renderer_vulkan/vk_state_tracker.h
index d90935f52..2f2d6b31f 100644
--- a/src/video_core/renderer_vulkan/vk_state_tracker.h
+++ b/src/video_core/renderer_vulkan/vk_state_tracker.h
@@ -79,7 +79,8 @@ public:
79 } 79 }
80 80
81 bool TouchDepthBias() { 81 bool TouchDepthBias() {
82 return Exchange(Dirty::DepthBias, false); 82 return Exchange(Dirty::DepthBias, false) ||
83 Exchange(VideoCommon::Dirty::DepthBiasGlobal, false);
83 } 84 }
84 85
85 bool TouchBlendConstants() { 86 bool TouchBlendConstants() {
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 329df2e49..f70c1f764 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -221,6 +221,7 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
221 BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear)); 221 BindRenderTarget(&render_targets.depth_buffer_id, FindDepthBuffer(is_clear));
222 } 222 }
223 const ImageViewId depth_buffer_id = render_targets.depth_buffer_id; 223 const ImageViewId depth_buffer_id = render_targets.depth_buffer_id;
224
224 PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id)); 225 PrepareImageView(depth_buffer_id, true, is_clear && IsFullClear(depth_buffer_id));
225 226
226 for (size_t index = 0; index < NUM_RT; ++index) { 227 for (size_t index = 0; index < NUM_RT; ++index) {
@@ -230,6 +231,8 @@ void TextureCache<P>::UpdateRenderTargets(bool is_clear) {
230 maxwell3d.regs.render_area.width, 231 maxwell3d.regs.render_area.width,
231 maxwell3d.regs.render_area.height, 232 maxwell3d.regs.render_area.height,
232 }; 233 };
234
235 flags[Dirty::DepthBiasGlobal] = true;
233} 236}
234 237
235template <class P> 238template <class P>
diff --git a/src/video_core/vulkan_common/vulkan_device.cpp b/src/video_core/vulkan_common/vulkan_device.cpp
index 6388ed2eb..0f807990c 100644
--- a/src/video_core/vulkan_common/vulkan_device.cpp
+++ b/src/video_core/vulkan_common/vulkan_device.cpp
@@ -623,6 +623,10 @@ Device::Device(VkInstance instance_, vk::PhysicalDevice physical_, VkSurfaceKHR
623 is_float16_supported = false; 623 is_float16_supported = false;
624 } 624 }
625 625
626 supports_d24_depth =
627 IsFormatSupported(VK_FORMAT_D24_UNORM_S8_UINT,
628 VK_FORMAT_FEATURE_DEPTH_STENCIL_ATTACHMENT_BIT, FormatType::Optimal);
629
626 graphics_queue = logical.GetQueue(graphics_family); 630 graphics_queue = logical.GetQueue(graphics_family);
627 present_queue = logical.GetQueue(present_family); 631 present_queue = logical.GetQueue(present_family);
628} 632}
diff --git a/src/video_core/vulkan_common/vulkan_device.h b/src/video_core/vulkan_common/vulkan_device.h
index d9e74f1aa..2d5daf6cd 100644
--- a/src/video_core/vulkan_common/vulkan_device.h
+++ b/src/video_core/vulkan_common/vulkan_device.h
@@ -332,6 +332,10 @@ public:
332 return sets_per_pool; 332 return sets_per_pool;
333 } 333 }
334 334
335 bool SupportsD24DepthBuffer() const {
336 return supports_d24_depth;
337 }
338
335private: 339private:
336 /// Checks if the physical device is suitable. 340 /// Checks if the physical device is suitable.
337 void CheckSuitability(bool requires_swapchain) const; 341 void CheckSuitability(bool requires_swapchain) const;
@@ -425,6 +429,7 @@ private:
425 bool has_broken_cube_compatibility{}; ///< Has broken cube compatiblity bit 429 bool has_broken_cube_compatibility{}; ///< Has broken cube compatiblity bit
426 bool has_renderdoc{}; ///< Has RenderDoc attached 430 bool has_renderdoc{}; ///< Has RenderDoc attached
427 bool has_nsight_graphics{}; ///< Has Nsight Graphics attached 431 bool has_nsight_graphics{}; ///< Has Nsight Graphics attached
432 bool supports_d24_depth{}; ///< Supports D24 depth buffers.
428 433
429 // Telemetry parameters 434 // Telemetry parameters
430 std::string vendor_name; ///< Device's driver name. 435 std::string vendor_name; ///< Device's driver name.
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/config.cpp b/src/yuzu/configuration/config.cpp
index 30a864135..faea5dda1 100644
--- a/src/yuzu/configuration/config.cpp
+++ b/src/yuzu/configuration/config.cpp
@@ -918,8 +918,7 @@ void Config::ReadSystemValues() {
918 const auto custom_rtc_enabled = 918 const auto custom_rtc_enabled =
919 ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool(); 919 ReadSetting(QStringLiteral("custom_rtc_enabled"), false).toBool();
920 if (custom_rtc_enabled) { 920 if (custom_rtc_enabled) {
921 Settings::values.custom_rtc = 921 Settings::values.custom_rtc = ReadSetting(QStringLiteral("custom_rtc"), 0).toLongLong();
922 std::chrono::seconds(ReadSetting(QStringLiteral("custom_rtc"), 0).toULongLong());
923 } else { 922 } else {
924 Settings::values.custom_rtc = std::nullopt; 923 Settings::values.custom_rtc = std::nullopt;
925 } 924 }
@@ -1450,9 +1449,7 @@ void Config::SaveSystemValues() {
1450 WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(), 1449 WriteSetting(QStringLiteral("custom_rtc_enabled"), Settings::values.custom_rtc.has_value(),
1451 false); 1450 false);
1452 WriteSetting(QStringLiteral("custom_rtc"), 1451 WriteSetting(QStringLiteral("custom_rtc"),
1453 QVariant::fromValue<long long>( 1452 QVariant::fromValue<long long>(Settings::values.custom_rtc.value_or(0)), 0);
1454 Settings::values.custom_rtc.value_or(std::chrono::seconds{}).count()),
1455 0);
1456 } 1453 }
1457 1454
1458 WriteGlobalSetting(Settings::values.sound_index); 1455 WriteGlobalSetting(Settings::values.sound_index);
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/configuration/configure_system.cpp b/src/yuzu/configuration/configure_system.cpp
index eea45f8ea..56c762d64 100644
--- a/src/yuzu/configuration/configure_system.cpp
+++ b/src/yuzu/configuration/configure_system.cpp
@@ -65,8 +65,7 @@ void ConfigureSystem::SetConfiguration() {
65 QStringLiteral("%1") 65 QStringLiteral("%1")
66 .arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'}) 66 .arg(Settings::values.rng_seed.GetValue().value_or(0), 8, 16, QLatin1Char{'0'})
67 .toUpper(); 67 .toUpper();
68 const auto rtc_time = Settings::values.custom_rtc.value_or( 68 const auto rtc_time = Settings::values.custom_rtc.value_or(QDateTime::currentSecsSinceEpoch());
69 std::chrono::seconds(QDateTime::currentSecsSinceEpoch()));
70 69
71 ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value()); 70 ui->rng_seed_checkbox->setChecked(Settings::values.rng_seed.GetValue().has_value());
72 ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() && 71 ui->rng_seed_edit->setEnabled(Settings::values.rng_seed.GetValue().has_value() &&
@@ -75,7 +74,7 @@ void ConfigureSystem::SetConfiguration() {
75 74
76 ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value()); 75 ui->custom_rtc_checkbox->setChecked(Settings::values.custom_rtc.has_value());
77 ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value()); 76 ui->custom_rtc_edit->setEnabled(Settings::values.custom_rtc.has_value());
78 ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time.count())); 77 ui->custom_rtc_edit->setDateTime(QDateTime::fromSecsSinceEpoch(rtc_time));
79 78
80 if (Settings::IsConfiguringGlobal()) { 79 if (Settings::IsConfiguringGlobal()) {
81 ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue()); 80 ui->combo_language->setCurrentIndex(Settings::values.language_index.GetValue());
@@ -108,10 +107,9 @@ void ConfigureSystem::ApplyConfiguration() {
108 // to allow in-game time to be fast forwarded 107 // to allow in-game time to be fast forwarded
109 if (Settings::IsConfiguringGlobal()) { 108 if (Settings::IsConfiguringGlobal()) {
110 if (ui->custom_rtc_checkbox->isChecked()) { 109 if (ui->custom_rtc_checkbox->isChecked()) {
111 Settings::values.custom_rtc = 110 Settings::values.custom_rtc = ui->custom_rtc_edit->dateTime().toSecsSinceEpoch();
112 std::chrono::seconds(ui->custom_rtc_edit->dateTime().toSecsSinceEpoch());
113 if (system.IsPoweredOn()) { 111 if (system.IsPoweredOn()) {
114 const s64 posix_time{Settings::values.custom_rtc->count() + 112 const s64 posix_time{*Settings::values.custom_rtc +
115 Service::Time::TimeManager::GetExternalTimeZoneOffset()}; 113 Service::Time::TimeManager::GetExternalTimeZoneOffset()};
116 system.GetTimeManager().UpdateLocalSystemClockTime(posix_time); 114 system.GetTimeManager().UpdateLocalSystemClockTime(posix_time);
117 } 115 }
diff --git a/src/yuzu/configuration/configure_tas.ui b/src/yuzu/configuration/configure_tas.ui
index 6caa19031..7d44895c4 100644
--- a/src/yuzu/configuration/configure_tas.ui
+++ b/src/yuzu/configuration/configure_tas.ui
@@ -14,14 +14,14 @@
14 <item row="0" column="0" colspan="4"> 14 <item row="0" column="0" colspan="4">
15 <widget class="QLabel" name="label_1"> 15 <widget class="QLabel" name="label_1">
16 <property name="text"> 16 <property name="text">
17 <string>Reads controller input from scripts in the same format as TAS-nx scripts.&lt;br/&gt;For a more detailed explanation please consult the FAQ on the yuzu website.</string> 17 <string>&lt;html&gt;&lt;head/&gt;&lt;body&gt;&lt;p&gt;Reads controller input from scripts in the same format as TAS-nx scripts.&lt;br/&gt;For a more detailed explanation, please consult the &lt;a href=&quot;https://yuzu-emu.org/help/feature/tas/&quot;&gt;&lt;span style=&quot; text-decoration: underline; color:#039be5;&quot;&gt;help page&lt;/span&gt;&lt;/a&gt; on the yuzu website.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
18 </property> 18 </property>
19 </widget> 19 </widget>
20 </item> 20 </item>
21 <item row="1" column="0" colspan="4"> 21 <item row="1" column="0" colspan="4">
22 <widget class="QLabel" name="label_2"> 22 <widget class="QLabel" name="label_2">
23 <property name="text"> 23 <property name="text">
24 <string>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (General -&gt; Hotkeys).</string> 24 <string>To check which hotkeys control the playback/recording, please refer to the Hotkey settings (Configure -&gt; General -&gt; Hotkeys).</string>
25 </property> 25 </property>
26 <property name="wordWrap"> 26 <property name="wordWrap">
27 <bool>true</bool> 27 <bool>true</bool>
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
diff --git a/src/yuzu_cmd/config.cpp b/src/yuzu_cmd/config.cpp
index 8ca20679a..0b8fde691 100644
--- a/src/yuzu_cmd/config.cpp
+++ b/src/yuzu_cmd/config.cpp
@@ -412,8 +412,7 @@ void Config::ReadValues() {
412 412
413 const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false); 413 const auto custom_rtc_enabled = sdl2_config->GetBoolean("System", "custom_rtc_enabled", false);
414 if (custom_rtc_enabled) { 414 if (custom_rtc_enabled) {
415 Settings::values.custom_rtc = 415 Settings::values.custom_rtc = sdl2_config->GetInteger("System", "custom_rtc", 0);
416 std::chrono::seconds(sdl2_config->GetInteger("System", "custom_rtc", 0));
417 } else { 416 } else {
418 Settings::values.custom_rtc = std::nullopt; 417 Settings::values.custom_rtc = std::nullopt;
419 } 418 }