diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/CMakeLists.txt | 3 | ||||
-rw-r--r-- | src/common/alignment.h | 21 | ||||
-rw-r--r-- | src/common/common_funcs.h | 29 | ||||
-rw-r--r-- | src/common/div_ceil.h | 8 | ||||
-rw-r--r-- | src/common/error.cpp (renamed from src/common/misc.cpp) | 6 | ||||
-rw-r--r-- | src/common/error.h | 21 | ||||
-rw-r--r-- | src/common/fs/fs_paths.h | 1 | ||||
-rw-r--r-- | src/common/fs/path_util.cpp | 1 | ||||
-rw-r--r-- | src/common/fs/path_util.h | 1 | ||||
-rw-r--r-- | src/common/host_memory.cpp | 2 | ||||
-rw-r--r-- | src/common/intrusive_red_black_tree.h | 17 | ||||
-rw-r--r-- | src/common/settings.cpp | 11 | ||||
-rw-r--r-- | src/common/settings.h | 22 | ||||
-rw-r--r-- | src/common/thread.cpp | 6 | ||||
-rw-r--r-- | src/common/threadsafe_queue.h | 27 | ||||
-rw-r--r-- | src/common/uuid.h | 7 | ||||
-rw-r--r-- | src/common/vector_math.h | 4 |
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 div_ceil.h dynamic_library.cpp dynamic_library.h + error.cpp + error.h fiber.cpp fiber.h fs/file.cpp @@ -88,7 +90,6 @@ add_library(common STATIC microprofile.cpp microprofile.h microprofileui.h - misc.cpp nvidia_flags.cpp nvidia_flags.h 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 @@ namespace Common { template <typename T> -requires std::is_unsigned_v<T>[[nodiscard]] constexpr T AlignUp(T value, size_t size) { +requires std::is_unsigned_v<T> +[[nodiscard]] constexpr T AlignUp(T value, size_t size) { auto mod{static_cast<T>(value % size)}; value -= mod; return static_cast<T>(mod == T{0} ? value : value + size); } template <typename T> -requires std::is_unsigned_v<T>[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) { +requires std::is_unsigned_v<T> +[[nodiscard]] constexpr T AlignUpLog2(T value, size_t align_log2) { return static_cast<T>((value + ((1ULL << align_log2) - 1)) >> align_log2 << align_log2); } template <typename T> -requires std::is_unsigned_v<T>[[nodiscard]] constexpr T AlignDown(T value, size_t size) { +requires std::is_unsigned_v<T> +[[nodiscard]] constexpr T AlignDown(T value, size_t size) { return static_cast<T>(value - value % size); } template <typename T> -requires std::is_unsigned_v<T>[[nodiscard]] constexpr bool Is4KBAligned(T value) { +requires std::is_unsigned_v<T> +[[nodiscard]] constexpr bool Is4KBAligned(T value) { return (value & 0xFFF) == 0; } template <typename T> -requires std::is_unsigned_v<T>[[nodiscard]] constexpr bool IsWordAligned(T value) { +requires std::is_unsigned_v<T> +[[nodiscard]] constexpr bool IsWordAligned(T value) { return (value & 0b11) == 0; } template <typename T> -requires std::is_integral_v<T>[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) { +requires std::is_integral_v<T> +[[nodiscard]] constexpr bool IsAligned(T value, size_t alignment) { using U = typename std::make_unsigned_t<T>; const U mask = static_cast<U>(alignment - 1); return (value & mask) == 0; } template <typename T, typename U> -requires std::is_integral_v<T>[[nodiscard]] constexpr T DivideUp(T x, U y) { +requires std::is_integral_v<T> +[[nodiscard]] constexpr T DivideUp(T x, U y) { return (x + (y - 1)) / y; } 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 @@ #pragma once -#include <algorithm> #include <array> -#include <string> +#include <iterator> #if !defined(ARCHITECTURE_x86_64) #include <cstdlib> // for exit @@ -49,16 +48,6 @@ __declspec(dllimport) void __stdcall DebugBreak(void); #endif // _MSC_VER ndef -// Generic function to get last error message. -// Call directly after the command or use the error num. -// This function might change the error code. -// Defined in misc.cpp. -[[nodiscard]] std::string GetLastErrorMsg(); - -// Like GetLastErrorMsg(), but passing an explicit error code. -// Defined in misc.cpp. -[[nodiscard]] std::string NativeErrorToString(int e); - #define DECLARE_ENUM_FLAG_OPERATORS(type) \ [[nodiscard]] constexpr type operator|(type a, type b) noexcept { \ using T = std::underlying_type_t<type>; \ @@ -72,6 +61,14 @@ __declspec(dllimport) void __stdcall DebugBreak(void); using T = std::underlying_type_t<type>; \ return static_cast<type>(static_cast<T>(a) ^ static_cast<T>(b)); \ } \ + [[nodiscard]] constexpr type operator<<(type a, type b) noexcept { \ + using T = std::underlying_type_t<type>; \ + return static_cast<type>(static_cast<T>(a) << static_cast<T>(b)); \ + } \ + [[nodiscard]] constexpr type operator>>(type a, type b) noexcept { \ + using T = std::underlying_type_t<type>; \ + return static_cast<type>(static_cast<T>(a) >> static_cast<T>(b)); \ + } \ constexpr type& operator|=(type& a, type b) noexcept { \ a = a | b; \ return a; \ @@ -84,6 +81,14 @@ __declspec(dllimport) void __stdcall DebugBreak(void); a = a ^ b; \ return a; \ } \ + constexpr type& operator<<=(type& a, type b) noexcept { \ + a = a << b; \ + return a; \ + } \ + constexpr type& operator>>=(type& a, type b) noexcept { \ + a = a >> b; \ + return a; \ + } \ [[nodiscard]] constexpr type operator~(type key) noexcept { \ using T = std::underlying_type_t<type>; \ 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 { /// Ceiled integer division. template <typename N, typename D> -requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeil(N number, - D divisor) { +requires std::is_integral_v<N> && std::is_unsigned_v<D> +[[nodiscard]] constexpr N DivCeil(N number, D divisor) { return static_cast<N>((static_cast<D>(number) + divisor - 1) / divisor); } /// Ceiled integer division with logarithmic divisor in base 2 template <typename N, typename D> -requires std::is_integral_v<N>&& std::is_unsigned_v<D>[[nodiscard]] constexpr N DivCeilLog2( - N value, D alignment_log2) { +requires std::is_integral_v<N> && std::is_unsigned_v<D> +[[nodiscard]] constexpr N DivCeilLog2(N value, D alignment_log2) { return static_cast<N>((static_cast<D>(value) + (D(1) << alignment_log2) - 1) >> alignment_log2); } 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 @@ #include <cstring> #endif -#include "common/common_funcs.h" +#include "common/error.h" + +namespace Common { std::string NativeErrorToString(int e) { #ifdef _WIN32 @@ -50,3 +52,5 @@ std::string GetLastErrorMsg() { return NativeErrorToString(errno); #endif } + +} // 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 @@ +// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#pragma once + +#include <string> + +namespace Common { + +// Generic function to get last error message. +// Call directly after the command or use the error num. +// This function might change the error code. +// Defined in error.cpp. +[[nodiscard]] std::string GetLastErrorMsg(); + +// Like GetLastErrorMsg(), but passing an explicit error code. +// Defined in error.cpp. +[[nodiscard]] std::string NativeErrorToString(int e); + +} // 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 @@ #define SCREENSHOTS_DIR "screenshots" #define SDMC_DIR "sdmc" #define SHADER_DIR "shader" +#define TAS_DIR "tas" // yuzu-specific files 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: GenerateYuzuPath(YuzuPath::ScreenshotsDir, yuzu_path / SCREENSHOTS_DIR); GenerateYuzuPath(YuzuPath::SDMCDir, yuzu_path / SDMC_DIR); GenerateYuzuPath(YuzuPath::ShaderDir, yuzu_path / SHADER_DIR); + GenerateYuzuPath(YuzuPath::TASDir, yuzu_path / TAS_DIR); } ~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 { ScreenshotsDir, // Where yuzu screenshots are stored. SDMCDir, // Where the emulated SDMC is stored. ShaderDir, // Where shaders are stored. + TASDir, // Where TAS scripts are stored. }; /** 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: } void UntrackPlaceholder(boost::icl::separate_interval_set<size_t>::iterator it) { - placeholders.erase(it); placeholder_host_pointers.erase(it->lower()); + placeholders.erase(it); } /// 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: template <typename T> concept HasLightCompareType = requires { - { std::is_same<typename T::LightCompareType, void>::value } - ->std::convertible_to<bool>; + { std::is_same<typename T::LightCompareType, void>::value } -> std::convertible_to<bool>; }; namespace impl { -template <typename T, typename Default> -consteval auto* GetLightCompareType() { - if constexpr (HasLightCompareType<T>) { - return static_cast<typename T::LightCompareType*>(nullptr); - } else { - return static_cast<Default*>(nullptr); + template <typename T, typename Default> + consteval auto* GetLightCompareType() { + if constexpr (HasLightCompareType<T>) { + return static_cast<typename T::LightCompareType*>(nullptr); + } else { + return static_cast<Default*>(nullptr); + } } -} } // namespace impl 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() { log_setting("Renderer_GPUAccuracyLevel", values.gpu_accuracy.GetValue()); log_setting("Renderer_UseAsynchronousGpuEmulation", values.use_asynchronous_gpu_emulation.GetValue()); - log_setting("Renderer_UseNvdecEmulation", values.use_nvdec_emulation.GetValue()); + log_setting("Renderer_NvdecEmulation", values.nvdec_emulation.GetValue()); log_setting("Renderer_AccelerateASTC", values.accelerate_astc.GetValue()); log_setting("Renderer_UseVsync", values.use_vsync.GetValue()); log_setting("Renderer_ShaderBackend", values.shader_backend.GetValue()); log_setting("Renderer_UseAsynchronousShaders", values.use_asynchronous_shaders.GetValue()); log_setting("Renderer_AnisotropicFilteringLevel", values.max_anisotropy.GetValue()); log_setting("Audio_OutputEngine", values.sink_id.GetValue()); - log_setting("Audio_EnableAudioStretching", values.enable_audio_stretching.GetValue()); log_setting("Audio_OutputDevice", values.audio_device_id.GetValue()); log_setting("DataStorage_UseVirtualSd", values.use_virtual_sd.GetValue()); log_path("DataStorage_CacheDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::CacheDir)); @@ -70,8 +69,9 @@ void LogSettings() { log_path("DataStorage_NANDDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::NANDDir)); log_path("DataStorage_SDMCDir", Common::FS::GetYuzuPath(Common::FS::YuzuPath::SDMCDir)); log_setting("Debugging_ProgramArgs", values.program_args.GetValue()); - log_setting("Services_BCATBackend", values.bcat_backend.GetValue()); - log_setting("Services_BCATBoxcatLocal", values.bcat_boxcat_local.GetValue()); + log_setting("Input_EnableMotion", values.motion_enabled.GetValue()); + log_setting("Input_EnableVibration", values.vibration_enabled.GetValue()); + log_setting("Input_EnableRawInput", values.enable_raw_input.GetValue()); } bool IsConfiguringGlobal() { @@ -112,7 +112,6 @@ void RestoreGlobalState(bool is_powered_on) { } // Audio - values.enable_audio_stretching.SetGlobal(true); values.volume.SetGlobal(true); // Core @@ -136,7 +135,7 @@ void RestoreGlobalState(bool is_powered_on) { values.use_disk_shader_cache.SetGlobal(true); values.gpu_accuracy.SetGlobal(true); values.use_asynchronous_gpu_emulation.SetGlobal(true); - values.use_nvdec_emulation.SetGlobal(true); + values.nvdec_emulation.SetGlobal(true); values.accelerate_astc.SetGlobal(true); values.use_vsync.SetGlobal(true); 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 @@ #include "common/common_types.h" #include "common/settings_input.h" -#include "input_common/udp/client.h" namespace Settings { @@ -48,6 +47,12 @@ enum class FullscreenMode : u32 { Exclusive = 1, }; +enum class NvdecEmulation : u32 { + Off = 0, + CPU = 1, + GPU = 2, +}; + /** The BasicSetting class is a simple resource manager. It defines a label and default value * alongside the actual value of the setting for simpler and less-error prone use with frontend * configurations. Setting a default value and label is required, though subclasses may deviate from @@ -409,7 +414,6 @@ struct Values { BasicSetting<std::string> audio_device_id{"auto", "output_device"}; BasicSetting<std::string> sink_id{"auto", "output_engine"}; BasicSetting<bool> audio_muted{false, "audio_muted"}; - Setting<bool> enable_audio_stretching{true, "enable_audio_stretching"}; RangedSetting<u8> volume{100, 0, 100, "volume"}; // Core @@ -466,7 +470,7 @@ struct Values { RangedSetting<GPUAccuracy> gpu_accuracy{GPUAccuracy::High, GPUAccuracy::Normal, GPUAccuracy::Extreme, "gpu_accuracy"}; Setting<bool> use_asynchronous_gpu_emulation{true, "use_asynchronous_gpu_emulation"}; - Setting<bool> use_nvdec_emulation{true, "use_nvdec_emulation"}; + Setting<NvdecEmulation> nvdec_emulation{NvdecEmulation::GPU, "nvdec_emulation"}; Setting<bool> accelerate_astc{true, "accelerate_astc"}; Setting<bool> use_vsync{true, "use_vsync"}; BasicRangedSetting<u16> fps_cap{1000, 1, 1000, "fps_cap"}; @@ -498,14 +502,20 @@ struct Values { Setting<bool> use_docked_mode{true, "use_docked_mode"}; + BasicSetting<bool> enable_raw_input{false, "enable_raw_input"}; + Setting<bool> vibration_enabled{true, "vibration_enabled"}; Setting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"}; Setting<bool> motion_enabled{true, "motion_enabled"}; BasicSetting<std::string> motion_device{"engine:motion_emu,update_period:100,sensitivity:0.01", "motion_device"}; - BasicSetting<std::string> udp_input_servers{InputCommon::CemuhookUDP::DEFAULT_SRV, - "udp_input_servers"}; + BasicSetting<std::string> udp_input_servers{"127.0.0.1:26760", "udp_input_servers"}; + + BasicSetting<bool> pause_tas_on_load{true, "pause_tas_on_load"}; + BasicSetting<bool> tas_enable{false, "tas_enable"}; + BasicSetting<bool> tas_loop{false, "tas_loop"}; + BasicSetting<bool> tas_swap_controllers{true, "tas_swap_controllers"}; BasicSetting<bool> mouse_panning{false, "mouse_panning"}; BasicRangedSetting<u8> mouse_panning_sensitivity{10, 1, 100, "mouse_panning_sensitivity"}; @@ -558,8 +568,6 @@ struct Values { BasicSetting<bool> use_dev_keys{false, "use_dev_keys"}; // Network - BasicSetting<std::string> bcat_backend{"none", "bcat_backend"}; - BasicSetting<bool> bcat_boxcat_local{false, "bcat_boxcat_local"}; BasicSetting<std::string> network_interface{std::string(), "network_interface"}; // 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 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. -#include "common/common_funcs.h" +#include <string> + +#include "common/error.h" #include "common/logging/log.h" #include "common/thread.h" #ifdef __APPLE__ @@ -21,8 +23,6 @@ #include <unistd.h> #endif -#include <string> - #ifdef __FreeBSD__ #define cpu_set_t cpuset_t #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 @@ #include <utility> namespace Common { -template <typename T> +template <typename T, bool with_stop_token = false> class SPSCQueue { public: SPSCQueue() { @@ -84,7 +84,7 @@ public: void Wait() { if (Empty()) { std::unique_lock lock{cv_mutex}; - cv.wait(lock, [this]() { return !Empty(); }); + cv.wait(lock, [this] { return !Empty(); }); } } @@ -95,6 +95,19 @@ public: return t; } + T PopWait(std::stop_token stop_token) { + if (Empty()) { + std::unique_lock lock{cv_mutex}; + cv.wait(lock, stop_token, [this] { return !Empty(); }); + } + if (stop_token.stop_requested()) { + return T{}; + } + T t; + Pop(t); + return t; + } + // not thread-safe void Clear() { size.store(0); @@ -123,13 +136,13 @@ private: ElementPtr* read_ptr; std::atomic_size_t size{0}; std::mutex cv_mutex; - std::condition_variable cv; + std::conditional_t<with_stop_token, std::condition_variable_any, std::condition_variable> cv; }; // a simple thread-safe, // single reader, multiple writer queue -template <typename T> +template <typename T, bool with_stop_token = false> class MPSCQueue { public: [[nodiscard]] std::size_t Size() const { @@ -166,13 +179,17 @@ public: return spsc_queue.PopWait(); } + T PopWait(std::stop_token stop_token) { + return spsc_queue.PopWait(stop_token); + } + // not thread-safe void Clear() { spsc_queue.Clear(); } private: - SPSCQueue<T> spsc_queue; + SPSCQueue<T, with_stop_token> spsc_queue; std::mutex write_lock; }; } // 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 { uuid = INVALID_UUID; } + [[nodiscard]] constexpr bool IsInvalid() const { + return uuid == INVALID_UUID; + } + [[nodiscard]] constexpr bool IsValid() const { + return !IsInvalid(); + } + // TODO(ogniK): Properly generate a Nintendo ID [[nodiscard]] constexpr u64 GetNintendoID() const { 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> // linear interpolation via float: 0.0=begin, 1.0=end template <typename X> -[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end, - const float t) { +[[nodiscard]] constexpr decltype(X{} * float{} + X{} * float{}) + Lerp(const X& begin, const X& end, const float t) { return begin * (1.f - t) + end * t; } |