diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/CMakeLists.txt | 5 | ||||
-rw-r--r-- | src/common/address_space.h | 7 | ||||
-rw-r--r-- | src/common/alignment.h | 18 | ||||
-rw-r--r-- | src/common/atomic_helpers.h | 2 | ||||
-rw-r--r-- | src/common/bit_util.h | 6 | ||||
-rw-r--r-- | src/common/concepts.h | 6 | ||||
-rw-r--r-- | src/common/demangle.cpp | 35 | ||||
-rw-r--r-- | src/common/demangle.h | 12 | ||||
-rw-r--r-- | src/common/div_ceil.h | 4 | ||||
-rw-r--r-- | src/common/expected.h | 60 | ||||
-rw-r--r-- | src/common/host_memory.cpp | 19 | ||||
-rw-r--r-- | src/common/input.h | 71 | ||||
-rw-r--r-- | src/common/intrusive_red_black_tree.h | 20 | ||||
-rw-r--r-- | src/common/make_unique_for_overwrite.h | 8 | ||||
-rw-r--r-- | src/common/polyfill_ranges.h | 8 | ||||
-rw-r--r-- | src/common/polyfill_thread.h | 123 | ||||
-rw-r--r-- | src/common/range_map.h | 139 | ||||
-rw-r--r-- | src/common/settings.cpp | 14 | ||||
-rw-r--r-- | src/common/settings.h | 30 | ||||
-rw-r--r-- | src/common/tree.h | 74 | ||||
-rw-r--r-- | src/common/vector_math.h | 16 |
21 files changed, 481 insertions, 196 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index eb05e46a8..9884a4a0b 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -38,6 +38,8 @@ add_library(common STATIC common_precompiled_headers.h common_types.h concepts.h + demangle.cpp + demangle.h div_ceil.h dynamic_library.cpp dynamic_library.h @@ -97,6 +99,7 @@ add_library(common STATIC point.h precompiled_headers.h quaternion.h + range_map.h reader_writer_queue.h ring_buffer.h ${CMAKE_CURRENT_BINARY_DIR}/scm_rev.cpp @@ -174,7 +177,7 @@ endif() create_target_directory_groups(common) target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads) -target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd) +target_link_libraries(common PRIVATE lz4::lz4 zstd::zstd LLVM::Demangle) if (YUZU_USE_PRECOMPILED_HEADERS) target_precompile_headers(common PRIVATE precompiled_headers.h) diff --git a/src/common/address_space.h b/src/common/address_space.h index 9222b2fdc..8683c23c3 100644 --- a/src/common/address_space.h +++ b/src/common/address_space.h @@ -12,7 +12,8 @@ namespace Common { template <typename VaType, size_t AddressSpaceBits> -concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >= AddressSpaceBits; +concept AddressSpaceValid = std::is_unsigned_v<VaType> && sizeof(VaType) * 8 >= +AddressSpaceBits; struct EmptyStruct {}; @@ -21,7 +22,7 @@ struct EmptyStruct {}; */ template <typename VaType, VaType UnmappedVa, typename PaType, PaType UnmappedPa, bool PaContigSplit, size_t AddressSpaceBits, typename ExtraBlockInfo = EmptyStruct> -requires AddressSpaceValid<VaType, AddressSpaceBits> + requires AddressSpaceValid<VaType, AddressSpaceBits> class FlatAddressSpaceMap { public: /// The maximum VA that this AS can technically reach @@ -109,7 +110,7 @@ private: * initial, fast linear pass and a subsequent slower pass that iterates until it finds a free block */ template <typename VaType, VaType UnmappedVa, size_t AddressSpaceBits> -requires AddressSpaceValid<VaType, AddressSpaceBits> + requires AddressSpaceValid<VaType, AddressSpaceBits> class FlatAllocator : public FlatAddressSpaceMap<VaType, UnmappedVa, bool, false, false, AddressSpaceBits> { private: diff --git a/src/common/alignment.h b/src/common/alignment.h index 7e897334b..fa715d497 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h @@ -10,7 +10,7 @@ namespace Common { template <typename T> -requires std::is_unsigned_v<T> + requires std::is_unsigned_v<T> [[nodiscard]] constexpr T AlignUp(T value, size_t size) { auto mod{static_cast<T>(value % size)}; value -= mod; @@ -18,31 +18,31 @@ requires std::is_unsigned_v<T> } template <typename T> -requires std::is_unsigned_v<T> + 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> + 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> + 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> + 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> + 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); @@ -50,7 +50,7 @@ requires std::is_integral_v<T> } template <typename T, typename U> -requires std::is_integral_v<T> + requires std::is_integral_v<T> [[nodiscard]] constexpr T DivideUp(T x, U y) { return (x + (y - 1)) / y; } @@ -73,11 +73,11 @@ public: constexpr AlignmentAllocator(const AlignmentAllocator<T2, Align>&) noexcept {} [[nodiscard]] T* allocate(size_type n) { - return static_cast<T*>(::operator new (n * sizeof(T), std::align_val_t{Align})); + return static_cast<T*>(::operator new(n * sizeof(T), std::align_val_t{Align})); } void deallocate(T* p, size_type n) { - ::operator delete (p, n * sizeof(T), std::align_val_t{Align}); + ::operator delete(p, n * sizeof(T), std::align_val_t{Align}); } template <typename T2> diff --git a/src/common/atomic_helpers.h b/src/common/atomic_helpers.h index aef3b66a4..d997f10ba 100644 --- a/src/common/atomic_helpers.h +++ b/src/common/atomic_helpers.h @@ -75,7 +75,7 @@ extern "C" void AnnotateHappensAfter(const char*, int, void*); #if defined(AE_VCPP) || defined(AE_ICC) #define AE_FORCEINLINE __forceinline #elif defined(AE_GCC) -//#define AE_FORCEINLINE __attribute__((always_inline)) +// #define AE_FORCEINLINE __attribute__((always_inline)) #define AE_FORCEINLINE inline #else #define AE_FORCEINLINE inline diff --git a/src/common/bit_util.h b/src/common/bit_util.h index e4e6287f3..13368b439 100644 --- a/src/common/bit_util.h +++ b/src/common/bit_util.h @@ -45,19 +45,19 @@ template <typename T> } template <typename T> -requires std::is_unsigned_v<T> + requires std::is_unsigned_v<T> [[nodiscard]] constexpr bool IsPow2(T value) { return std::has_single_bit(value); } template <typename T> -requires std::is_integral_v<T> + requires std::is_integral_v<T> [[nodiscard]] T NextPow2(T value) { return static_cast<T>(1ULL << ((8U * sizeof(T)) - std::countl_zero(value - 1U))); } template <size_t bit_index, typename T> -requires std::is_integral_v<T> + requires std::is_integral_v<T> [[nodiscard]] constexpr bool Bit(const T value) { static_assert(bit_index < BitSize<T>(), "bit_index must be smaller than size of T"); return ((value >> bit_index) & T(1)) == T(1); diff --git a/src/common/concepts.h b/src/common/concepts.h index a9acff3e7..61df1d32a 100644 --- a/src/common/concepts.h +++ b/src/common/concepts.h @@ -16,9 +16,9 @@ concept IsContiguousContainer = std::contiguous_iterator<typename T::iterator>; // is available on all supported platforms. template <typename Derived, typename Base> concept DerivedFrom = requires { - std::is_base_of_v<Base, Derived>; - std::is_convertible_v<const volatile Derived*, const volatile Base*>; -}; + std::is_base_of_v<Base, Derived>; + std::is_convertible_v<const volatile Derived*, const volatile Base*>; + }; // TODO: Replace with std::convertible_to when libc++ implements it. template <typename From, typename To> diff --git a/src/common/demangle.cpp b/src/common/demangle.cpp new file mode 100644 index 000000000..3310faf86 --- /dev/null +++ b/src/common/demangle.cpp @@ -0,0 +1,35 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#include <llvm/Demangle/Demangle.h> + +#include "common/demangle.h" +#include "common/scope_exit.h" + +namespace Common { + +std::string DemangleSymbol(const std::string& mangled) { + auto is_itanium = [](const std::string& name) -> bool { + // A valid Itanium encoding requires 1-4 leading underscores, followed by 'Z'. + auto pos = name.find_first_not_of('_'); + return pos > 0 && pos <= 4 && pos < name.size() && name[pos] == 'Z'; + }; + + if (mangled.empty()) { + return mangled; + } + + char* demangled = nullptr; + SCOPE_EXIT({ std::free(demangled); }); + + if (is_itanium(mangled)) { + demangled = llvm::itaniumDemangle(mangled.c_str(), nullptr, nullptr, nullptr); + } + + if (!demangled) { + return mangled; + } + return demangled; +} + +} // namespace Common diff --git a/src/common/demangle.h b/src/common/demangle.h new file mode 100644 index 000000000..f072d22f3 --- /dev/null +++ b/src/common/demangle.h @@ -0,0 +1,12 @@ +// SPDX-FileCopyrightText: Copyright 2020 yuzu Emulator Project +// SPDX-License-Identifier: GPL-2.0-or-later + +#pragma once + +#include <string> + +namespace Common { + +std::string DemangleSymbol(const std::string& mangled); + +} // namespace Common diff --git a/src/common/div_ceil.h b/src/common/div_ceil.h index eebc279c2..c12477d42 100644 --- a/src/common/div_ceil.h +++ b/src/common/div_ceil.h @@ -10,14 +10,14 @@ namespace Common { /// Ceiled integer division. template <typename N, typename D> -requires std::is_integral_v<N> && std::is_unsigned_v<D> + 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> + 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/expected.h b/src/common/expected.h index 6e6c86ee7..5fccfbcbd 100644 --- a/src/common/expected.h +++ b/src/common/expected.h @@ -64,7 +64,7 @@ struct no_init_t { * Additionally, this requires E to be trivially destructible */ template <typename T, typename E, bool = std::is_trivially_destructible_v<T>> -requires std::is_trivially_destructible_v<E> + requires std::is_trivially_destructible_v<E> struct expected_storage_base { constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {} @@ -111,7 +111,7 @@ struct expected_storage_base { * Additionally, this requires E to be trivially destructible */ template <typename T, typename E> -requires std::is_trivially_destructible_v<E> + requires std::is_trivially_destructible_v<E> struct expected_storage_base<T, E, true> { constexpr expected_storage_base() : m_val{T{}}, m_has_val{true} {} @@ -251,7 +251,7 @@ struct expected_operations_base : expected_storage_base<T, E> { * Additionally, this requires E to be trivially copy constructible */ template <typename T, typename E, bool = std::is_trivially_copy_constructible_v<T>> -requires std::is_trivially_copy_constructible_v<E> + requires std::is_trivially_copy_constructible_v<E> struct expected_copy_base : expected_operations_base<T, E> { using expected_operations_base<T, E>::expected_operations_base; }; @@ -261,7 +261,7 @@ struct expected_copy_base : expected_operations_base<T, E> { * Additionally, this requires E to be trivially copy constructible */ template <typename T, typename E> -requires std::is_trivially_copy_constructible_v<E> + requires std::is_trivially_copy_constructible_v<E> struct expected_copy_base<T, E, false> : expected_operations_base<T, E> { using expected_operations_base<T, E>::expected_operations_base; @@ -289,7 +289,7 @@ struct expected_copy_base<T, E, false> : expected_operations_base<T, E> { * Additionally, this requires E to be trivially move constructible */ template <typename T, typename E, bool = std::is_trivially_move_constructible_v<T>> -requires std::is_trivially_move_constructible_v<E> + requires std::is_trivially_move_constructible_v<E> struct expected_move_base : expected_copy_base<T, E> { using expected_copy_base<T, E>::expected_copy_base; }; @@ -299,7 +299,7 @@ struct expected_move_base : expected_copy_base<T, E> { * Additionally, this requires E to be trivially move constructible */ template <typename T, typename E> -requires std::is_trivially_move_constructible_v<E> + requires std::is_trivially_move_constructible_v<E> struct expected_move_base<T, E, false> : expected_copy_base<T, E> { using expected_copy_base<T, E>::expected_copy_base; @@ -330,9 +330,9 @@ template <typename T, typename E, bool = std::conjunction_v<std::is_trivially_copy_assignable<T>, std::is_trivially_copy_constructible<T>, std::is_trivially_destructible<T>>> -requires std::conjunction_v<std::is_trivially_copy_assignable<E>, - std::is_trivially_copy_constructible<E>, - std::is_trivially_destructible<E>> + requires std::conjunction_v<std::is_trivially_copy_assignable<E>, + std::is_trivially_copy_constructible<E>, + std::is_trivially_destructible<E>> struct expected_copy_assign_base : expected_move_base<T, E> { using expected_move_base<T, E>::expected_move_base; }; @@ -342,9 +342,9 @@ struct expected_copy_assign_base : expected_move_base<T, E> { * Additionally, this requires E to be trivially copy assignable */ template <typename T, typename E> -requires std::conjunction_v<std::is_trivially_copy_assignable<E>, - std::is_trivially_copy_constructible<E>, - std::is_trivially_destructible<E>> + requires std::conjunction_v<std::is_trivially_copy_assignable<E>, + std::is_trivially_copy_constructible<E>, + std::is_trivially_destructible<E>> struct expected_copy_assign_base<T, E, false> : expected_move_base<T, E> { using expected_move_base<T, E>::expected_move_base; @@ -371,9 +371,9 @@ template <typename T, typename E, bool = std::conjunction_v<std::is_trivially_move_assignable<T>, std::is_trivially_move_constructible<T>, std::is_trivially_destructible<T>>> -requires std::conjunction_v<std::is_trivially_move_assignable<E>, - std::is_trivially_move_constructible<E>, - std::is_trivially_destructible<E>> + requires std::conjunction_v<std::is_trivially_move_assignable<E>, + std::is_trivially_move_constructible<E>, + std::is_trivially_destructible<E>> struct expected_move_assign_base : expected_copy_assign_base<T, E> { using expected_copy_assign_base<T, E>::expected_copy_assign_base; }; @@ -383,9 +383,9 @@ struct expected_move_assign_base : expected_copy_assign_base<T, E> { * Additionally, this requires E to be trivially move assignable */ template <typename T, typename E> -requires std::conjunction_v<std::is_trivially_move_assignable<E>, - std::is_trivially_move_constructible<E>, - std::is_trivially_destructible<E>> + requires std::conjunction_v<std::is_trivially_move_assignable<E>, + std::is_trivially_move_constructible<E>, + std::is_trivially_destructible<E>> struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E> { using expected_copy_assign_base<T, E>::expected_copy_assign_base; @@ -412,7 +412,7 @@ struct expected_move_assign_base<T, E, false> : expected_copy_assign_base<T, E> */ template <typename T, typename E, bool EnableCopy = std::is_copy_constructible_v<T>, bool EnableMove = std::is_move_constructible_v<T>> -requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>> + requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>> struct expected_delete_ctor_base { expected_delete_ctor_base() = default; expected_delete_ctor_base(const expected_delete_ctor_base&) = default; @@ -422,7 +422,7 @@ struct expected_delete_ctor_base { }; template <typename T, typename E> -requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>> + requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>> struct expected_delete_ctor_base<T, E, true, false> { expected_delete_ctor_base() = default; expected_delete_ctor_base(const expected_delete_ctor_base&) = default; @@ -432,7 +432,7 @@ struct expected_delete_ctor_base<T, E, true, false> { }; template <typename T, typename E> -requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>> + requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>> struct expected_delete_ctor_base<T, E, false, true> { expected_delete_ctor_base() = default; expected_delete_ctor_base(const expected_delete_ctor_base&) = delete; @@ -442,7 +442,7 @@ struct expected_delete_ctor_base<T, E, false, true> { }; template <typename T, typename E> -requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>> + requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>> struct expected_delete_ctor_base<T, E, false, false> { expected_delete_ctor_base() = default; expected_delete_ctor_base(const expected_delete_ctor_base&) = delete; @@ -460,8 +460,8 @@ template < typename T, typename E, bool EnableCopy = std::conjunction_v<std::is_copy_constructible<T>, std::is_copy_assignable<T>>, bool EnableMove = std::conjunction_v<std::is_move_constructible<T>, std::is_move_assignable<T>>> -requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>, - std::is_copy_assignable<E>, std::is_move_assignable<E>> + requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>, + std::is_copy_assignable<E>, std::is_move_assignable<E>> struct expected_delete_assign_base { expected_delete_assign_base() = default; expected_delete_assign_base(const expected_delete_assign_base&) = default; @@ -471,8 +471,8 @@ struct expected_delete_assign_base { }; template <typename T, typename E> -requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>, - std::is_copy_assignable<E>, std::is_move_assignable<E>> + requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>, + std::is_copy_assignable<E>, std::is_move_assignable<E>> struct expected_delete_assign_base<T, E, true, false> { expected_delete_assign_base() = default; expected_delete_assign_base(const expected_delete_assign_base&) = default; @@ -482,8 +482,8 @@ struct expected_delete_assign_base<T, E, true, false> { }; template <typename T, typename E> -requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>, - std::is_copy_assignable<E>, std::is_move_assignable<E>> + requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>, + std::is_copy_assignable<E>, std::is_move_assignable<E>> struct expected_delete_assign_base<T, E, false, true> { expected_delete_assign_base() = default; expected_delete_assign_base(const expected_delete_assign_base&) = default; @@ -493,8 +493,8 @@ struct expected_delete_assign_base<T, E, false, true> { }; template <typename T, typename E> -requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>, - std::is_copy_assignable<E>, std::is_move_assignable<E>> + requires std::conjunction_v<std::is_copy_constructible<E>, std::is_move_constructible<E>, + std::is_copy_assignable<E>, std::is_move_assignable<E>> struct expected_delete_assign_base<T, E, false, false> { expected_delete_assign_base() = default; expected_delete_assign_base(const expected_delete_assign_base&) = default; diff --git a/src/common/host_memory.cpp b/src/common/host_memory.cpp index 909f6cf3f..611c7d1a3 100644 --- a/src/common/host_memory.cpp +++ b/src/common/host_memory.cpp @@ -393,12 +393,27 @@ public: } // Virtual memory initialization - virtual_base = static_cast<u8*>( - mmap(nullptr, virtual_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); +#if defined(__FreeBSD__) + virtual_base = + static_cast<u8*>(mmap(nullptr, virtual_size, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED_SUPER, -1, 0)); + if (virtual_base == MAP_FAILED) { + virtual_base = static_cast<u8*>( + mmap(nullptr, virtual_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); + if (virtual_base == MAP_FAILED) { + LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno)); + throw std::bad_alloc{}; + } + } +#else + virtual_base = static_cast<u8*>(mmap(nullptr, virtual_size, PROT_NONE, + MAP_PRIVATE | MAP_ANONYMOUS | MAP_NORESERVE, -1, 0)); if (virtual_base == MAP_FAILED) { LOG_CRITICAL(HW_Memory, "mmap failed: {}", strerror(errno)); throw std::bad_alloc{}; } + madvise(virtual_base, virtual_size, MADV_HUGEPAGE); +#endif good = true; } diff --git a/src/common/input.h b/src/common/input.h index fc14fd7bf..d61cd7ca8 100644 --- a/src/common/input.h +++ b/src/common/input.h @@ -51,6 +51,8 @@ enum class PollingMode { NFC, // Enable infrared camera polling IR, + // Enable ring controller polling + Ring, }; enum class CameraFormat { @@ -62,21 +64,22 @@ enum class CameraFormat { None, }; -// Vibration reply from the controller -enum class VibrationError { - None, +// Different results that can happen from a device request +enum class DriverResult { + Success, + WrongReply, + Timeout, + UnsupportedControllerType, + HandleInUse, + ErrorReadingData, + ErrorWritingData, + NoDeviceDetected, + InvalidHandle, NotSupported, Disabled, Unknown, }; -// Polling mode reply from the controller -enum class PollingError { - None, - NotSupported, - Unknown, -}; - // Nfc reply from the controller enum class NfcState { Success, @@ -90,13 +93,6 @@ enum class NfcState { Unknown, }; -// Ir camera reply from the controller -enum class CameraError { - None, - NotSupported, - Unknown, -}; - // Hint for amplification curve to be used enum class VibrationAmplificationType { Linear, @@ -190,6 +186,8 @@ struct TouchStatus { struct BodyColorStatus { u32 body{}; u32 buttons{}; + u32 left_grip{}; + u32 right_grip{}; }; // HD rumble data @@ -228,17 +226,31 @@ enum class ButtonNames { Engine, // This will display the button by value instead of the button name Value, + + // Joycon button names ButtonLeft, ButtonRight, ButtonDown, ButtonUp, - TriggerZ, - TriggerR, - TriggerL, ButtonA, ButtonB, ButtonX, ButtonY, + ButtonPlus, + ButtonMinus, + ButtonHome, + ButtonCapture, + ButtonStickL, + ButtonStickR, + TriggerL, + TriggerZL, + TriggerSL, + TriggerR, + TriggerZR, + TriggerSR, + + // GC button names + TriggerZ, ButtonStart, // DS4 button names @@ -292,9 +304,6 @@ class InputDevice { public: virtual ~InputDevice() = default; - // Request input device to update if necessary - virtual void SoftUpdate() {} - // Force input device to update data regardless of the current state virtual void ForceUpdate() {} @@ -319,22 +328,24 @@ class OutputDevice { public: virtual ~OutputDevice() = default; - virtual void SetLED([[maybe_unused]] const LedStatus& led_status) {} + virtual DriverResult SetLED([[maybe_unused]] const LedStatus& led_status) { + return DriverResult::NotSupported; + } - virtual VibrationError SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) { - return VibrationError::NotSupported; + virtual DriverResult SetVibration([[maybe_unused]] const VibrationStatus& vibration_status) { + return DriverResult::NotSupported; } virtual bool IsVibrationEnabled() { return false; } - virtual PollingError SetPollingMode([[maybe_unused]] PollingMode polling_mode) { - return PollingError::NotSupported; + virtual DriverResult SetPollingMode([[maybe_unused]] PollingMode polling_mode) { + return DriverResult::NotSupported; } - virtual CameraError SetCameraFormat([[maybe_unused]] CameraFormat camera_format) { - return CameraError::NotSupported; + virtual DriverResult SetCameraFormat([[maybe_unused]] CameraFormat camera_format) { + return DriverResult::NotSupported; } virtual NfcState SupportsNfc() const { diff --git a/src/common/intrusive_red_black_tree.h b/src/common/intrusive_red_black_tree.h index 93046615e..5f6b34e82 100644 --- a/src/common/intrusive_red_black_tree.h +++ b/src/common/intrusive_red_black_tree.h @@ -242,19 +242,21 @@ public: template <typename T> concept HasRedBlackKeyType = requires { - { std::is_same<typename T::RedBlackKeyType, void>::value } -> std::convertible_to<bool>; -}; + { + std::is_same<typename T::RedBlackKeyType, void>::value + } -> std::convertible_to<bool>; + }; namespace impl { - template <typename T, typename Default> - consteval auto* GetRedBlackKeyType() { - if constexpr (HasRedBlackKeyType<T>) { - return static_cast<typename T::RedBlackKeyType*>(nullptr); - } else { - return static_cast<Default*>(nullptr); - } +template <typename T, typename Default> +consteval auto* GetRedBlackKeyType() { + if constexpr (HasRedBlackKeyType<T>) { + return static_cast<typename T::RedBlackKeyType*>(nullptr); + } else { + return static_cast<Default*>(nullptr); } +} } // namespace impl diff --git a/src/common/make_unique_for_overwrite.h b/src/common/make_unique_for_overwrite.h index c7413cf51..17f81bba4 100644 --- a/src/common/make_unique_for_overwrite.h +++ b/src/common/make_unique_for_overwrite.h @@ -9,17 +9,19 @@ namespace Common { template <class T> -requires(!std::is_array_v<T>) std::unique_ptr<T> make_unique_for_overwrite() { + requires(!std::is_array_v<T>) +std::unique_ptr<T> make_unique_for_overwrite() { return std::unique_ptr<T>(new T); } template <class T> -requires std::is_unbounded_array_v<T> std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) { + requires std::is_unbounded_array_v<T> +std::unique_ptr<T> make_unique_for_overwrite(std::size_t n) { return std::unique_ptr<T>(new std::remove_extent_t<T>[n]); } template <class T, class... Args> -requires std::is_bounded_array_v<T> + requires std::is_bounded_array_v<T> void make_unique_for_overwrite(Args&&...) = delete; } // namespace Common diff --git a/src/common/polyfill_ranges.h b/src/common/polyfill_ranges.h index ca44bfaef..512dbcbcb 100644 --- a/src/common/polyfill_ranges.h +++ b/src/common/polyfill_ranges.h @@ -18,9 +18,9 @@ namespace ranges { template <typename T> concept range = requires(T& t) { - begin(t); - end(t); -}; + begin(t); + end(t); + }; template <typename T> concept input_range = range<T>; @@ -421,7 +421,7 @@ struct generate_fn { } template <typename R, std::copy_constructible F> - requires std::invocable<F&> && ranges::output_range<R> + requires std::invocable<F&> && ranges::output_range<R> constexpr ranges::iterator_t<R> operator()(R&& r, F gen) const { return operator()(ranges::begin(r), ranges::end(r), std::move(gen)); } diff --git a/src/common/polyfill_thread.h b/src/common/polyfill_thread.h index 5a8d1ce08..b5ef055db 100644 --- a/src/common/polyfill_thread.h +++ b/src/common/polyfill_thread.h @@ -11,6 +11,8 @@ #ifdef __cpp_lib_jthread +#include <chrono> +#include <condition_variable> #include <stop_token> #include <thread> @@ -21,23 +23,36 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred&& pred) { cv.wait(lock, token, std::move(pred)); } +template <typename Rep, typename Period> +bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) { + std::condition_variable_any cv; + std::mutex m; + + // Perform the timed wait. + std::unique_lock lk{m}; + return !cv.wait_for(lk, token, rel_time, [&] { return token.stop_requested(); }); +} + } // namespace Common #else #include <atomic> +#include <chrono> +#include <condition_variable> #include <functional> -#include <list> +#include <map> #include <memory> #include <mutex> #include <optional> #include <thread> #include <type_traits> +#include <utility> namespace std { namespace polyfill { -using stop_state_callbacks = list<function<void()>>; +using stop_state_callback = size_t; class stop_state { public: @@ -45,61 +60,69 @@ public: ~stop_state() = default; bool request_stop() { - stop_state_callbacks callbacks; + unique_lock lk{m_lock}; - { - scoped_lock lk{m_lock}; + if (m_stop_requested) { + // Already set, nothing to do. + return false; + } - if (m_stop_requested.load()) { - // Already set, nothing to do - return false; - } + // Mark stop requested. + m_stop_requested = true; - // Set as requested - m_stop_requested = true; + while (!m_callbacks.empty()) { + // Get an iterator to the first element. + const auto it = m_callbacks.begin(); - // Copy callback list - callbacks = m_callbacks; - } + // Move the callback function out of the map. + function<void()> f; + swap(it->second, f); + + // Erase the now-empty map element. + m_callbacks.erase(it); - for (auto callback : callbacks) { - callback(); + // Run the callback. + if (f) { + f(); + } } return true; } bool stop_requested() const { - return m_stop_requested.load(); + unique_lock lk{m_lock}; + return m_stop_requested; } - stop_state_callbacks::const_iterator insert_callback(function<void()> f) { - stop_state_callbacks::const_iterator ret{}; - bool should_run{}; - - { - scoped_lock lk{m_lock}; - should_run = m_stop_requested.load(); - m_callbacks.push_front(f); - ret = m_callbacks.begin(); - } + stop_state_callback insert_callback(function<void()> f) { + unique_lock lk{m_lock}; - if (should_run) { - f(); + if (m_stop_requested) { + // Stop already requested. Don't insert anything, + // just run the callback synchronously. + if (f) { + f(); + } + return 0; } + // Insert the callback. + stop_state_callback ret = ++m_next_callback; + m_callbacks.emplace(ret, move(f)); return ret; } - void remove_callback(stop_state_callbacks::const_iterator it) { - scoped_lock lk{m_lock}; - m_callbacks.erase(it); + void remove_callback(stop_state_callback cb) { + unique_lock lk{m_lock}; + m_callbacks.erase(cb); } private: - mutex m_lock; - atomic<bool> m_stop_requested; - stop_state_callbacks m_callbacks; + mutable recursive_mutex m_lock; + map<stop_state_callback, function<void()>> m_callbacks; + stop_state_callback m_next_callback{0}; + bool m_stop_requested{false}; }; } // namespace polyfill @@ -190,7 +213,7 @@ public: using callback_type = Callback; template <typename C> - requires constructible_from<Callback, C> + requires constructible_from<Callback, C> explicit stop_callback(const stop_token& st, C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>) : m_stop_state(st.m_stop_state) { @@ -199,7 +222,7 @@ public: } } template <typename C> - requires constructible_from<Callback, C> + requires constructible_from<Callback, C> explicit stop_callback(stop_token&& st, C&& cb) noexcept(is_nothrow_constructible_v<Callback, C>) : m_stop_state(move(st.m_stop_state)) { @@ -209,7 +232,7 @@ public: } ~stop_callback() { if (m_stop_state && m_callback) { - m_stop_state->remove_callback(*m_callback); + m_stop_state->remove_callback(m_callback); } } @@ -220,7 +243,7 @@ public: private: shared_ptr<polyfill::stop_state> m_stop_state; - optional<polyfill::stop_state_callbacks::const_iterator> m_callback; + polyfill::stop_state_callback m_callback; }; template <typename Callback> @@ -318,6 +341,28 @@ void CondvarWait(Condvar& cv, Lock& lock, std::stop_token token, Pred pred) { cv.wait(lock, [&] { return pred() || token.stop_requested(); }); } +template <typename Rep, typename Period> +bool StoppableTimedWait(std::stop_token token, const std::chrono::duration<Rep, Period>& rel_time) { + if (token.stop_requested()) { + return false; + } + + bool stop_requested = false; + std::condition_variable cv; + std::mutex m; + + std::stop_callback cb(token, [&] { + // Wake up the waiting thread. + std::unique_lock lk{m}; + stop_requested = true; + cv.notify_one(); + }); + + // Perform the timed wait. + std::unique_lock lk{m}; + return !cv.wait_for(lk, rel_time, [&] { return stop_requested; }); +} + } // namespace Common #endif diff --git a/src/common/range_map.h b/src/common/range_map.h new file mode 100644 index 000000000..79c7ef547 --- /dev/null +++ b/src/common/range_map.h @@ -0,0 +1,139 @@ +// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project +// SPDX-License-Identifier: GPL-3.0-or-later + +#pragma once + +#include <map> +#include <type_traits> + +#include "common/common_types.h" + +namespace Common { + +template <typename KeyTBase, typename ValueT> +class RangeMap { +private: + using KeyT = + std::conditional_t<std::is_signed_v<KeyTBase>, KeyTBase, std::make_signed_t<KeyTBase>>; + +public: + explicit RangeMap(ValueT null_value_) : null_value{null_value_} { + container.emplace(std::numeric_limits<KeyT>::min(), null_value); + }; + ~RangeMap() = default; + + void Map(KeyTBase address, KeyTBase address_end, ValueT value) { + KeyT new_address = static_cast<KeyT>(address); + KeyT new_address_end = static_cast<KeyT>(address_end); + if (new_address < 0) { + new_address = 0; + } + if (new_address_end < 0) { + new_address_end = 0; + } + InternalMap(new_address, new_address_end, value); + } + + void Unmap(KeyTBase address, KeyTBase address_end) { + Map(address, address_end, null_value); + } + + [[nodiscard]] size_t GetContinousSizeFrom(KeyTBase address) const { + const KeyT new_address = static_cast<KeyT>(address); + if (new_address < 0) { + return 0; + } + return ContinousSizeInternal(new_address); + } + + [[nodiscard]] ValueT GetValueAt(KeyT address) const { + const KeyT new_address = static_cast<KeyT>(address); + if (new_address < 0) { + return null_value; + } + return GetValueInternal(new_address); + } + +private: + using MapType = std::map<KeyT, ValueT>; + using IteratorType = typename MapType::iterator; + using ConstIteratorType = typename MapType::const_iterator; + + size_t ContinousSizeInternal(KeyT address) const { + const auto it = GetFirstElementBeforeOrOn(address); + if (it == container.end() || it->second == null_value) { + return 0; + } + const auto it_end = std::next(it); + if (it_end == container.end()) { + return std::numeric_limits<KeyT>::max() - address; + } + return it_end->first - address; + } + + ValueT GetValueInternal(KeyT address) const { + const auto it = GetFirstElementBeforeOrOn(address); + if (it == container.end()) { + return null_value; + } + return it->second; + } + + ConstIteratorType GetFirstElementBeforeOrOn(KeyT address) const { + auto it = container.lower_bound(address); + if (it == container.begin()) { + return it; + } + if (it != container.end() && (it->first == address)) { + return it; + } + --it; + return it; + } + + ValueT GetFirstValueWithin(KeyT address) { + auto it = container.lower_bound(address); + if (it == container.begin()) { + return it->second; + } + if (it == container.end()) [[unlikely]] { // this would be a bug + return null_value; + } + --it; + return it->second; + } + + ValueT GetLastValueWithin(KeyT address) { + auto it = container.upper_bound(address); + if (it == container.end()) { + return null_value; + } + if (it == container.begin()) [[unlikely]] { // this would be a bug + return it->second; + } + --it; + return it->second; + } + + void InternalMap(KeyT address, KeyT address_end, ValueT value) { + const bool must_add_start = GetFirstValueWithin(address) != value; + const ValueT last_value = GetLastValueWithin(address_end); + const bool must_add_end = last_value != value; + auto it = container.lower_bound(address); + const auto it_end = container.upper_bound(address_end); + while (it != it_end) { + it = container.erase(it); + } + if (must_add_start) { + container.emplace(address, value); + } + if (must_add_end) { + container.emplace(address_end, last_value); + } + } + + ValueT null_value; + MapType container; +}; + +} // namespace Common diff --git a/src/common/settings.cpp b/src/common/settings.cpp index 149e621f9..b1a2aa8b2 100644 --- a/src/common/settings.cpp +++ b/src/common/settings.cpp @@ -129,6 +129,10 @@ void UpdateRescalingInfo() { info.up_scale = 1; info.down_shift = 0; break; + case ResolutionSetup::Res3_2X: + info.up_scale = 3; + info.down_shift = 1; + break; case ResolutionSetup::Res2X: info.up_scale = 2; info.down_shift = 0; @@ -149,6 +153,14 @@ void UpdateRescalingInfo() { info.up_scale = 6; info.down_shift = 0; break; + case ResolutionSetup::Res7X: + info.up_scale = 7; + info.down_shift = 0; + break; + case ResolutionSetup::Res8X: + info.up_scale = 8; + info.down_shift = 0; + break; default: ASSERT(false); info.up_scale = 1; @@ -185,6 +197,7 @@ void RestoreGlobalState(bool is_powered_on) { // Renderer values.fsr_sharpening_slider.SetGlobal(true); values.renderer_backend.SetGlobal(true); + values.renderer_force_max_clock.SetGlobal(true); values.vulkan_device.SetGlobal(true); values.aspect_ratio.SetGlobal(true); values.max_anisotropy.SetGlobal(true); @@ -200,6 +213,7 @@ void RestoreGlobalState(bool is_powered_on) { values.use_asynchronous_shaders.SetGlobal(true); values.use_fast_gpu_time.SetGlobal(true); values.use_pessimistic_flushes.SetGlobal(true); + values.use_vulkan_driver_pipeline_cache.SetGlobal(true); values.bg_red.SetGlobal(true); values.bg_green.SetGlobal(true); values.bg_blue.SetGlobal(true); diff --git a/src/common/settings.h b/src/common/settings.h index 6b199af93..64db66f37 100644 --- a/src/common/settings.h +++ b/src/common/settings.h @@ -56,11 +56,14 @@ enum class ResolutionSetup : u32 { Res1_2X = 0, Res3_4X = 1, Res1X = 2, - Res2X = 3, - Res3X = 4, - Res4X = 5, - Res5X = 6, - Res6X = 7, + Res3_2X = 3, + Res2X = 4, + Res3X = 5, + Res4X = 6, + Res5X = 7, + Res6X = 8, + Res7X = 9, + Res8X = 10, }; enum class ScalingFilter : u32 { @@ -128,7 +131,8 @@ public: * @param default_val Intial value of the setting, and default value of the setting * @param name Label for the setting */ - explicit Setting(const Type& default_val, const std::string& name) requires(!ranged) + explicit Setting(const Type& default_val, const std::string& name) + requires(!ranged) : value{default_val}, default_value{default_val}, label{name} {} virtual ~Setting() = default; @@ -141,7 +145,8 @@ public: * @param name Label for the setting */ explicit Setting(const Type& default_val, const Type& min_val, const Type& max_val, - const std::string& name) requires(ranged) + const std::string& name) + requires(ranged) : value{default_val}, default_value{default_val}, maximum{max_val}, minimum{min_val}, label{name} {} @@ -229,7 +234,8 @@ public: * @param default_val Intial value of the setting, and default value of the setting * @param name Label for the setting */ - explicit SwitchableSetting(const Type& default_val, const std::string& name) requires(!ranged) + explicit SwitchableSetting(const Type& default_val, const std::string& name) + requires(!ranged) : Setting<Type>{default_val, name} {} virtual ~SwitchableSetting() = default; @@ -242,7 +248,8 @@ public: * @param name Label for the setting */ explicit SwitchableSetting(const Type& default_val, const Type& min_val, const Type& max_val, - const std::string& name) requires(ranged) + const std::string& name) + requires(ranged) : Setting<Type, true>{default_val, min_val, max_val, name} {} /** @@ -415,6 +422,7 @@ struct Values { // Renderer SwitchableSetting<RendererBackend, true> renderer_backend{ RendererBackend::Vulkan, RendererBackend::OpenGL, RendererBackend::Null, "backend"}; + SwitchableSetting<bool> renderer_force_max_clock{false, "force_max_clock"}; Setting<bool> renderer_debug{false, "debug"}; Setting<bool> renderer_shader_feedback{false, "shader_feedback"}; Setting<bool> enable_nsight_aftermath{false, "nsight_aftermath"}; @@ -451,6 +459,8 @@ struct Values { SwitchableSetting<bool> use_asynchronous_shaders{false, "use_asynchronous_shaders"}; SwitchableSetting<bool> use_fast_gpu_time{true, "use_fast_gpu_time"}; SwitchableSetting<bool> use_pessimistic_flushes{false, "use_pessimistic_flushes"}; + SwitchableSetting<bool> use_vulkan_driver_pipeline_cache{true, + "use_vulkan_driver_pipeline_cache"}; SwitchableSetting<u8> bg_red{0, "bg_red"}; SwitchableSetting<u8> bg_green{0, "bg_green"}; @@ -477,6 +487,7 @@ struct Values { Setting<bool> enable_raw_input{false, "enable_raw_input"}; Setting<bool> controller_navigation{true, "controller_navigation"}; + Setting<bool> enable_joycon_driver{true, "enable_joycon_driver"}; SwitchableSetting<bool> vibration_enabled{true, "vibration_enabled"}; SwitchableSetting<bool> enable_accurate_vibrations{false, "enable_accurate_vibrations"}; @@ -531,6 +542,7 @@ struct Values { Setting<bool> reporting_services{false, "reporting_services"}; Setting<bool> quest_flag{false, "quest_flag"}; Setting<bool> disable_macro_jit{false, "disable_macro_jit"}; + Setting<bool> disable_macro_hle{false, "disable_macro_hle"}; Setting<bool> extended_logging{false, "extended_logging"}; Setting<bool> use_debug_asserts{false, "use_debug_asserts"}; Setting<bool> use_auto_stub{false, "use_auto_stub"}; diff --git a/src/common/tree.h b/src/common/tree.h index f77859209..f4fc43de3 100644 --- a/src/common/tree.h +++ b/src/common/tree.h @@ -103,12 +103,12 @@ concept IsRBEntry = CheckRBEntry<T>::value; template <typename T> concept HasRBEntry = requires(T& t, const T& ct) { - { t.GetRBEntry() } -> std::same_as<RBEntry<T>&>; - { ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>; -}; + { t.GetRBEntry() } -> std::same_as<RBEntry<T>&>; + { ct.GetRBEntry() } -> std::same_as<const RBEntry<T>&>; + }; template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> class RBHead { private: T* m_rbh_root = nullptr; @@ -130,90 +130,90 @@ public: }; template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr RBEntry<T>& RB_ENTRY(T* t) { return t->GetRBEntry(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr const RBEntry<T>& RB_ENTRY(const T* t) { return t->GetRBEntry(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr T* RB_LEFT(T* t) { return RB_ENTRY(t).Left(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr const T* RB_LEFT(const T* t) { return RB_ENTRY(t).Left(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr T* RB_RIGHT(T* t) { return RB_ENTRY(t).Right(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr const T* RB_RIGHT(const T* t) { return RB_ENTRY(t).Right(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr T* RB_PARENT(T* t) { return RB_ENTRY(t).Parent(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr const T* RB_PARENT(const T* t) { return RB_ENTRY(t).Parent(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_SET_LEFT(T* t, T* e) { RB_ENTRY(t).SetLeft(e); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_SET_RIGHT(T* t, T* e) { RB_ENTRY(t).SetRight(e); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_SET_PARENT(T* t, T* e) { RB_ENTRY(t).SetParent(e); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr bool RB_IS_BLACK(const T* t) { return RB_ENTRY(t).IsBlack(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr bool RB_IS_RED(const T* t) { return RB_ENTRY(t).IsRed(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> [[nodiscard]] constexpr RBColor RB_COLOR(const T* t) { return RB_ENTRY(t).Color(); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_SET_COLOR(T* t, RBColor c) { RB_ENTRY(t).SetColor(c); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_SET(T* elm, T* parent) { auto& rb_entry = RB_ENTRY(elm); rb_entry.SetParent(parent); @@ -223,14 +223,14 @@ constexpr void RB_SET(T* elm, T* parent) { } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_SET_BLACKRED(T* black, T* red) { RB_SET_COLOR(black, RBColor::RB_BLACK); RB_SET_COLOR(red, RBColor::RB_RED); } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) { tmp = RB_RIGHT(elm); if (RB_SET_RIGHT(elm, RB_LEFT(tmp)); RB_RIGHT(elm) != nullptr) { @@ -252,7 +252,7 @@ constexpr void RB_ROTATE_LEFT(RBHead<T>& head, T* elm, T*& tmp) { } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) { tmp = RB_LEFT(elm); if (RB_SET_LEFT(elm, RB_RIGHT(tmp)); RB_LEFT(elm) != nullptr) { @@ -274,7 +274,7 @@ constexpr void RB_ROTATE_RIGHT(RBHead<T>& head, T* elm, T*& tmp) { } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) { T* tmp; while ((elm == nullptr || RB_IS_BLACK(elm)) && elm != head.Root()) { @@ -358,7 +358,7 @@ constexpr void RB_REMOVE_COLOR(RBHead<T>& head, T* parent, T* elm) { } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) { T* child = nullptr; T* parent = nullptr; @@ -451,7 +451,7 @@ constexpr T* RB_REMOVE(RBHead<T>& head, T* elm) { } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) { T *parent = nullptr, *tmp = nullptr; while ((parent = RB_PARENT(elm)) != nullptr && RB_IS_RED(parent)) { @@ -499,7 +499,7 @@ constexpr void RB_INSERT_COLOR(RBHead<T>& head, T* elm) { } template <typename T, typename Compare> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) { T* parent = nullptr; T* tmp = head.Root(); @@ -534,7 +534,7 @@ constexpr T* RB_INSERT(RBHead<T>& head, T* elm, Compare cmp) { } template <typename T, typename Compare> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) { T* tmp = head.Root(); @@ -553,7 +553,7 @@ constexpr T* RB_FIND(RBHead<T>& head, T* elm, Compare cmp) { } template <typename T, typename Compare> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) { T* tmp = head.Root(); T* res = nullptr; @@ -574,7 +574,7 @@ constexpr T* RB_NFIND(RBHead<T>& head, T* elm, Compare cmp) { } template <typename T, typename U, typename Compare> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) { T* tmp = head.Root(); @@ -593,7 +593,7 @@ constexpr T* RB_FIND_KEY(RBHead<T>& head, const U& key, Compare cmp) { } template <typename T, typename U, typename Compare> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) { T* tmp = head.Root(); T* res = nullptr; @@ -614,7 +614,7 @@ constexpr T* RB_NFIND_KEY(RBHead<T>& head, const U& key, Compare cmp) { } template <typename T, typename Compare> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) { T* tmp = head.Root(); @@ -631,7 +631,7 @@ constexpr T* RB_FIND_EXISTING(RBHead<T>& head, T* elm, Compare cmp) { } template <typename T, typename U, typename Compare> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) { T* tmp = head.Root(); @@ -648,7 +648,7 @@ constexpr T* RB_FIND_EXISTING_KEY(RBHead<T>& head, const U& key, Compare cmp) { } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_NEXT(T* elm) { if (RB_RIGHT(elm)) { elm = RB_RIGHT(elm); @@ -669,7 +669,7 @@ constexpr T* RB_NEXT(T* elm) { } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_PREV(T* elm) { if (RB_LEFT(elm)) { elm = RB_LEFT(elm); @@ -690,7 +690,7 @@ constexpr T* RB_PREV(T* elm) { } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_MIN(RBHead<T>& head) { T* tmp = head.Root(); T* parent = nullptr; @@ -704,7 +704,7 @@ constexpr T* RB_MIN(RBHead<T>& head) { } template <typename T> -requires HasRBEntry<T> + requires HasRBEntry<T> constexpr T* RB_MAX(RBHead<T>& head) { T* tmp = head.Root(); T* parent = nullptr; diff --git a/src/common/vector_math.h b/src/common/vector_math.h index e62eeea2e..0e2095c45 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -348,9 +348,7 @@ public: // _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all // component names (x<->r) and permutations (xy<->yx) #define _DEFINE_SWIZZLER2(a, b, name) \ - [[nodiscard]] constexpr Vec2<T> name() const { \ - return Vec2<T>(a, b); \ - } + [[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); } #define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \ _DEFINE_SWIZZLER2(a, b, a##b); \ _DEFINE_SWIZZLER2(a, b, a2##b2); \ @@ -543,9 +541,7 @@ public: // DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and // permutations (xy<->yx) #define _DEFINE_SWIZZLER2(a, b, name) \ - [[nodiscard]] constexpr Vec2<T> name() const { \ - return Vec2<T>(a, b); \ - } + [[nodiscard]] constexpr Vec2<T> name() const { return Vec2<T>(a, b); } #define DEFINE_SWIZZLER2_COMP1(a, a2) \ _DEFINE_SWIZZLER2(a, a, a##a); \ _DEFINE_SWIZZLER2(a, a, a2##a2) @@ -570,9 +566,7 @@ public: #undef _DEFINE_SWIZZLER2 #define _DEFINE_SWIZZLER3(a, b, c, name) \ - [[nodiscard]] constexpr Vec3<T> name() const { \ - return Vec3<T>(a, b, c); \ - } + [[nodiscard]] constexpr Vec3<T> name() const { return Vec3<T>(a, b, c); } #define DEFINE_SWIZZLER3_COMP1(a, a2) \ _DEFINE_SWIZZLER3(a, a, a, a##a##a); \ _DEFINE_SWIZZLER3(a, a, a, a2##a2##a2) @@ -641,8 +635,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; } |