diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/common/alignment.h | 4 | ||||
-rw-r--r-- | src/common/bit_set.h | 2 | ||||
-rw-r--r-- | src/common/break_points.cpp | 90 | ||||
-rw-r--r-- | src/common/break_points.h | 49 | ||||
-rw-r--r-- | src/common/color.h | 50 | ||||
-rw-r--r-- | src/common/common_funcs.h | 4 | ||||
-rw-r--r-- | src/common/common_paths.h | 1 | ||||
-rw-r--r-- | src/common/file_util.cpp | 36 | ||||
-rw-r--r-- | src/common/file_util.h | 35 | ||||
-rw-r--r-- | src/common/hash.h | 4 | ||||
-rw-r--r-- | src/common/hex_util.cpp | 31 | ||||
-rw-r--r-- | src/common/hex_util.h | 41 | ||||
-rw-r--r-- | src/common/logging/backend.cpp | 30 | ||||
-rw-r--r-- | src/common/logging/log.h | 25 | ||||
-rw-r--r-- | src/common/logging/text_formatter.h | 1 | ||||
-rw-r--r-- | src/common/math_util.h | 10 | ||||
-rw-r--r-- | src/common/misc.cpp | 2 | ||||
-rw-r--r-- | src/common/string_util.cpp | 8 | ||||
-rw-r--r-- | src/common/swap.h | 2 | ||||
-rw-r--r-- | src/common/thread_queue_list.h | 10 | ||||
-rw-r--r-- | src/common/threadsafe_queue.h | 32 | ||||
-rw-r--r-- | src/common/timer.cpp | 95 | ||||
-rw-r--r-- | src/common/timer.h | 17 | ||||
-rw-r--r-- | src/common/vector_math.h | 362 | ||||
-rw-r--r-- | src/common/x64/xbyak_abi.h | 20 | ||||
-rw-r--r-- | src/common/x64/xbyak_util.h | 8 |
27 files changed, 495 insertions, 478 deletions
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt index d5d4f6f82..d9424ea91 100644 --- a/src/common/CMakeLists.txt +++ b/src/common/CMakeLists.txt @@ -29,8 +29,6 @@ add_library(common STATIC assert.h bit_field.h bit_set.h - break_points.cpp - break_points.h cityhash.cpp cityhash.h color.h @@ -40,6 +38,8 @@ add_library(common STATIC file_util.cpp file_util.h hash.h + hex_util.cpp + hex_util.h logging/backend.cpp logging/backend.h logging/filter.cpp diff --git a/src/common/alignment.h b/src/common/alignment.h index b77da4a92..b9dd38746 100644 --- a/src/common/alignment.h +++ b/src/common/alignment.h @@ -9,13 +9,13 @@ namespace Common { template <typename T> constexpr T AlignUp(T value, size_t size) { - static_assert(std::is_unsigned<T>::value, "T must be an unsigned value."); + static_assert(std::is_unsigned_v<T>, "T must be an unsigned value."); return static_cast<T>(value + (size - value % size) % size); } template <typename T> constexpr T AlignDown(T value, size_t size) { - static_assert(std::is_unsigned<T>::value, "T must be an unsigned value."); + static_assert(std::is_unsigned_v<T>, "T must be an unsigned value."); return static_cast<T>(value - value % size); } diff --git a/src/common/bit_set.h b/src/common/bit_set.h index 84e3cbe58..5a197d8c1 100644 --- a/src/common/bit_set.h +++ b/src/common/bit_set.h @@ -96,7 +96,7 @@ static inline int LeastSignificantSetBit(u64 val) { template <typename IntTy> class BitSet { - static_assert(!std::is_signed<IntTy>::value, "BitSet should not be used with signed types"); + static_assert(!std::is_signed_v<IntTy>, "BitSet should not be used with signed types"); public: // A reference to a particular bit, returned from operator[]. diff --git a/src/common/break_points.cpp b/src/common/break_points.cpp deleted file mode 100644 index fa367a4ca..000000000 --- a/src/common/break_points.cpp +++ /dev/null @@ -1,90 +0,0 @@ -// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project -// Licensed under GPLv2 or any later version -// Refer to the license.txt file included. - -#include <algorithm> -#include <sstream> -#include "common/break_points.h" - -bool BreakPoints::IsAddressBreakPoint(u32 iAddress) const { - auto cond = [&iAddress](const TBreakPoint& bp) { return bp.iAddress == iAddress; }; - auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); - return it != m_BreakPoints.end(); -} - -bool BreakPoints::IsTempBreakPoint(u32 iAddress) const { - auto cond = [&iAddress](const TBreakPoint& bp) { - return bp.iAddress == iAddress && bp.bTemporary; - }; - auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); - return it != m_BreakPoints.end(); -} - -BreakPoints::TBreakPointsStr BreakPoints::GetStrings() const { - TBreakPointsStr bps; - for (auto breakpoint : m_BreakPoints) { - if (!breakpoint.bTemporary) { - std::stringstream bp; - bp << std::hex << breakpoint.iAddress << " " << (breakpoint.bOn ? "n" : ""); - bps.push_back(bp.str()); - } - } - - return bps; -} - -void BreakPoints::AddFromStrings(const TBreakPointsStr& bps) { - for (auto bps_item : bps) { - TBreakPoint bp; - std::stringstream bpstr; - bpstr << std::hex << bps_item; - bpstr >> bp.iAddress; - bp.bOn = bps_item.find("n") != bps_item.npos; - bp.bTemporary = false; - Add(bp); - } -} - -void BreakPoints::Add(const TBreakPoint& bp) { - if (!IsAddressBreakPoint(bp.iAddress)) { - m_BreakPoints.push_back(bp); - // if (jit) - // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); - } -} - -void BreakPoints::Add(u32 em_address, bool temp) { - if (!IsAddressBreakPoint(em_address)) // only add new addresses - { - TBreakPoint pt; // breakpoint settings - pt.bOn = true; - pt.bTemporary = temp; - pt.iAddress = em_address; - - m_BreakPoints.push_back(pt); - - // if (jit) - // jit->GetBlockCache()->InvalidateICache(em_address, 4); - } -} - -void BreakPoints::Remove(u32 em_address) { - auto cond = [&em_address](const TBreakPoint& bp) { return bp.iAddress == em_address; }; - auto it = std::find_if(m_BreakPoints.begin(), m_BreakPoints.end(), cond); - if (it != m_BreakPoints.end()) - m_BreakPoints.erase(it); -} - -void BreakPoints::Clear() { - // if (jit) - //{ - // std::for_each(m_BreakPoints.begin(), m_BreakPoints.end(), - // [](const TBreakPoint& bp) - // { - // jit->GetBlockCache()->InvalidateICache(bp.iAddress, 4); - // } - // ); - //} - - m_BreakPoints.clear(); -} diff --git a/src/common/break_points.h b/src/common/break_points.h deleted file mode 100644 index e15b9f842..000000000 --- a/src/common/break_points.h +++ /dev/null @@ -1,49 +0,0 @@ -// 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> -#include <vector> -#include "common/common_types.h" - -class DebugInterface; - -struct TBreakPoint { - u32 iAddress; - bool bOn; - bool bTemporary; -}; - -// Code breakpoints. -class BreakPoints { -public: - typedef std::vector<TBreakPoint> TBreakPoints; - typedef std::vector<std::string> TBreakPointsStr; - - const TBreakPoints& GetBreakPoints() { - return m_BreakPoints; - } - - TBreakPointsStr GetStrings() const; - void AddFromStrings(const TBreakPointsStr& bps); - - // is address breakpoint - bool IsAddressBreakPoint(u32 iAddress) const; - bool IsTempBreakPoint(u32 iAddress) const; - - // Add BreakPoint - void Add(u32 em_address, bool temp = false); - void Add(const TBreakPoint& bp); - - // Remove Breakpoint - void Remove(u32 iAddress); - void Clear(); - - void DeleteByAddress(u32 Address); - -private: - TBreakPoints m_BreakPoints; - u32 m_iBreakOnCount; -}; diff --git a/src/common/color.h b/src/common/color.h index 24a445dac..0379040be 100644 --- a/src/common/color.h +++ b/src/common/color.h @@ -4,6 +4,8 @@ #pragma once +#include <cstring> + #include "common/common_types.h" #include "common/swap.h" #include "common/vector_math.h" @@ -55,7 +57,7 @@ constexpr u8 Convert8To6(u8 value) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGBA8(const u8* bytes) { +inline Math::Vec4<u8> DecodeRGBA8(const u8* bytes) { return {bytes[3], bytes[2], bytes[1], bytes[0]}; } @@ -64,7 +66,7 @@ inline const Math::Vec4<u8> DecodeRGBA8(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGB8(const u8* bytes) { +inline Math::Vec4<u8> DecodeRGB8(const u8* bytes) { return {bytes[2], bytes[1], bytes[0], 255}; } @@ -73,7 +75,7 @@ inline const Math::Vec4<u8> DecodeRGB8(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRG8(const u8* bytes) { +inline Math::Vec4<u8> DecodeRG8(const u8* bytes) { return {bytes[1], bytes[0], 0, 255}; } @@ -82,8 +84,9 @@ inline const Math::Vec4<u8> DecodeRG8(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGB565(const u8* bytes) { - const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); +inline Math::Vec4<u8> DecodeRGB565(const u8* bytes) { + u16_le pixel; + std::memcpy(&pixel, bytes, sizeof(pixel)); return {Convert5To8((pixel >> 11) & 0x1F), Convert6To8((pixel >> 5) & 0x3F), Convert5To8(pixel & 0x1F), 255}; } @@ -93,8 +96,9 @@ inline const Math::Vec4<u8> DecodeRGB565(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) { - const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); +inline Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) { + u16_le pixel; + std::memcpy(&pixel, bytes, sizeof(pixel)); return {Convert5To8((pixel >> 11) & 0x1F), Convert5To8((pixel >> 6) & 0x1F), Convert5To8((pixel >> 1) & 0x1F), Convert1To8(pixel & 0x1)}; } @@ -104,8 +108,9 @@ inline const Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) { * @param bytes Pointer to encoded source color * @return Result color decoded as Math::Vec4<u8> */ -inline const Math::Vec4<u8> DecodeRGBA4(const u8* bytes) { - const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); +inline Math::Vec4<u8> DecodeRGBA4(const u8* bytes) { + u16_le pixel; + std::memcpy(&pixel, bytes, sizeof(pixel)); return {Convert4To8((pixel >> 12) & 0xF), Convert4To8((pixel >> 8) & 0xF), Convert4To8((pixel >> 4) & 0xF), Convert4To8(pixel & 0xF)}; } @@ -116,7 +121,9 @@ inline const Math::Vec4<u8> DecodeRGBA4(const u8* bytes) { * @return Depth value as an u32 */ inline u32 DecodeD16(const u8* bytes) { - return *reinterpret_cast<const u16_le*>(bytes); + u16_le data; + std::memcpy(&data, bytes, sizeof(data)); + return data; } /** @@ -133,7 +140,7 @@ inline u32 DecodeD24(const u8* bytes) { * @param bytes Pointer to encoded source values * @return Resulting values stored as a Math::Vec2 */ -inline const Math::Vec2<u32> DecodeD24S8(const u8* bytes) { +inline Math::Vec2<u32> DecodeD24S8(const u8* bytes) { return {static_cast<u32>((bytes[2] << 16) | (bytes[1] << 8) | bytes[0]), bytes[3]}; } @@ -175,8 +182,10 @@ inline void EncodeRG8(const Math::Vec4<u8>& color, u8* bytes) { * @param bytes Destination pointer to store encoded color */ inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) { - *reinterpret_cast<u16_le*>(bytes) = + const u16_le data = (Convert8To5(color.r()) << 11) | (Convert8To6(color.g()) << 5) | Convert8To5(color.b()); + + std::memcpy(bytes, &data, sizeof(data)); } /** @@ -185,9 +194,10 @@ inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) { * @param bytes Destination pointer to store encoded color */ inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) { - *reinterpret_cast<u16_le*>(bytes) = (Convert8To5(color.r()) << 11) | - (Convert8To5(color.g()) << 6) | - (Convert8To5(color.b()) << 1) | Convert8To1(color.a()); + const u16_le data = (Convert8To5(color.r()) << 11) | (Convert8To5(color.g()) << 6) | + (Convert8To5(color.b()) << 1) | Convert8To1(color.a()); + + std::memcpy(bytes, &data, sizeof(data)); } /** @@ -196,9 +206,10 @@ inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) { * @param bytes Destination pointer to store encoded color */ inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) { - *reinterpret_cast<u16_le*>(bytes) = (Convert8To4(color.r()) << 12) | - (Convert8To4(color.g()) << 8) | - (Convert8To4(color.b()) << 4) | Convert8To4(color.a()); + const u16 data = (Convert8To4(color.r()) << 12) | (Convert8To4(color.g()) << 8) | + (Convert8To4(color.b()) << 4) | Convert8To4(color.a()); + + std::memcpy(bytes, &data, sizeof(data)); } /** @@ -207,7 +218,8 @@ inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) { * @param bytes Pointer where to store the encoded value */ inline void EncodeD16(u32 value, u8* bytes) { - *reinterpret_cast<u16_le*>(bytes) = value & 0xFFFF; + const u16_le data = static_cast<u16>(value); + std::memcpy(bytes, &data, sizeof(data)); } /** diff --git a/src/common/common_funcs.h b/src/common/common_funcs.h index 93f1c0044..8b0d34da6 100644 --- a/src/common/common_funcs.h +++ b/src/common/common_funcs.h @@ -6,7 +6,7 @@ #include <string> -#if !defined(ARCHITECTURE_x86_64) && !defined(ARCHITECTURE_ARM) +#if !defined(ARCHITECTURE_x86_64) #include <cstdlib> // for exit #endif #include "common/common_types.h" @@ -32,8 +32,6 @@ #ifdef ARCHITECTURE_x86_64 #define Crash() __asm__ __volatile__("int $3") -#elif defined(ARCHITECTURE_ARM) -#define Crash() __asm__ __volatile__("trap") #else #define Crash() exit(1) #endif diff --git a/src/common/common_paths.h b/src/common/common_paths.h index 6799a357a..df2ce80b1 100644 --- a/src/common/common_paths.h +++ b/src/common/common_paths.h @@ -32,6 +32,7 @@ #define SDMC_DIR "sdmc" #define NAND_DIR "nand" #define SYSDATA_DIR "sysdata" +#define KEYS_DIR "keys" #define LOG_DIR "log" // Filenames diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp index b8dd92b65..b30a67ff9 100644 --- a/src/common/file_util.cpp +++ b/src/common/file_util.cpp @@ -706,6 +706,7 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) { paths.emplace(UserPath::SDMCDir, user_path + SDMC_DIR DIR_SEP); paths.emplace(UserPath::NANDDir, user_path + NAND_DIR DIR_SEP); paths.emplace(UserPath::SysDataDir, user_path + SYSDATA_DIR DIR_SEP); + paths.emplace(UserPath::KeysDir, user_path + KEYS_DIR DIR_SEP); // TODO: Put the logs in a better location for each OS paths.emplace(UserPath::LogDir, user_path + LOG_DIR DIR_SEP); } @@ -736,6 +737,25 @@ const std::string& GetUserPath(UserPath path, const std::string& new_path) { return paths[path]; } +std::string GetHactoolConfigurationPath() { +#ifdef _WIN32 + PWSTR pw_local_path = nullptr; + if (SHGetKnownFolderPath(FOLDERID_Profile, 0, nullptr, &pw_local_path) != S_OK) + return ""; + std::string local_path = Common::UTF16ToUTF8(pw_local_path); + CoTaskMemFree(pw_local_path); + return local_path + "\\.switch"; +#else + return GetHomeDirectory() + "/.switch"; +#endif +} + +std::string GetNANDRegistrationDir(bool system) { + if (system) + return GetUserPath(UserPath::NANDDir) + "system/Contents/registered/"; + return GetUserPath(UserPath::NANDDir) + "user/Contents/registered/"; +} + size_t WriteStringToFile(bool text_file, const std::string& str, const char* filename) { return FileUtil::IOFile(filename, text_file ? "w" : "wb").WriteBytes(str.data(), str.size()); } @@ -870,11 +890,21 @@ std::string_view RemoveTrailingSlash(std::string_view path) { return path; } -std::string SanitizePath(std::string_view path_) { +std::string SanitizePath(std::string_view path_, DirectorySeparator directory_separator) { std::string path(path_); - std::replace(path.begin(), path.end(), '\\', '/'); + char type1 = directory_separator == DirectorySeparator::BackwardSlash ? '/' : '\\'; + char type2 = directory_separator == DirectorySeparator::BackwardSlash ? '\\' : '/'; + + if (directory_separator == DirectorySeparator::PlatformDefault) { +#ifdef _WIN32 + type1 = '/'; + type2 = '\\'; +#endif + } + + std::replace(path.begin(), path.end(), type1, type2); path.erase(std::unique(path.begin(), path.end(), - [](char c1, char c2) { return c1 == '/' && c2 == '/'; }), + [type2](char c1, char c2) { return c1 == type2 && c2 == type2; }), path.end()); return std::string(RemoveTrailingSlash(path)); } diff --git a/src/common/file_util.h b/src/common/file_util.h index bc9272d89..2f13d0b6b 100644 --- a/src/common/file_util.h +++ b/src/common/file_util.h @@ -8,6 +8,7 @@ #include <cstdio> #include <fstream> #include <functional> +#include <limits> #include <string> #include <string_view> #include <type_traits> @@ -23,6 +24,7 @@ namespace FileUtil { enum class UserPath { CacheDir, ConfigDir, + KeysDir, LogDir, NANDDir, RootDir, @@ -125,6 +127,10 @@ bool SetCurrentDir(const std::string& directory); // directory. To be used in "multi-user" mode (that is, installed). const std::string& GetUserPath(UserPath path, const std::string& new_path = ""); +std::string GetHactoolConfigurationPath(); + +std::string GetNANDRegistrationDir(bool system = false); + // Returns the path to where the sys file are std::string GetSysDirectory(); @@ -178,8 +184,12 @@ std::vector<T> SliceVector(const std::vector<T>& vector, size_t first, size_t la return std::vector<T>(vector.begin() + first, vector.begin() + first + last); } -// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. -std::string SanitizePath(std::string_view path); +enum class DirectorySeparator { ForwardSlash, BackwardSlash, PlatformDefault }; + +// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. Makes '/' into '\\' +// depending if directory_separator is BackwardSlash or PlatformDefault and running on windows +std::string SanitizePath(std::string_view path, + DirectorySeparator directory_separator = DirectorySeparator::ForwardSlash); // simple wrapper for cstdlib file functions to // hopefully will make error checking easier @@ -204,39 +214,42 @@ public: template <typename T> size_t ReadArray(T* data, size_t length) const { - static_assert(std::is_trivially_copyable<T>(), + static_assert(std::is_trivially_copyable_v<T>, "Given array does not consist of trivially copyable objects"); - if (!IsOpen()) - return -1; + if (!IsOpen()) { + return std::numeric_limits<size_t>::max(); + } return std::fread(data, sizeof(T), length, m_file); } template <typename T> size_t WriteArray(const T* data, size_t length) { - static_assert(std::is_trivially_copyable<T>(), + static_assert(std::is_trivially_copyable_v<T>, "Given array does not consist of trivially copyable objects"); - if (!IsOpen()) - return -1; + if (!IsOpen()) { + return std::numeric_limits<size_t>::max(); + } + return std::fwrite(data, sizeof(T), length, m_file); } template <typename T> size_t ReadBytes(T* data, size_t length) const { - static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable"); + static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable"); return ReadArray(reinterpret_cast<char*>(data), length); } template <typename T> size_t WriteBytes(const T* data, size_t length) { - static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable"); + static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable"); return WriteArray(reinterpret_cast<const char*>(data), length); } template <typename T> size_t WriteObject(const T& object) { - static_assert(!std::is_pointer<T>::value, "Given object is a pointer"); + static_assert(!std::is_pointer_v<T>, "WriteObject arguments must not be a pointer"); return WriteArray(&object, 1); } diff --git a/src/common/hash.h b/src/common/hash.h index 73c326980..2c761e545 100644 --- a/src/common/hash.h +++ b/src/common/hash.h @@ -28,7 +28,7 @@ static inline u64 ComputeHash64(const void* data, size_t len) { */ template <typename T> static inline u64 ComputeStructHash64(const T& data) { - static_assert(std::is_trivially_copyable<T>(), + static_assert(std::is_trivially_copyable_v<T>, "Type passed to ComputeStructHash64 must be trivially copyable"); return ComputeHash64(&data, sizeof(data)); } @@ -38,7 +38,7 @@ template <typename T> struct HashableStruct { // In addition to being trivially copyable, T must also have a trivial default constructor, // because any member initialization would be overridden by memset - static_assert(std::is_trivial<T>(), "Type passed to HashableStruct must be trivial"); + static_assert(std::is_trivial_v<T>, "Type passed to HashableStruct must be trivial"); /* * We use a union because "implicitly-defined copy/move constructor for a union X copies the * object representation of X." and "implicitly-defined copy assignment operator for a union X diff --git a/src/common/hex_util.cpp b/src/common/hex_util.cpp new file mode 100644 index 000000000..609144def --- /dev/null +++ b/src/common/hex_util.cpp @@ -0,0 +1,31 @@ +// Copyright 2013 Dolphin Emulator Project / 2014 Citra Emulator Project +// Licensed under GPLv2 or any later version +// Refer to the license.txt file included. + +#include "common/hex_util.h" + +namespace Common { + +u8 ToHexNibble(char c1) { + if (c1 >= 65 && c1 <= 70) + return c1 - 55; + if (c1 >= 97 && c1 <= 102) + return c1 - 87; + if (c1 >= 48 && c1 <= 57) + return c1 - 48; + throw std::logic_error("Invalid hex digit"); +} + +std::array<u8, 16> operator""_array16(const char* str, size_t len) { + if (len != 32) + throw std::logic_error("Not of correct size."); + return HexStringToArray<16>(str); +} + +std::array<u8, 32> operator""_array32(const char* str, size_t len) { + if (len != 64) + throw std::logic_error("Not of correct size."); + return HexStringToArray<32>(str); +} + +} // namespace Common diff --git a/src/common/hex_util.h b/src/common/hex_util.h new file mode 100644 index 000000000..5fb79bb72 --- /dev/null +++ b/src/common/hex_util.h @@ -0,0 +1,41 @@ +// 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 <array> +#include <cstddef> +#include <string> +#include <fmt/format.h> +#include "common/common_types.h" + +namespace Common { + +u8 ToHexNibble(char c1); + +template <size_t Size, bool le = false> +std::array<u8, Size> HexStringToArray(std::string_view str) { + std::array<u8, Size> out{}; + if constexpr (le) { + for (size_t i = 2 * Size - 2; i <= 2 * Size; i -= 2) + out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]); + } else { + for (size_t i = 0; i < 2 * Size; i += 2) + out[i / 2] = (ToHexNibble(str[i]) << 4) | ToHexNibble(str[i + 1]); + } + return out; +} + +template <size_t Size> +std::string HexArrayToString(std::array<u8, Size> array, bool upper = true) { + std::string out; + for (u8 c : array) + out += fmt::format(upper ? "{:02X}" : "{:02x}", c); + return out; +} + +std::array<u8, 0x10> operator"" _array16(const char* str, size_t len); +std::array<u8, 0x20> operator"" _array32(const char* str, size_t len); + +} // namespace Common diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp index 59b999935..1323f8d0f 100644 --- a/src/common/logging/backend.cpp +++ b/src/common/logging/backend.cpp @@ -168,25 +168,49 @@ void FileBackend::Write(const Entry& entry) { SUB(Service, AM) \ SUB(Service, AOC) \ SUB(Service, APM) \ + SUB(Service, ARP) \ SUB(Service, BCAT) \ + SUB(Service, BPC) \ + SUB(Service, BTDRV) \ + SUB(Service, BTM) \ + SUB(Service, Capture) \ + SUB(Service, ERPT) \ + SUB(Service, ETicket) \ + SUB(Service, EUPLD) \ SUB(Service, Fatal) \ + SUB(Service, FGM) \ SUB(Service, Friend) \ SUB(Service, FS) \ + SUB(Service, GRC) \ SUB(Service, HID) \ + SUB(Service, LBL) \ + SUB(Service, LDN) \ + SUB(Service, LDR) \ SUB(Service, LM) \ + SUB(Service, Migration) \ + SUB(Service, Mii) \ SUB(Service, MM) \ + SUB(Service, NCM) \ + SUB(Service, NFC) \ SUB(Service, NFP) \ SUB(Service, NIFM) \ + SUB(Service, NIM) \ SUB(Service, NS) \ SUB(Service, NVDRV) \ + SUB(Service, PCIE) \ SUB(Service, PCTL) \ + SUB(Service, PCV) \ + SUB(Service, PM) \ SUB(Service, PREPO) \ + SUB(Service, PSC) \ SUB(Service, SET) \ SUB(Service, SM) \ SUB(Service, SPL) \ SUB(Service, SSL) \ SUB(Service, Time) \ + SUB(Service, USB) \ SUB(Service, VI) \ + SUB(Service, WLAN) \ CLS(HW) \ SUB(HW, Memory) \ SUB(HW, LCD) \ @@ -203,6 +227,7 @@ void FileBackend::Write(const Entry& entry) { CLS(Input) \ CLS(Network) \ CLS(Loader) \ + CLS(Crypto) \ CLS(WebService) // GetClassName is a macro defined by Windows.h, grrr... @@ -277,13 +302,14 @@ Backend* GetBackend(std::string_view backend_name) { void FmtLogMessageImpl(Class log_class, Level log_level, const char* filename, unsigned int line_num, const char* function, const char* format, const fmt::format_args& args) { - auto filter = Impl::Instance().GetGlobalFilter(); + auto& instance = Impl::Instance(); + const auto& filter = instance.GetGlobalFilter(); if (!filter.CheckMessage(log_class, log_level)) return; Entry entry = CreateEntry(log_class, log_level, filename, line_num, function, fmt::vformat(format, args)); - Impl::Instance().PushEntry(std::move(entry)); + instance.PushEntry(std::move(entry)); } } // namespace Log diff --git a/src/common/logging/log.h b/src/common/logging/log.h index e7115933f..e12f47f8f 100644 --- a/src/common/logging/log.h +++ b/src/common/logging/log.h @@ -54,26 +54,50 @@ enum class Class : ClassType { Service_AM, ///< The AM (Applet manager) service Service_AOC, ///< The AOC (AddOn Content) service Service_APM, ///< The APM (Performance) service + Service_ARP, ///< The ARP service Service_Audio, ///< The Audio (Audio control) service Service_BCAT, ///< The BCAT service + Service_BPC, ///< The BPC service + Service_BTDRV, ///< The Bluetooth driver service + Service_BTM, ///< The BTM service + Service_Capture, ///< The capture service + Service_ERPT, ///< The error reporting service + Service_ETicket, ///< The ETicket service + Service_EUPLD, ///< The error upload service Service_Fatal, ///< The Fatal service + Service_FGM, ///< The FGM service Service_Friend, ///< The friend service Service_FS, ///< The FS (Filesystem) service + Service_GRC, ///< The game recording service Service_HID, ///< The HID (Human interface device) service + Service_LBL, ///< The LBL (LCD backlight) service + Service_LDN, ///< The LDN (Local domain network) service + Service_LDR, ///< The loader service Service_LM, ///< The LM (Logger) service + Service_Migration, ///< The migration service + Service_Mii, ///< The Mii service Service_MM, ///< The MM (Multimedia) service + Service_NCM, ///< The NCM service + Service_NFC, ///< The NFC (Near-field communication) service Service_NFP, ///< The NFP service Service_NIFM, ///< The NIFM (Network interface) service + Service_NIM, ///< The NIM service Service_NS, ///< The NS services Service_NVDRV, ///< The NVDRV (Nvidia driver) service + Service_PCIE, ///< The PCIe service Service_PCTL, ///< The PCTL (Parental control) service + Service_PCV, ///< The PCV service + Service_PM, ///< The PM service Service_PREPO, ///< The PREPO (Play report) service + Service_PSC, ///< The PSC service Service_SET, ///< The SET (Settings) service Service_SM, ///< The SM (Service manager) service Service_SPL, ///< The SPL service Service_SSL, ///< The SSL service Service_Time, ///< The time service + Service_USB, ///< The USB (Universal Serial Bus) service Service_VI, ///< The VI (Video interface) service + Service_WLAN, ///< The WLAN (Wireless local area network) service HW, ///< Low-level hardware emulation HW_Memory, ///< Memory-map and address translation HW_LCD, ///< LCD register emulation @@ -88,6 +112,7 @@ enum class Class : ClassType { Audio_DSP, ///< The HLE implementation of the DSP Audio_Sink, ///< Emulator audio output backend Loader, ///< ROM loader + Crypto, ///< Cryptographic engine/functions Input, ///< Input emulation Network, ///< Network emulation WebService, ///< Interface to yuzu Web Services diff --git a/src/common/logging/text_formatter.h b/src/common/logging/text_formatter.h index c587faefb..9609cec7c 100644 --- a/src/common/logging/text_formatter.h +++ b/src/common/logging/text_formatter.h @@ -5,6 +5,7 @@ #pragma once #include <cstddef> +#include <string> namespace Log { diff --git a/src/common/math_util.h b/src/common/math_util.h index c6a83c953..343cdd902 100644 --- a/src/common/math_util.h +++ b/src/common/math_util.h @@ -19,12 +19,12 @@ inline bool IntervalsIntersect(unsigned start0, unsigned length0, unsigned start template <class T> struct Rectangle { - T left; - T top; - T right; - T bottom; + T left{}; + T top{}; + T right{}; + T bottom{}; - Rectangle() {} + Rectangle() = default; Rectangle(T left, T top, T right, T bottom) : left(left), top(top), right(right), bottom(bottom) {} diff --git a/src/common/misc.cpp b/src/common/misc.cpp index 217a87098..3fa8a3bc4 100644 --- a/src/common/misc.cpp +++ b/src/common/misc.cpp @@ -4,7 +4,7 @@ #include <cstddef> #ifdef _WIN32 -#include <Windows.h> +#include <windows.h> #else #include <cerrno> #include <cstring> diff --git a/src/common/string_util.cpp b/src/common/string_util.cpp index 1f0456aee..0ca663032 100644 --- a/src/common/string_util.cpp +++ b/src/common/string_util.cpp @@ -2,12 +2,12 @@ // Licensed under GPLv2 or any later version // Refer to the license.txt file included. +#include <algorithm> #include <cctype> #include <cerrno> #include <cstdio> #include <cstdlib> #include <cstring> -#include <boost/range/algorithm/transform.hpp> #include "common/common_paths.h" #include "common/logging/log.h" #include "common/string_util.h" @@ -24,13 +24,15 @@ namespace Common { /// Make a string lowercase std::string ToLower(std::string str) { - boost::transform(str, str.begin(), ::tolower); + std::transform(str.begin(), str.end(), str.begin(), + [](unsigned char c) { return std::tolower(c); }); return str; } /// Make a string uppercase std::string ToUpper(std::string str) { - boost::transform(str, str.begin(), ::toupper); + std::transform(str.begin(), str.end(), str.begin(), + [](unsigned char c) { return std::toupper(c); }); return str; } diff --git a/src/common/swap.h b/src/common/swap.h index fc7af4280..32af0b6ac 100644 --- a/src/common/swap.h +++ b/src/common/swap.h @@ -69,7 +69,7 @@ inline u32 swap32(u32 _data) { inline u64 swap64(u64 _data) { return _byteswap_uint64(_data); } -#elif ARCHITECTURE_ARM +#elif defined(ARCHITECTURE_ARM) && (__ARM_ARCH >= 6) inline u16 swap16(u16 _data) { u32 data = _data; __asm__("rev16 %0, %1\n" : "=l"(data) : "l"(data)); diff --git a/src/common/thread_queue_list.h b/src/common/thread_queue_list.h index 38a450d69..133122c5f 100644 --- a/src/common/thread_queue_list.h +++ b/src/common/thread_queue_list.h @@ -16,7 +16,7 @@ struct ThreadQueueList { // (dynamically resizable) circular buffers to remove their overhead when // inserting and popping. - typedef unsigned int Priority; + using Priority = unsigned int; // Number of priority levels. (Valid levels are [0..NUM_QUEUES).) static const Priority NUM_QUEUES = N; @@ -26,9 +26,9 @@ struct ThreadQueueList { } // Only for debugging, returns priority level. - Priority contains(const T& uid) { + Priority contains(const T& uid) const { for (Priority i = 0; i < NUM_QUEUES; ++i) { - Queue& cur = queues[i]; + const Queue& cur = queues[i]; if (std::find(cur.data.cbegin(), cur.data.cend(), uid) != cur.data.cend()) { return i; } @@ -37,8 +37,8 @@ struct ThreadQueueList { return -1; } - T get_first() { - Queue* cur = first; + T get_first() const { + const Queue* cur = first; while (cur != nullptr) { if (!cur->data.empty()) { return cur->data.front(); diff --git a/src/common/threadsafe_queue.h b/src/common/threadsafe_queue.h index a0c731e8c..edf13bc49 100644 --- a/src/common/threadsafe_queue.h +++ b/src/common/threadsafe_queue.h @@ -33,9 +33,11 @@ public: bool Empty() const { return !read_ptr->next.load(); } + T& Front() const { return read_ptr->current; } + template <typename Arg> void Push(Arg&& t) { // create the element, add it to the queue @@ -108,15 +110,41 @@ private: // single reader, multiple writer queue template <typename T, bool NeedSize = true> -class MPSCQueue : public SPSCQueue<T, NeedSize> { +class MPSCQueue { public: + u32 Size() const { + return spsc_queue.Size(); + } + + bool Empty() const { + return spsc_queue.Empty(); + } + + T& Front() const { + return spsc_queue.Front(); + } + template <typename Arg> void Push(Arg&& t) { std::lock_guard<std::mutex> lock(write_lock); - SPSCQueue<T, NeedSize>::Push(t); + spsc_queue.Push(t); + } + + void Pop() { + return spsc_queue.Pop(); + } + + bool Pop(T& t) { + return spsc_queue.Pop(t); + } + + // not thread-safe + void Clear() { + spsc_queue.Clear(); } private: + SPSCQueue<T, NeedSize> spsc_queue; std::mutex write_lock; }; } // namespace Common diff --git a/src/common/timer.cpp b/src/common/timer.cpp index f0c5b1a43..2dc15e434 100644 --- a/src/common/timer.cpp +++ b/src/common/timer.cpp @@ -3,31 +3,16 @@ // Refer to the license.txt file included. #include <ctime> - #include <fmt/format.h> - -#ifdef _WIN32 -#include <windows.h> -// windows.h needs to be included before other windows headers -#include <mmsystem.h> -#include <sys/timeb.h> -#else -#include <sys/time.h> -#endif #include "common/common_types.h" #include "common/string_util.h" #include "common/timer.h" namespace Common { -u32 Timer::GetTimeMs() { -#ifdef _WIN32 - return timeGetTime(); -#else - struct timeval t; - (void)gettimeofday(&t, nullptr); - return ((u32)(t.tv_sec * 1000 + t.tv_usec / 1000)); -#endif +std::chrono::milliseconds Timer::GetTimeMs() { + return std::chrono::duration_cast<std::chrono::milliseconds>( + std::chrono::system_clock::now().time_since_epoch()); } // -------------------------------------------- @@ -63,7 +48,7 @@ void Timer::Update() { // ------------------------------------- // Get the number of milliseconds since the last Update() -u64 Timer::GetTimeDifference() { +std::chrono::milliseconds Timer::GetTimeDifference() { return GetTimeMs() - m_LastTime; } @@ -74,11 +59,11 @@ void Timer::AddTimeDifference() { } // Get the time elapsed since the Start() -u64 Timer::GetTimeElapsed() { +std::chrono::milliseconds Timer::GetTimeElapsed() { // If we have not started yet, return 1 (because then I don't // have to change the FPS calculation in CoreRerecording.cpp . - if (m_StartTime == 0) - return 1; + if (m_StartTime.count() == 0) + return std::chrono::milliseconds(1); // Return the final timer time if the timer is stopped if (!m_Running) @@ -90,49 +75,34 @@ u64 Timer::GetTimeElapsed() { // Get the formatted time elapsed since the Start() std::string Timer::GetTimeElapsedFormatted() const { // If we have not started yet, return zero - if (m_StartTime == 0) + if (m_StartTime.count() == 0) return "00:00:00:000"; // The number of milliseconds since the start. // Use a different value if the timer is stopped. - u64 Milliseconds; + std::chrono::milliseconds Milliseconds; if (m_Running) Milliseconds = GetTimeMs() - m_StartTime; else Milliseconds = m_LastTime - m_StartTime; // Seconds - u32 Seconds = (u32)(Milliseconds / 1000); + std::chrono::seconds Seconds = std::chrono::duration_cast<std::chrono::seconds>(Milliseconds); // Minutes - u32 Minutes = Seconds / 60; + std::chrono::minutes Minutes = std::chrono::duration_cast<std::chrono::minutes>(Milliseconds); // Hours - u32 Hours = Minutes / 60; + std::chrono::hours Hours = std::chrono::duration_cast<std::chrono::hours>(Milliseconds); - std::string TmpStr = fmt::format("{:02}:{:02}:{:02}:{:03}", Hours, Minutes % 60, Seconds % 60, - Milliseconds % 1000); + std::string TmpStr = fmt::format("{:02}:{:02}:{:02}:{:03}", Hours.count(), Minutes.count() % 60, + Seconds.count() % 60, Milliseconds.count() % 1000); return TmpStr; } -// Get current time -void Timer::IncreaseResolution() { -#ifdef _WIN32 - timeBeginPeriod(1); -#endif -} - -void Timer::RestoreResolution() { -#ifdef _WIN32 - timeEndPeriod(1); -#endif -} - // Get the number of seconds since January 1 1970 -u64 Timer::GetTimeSinceJan1970() { - time_t ltime; - time(<ime); - return ((u64)ltime); +std::chrono::seconds Timer::GetTimeSinceJan1970() { + return std::chrono::duration_cast<std::chrono::seconds>(GetTimeMs()); } -u64 Timer::GetLocalTimeSinceJan1970() { +std::chrono::seconds Timer::GetLocalTimeSinceJan1970() { time_t sysTime, tzDiff, tzDST; struct tm* gmTime; @@ -149,7 +119,7 @@ u64 Timer::GetLocalTimeSinceJan1970() { gmTime = gmtime(&sysTime); tzDiff = sysTime - mktime(gmTime); - return (u64)(sysTime + tzDiff + tzDST); + return std::chrono::seconds(sysTime + tzDiff + tzDST); } // Return the current time formatted as Minutes:Seconds:Milliseconds @@ -164,30 +134,16 @@ std::string Timer::GetTimeFormatted() { strftime(tmp, 6, "%M:%S", gmTime); -// Now tack on the milliseconds -#ifdef _WIN32 - struct timeb tp; - (void)::ftime(&tp); - return fmt::format("{}:{:03}", tmp, tp.millitm); -#else - struct timeval t; - (void)gettimeofday(&t, nullptr); - return fmt::format("{}:{:03}", tmp, static_cast<int>(t.tv_usec / 1000)); -#endif + u64 milliseconds = static_cast<u64>(GetTimeMs().count()) % 1000; + return fmt::format("{}:{:03}", tmp, milliseconds); } // Returns a timestamp with decimals for precise time comparisons // ---------------- double Timer::GetDoubleTime() { -#ifdef _WIN32 - struct timeb tp; - (void)::ftime(&tp); -#else - struct timeval t; - (void)gettimeofday(&t, nullptr); -#endif // Get continuous timestamp - u64 TmpSeconds = Common::Timer::GetTimeSinceJan1970(); + u64 TmpSeconds = static_cast<u64>(Common::Timer::GetTimeSinceJan1970().count()); + double ms = static_cast<u64>(GetTimeMs().count()) % 1000; // Remove a few years. We only really want enough seconds to make // sure that we are detecting actual actions, perhaps 60 seconds is @@ -196,12 +152,7 @@ double Timer::GetDoubleTime() { TmpSeconds = TmpSeconds - (38 * 365 * 24 * 60 * 60); // Make a smaller integer that fits in the double - u32 Seconds = (u32)TmpSeconds; -#ifdef _WIN32 - double ms = tp.millitm / 1000.0 / 1000.0; -#else - double ms = t.tv_usec / 1000000.0; -#endif + u32 Seconds = static_cast<u32>(TmpSeconds); double TmpTime = Seconds + ms; return TmpTime; diff --git a/src/common/timer.h b/src/common/timer.h index 78d37426b..27b521baa 100644 --- a/src/common/timer.h +++ b/src/common/timer.h @@ -4,6 +4,7 @@ #pragma once +#include <chrono> #include <string> #include "common/common_types.h" @@ -18,24 +19,22 @@ public: // The time difference is always returned in milliseconds, regardless of alternative internal // representation - u64 GetTimeDifference(); + std::chrono::milliseconds GetTimeDifference(); void AddTimeDifference(); - static void IncreaseResolution(); - static void RestoreResolution(); - static u64 GetTimeSinceJan1970(); - static u64 GetLocalTimeSinceJan1970(); + static std::chrono::seconds GetTimeSinceJan1970(); + static std::chrono::seconds GetLocalTimeSinceJan1970(); static double GetDoubleTime(); static std::string GetTimeFormatted(); std::string GetTimeElapsedFormatted() const; - u64 GetTimeElapsed(); + std::chrono::milliseconds GetTimeElapsed(); - static u32 GetTimeMs(); + static std::chrono::milliseconds GetTimeMs(); private: - u64 m_LastTime; - u64 m_StartTime; + std::chrono::milliseconds m_LastTime; + std::chrono::milliseconds m_StartTime; bool m_Running; }; diff --git a/src/common/vector_math.h b/src/common/vector_math.h index cca43bd4c..8feb49941 100644 --- a/src/common/vector_math.h +++ b/src/common/vector_math.h @@ -43,139 +43,135 @@ template <typename T> class Vec4; template <typename T> -static inline Vec2<T> MakeVec(const T& x, const T& y); -template <typename T> -static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z); -template <typename T> -static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w); - -template <typename T> class Vec2 { public: T x{}; T y{}; - Vec2() = default; - Vec2(const T& _x, const T& _y) : x(_x), y(_y) {} + constexpr Vec2() = default; + constexpr Vec2(const T& x_, const T& y_) : x(x_), y(y_) {} template <typename T2> - Vec2<T2> Cast() const { - return Vec2<T2>((T2)x, (T2)y); + constexpr Vec2<T2> Cast() const { + return Vec2<T2>(static_cast<T2>(x), static_cast<T2>(y)); } - static Vec2 AssignToAll(const T& f) { - return Vec2<T>(f, f); + static constexpr Vec2 AssignToAll(const T& f) { + return Vec2{f, f}; } - Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const { - return MakeVec(x + other.x, y + other.y); + constexpr Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const { + return {x + other.x, y + other.y}; } - void operator+=(const Vec2& other) { + constexpr Vec2& operator+=(const Vec2& other) { x += other.x; y += other.y; + return *this; } - Vec2<decltype(T{} - T{})> operator-(const Vec2& other) const { - return MakeVec(x - other.x, y - other.y); + constexpr Vec2<decltype(T{} - T{})> operator-(const Vec2& other) const { + return {x - other.x, y - other.y}; } - void operator-=(const Vec2& other) { + constexpr Vec2& operator-=(const Vec2& other) { x -= other.x; y -= other.y; + return *this; } template <typename U = T> - Vec2<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { - return MakeVec(-x, -y); + constexpr Vec2<std::enable_if_t<std::is_signed_v<U>, U>> operator-() const { + return {-x, -y}; } - Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const { - return MakeVec(x * other.x, y * other.y); + constexpr Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const { + return {x * other.x, y * other.y}; } + template <typename V> - Vec2<decltype(T{} * V{})> operator*(const V& f) const { - return MakeVec(x * f, y * f); + constexpr Vec2<decltype(T{} * V{})> operator*(const V& f) const { + return {x * f, y * f}; } + template <typename V> - void operator*=(const V& f) { + constexpr Vec2& operator*=(const V& f) { *this = *this * f; + return *this; } + template <typename V> - Vec2<decltype(T{} / V{})> operator/(const V& f) const { - return MakeVec(x / f, y / f); + constexpr Vec2<decltype(T{} / V{})> operator/(const V& f) const { + return {x / f, y / f}; } + template <typename V> - void operator/=(const V& f) { + constexpr Vec2& operator/=(const V& f) { *this = *this / f; + return *this; } - T Length2() const { + constexpr T Length2() const { return x * x + y * y; } // Only implemented for T=float float Length() const; - void SetLength(const float l); - Vec2 WithLength(const float l) const; - float Distance2To(Vec2& other); - Vec2 Normalized() const; float Normalize(); // returns the previous length, which is often useful - T& operator[](int i) // allow vector[1] = 3 (vector.y=3) - { + constexpr T& operator[](std::size_t i) { return *((&x) + i); } - T operator[](const int i) const { + constexpr const T& operator[](std::size_t i) const { return *((&x) + i); } - void SetZero() { + constexpr void SetZero() { x = 0; y = 0; } // Common aliases: UV (texel coordinates), ST (texture coordinates) - T& u() { + constexpr T& u() { return x; } - T& v() { + constexpr T& v() { return y; } - T& s() { + constexpr T& s() { return x; } - T& t() { + constexpr T& t() { return y; } - const T& u() const { + constexpr const T& u() const { return x; } - const T& v() const { + constexpr const T& v() const { return y; } - const T& s() const { + constexpr const T& s() const { return x; } - const T& t() const { + constexpr const T& t() const { return y; } // swizzlers - create a subvector of specific components - const Vec2 yx() const { + constexpr Vec2 yx() const { return Vec2(y, x); } - const Vec2 vu() const { + constexpr Vec2 vu() const { return Vec2(y, x); } - const Vec2 ts() const { + constexpr Vec2 ts() const { return Vec2(y, x); } }; template <typename T, typename V> -Vec2<T> operator*(const V& f, const Vec2<T>& vec) { +constexpr Vec2<T> operator*(const V& f, const Vec2<T>& vec) { return Vec2<T>(f * vec.x, f * vec.y); } -typedef Vec2<float> Vec2f; +using Vec2f = Vec2<float>; template <> inline float Vec2<float>::Length() const { @@ -196,147 +192,151 @@ public: T y{}; T z{}; - Vec3() = default; - Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {} + constexpr Vec3() = default; + constexpr Vec3(const T& x_, const T& y_, const T& z_) : x(x_), y(y_), z(z_) {} template <typename T2> - Vec3<T2> Cast() const { - return MakeVec<T2>((T2)x, (T2)y, (T2)z); + constexpr Vec3<T2> Cast() const { + return Vec3<T2>(static_cast<T2>(x), static_cast<T2>(y), static_cast<T2>(z)); } - // Only implemented for T=int and T=float - static Vec3 FromRGB(unsigned int rgb); - unsigned int ToRGB() const; // alpha bits set to zero - - static Vec3 AssignToAll(const T& f) { - return MakeVec(f, f, f); + static constexpr Vec3 AssignToAll(const T& f) { + return Vec3(f, f, f); } - Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const { - return MakeVec(x + other.x, y + other.y, z + other.z); + constexpr Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const { + return {x + other.x, y + other.y, z + other.z}; } - void operator+=(const Vec3& other) { + + constexpr Vec3& operator+=(const Vec3& other) { x += other.x; y += other.y; z += other.z; + return *this; } - Vec3<decltype(T{} - T{})> operator-(const Vec3& other) const { - return MakeVec(x - other.x, y - other.y, z - other.z); + + constexpr Vec3<decltype(T{} - T{})> operator-(const Vec3& other) const { + return {x - other.x, y - other.y, z - other.z}; } - void operator-=(const Vec3& other) { + + constexpr Vec3& operator-=(const Vec3& other) { x -= other.x; y -= other.y; z -= other.z; + return *this; } template <typename U = T> - Vec3<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { - return MakeVec(-x, -y, -z); + constexpr Vec3<std::enable_if_t<std::is_signed_v<U>, U>> operator-() const { + return {-x, -y, -z}; } - Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const { - return MakeVec(x * other.x, y * other.y, z * other.z); + + constexpr Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const { + return {x * other.x, y * other.y, z * other.z}; } + template <typename V> - Vec3<decltype(T{} * V{})> operator*(const V& f) const { - return MakeVec(x * f, y * f, z * f); + constexpr Vec3<decltype(T{} * V{})> operator*(const V& f) const { + return {x * f, y * f, z * f}; } + template <typename V> - void operator*=(const V& f) { + constexpr Vec3& operator*=(const V& f) { *this = *this * f; + return *this; } template <typename V> - Vec3<decltype(T{} / V{})> operator/(const V& f) const { - return MakeVec(x / f, y / f, z / f); + constexpr Vec3<decltype(T{} / V{})> operator/(const V& f) const { + return {x / f, y / f, z / f}; } + template <typename V> - void operator/=(const V& f) { + constexpr Vec3& operator/=(const V& f) { *this = *this / f; + return *this; } - T Length2() const { + constexpr T Length2() const { return x * x + y * y + z * z; } // Only implemented for T=float float Length() const; - void SetLength(const float l); - Vec3 WithLength(const float l) const; - float Distance2To(Vec3& other); Vec3 Normalized() const; float Normalize(); // returns the previous length, which is often useful - T& operator[](int i) // allow vector[2] = 3 (vector.z=3) - { + constexpr T& operator[](std::size_t i) { return *((&x) + i); } - T operator[](const int i) const { + + constexpr const T& operator[](std::size_t i) const { return *((&x) + i); } - void SetZero() { + constexpr void SetZero() { x = 0; y = 0; z = 0; } // Common aliases: UVW (texel coordinates), RGB (colors), STQ (texture coordinates) - T& u() { + constexpr T& u() { return x; } - T& v() { + constexpr T& v() { return y; } - T& w() { + constexpr T& w() { return z; } - T& r() { + constexpr T& r() { return x; } - T& g() { + constexpr T& g() { return y; } - T& b() { + constexpr T& b() { return z; } - T& s() { + constexpr T& s() { return x; } - T& t() { + constexpr T& t() { return y; } - T& q() { + constexpr T& q() { return z; } - const T& u() const { + constexpr const T& u() const { return x; } - const T& v() const { + constexpr const T& v() const { return y; } - const T& w() const { + constexpr const T& w() const { return z; } - const T& r() const { + constexpr const T& r() const { return x; } - const T& g() const { + constexpr const T& g() const { return y; } - const T& b() const { + constexpr const T& b() const { return z; } - const T& s() const { + constexpr const T& s() const { return x; } - const T& t() const { + constexpr const T& t() const { return y; } - const T& q() const { + constexpr const T& q() const { return z; } @@ -345,7 +345,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) \ - const Vec2<T> name() const { \ + constexpr Vec2<T> name() const { \ return Vec2<T>(a, b); \ } #define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \ @@ -366,7 +366,7 @@ public: }; template <typename T, typename V> -Vec3<T> operator*(const V& f, const Vec3<T>& vec) { +constexpr Vec3<T> operator*(const V& f, const Vec3<T>& vec) { return Vec3<T>(f * vec.x, f * vec.y, f * vec.z); } @@ -387,7 +387,7 @@ inline float Vec3<float>::Normalize() { return length; } -typedef Vec3<float> Vec3f; +using Vec3f = Vec3<float>; template <typename T> class Vec4 { @@ -397,86 +397,88 @@ public: T z{}; T w{}; - Vec4() = default; - Vec4(const T& _x, const T& _y, const T& _z, const T& _w) : x(_x), y(_y), z(_z), w(_w) {} + constexpr Vec4() = default; + constexpr Vec4(const T& x_, const T& y_, const T& z_, const T& w_) + : x(x_), y(y_), z(z_), w(w_) {} template <typename T2> - Vec4<T2> Cast() const { - return Vec4<T2>((T2)x, (T2)y, (T2)z, (T2)w); + constexpr Vec4<T2> Cast() const { + return Vec4<T2>(static_cast<T2>(x), static_cast<T2>(y), static_cast<T2>(z), + static_cast<T2>(w)); } - // Only implemented for T=int and T=float - static Vec4 FromRGBA(unsigned int rgba); - unsigned int ToRGBA() const; - - static Vec4 AssignToAll(const T& f) { - return Vec4<T>(f, f, f, f); + static constexpr Vec4 AssignToAll(const T& f) { + return Vec4(f, f, f, f); } - Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const { - return MakeVec(x + other.x, y + other.y, z + other.z, w + other.w); + constexpr Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const { + return {x + other.x, y + other.y, z + other.z, w + other.w}; } - void operator+=(const Vec4& other) { + + constexpr Vec4& operator+=(const Vec4& other) { x += other.x; y += other.y; z += other.z; w += other.w; + return *this; } - Vec4<decltype(T{} - T{})> operator-(const Vec4& other) const { - return MakeVec(x - other.x, y - other.y, z - other.z, w - other.w); + + constexpr Vec4<decltype(T{} - T{})> operator-(const Vec4& other) const { + return {x - other.x, y - other.y, z - other.z, w - other.w}; } - void operator-=(const Vec4& other) { + + constexpr Vec4& operator-=(const Vec4& other) { x -= other.x; y -= other.y; z -= other.z; w -= other.w; + return *this; } template <typename U = T> - Vec4<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { - return MakeVec(-x, -y, -z, -w); + constexpr Vec4<std::enable_if_t<std::is_signed_v<U>, U>> operator-() const { + return {-x, -y, -z, -w}; } - Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const { - return MakeVec(x * other.x, y * other.y, z * other.z, w * other.w); + + constexpr Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const { + return {x * other.x, y * other.y, z * other.z, w * other.w}; } + template <typename V> - Vec4<decltype(T{} * V{})> operator*(const V& f) const { - return MakeVec(x * f, y * f, z * f, w * f); + constexpr Vec4<decltype(T{} * V{})> operator*(const V& f) const { + return {x * f, y * f, z * f, w * f}; } + template <typename V> - void operator*=(const V& f) { + constexpr Vec4& operator*=(const V& f) { *this = *this * f; + return *this; } + template <typename V> - Vec4<decltype(T{} / V{})> operator/(const V& f) const { - return MakeVec(x / f, y / f, z / f, w / f); + constexpr Vec4<decltype(T{} / V{})> operator/(const V& f) const { + return {x / f, y / f, z / f, w / f}; } + template <typename V> - void operator/=(const V& f) { + constexpr Vec4& operator/=(const V& f) { *this = *this / f; + return *this; } - T Length2() const { + constexpr T Length2() const { return x * x + y * y + z * z + w * w; } - // Only implemented for T=float - float Length() const; - void SetLength(const float l); - Vec4 WithLength(const float l) const; - float Distance2To(Vec4& other); - Vec4 Normalized() const; - float Normalize(); // returns the previous length, which is often useful - - T& operator[](int i) // allow vector[2] = 3 (vector.z=3) - { + constexpr T& operator[](std::size_t i) { return *((&x) + i); } - T operator[](const int i) const { + + constexpr const T& operator[](std::size_t i) const { return *((&x) + i); } - void SetZero() { + constexpr void SetZero() { x = 0; y = 0; z = 0; @@ -484,29 +486,29 @@ public: } // Common alias: RGBA (colors) - T& r() { + constexpr T& r() { return x; } - T& g() { + constexpr T& g() { return y; } - T& b() { + constexpr T& b() { return z; } - T& a() { + constexpr T& a() { return w; } - const T& r() const { + constexpr const T& r() const { return x; } - const T& g() const { + constexpr const T& g() const { return y; } - const T& b() const { + constexpr const T& b() const { return z; } - const T& a() const { + constexpr const T& a() const { return w; } @@ -518,7 +520,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) \ - const Vec2<T> name() const { \ + constexpr Vec2<T> name() const { \ return Vec2<T>(a, b); \ } #define DEFINE_SWIZZLER2_COMP1(a, a2) \ @@ -545,7 +547,7 @@ public: #undef _DEFINE_SWIZZLER2 #define _DEFINE_SWIZZLER3(a, b, c, name) \ - const Vec3<T> name() const { \ + constexpr Vec3<T> name() const { \ return Vec3<T>(a, b, c); \ } #define DEFINE_SWIZZLER3_COMP1(a, a2) \ @@ -579,51 +581,51 @@ public: }; template <typename T, typename V> -Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) { - return MakeVec(f * vec.x, f * vec.y, f * vec.z, f * vec.w); +constexpr Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) { + return {f * vec.x, f * vec.y, f * vec.z, f * vec.w}; } -typedef Vec4<float> Vec4f; +using Vec4f = Vec4<float>; template <typename T> -static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) { +constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) { return a.x * b.x + a.y * b.y; } template <typename T> -static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) { +constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) { return a.x * b.x + a.y * b.y + a.z * b.z; } template <typename T> -static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) { +constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; } template <typename T> -static inline Vec3<decltype(T{} * T{} - T{} * T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) { - return MakeVec(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); +constexpr Vec3<decltype(T{} * T{} - T{} * T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) { + return {a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x}; } // linear interpolation via float: 0.0=begin, 1.0=end template <typename X> -static inline decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end, - const float t) { +constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end, + const float t) { return begin * (1.f - t) + end * t; } // linear interpolation via int: 0=begin, base=end template <typename X, int base> -static inline decltype((X{} * int{} + X{} * int{}) / base) LerpInt(const X& begin, const X& end, - const int t) { +constexpr decltype((X{} * int{} + X{} * int{}) / base) LerpInt(const X& begin, const X& end, + const int t) { return (begin * (base - t) + end * t) / base; } // bilinear interpolation. s is for interpolating x00-x01 and x10-x11, and t is for the second // interpolation. template <typename X> -inline auto BilinearInterp(const X& x00, const X& x01, const X& x10, const X& x11, const float s, - const float t) { +constexpr auto BilinearInterp(const X& x00, const X& x01, const X& x10, const X& x11, const float s, + const float t) { auto y0 = Lerp(x00, x01, s); auto y1 = Lerp(x10, x11, s); return Lerp(y0, y1, t); @@ -631,42 +633,42 @@ inline auto BilinearInterp(const X& x00, const X& x01, const X& x10, const X& x1 // Utility vector factories template <typename T> -static inline Vec2<T> MakeVec(const T& x, const T& y) { +constexpr Vec2<T> MakeVec(const T& x, const T& y) { return Vec2<T>{x, y}; } template <typename T> -static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z) { +constexpr Vec3<T> MakeVec(const T& x, const T& y, const T& z) { return Vec3<T>{x, y, z}; } template <typename T> -static inline Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) { +constexpr Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) { return MakeVec(x, y, zw[0], zw[1]); } template <typename T> -static inline Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) { +constexpr Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) { return MakeVec(xy[0], xy[1], z); } template <typename T> -static inline Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) { +constexpr Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) { return MakeVec(x, yz[0], yz[1]); } template <typename T> -static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) { +constexpr Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) { return Vec4<T>{x, y, z, w}; } template <typename T> -static inline Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) { +constexpr Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) { return MakeVec(xy[0], xy[1], z, w); } template <typename T> -static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) { +constexpr Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) { return MakeVec(x, yz[0], yz[1], w); } @@ -674,17 +676,17 @@ static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) { // Even if someone wanted to use an odd object like Vec2<Vec2<T>>, the compiler would error // out soon enough due to misuse of the returned structure. template <typename T> -static inline Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) { +constexpr Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) { return MakeVec(xy[0], xy[1], zw[0], zw[1]); } template <typename T> -static inline Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) { +constexpr Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) { return MakeVec(xyz[0], xyz[1], xyz[2], w); } template <typename T> -static inline Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) { +constexpr Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) { return MakeVec(x, yzw[0], yzw[1], yzw[2]); } diff --git a/src/common/x64/xbyak_abi.h b/src/common/x64/xbyak_abi.h index fd3fbdd4b..927da9187 100644 --- a/src/common/x64/xbyak_abi.h +++ b/src/common/x64/xbyak_abi.h @@ -9,10 +9,9 @@ #include "common/assert.h" #include "common/bit_set.h" -namespace Common { -namespace X64 { +namespace Common::X64 { -int RegToIndex(const Xbyak::Reg& reg) { +inline int RegToIndex(const Xbyak::Reg& reg) { using Kind = Xbyak::Reg::Kind; ASSERT_MSG((reg.getKind() & (Kind::REG | Kind::XMM)) != 0, "RegSet only support GPRs and XMM registers."); @@ -152,8 +151,8 @@ constexpr size_t ABI_SHADOW_SPACE = 0; #endif -void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t needed_frame_size, - s32* out_subtraction, s32* out_xmm_offset) { +inline void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t needed_frame_size, + s32* out_subtraction, s32* out_xmm_offset) { int count = (regs & ABI_ALL_GPRS).Count(); rsp_alignment -= count * 8; size_t subtraction = 0; @@ -174,8 +173,8 @@ void ABI_CalculateFrameSize(BitSet32 regs, size_t rsp_alignment, size_t needed_f *out_xmm_offset = (s32)(subtraction - xmm_base_subtraction); } -size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs, - size_t rsp_alignment, size_t needed_frame_size = 0) { +inline size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs, + size_t rsp_alignment, size_t needed_frame_size = 0) { s32 subtraction, xmm_offset; ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset); @@ -195,8 +194,8 @@ size_t ABI_PushRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs return ABI_SHADOW_SPACE; } -void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs, size_t rsp_alignment, - size_t needed_frame_size = 0) { +inline void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs, + size_t rsp_alignment, size_t needed_frame_size = 0) { s32 subtraction, xmm_offset; ABI_CalculateFrameSize(regs, rsp_alignment, needed_frame_size, &subtraction, &xmm_offset); @@ -217,5 +216,4 @@ void ABI_PopRegistersAndAdjustStack(Xbyak::CodeGenerator& code, BitSet32 regs, s } } -} // namespace X64 -} // namespace Common +} // namespace Common::X64 diff --git a/src/common/x64/xbyak_util.h b/src/common/x64/xbyak_util.h index 0f52f704b..02323a017 100644 --- a/src/common/x64/xbyak_util.h +++ b/src/common/x64/xbyak_util.h @@ -8,8 +8,7 @@ #include <xbyak.h> #include "common/x64/xbyak_abi.h" -namespace Common { -namespace X64 { +namespace Common::X64 { // Constants for use with cmpps/cmpss enum { @@ -34,7 +33,7 @@ inline bool IsWithin2G(const Xbyak::CodeGenerator& code, uintptr_t target) { template <typename T> inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) { - static_assert(std::is_pointer<T>(), "Argument must be a (function) pointer."); + static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer."); size_t addr = reinterpret_cast<size_t>(f); if (IsWithin2G(code, addr)) { code.call(f); @@ -45,5 +44,4 @@ inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) { } } -} // namespace X64 -} // namespace Common +} // namespace Common::X64 |