summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
Diffstat (limited to 'src/common')
-rw-r--r--src/common/CMakeLists.txt3
-rw-r--r--src/common/alignment.h21
-rw-r--r--src/common/common_funcs.h29
-rw-r--r--src/common/div_ceil.h8
-rw-r--r--src/common/error.cpp (renamed from src/common/misc.cpp)6
-rw-r--r--src/common/error.h21
-rw-r--r--src/common/fs/fs_paths.h1
-rw-r--r--src/common/fs/path_util.cpp1
-rw-r--r--src/common/fs/path_util.h1
-rw-r--r--src/common/host_memory.cpp2
-rw-r--r--src/common/intrusive_red_black_tree.h17
-rw-r--r--src/common/settings.cpp11
-rw-r--r--src/common/settings.h22
-rw-r--r--src/common/thread.cpp6
-rw-r--r--src/common/threadsafe_queue.h27
-rw-r--r--src/common/uuid.h7
-rw-r--r--src/common/vector_math.h4
17 files changed, 129 insertions, 58 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index 57922b51c..b18a2a2f5 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -53,6 +53,8 @@ add_library(common STATIC
53 div_ceil.h 53 div_ceil.h
54 dynamic_library.cpp 54 dynamic_library.cpp
55 dynamic_library.h 55 dynamic_library.h
56 error.cpp
57 error.h
56 fiber.cpp 58 fiber.cpp
57 fiber.h 59 fiber.h
58 fs/file.cpp 60 fs/file.cpp
@@ -88,7 +90,6 @@ add_library(common STATIC
88 microprofile.cpp 90 microprofile.cpp
89 microprofile.h 91 microprofile.h
90 microprofileui.h 92 microprofileui.h
91 misc.cpp
92 nvidia_flags.cpp 93 nvidia_flags.cpp
93 nvidia_flags.h 94 nvidia_flags.h
94 page_table.cpp 95 page_table.cpp
diff --git a/src/common/alignment.h b/src/common/alignment.h
index 32d796ffa..1b56569d1 100644
--- a/src/common/alignment.h
+++ b/src/common/alignment.h
@@ -9,41 +9,48 @@
9namespace Common { 9namespace Common {
10 10
11template <typename T> 11template <typename T>
12requires std::is_unsigned_v<T>[[nodiscard]] constexpr T AlignUp(T value, size_t size) { 12requires std::is_unsigned_v<T>
13[[nodiscard]] constexpr T AlignUp(T value, size_t size) {
13 auto mod{static_cast<T>(value % size)}; 14 auto mod{static_cast<T>(value % size)};
14 value -= mod; 15 value -= mod;
15 return static_cast<T>(mod == T{0} ? value : value + size); 16 return static_cast<T>(mod == T{0} ? value : value + size);
16} 17}
17 18
18template <typename T> 19template <typename T>
19requires std::is_unsigned_v<T>[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) { 20requires std::is_unsigned_v<T>
21[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) {
20 return static_cast<T>((value + ((1ULL << align_log2) - 1)) >> align_log2 << align_log2); 22 return static_cast<T>((value + ((1ULL << align_log2) - 1)) >> align_log2 << align_log2);
21} 23}
22 24
23template <typename T> 25template <typename T>
24requires std::is_unsigned_v<T>[[nodiscard]] constexpr T AlignDown(T value, size_t size) { 26requires std::is_unsigned_v<T>
27[[nodiscard]] constexpr T AlignDown(T value, size_t size) {
25 return static_cast<T>(value - value % size); 28 return static_cast<T>(value - value % size);
26} 29}
27 30
28template <typename T> 31template <typename T>
29requires std::is_unsigned_v<T>[[nodiscard]] constexpr bool Is4KBAligned(T value) { 32requires std::is_unsigned_v<T>
33[[nodiscard]] constexpr bool Is4KBAligned(T value) {
30 return (value & 0xFFF) == 0; 34 return (value & 0xFFF) == 0;
31} 35}
32 36
33template <typename T> 37template <typename T>
34requires std::is_unsigned_v<T>[[nodiscard]] constexpr bool IsWordAligned(T value) { 38requires std::is_unsigned_v<T>
39[[nodiscard]] constexpr bool IsWordAligned(T value) {
35 return (value & 0b11) == 0; 40 return (value & 0b11) == 0;
36} 41}
37 42
38template <typename T> 43template <typename T>
39requires std::is_integral_v<T>[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) { 44requires std::is_integral_v<T>
45[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) {
40 using U = typename std::make_unsigned_t<T>; 46 using U = typename std::make_unsigned_t<T>;
41 const U mask = static_cast<U>(alignment - 1); 47 const U mask = static_cast<U>(alignment - 1);
42 return (value & mask) == 0; 48 return (value & mask) == 0;
43} 49}
44 50
45template <typename T, typename U> 51template <typename T, typename U>
46requires std::is_integral_v<T>[[nodiscard]] constexpr T DivideUp(T x, U y) { 52requires std::is_integral_v<T>
53[[nodiscard]] constexpr T DivideUp(T x, U y) {
47 return (x + (y - 1)) / y; 54 return (x + (y - 1)) / y;
48} 55}
49 56
diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h
index 53bd7da60..4c1e29de6 100644
--- a/src/common/common_funcs.h
+++ b/src/common/common_funcs.h
@@ -4,9 +4,8 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <algorithm>
8#include <array> 7#include <array>
9#include <string> 8#include <iterator>
10 9
11#if !defined(ARCHITECTURE_x86_64) 10#if !defined(ARCHITECTURE_x86_64)
12#include <cstdlib> // for exit 11#include <cstdlib> // for exit
@@ -49,16 +48,6 @@ __declspec(dllimport) void __stdcall DebugBreak(void);
49 48
50#endif // _MSC_VER ndef 49#endif // _MSC_VER ndef
51 50
52// Generic function to get last error message.
53// Call directly after the command or use the error num.
54// This function might change the error code.
55// Defined in misc.cpp.
56[[nodiscard]] std::string GetLastErrorMsg();
57
58// Like GetLastErrorMsg(), but passing an explicit error code.
59// Defined in misc.cpp.
60[[nodiscard]] std::string NativeErrorToString(int e);
61
62#define DECLARE_ENUM_FLAG_OPERATORS(type) \ 51#define DECLARE_ENUM_FLAG_OPERATORS(type) \
63 [[nodiscard]] constexpr type operator|(type a, type b) noexcept { \ 52 [[nodiscard]] constexpr type operator|(type a, type b) noexcept { \
64 using T = std::underlying_type_t<type>; \ 53 using T = std::underlying_type_t<type>; \
@@ -72,6 +61,14 @@ __declspec(dllimport) void __stdcall DebugBreak(void);
72 using T = std::underlying_type_t<type>; \ 61 using T = std::underlying_type_t<type>; \
73 return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \ 62 return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \
74 } \ 63 } \
64 [[nodiscard]] constexpr type operator<<(type a, type b) noexcept { \
65 using T = std::underlying_type_t<type>; \
66 return static_cast<type>(static_cast<T>(a) << static_cast<T>(b)); \
67 } \
68 [[nodiscard]] constexpr type operator>>(type a, type b) noexcept { \
69 using T = std::underlying_type_t<type>; \
70 return static_cast<type>(static_cast<T>(a) >> static_cast<T>(b)); \
71 } \
75 constexpr type& operator|=(type& a, type b) noexcept { \ 72 constexpr type& operator|=(type& a, type b) noexcept { \
76 a = a | b; \ 73 a = a | b; \
77 return a; \ 74 return a; \
@@ -84,6 +81,14 @@ __declspec(dllimport) void __stdcall DebugBreak(void);
84 a = a ^ b; \ 81 a = a ^ b; \
85 return a; \ 82 return a; \
86 } \ 83 } \
84 constexpr type& operator<<=(type& a, type b) noexcept { \
85 a = a << b; \
86 return a; \
87 } \
88 constexpr type& operator>>=(type& a, type b) noexcept { \
89 a = a >> b; \
90 return a; \
91 } \
87 [[nodiscard]] constexpr type operator~(type key) noexcept { \ 92 [[nodiscard]] constexpr type operator~(type key) noexcept { \
88 using T = std::underlying_type_t<type>; \ 93 using T = std::underlying_type_t<type>; \
89 return static_cast<type>(~static_cast<T>(key)); \ 94 return static_cast<type>(~static_cast<T>(key)); \
diff --git a/src/common/div_ceil.h b/src/common/div_ceil.h
index 95e1489a9..e1db35464 100644
--- a/src/common/div_ceil.h
+++ b/src/common/div_ceil.h
@@ -11,15 +11,15 @@ namespace Common {
11 11
12/// Ceiled integer division. 12/// Ceiled integer division.
13template <typename N, typename D> 13template <typename N, typename D>
14requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeil(N number, 14requires std::is_integral_v<N> && std::is_unsigned_v<D>
15 D divisor) { 15[[nodiscard]] constexpr N DivCeil(N number, D divisor) {
16 return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor); 16 return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor);
17} 17}
18 18
19/// Ceiled integer division with logarithmic divisor in base 2 19/// Ceiled integer division with logarithmic divisor in base 2
20template <typename N, typename D> 20template <typename N, typename D>
21requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeilLog2( 21requires std::is_integral_v<N> && std::is_unsigned_v<D>
22 N value, D alignment_log2) { 22[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) {
23 return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2); 23 return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2);
24} 24}
25 25
diff --git a/src/common/misc.cpp b/src/common/error.cpp
index 495385b9e..d4455e310 100644
--- a/src/common/misc.cpp
+++ b/src/common/error.cpp
@@ -10,7 +10,9 @@
10#include <cstring> 10#include <cstring>
11#endif 11#endif
12 12
13#include "common/common_funcs.h" 13#include "common/error.h"
14
15namespace Common {
14 16
15std::string NativeErrorToString(int e) { 17std::string NativeErrorToString(int e) {
16#ifdef _WIN32 18#ifdef _WIN32
@@ -50,3 +52,5 @@ std::string GetLastErrorMsg() {
50 return NativeErrorToString(errno); 52 return NativeErrorToString(errno);
51#endif 53#endif
52} 54}
55
56} // namespace Common
diff --git a/src/common/error.h b/src/common/error.h
new file mode 100644
index 000000000..e084d4b0f
--- /dev/null
+++ b/src/common/error.h
@@ -0,0 +1,21 @@
1// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include <string>
8
9namespace Common {
10
11// Generic function to get last error message.
12// Call directly after the command or use the error num.
13// This function might change the error code.
14// Defined in error.cpp.
15[[nodiscard]] std::string GetLastErrorMsg();
16
17// Like GetLastErrorMsg(), but passing an explicit error code.
18// Defined in error.cpp.
19[[nodiscard]] std::string NativeErrorToString(int e);
20
21} // namespace Common
diff --git a/src/common/fs/fs_paths.h b/src/common/fs/fs_paths.h
index b32614797..5d447f108 100644
--- a/src/common/fs/fs_paths.h
+++ b/src/common/fs/fs_paths.h
@@ -21,6 +21,7 @@
21#define SCREENSHOTS_DIR "screenshots" 21#define SCREENSHOTS_DIR "screenshots"
22#define SDMC_DIR "sdmc" 22#define SDMC_DIR "sdmc"
23#define SHADER_DIR "shader" 23#define SHADER_DIR "shader"
24#define TAS_DIR "tas"
24 25
25// yuzu-specific files 26// yuzu-specific files
26 27
diff --git a/src/common/fs/path_util.cpp b/src/common/fs/path_util.cpp
index 6cdd14f13..43b79bd6d 100644
--- a/src/common/fs/path_util.cpp
+++ b/src/common/fs/path_util.cpp
@@ -116,6 +116,7 @@ private:
116 GenerateYuzuPath(YuzuPath::ScreenshotsDir, yuzu_path / SCREENSHOTS_DIR); 116 GenerateYuzuPath(YuzuPath::ScreenshotsDir, yuzu_path / SCREENSHOTS_DIR);
117 GenerateYuzuPath(YuzuPath::SDMCDir, yuzu_path / SDMC_DIR); 117 GenerateYuzuPath(YuzuPath::SDMCDir, yuzu_path / SDMC_DIR);
118 GenerateYuzuPath(YuzuPath::ShaderDir, yuzu_path / SHADER_DIR); 118 GenerateYuzuPath(YuzuPath::ShaderDir, yuzu_path / SHADER_DIR);
119 GenerateYuzuPath(YuzuPath::TASDir, yuzu_path / TAS_DIR);
119 } 120 }
120 121
121 ~PathManagerImpl() = default; 122 ~PathManagerImpl() = default;
diff --git a/src/common/fs/path_util.h b/src/common/fs/path_util.h
index f956ac9a2..0a9e3a145 100644
--- a/src/common/fs/path_util.h
+++ b/src/common/fs/path_util.h
@@ -23,6 +23,7 @@ enum class YuzuPath {
23 ScreenshotsDir, // Where yuzu screenshots are stored. 23 ScreenshotsDir, // Where yuzu screenshots are stored.
24 SDMCDir, // Where the emulated SDMC is stored. 24 SDMCDir, // Where the emulated SDMC is stored.
25 ShaderDir, // Where shaders are stored. 25 ShaderDir, // Where shaders are stored.
26 TASDir, // Where TAS scripts are stored.
26}; 27};
27 28
28/** 29/**
diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp
index 6661244cf..b44a44949 100644
--- a/src/common/host_memory.cpp
+++ b/src/common/host_memory.cpp
@@ -314,8 +314,8 @@ private:
314 } 314 }
315 315
316 void UntrackPlaceholder(boost::icl::separate_interval_set<size_t>::iterator it) { 316 void UntrackPlaceholder(boost::icl::separate_interval_set<size_t>::iterator it) {
317 placeholders.erase(it);
318 placeholder_host_pointers.erase(it->lower()); 317 placeholder_host_pointers.erase(it->lower());
318 placeholders.erase(it);
319 } 319 }
320 320
321 /// Return true when a given memory region is a "nieche" and the placeholders don't have to be 321 /// Return true when a given memory region is a "nieche" and the placeholders don't have to be
diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h
index 1f696fe80..3173cc449 100644
--- a/src/common/intrusive_red_black_tree.h
+++ b/src/common/intrusive_red_black_tree.h
@@ -235,20 +235,19 @@ public:
235 235
236template <typename T> 236template <typename T>
237concept HasLightCompareType = requires { 237concept HasLightCompareType = requires {
238 { std::is_same<typename T::LightCompareType, void>::value } 238 { std::is_same<typename T::LightCompareType, void>::value } -> std::convertible_to<bool>;
239 ->std::convertible_to<bool>;
240}; 239};
241 240
242namespace impl { 241namespace impl {
243 242
244template <typename T, typename Default> 243 template <typename T, typename Default>
245consteval auto* GetLightCompareType() { 244 consteval auto* GetLightCompareType() {
246 if constexpr (HasLightCompareType<T>) { 245 if constexpr (HasLightCompareType<T>) {
247 return static_cast<typename T::LightCompareType*>(nullptr); 246 return static_cast<typename T::LightCompareType*>(nullptr);
248 } else { 247 } else {
249 return static_cast<Default*>(nullptr); 248 return static_cast<Default*>(nullptr);
249 }
250 } 250 }
251}
252 251
253} // namespace impl 252} // namespace impl
254 253
diff --git a/src/common/settings.cpp b/src/common/settings.cpp
index fd3b639cd..9dd5e3efb 100644
--- a/src/common/settings.cpp
+++ b/src/common/settings.cpp
@@ -54,14 +54,13 @@ void LogSettings() {
54 log_setting("Renderer_GPUAccuracyLevel", values.gpu_accuracy.GetValue()); 54 log_setting("Renderer_GPUAccuracyLevel", values.gpu_accuracy.GetValue());
55 log_setting("Renderer_UseAsynchronousGpuEmulation", 55 log_setting("Renderer_UseAsynchronousGpuEmulation",
56 values.use_asynchronous_gpu_emulation.GetValue()); 56 values.use_asynchronous_gpu_emulation.GetValue());
57 log_setting("Renderer_UseNvdecEmulation", values.use_nvdec_emulation.GetValue()); 57 log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue());
58 log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue()); 58 log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue());
59 log_setting("Renderer_UseVsync", values.use_vsync.GetValue()); 59 log_setting("Renderer_UseVsync", values.use_vsync.GetValue());
60 log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue()); 60 log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue());
61 log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); 61 log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue());
62 log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); 62 log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue());
63 log_setting("Audio_OutputEngine", values.sink_id.GetValue()); 63 log_setting("Audio_OutputEngine", values.sink_id.GetValue());
64 log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue());
65 log_setting("Audio_OutputDevice", values.audio_device_id.GetValue()); 64 log_setting("Audio_OutputDevice", values.audio_device_id.GetValue());
66 log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd.GetValue()); 65 log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd.GetValue());
67 log_path("DataStorage_CacheDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir)); 66 log_path("DataStorage_CacheDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir));
@@ -70,8 +69,9 @@ void LogSettings() {
70 log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir)); 69 log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir));
71 log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir)); 70 log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir));
72 log_setting("Debugging_ProgramArgs", values.program_args.GetValue()); 71 log_setting("Debugging_ProgramArgs", values.program_args.GetValue());
73 log_setting("Services_BCATBackend", values.bcat_backend.GetValue()); 72 log_setting("Input_EnableMotion", values.motion_enabled.GetValue());
74 log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local.GetValue()); 73 log_setting("Input_EnableVibration", values.vibration_enabled.GetValue());
74 log_setting("Input_EnableRawInput", values.enable_raw_input.GetValue());
75} 75}
76 76
77bool IsConfiguringGlobal() { 77bool IsConfiguringGlobal() {
@@ -112,7 +112,6 @@ void RestoreGlobalState(bool is_powered_on) {
112 } 112 }
113 113
114 // Audio 114 // Audio
115 values.enable_audio_stretching.SetGlobal(true);
116 values.volume.SetGlobal(true); 115 values.volume.SetGlobal(true);
117 116
118 // Core 117 // Core
@@ -136,7 +135,7 @@ void RestoreGlobalState(bool is_powered_on) {
136 values.use_disk_shader_cache.SetGlobal(true); 135 values.use_disk_shader_cache.SetGlobal(true);
137 values.gpu_accuracy.SetGlobal(true); 136 values.gpu_accuracy.SetGlobal(true);
138 values.use_asynchronous_gpu_emulation.SetGlobal(true); 137 values.use_asynchronous_gpu_emulation.SetGlobal(true);
139 values.use_nvdec_emulation.SetGlobal(true); 138 values.nvdec_emulation.SetGlobal(true);
140 values.accelerate_astc.SetGlobal(true); 139 values.accelerate_astc.SetGlobal(true);
141 values.use_vsync.SetGlobal(true); 140 values.use_vsync.SetGlobal(true);
142 values.shader_backend.SetGlobal(true); 141 values.shader_backend.SetGlobal(true);
diff --git a/src/common/settings.h b/src/common/settings.h
index ec4d381e8..402339443 100644
--- a/src/common/settings.h
+++ b/src/common/settings.h
@@ -16,7 +16,6 @@
16 16
17#include "common/common_types.h" 17#include "common/common_types.h"
18#include "common/settings_input.h" 18#include "common/settings_input.h"
19#include "input_common/udp/client.h"
20 19
21namespace Settings { 20namespace Settings {
22 21
@@ -48,6 +47,12 @@ enum class FullscreenMode : u32 {
48 Exclusive = 1, 47 Exclusive = 1,
49}; 48};
50 49
50enum class NvdecEmulation : u32 {
51 Off = 0,
52 CPU = 1,
53 GPU = 2,
54};
55
51/** The BasicSetting class is a simple resource manager. It defines a label and default value 56/** The BasicSetting class is a simple resource manager. It defines a label and default value
52 * alongside the actual value of the setting for simpler and less-error prone use with frontend 57 * alongside the actual value of the setting for simpler and less-error prone use with frontend
53 * configurations. Setting a default value and label is required, though subclasses may deviate from 58 * configurations. Setting a default value and label is required, though subclasses may deviate from
@@ -409,7 +414,6 @@ struct Values {
409 BasicSetting<std::string> audio_device_id{"auto", "output_device"}; 414 BasicSetting<std::string> audio_device_id{"auto", "output_device"};
410 BasicSetting<std::string> sink_id{"auto", "output_engine"}; 415 BasicSetting<std::string> sink_id{"auto", "output_engine"};
411 BasicSetting<bool> audio_muted{false, "audio_muted"}; 416 BasicSetting<bool> audio_muted{false, "audio_muted"};
412 Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"};
413 RangedSetting<u8> volume{100, 0, 100, "volume"}; 417 RangedSetting<u8> volume{100, 0, 100, "volume"};
414 418
415 // Core 419 // Core
@@ -466,7 +470,7 @@ struct Values {
466 RangedSetting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal, 470 RangedSetting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal,
467 GPUAccuracy::Extreme, "gpu_accuracy"}; 471 GPUAccuracy::Extreme, "gpu_accuracy"};
468 Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"}; 472 Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"};
469 Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"}; 473 Setting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"};
470 Setting<bool> accelerate_astc{true, "accelerate_astc"}; 474 Setting<bool> accelerate_astc{true, "accelerate_astc"};
471 Setting<bool> use_vsync{true, "use_vsync"}; 475 Setting<bool> use_vsync{true, "use_vsync"};
472 BasicRangedSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"}; 476 BasicRangedSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"};
@@ -498,14 +502,20 @@ struct Values {
498 502
499 Setting<bool> use_docked_mode{true, "use_docked_mode"}; 503 Setting<bool> use_docked_mode{true, "use_docked_mode"};
500 504
505 BasicSetting<bool> enable_raw_input{false, "enable_raw_input"};
506
501 Setting<bool> vibration_enabled{true, "vibration_enabled"}; 507 Setting<bool> vibration_enabled{true, "vibration_enabled"};
502 Setting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"}; 508 Setting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"};
503 509
504 Setting<bool> motion_enabled{true, "motion_enabled"}; 510 Setting<bool> motion_enabled{true, "motion_enabled"};
505 BasicSetting<std::string> motion_device{"engine:motion_emu,update_period:100,sensitivity:0.01", 511 BasicSetting<std::string> motion_device{"engine:motion_emu,update_period:100,sensitivity:0.01",
506 "motion_device"}; 512 "motion_device"};
507 BasicSetting<std::string> udp_input_servers{InputCommon::CemuhookUDP::DEFAULT_SRV, 513 BasicSetting<std::string> udp_input_servers{"127.0.0.1:26760", "udp_input_servers"};
508 "udp_input_servers"}; 514
515 BasicSetting<bool> pause_tas_on_load{true, "pause_tas_on_load"};
516 BasicSetting<bool> tas_enable{false, "tas_enable"};
517 BasicSetting<bool> tas_loop{false, "tas_loop"};
518 BasicSetting<bool> tas_swap_controllers{true, "tas_swap_controllers"};
509 519
510 BasicSetting<bool> mouse_panning{false, "mouse_panning"}; 520 BasicSetting<bool> mouse_panning{false, "mouse_panning"};
511 BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"}; 521 BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"};
@@ -558,8 +568,6 @@ struct Values {
558 BasicSetting<bool> use_dev_keys{false, "use_dev_keys"}; 568 BasicSetting<bool> use_dev_keys{false, "use_dev_keys"};
559 569
560 // Network 570 // Network
561 BasicSetting<std::string> bcat_backend{"none", "bcat_backend"};
562 BasicSetting<bool> bcat_boxcat_local{false, "bcat_boxcat_local"};
563 BasicSetting<std::string> network_interface{std::string(), "network_interface"}; 571 BasicSetting<std::string> network_interface{std::string(), "network_interface"};
564 572
565 // WebService 573 // WebService
diff --git a/src/common/thread.cpp b/src/common/thread.cpp
index d2c1ac60d..946a1114d 100644
--- a/src/common/thread.cpp
+++ b/src/common/thread.cpp
@@ -2,7 +2,9 @@
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include "common/common_funcs.h" 5#include <string>
6
7#include "common/error.h"
6#include "common/logging/log.h" 8#include "common/logging/log.h"
7#include "common/thread.h" 9#include "common/thread.h"
8#ifdef __APPLE__ 10#ifdef __APPLE__
@@ -21,8 +23,6 @@
21#include <unistd.h> 23#include <unistd.h>
22#endif 24#endif
23 25
24#include <string>
25
26#ifdef __FreeBSD__ 26#ifdef __FreeBSD__
27#define cpu_set_t cpuset_t 27#define cpu_set_t cpuset_t
28#endif 28#endif
diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h
index 8430b9778..2c8c2b90e 100644
--- a/src/common/threadsafe_queue.h
+++ b/src/common/threadsafe_queue.h
@@ -14,7 +14,7 @@
14#include <utility> 14#include <utility>
15 15
16namespace Common { 16namespace Common {
17template <typename T> 17template <typename T, bool with_stop_token = false>
18class SPSCQueue { 18class SPSCQueue {
19public: 19public:
20 SPSCQueue() { 20 SPSCQueue() {
@@ -84,7 +84,7 @@ public:
84 void Wait() { 84 void Wait() {
85 if (Empty()) { 85 if (Empty()) {
86 std::unique_lock lock{cv_mutex}; 86 std::unique_lock lock{cv_mutex};
87 cv.wait(lock, [this]() { return !Empty(); }); 87 cv.wait(lock, [this] { return !Empty(); });
88 } 88 }
89 } 89 }
90 90
@@ -95,6 +95,19 @@ public:
95 return t; 95 return t;
96 } 96 }
97 97
98 T PopWait(std::stop_token stop_token) {
99 if (Empty()) {
100 std::unique_lock lock{cv_mutex};
101 cv.wait(lock, stop_token, [this] { return !Empty(); });
102 }
103 if (stop_token.stop_requested()) {
104 return T{};
105 }
106 T t;
107 Pop(t);
108 return t;
109 }
110
98 // not thread-safe 111 // not thread-safe
99 void Clear() { 112 void Clear() {
100 size.store(0); 113 size.store(0);
@@ -123,13 +136,13 @@ private:
123 ElementPtr* read_ptr; 136 ElementPtr* read_ptr;
124 std::atomic_size_t size{0}; 137 std::atomic_size_t size{0};
125 std::mutex cv_mutex; 138 std::mutex cv_mutex;
126 std::condition_variable cv; 139 std::conditional_t<with_stop_token, std::condition_variable_any, std::condition_variable> cv;
127}; 140};
128 141
129// a simple thread-safe, 142// a simple thread-safe,
130// single reader, multiple writer queue 143// single reader, multiple writer queue
131 144
132template <typename T> 145template <typename T, bool with_stop_token = false>
133class MPSCQueue { 146class MPSCQueue {
134public: 147public:
135 [[nodiscard]] std::size_t Size() const { 148 [[nodiscard]] std::size_t Size() const {
@@ -166,13 +179,17 @@ public:
166 return spsc_queue.PopWait(); 179 return spsc_queue.PopWait();
167 } 180 }
168 181
182 T PopWait(std::stop_token stop_token) {
183 return spsc_queue.PopWait(stop_token);
184 }
185
169 // not thread-safe 186 // not thread-safe
170 void Clear() { 187 void Clear() {
171 spsc_queue.Clear(); 188 spsc_queue.Clear();
172 } 189 }
173 190
174private: 191private:
175 SPSCQueue<T> spsc_queue; 192 SPSCQueue<T, with_stop_token> spsc_queue;
176 std::mutex write_lock; 193 std::mutex write_lock;
177}; 194};
178} // namespace Common 195} // namespace Common
diff --git a/src/common/uuid.h b/src/common/uuid.h
index 2353179d8..8ea01f8da 100644
--- a/src/common/uuid.h
+++ b/src/common/uuid.h
@@ -58,6 +58,13 @@ struct UUID {
58 uuid = INVALID_UUID; 58 uuid = INVALID_UUID;
59 } 59 }
60 60
61 [[nodiscard]] constexpr bool IsInvalid() const {
62 return uuid == INVALID_UUID;
63 }
64 [[nodiscard]] constexpr bool IsValid() const {
65 return !IsInvalid();
66 }
67
61 // TODO(ogniK): Properly generate a Nintendo ID 68 // TODO(ogniK): Properly generate a Nintendo ID
62 [[nodiscard]] constexpr u64 GetNintendoID() const { 69 [[nodiscard]] constexpr u64 GetNintendoID() const {
63 return uuid[0]; 70 return uuid[0];
diff --git a/src/common/vector_math.h b/src/common/vector_math.h
index 22dba3c2d..ba7c363c1 100644
--- a/src/common/vector_math.h
+++ b/src/common/vector_math.h
@@ -667,8 +667,8 @@ template <typename T>
667 667
668// linear interpolation via float: 0.0=begin, 1.0=end 668// linear interpolation via float: 0.0=begin, 1.0=end
669template <typename X> 669template <typename X>
670[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end, 670[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{})
671 const float t) { 671 Lerp(const X& begin, const X& end, const float t) {
672 return begin * (1.f - t) + end * t; 672 return begin * (1.f - t) + end * t;
673} 673}
674 674