summaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorGravatar David Marcec2018-08-11 10:35:47 +1000
committerGravatar David Marcec2018-08-11 10:35:47 +1000
commitb76ddb7647cbb390cce4143d91a1db171b0fa503 (patch)
treea6e2e334e82b035923c41458150604dd5fb31d65 /src/common
parentAdded IsUserRegistrationRequestPermitted (diff)
parentMerge pull request #1007 from MerryMage/dynarmic (diff)
downloadyuzu-b76ddb7647cbb390cce4143d91a1db171b0fa503.tar.gz
yuzu-b76ddb7647cbb390cce4143d91a1db171b0fa503.tar.xz
yuzu-b76ddb7647cbb390cce4143d91a1db171b0fa503.zip
Merge remote-tracking branch 'origin/master' into better-account
Diffstat (limited to 'src/common')
-rw-r--r--src/common/alignment.h4
-rw-r--r--src/common/bit_set.h2
-rw-r--r--src/common/color.h50
-rw-r--r--src/common/file_util.cpp16
-rw-r--r--src/common/file_util.h18
-rw-r--r--src/common/hash.h4
-rw-r--r--src/common/logging/backend.cpp8
-rw-r--r--src/common/logging/log.h8
-rw-r--r--src/common/vector_math.h362
-rw-r--r--src/common/x64/xbyak_util.h2
10 files changed, 259 insertions, 215 deletions
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 {
9 9
10template <typename T> 10template <typename T>
11constexpr T AlignUp(T value, size_t size) { 11constexpr T AlignUp(T value, size_t size) {
12 static_assert(std::is_unsigned<T>::value, "T must be an unsigned value."); 12 static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
13 return static_cast<T>(value + (size - value % size) % size); 13 return static_cast<T>(value + (size - value % size) % size);
14} 14}
15 15
16template <typename T> 16template <typename T>
17constexpr T AlignDown(T value, size_t size) { 17constexpr T AlignDown(T value, size_t size) {
18 static_assert(std::is_unsigned<T>::value, "T must be an unsigned value."); 18 static_assert(std::is_unsigned_v<T>, "T must be an unsigned value.");
19 return static_cast<T>(value - value % size); 19 return static_cast<T>(value - value % size);
20} 20}
21 21
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) {
96 96
97template <typename IntTy> 97template <typename IntTy>
98class BitSet { 98class BitSet {
99 static_assert(!std::is_signed<IntTy>::value, "BitSet should not be used with signed types"); 99 static_assert(!std::is_signed_v<IntTy>, "BitSet should not be used with signed types");
100 100
101public: 101public:
102 // A reference to a particular bit, returned from operator[]. 102 // A reference to a particular bit, returned from operator[].
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 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <cstring>
8
7#include "common/common_types.h" 9#include "common/common_types.h"
8#include "common/swap.h" 10#include "common/swap.h"
9#include "common/vector_math.h" 11#include "common/vector_math.h"
@@ -55,7 +57,7 @@ constexpr u8 Convert8To6(u8 value) {
55 * @param bytes Pointer to encoded source color 57 * @param bytes Pointer to encoded source color
56 * @return Result color decoded as Math::Vec4<u8> 58 * @return Result color decoded as Math::Vec4<u8>
57 */ 59 */
58inline const Math::Vec4<u8> DecodeRGBA8(const u8* bytes) { 60inline Math::Vec4<u8> DecodeRGBA8(const u8* bytes) {
59 return {bytes[3], bytes[2], bytes[1], bytes[0]}; 61 return {bytes[3], bytes[2], bytes[1], bytes[0]};
60} 62}
61 63
@@ -64,7 +66,7 @@ inline const Math::Vec4<u8> DecodeRGBA8(const u8* bytes) {
64 * @param bytes Pointer to encoded source color 66 * @param bytes Pointer to encoded source color
65 * @return Result color decoded as Math::Vec4<u8> 67 * @return Result color decoded as Math::Vec4<u8>
66 */ 68 */
67inline const Math::Vec4<u8> DecodeRGB8(const u8* bytes) { 69inline Math::Vec4<u8> DecodeRGB8(const u8* bytes) {
68 return {bytes[2], bytes[1], bytes[0], 255}; 70 return {bytes[2], bytes[1], bytes[0], 255};
69} 71}
70 72
@@ -73,7 +75,7 @@ inline const Math::Vec4<u8> DecodeRGB8(const u8* bytes) {
73 * @param bytes Pointer to encoded source color 75 * @param bytes Pointer to encoded source color
74 * @return Result color decoded as Math::Vec4<u8> 76 * @return Result color decoded as Math::Vec4<u8>
75 */ 77 */
76inline const Math::Vec4<u8> DecodeRG8(const u8* bytes) { 78inline Math::Vec4<u8> DecodeRG8(const u8* bytes) {
77 return {bytes[1], bytes[0], 0, 255}; 79 return {bytes[1], bytes[0], 0, 255};
78} 80}
79 81
@@ -82,8 +84,9 @@ inline const Math::Vec4<u8> DecodeRG8(const u8* bytes) {
82 * @param bytes Pointer to encoded source color 84 * @param bytes Pointer to encoded source color
83 * @return Result color decoded as Math::Vec4<u8> 85 * @return Result color decoded as Math::Vec4<u8>
84 */ 86 */
85inline const Math::Vec4<u8> DecodeRGB565(const u8* bytes) { 87inline Math::Vec4<u8> DecodeRGB565(const u8* bytes) {
86 const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); 88 u16_le pixel;
89 std::memcpy(&pixel, bytes, sizeof(pixel));
87 return {Convert5To8((pixel >> 11) & 0x1F), Convert6To8((pixel >> 5) & 0x3F), 90 return {Convert5To8((pixel >> 11) & 0x1F), Convert6To8((pixel >> 5) & 0x3F),
88 Convert5To8(pixel & 0x1F), 255}; 91 Convert5To8(pixel & 0x1F), 255};
89} 92}
@@ -93,8 +96,9 @@ inline const Math::Vec4<u8> DecodeRGB565(const u8* bytes) {
93 * @param bytes Pointer to encoded source color 96 * @param bytes Pointer to encoded source color
94 * @return Result color decoded as Math::Vec4<u8> 97 * @return Result color decoded as Math::Vec4<u8>
95 */ 98 */
96inline const Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) { 99inline Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) {
97 const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); 100 u16_le pixel;
101 std::memcpy(&pixel, bytes, sizeof(pixel));
98 return {Convert5To8((pixel >> 11) & 0x1F), Convert5To8((pixel >> 6) & 0x1F), 102 return {Convert5To8((pixel >> 11) & 0x1F), Convert5To8((pixel >> 6) & 0x1F),
99 Convert5To8((pixel >> 1) & 0x1F), Convert1To8(pixel & 0x1)}; 103 Convert5To8((pixel >> 1) & 0x1F), Convert1To8(pixel & 0x1)};
100} 104}
@@ -104,8 +108,9 @@ inline const Math::Vec4<u8> DecodeRGB5A1(const u8* bytes) {
104 * @param bytes Pointer to encoded source color 108 * @param bytes Pointer to encoded source color
105 * @return Result color decoded as Math::Vec4<u8> 109 * @return Result color decoded as Math::Vec4<u8>
106 */ 110 */
107inline const Math::Vec4<u8> DecodeRGBA4(const u8* bytes) { 111inline Math::Vec4<u8> DecodeRGBA4(const u8* bytes) {
108 const u16_le pixel = *reinterpret_cast<const u16_le*>(bytes); 112 u16_le pixel;
113 std::memcpy(&pixel, bytes, sizeof(pixel));
109 return {Convert4To8((pixel >> 12) & 0xF), Convert4To8((pixel >> 8) & 0xF), 114 return {Convert4To8((pixel >> 12) & 0xF), Convert4To8((pixel >> 8) & 0xF),
110 Convert4To8((pixel >> 4) & 0xF), Convert4To8(pixel & 0xF)}; 115 Convert4To8((pixel >> 4) & 0xF), Convert4To8(pixel & 0xF)};
111} 116}
@@ -116,7 +121,9 @@ inline const Math::Vec4<u8> DecodeRGBA4(const u8* bytes) {
116 * @return Depth value as an u32 121 * @return Depth value as an u32
117 */ 122 */
118inline u32 DecodeD16(const u8* bytes) { 123inline u32 DecodeD16(const u8* bytes) {
119 return *reinterpret_cast<const u16_le*>(bytes); 124 u16_le data;
125 std::memcpy(&data, bytes, sizeof(data));
126 return data;
120} 127}
121 128
122/** 129/**
@@ -133,7 +140,7 @@ inline u32 DecodeD24(const u8* bytes) {
133 * @param bytes Pointer to encoded source values 140 * @param bytes Pointer to encoded source values
134 * @return Resulting values stored as a Math::Vec2 141 * @return Resulting values stored as a Math::Vec2
135 */ 142 */
136inline const Math::Vec2<u32> DecodeD24S8(const u8* bytes) { 143inline Math::Vec2<u32> DecodeD24S8(const u8* bytes) {
137 return {static_cast<u32>((bytes[2] << 16) | (bytes[1] << 8) | bytes[0]), bytes[3]}; 144 return {static_cast<u32>((bytes[2] << 16) | (bytes[1] << 8) | bytes[0]), bytes[3]};
138} 145}
139 146
@@ -175,8 +182,10 @@ inline void EncodeRG8(const Math::Vec4<u8>& color, u8* bytes) {
175 * @param bytes Destination pointer to store encoded color 182 * @param bytes Destination pointer to store encoded color
176 */ 183 */
177inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) { 184inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) {
178 *reinterpret_cast<u16_le*>(bytes) = 185 const u16_le data =
179 (Convert8To5(color.r()) << 11) | (Convert8To6(color.g()) << 5) | Convert8To5(color.b()); 186 (Convert8To5(color.r()) << 11) | (Convert8To6(color.g()) << 5) | Convert8To5(color.b());
187
188 std::memcpy(bytes, &data, sizeof(data));
180} 189}
181 190
182/** 191/**
@@ -185,9 +194,10 @@ inline void EncodeRGB565(const Math::Vec4<u8>& color, u8* bytes) {
185 * @param bytes Destination pointer to store encoded color 194 * @param bytes Destination pointer to store encoded color
186 */ 195 */
187inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) { 196inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) {
188 *reinterpret_cast<u16_le*>(bytes) = (Convert8To5(color.r()) << 11) | 197 const u16_le data = (Convert8To5(color.r()) << 11) | (Convert8To5(color.g()) << 6) |
189 (Convert8To5(color.g()) << 6) | 198 (Convert8To5(color.b()) << 1) | Convert8To1(color.a());
190 (Convert8To5(color.b()) << 1) | Convert8To1(color.a()); 199
200 std::memcpy(bytes, &data, sizeof(data));
191} 201}
192 202
193/** 203/**
@@ -196,9 +206,10 @@ inline void EncodeRGB5A1(const Math::Vec4<u8>& color, u8* bytes) {
196 * @param bytes Destination pointer to store encoded color 206 * @param bytes Destination pointer to store encoded color
197 */ 207 */
198inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) { 208inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) {
199 *reinterpret_cast<u16_le*>(bytes) = (Convert8To4(color.r()) << 12) | 209 const u16 data = (Convert8To4(color.r()) << 12) | (Convert8To4(color.g()) << 8) |
200 (Convert8To4(color.g()) << 8) | 210 (Convert8To4(color.b()) << 4) | Convert8To4(color.a());
201 (Convert8To4(color.b()) << 4) | Convert8To4(color.a()); 211
212 std::memcpy(bytes, &data, sizeof(data));
202} 213}
203 214
204/** 215/**
@@ -207,7 +218,8 @@ inline void EncodeRGBA4(const Math::Vec4<u8>& color, u8* bytes) {
207 * @param bytes Pointer where to store the encoded value 218 * @param bytes Pointer where to store the encoded value
208 */ 219 */
209inline void EncodeD16(u32 value, u8* bytes) { 220inline void EncodeD16(u32 value, u8* bytes) {
210 *reinterpret_cast<u16_le*>(bytes) = value & 0xFFFF; 221 const u16_le data = static_cast<u16>(value);
222 std::memcpy(bytes, &data, sizeof(data));
211} 223}
212 224
213/** 225/**
diff --git a/src/common/file_util.cpp b/src/common/file_util.cpp
index 7aeda737f..3ce590062 100644
--- a/src/common/file_util.cpp
+++ b/src/common/file_util.cpp
@@ -884,11 +884,21 @@ std::string_view RemoveTrailingSlash(std::string_view path) {
884 return path; 884 return path;
885} 885}
886 886
887std::string SanitizePath(std::string_view path_) { 887std::string SanitizePath(std::string_view path_, DirectorySeparator directory_separator) {
888 std::string path(path_); 888 std::string path(path_);
889 std::replace(path.begin(), path.end(), '\\', '/'); 889 char type1 = directory_separator == DirectorySeparator::BackwardSlash ? '/' : '\\';
890 char type2 = directory_separator == DirectorySeparator::BackwardSlash ? '\\' : '/';
891
892 if (directory_separator == DirectorySeparator::PlatformDefault) {
893#ifdef _WIN32
894 type1 = '/';
895 type2 = '\\';
896#endif
897 }
898
899 std::replace(path.begin(), path.end(), type1, type2);
890 path.erase(std::unique(path.begin(), path.end(), 900 path.erase(std::unique(path.begin(), path.end(),
891 [](char c1, char c2) { return c1 == '/' && c2 == '/'; }), 901 [type2](char c1, char c2) { return c1 == type2 && c2 == type2; }),
892 path.end()); 902 path.end());
893 return std::string(RemoveTrailingSlash(path)); 903 return std::string(RemoveTrailingSlash(path));
894} 904}
diff --git a/src/common/file_util.h b/src/common/file_util.h
index 430dac41c..2711872ae 100644
--- a/src/common/file_util.h
+++ b/src/common/file_util.h
@@ -182,8 +182,12 @@ std::vector<T> SliceVector(const std::vector<T>& vector, size_t first, size_t la
182 return std::vector<T>(vector.begin() + first, vector.begin() + first + last); 182 return std::vector<T>(vector.begin() + first, vector.begin() + first + last);
183} 183}
184 184
185// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. 185enum class DirectorySeparator { ForwardSlash, BackwardSlash, PlatformDefault };
186std::string SanitizePath(std::string_view path); 186
187// Removes trailing slash, makes all '\\' into '/', and removes duplicate '/'. Makes '/' into '\\'
188// depending if directory_separator is BackwardSlash or PlatformDefault and running on windows
189std::string SanitizePath(std::string_view path,
190 DirectorySeparator directory_separator = DirectorySeparator::ForwardSlash);
187 191
188// simple wrapper for cstdlib file functions to 192// simple wrapper for cstdlib file functions to
189// hopefully will make error checking easier 193// hopefully will make error checking easier
@@ -208,7 +212,7 @@ public:
208 212
209 template <typename T> 213 template <typename T>
210 size_t ReadArray(T* data, size_t length) const { 214 size_t ReadArray(T* data, size_t length) const {
211 static_assert(std::is_trivially_copyable<T>(), 215 static_assert(std::is_trivially_copyable_v<T>,
212 "Given array does not consist of trivially copyable objects"); 216 "Given array does not consist of trivially copyable objects");
213 217
214 if (!IsOpen()) { 218 if (!IsOpen()) {
@@ -220,7 +224,7 @@ public:
220 224
221 template <typename T> 225 template <typename T>
222 size_t WriteArray(const T* data, size_t length) { 226 size_t WriteArray(const T* data, size_t length) {
223 static_assert(std::is_trivially_copyable<T>(), 227 static_assert(std::is_trivially_copyable_v<T>,
224 "Given array does not consist of trivially copyable objects"); 228 "Given array does not consist of trivially copyable objects");
225 if (!IsOpen()) { 229 if (!IsOpen()) {
226 return std::numeric_limits<size_t>::max(); 230 return std::numeric_limits<size_t>::max();
@@ -231,19 +235,19 @@ public:
231 235
232 template <typename T> 236 template <typename T>
233 size_t ReadBytes(T* data, size_t length) const { 237 size_t ReadBytes(T* data, size_t length) const {
234 static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable"); 238 static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
235 return ReadArray(reinterpret_cast<char*>(data), length); 239 return ReadArray(reinterpret_cast<char*>(data), length);
236 } 240 }
237 241
238 template <typename T> 242 template <typename T>
239 size_t WriteBytes(const T* data, size_t length) { 243 size_t WriteBytes(const T* data, size_t length) {
240 static_assert(std::is_trivially_copyable<T>(), "T must be trivially copyable"); 244 static_assert(std::is_trivially_copyable_v<T>, "T must be trivially copyable");
241 return WriteArray(reinterpret_cast<const char*>(data), length); 245 return WriteArray(reinterpret_cast<const char*>(data), length);
242 } 246 }
243 247
244 template <typename T> 248 template <typename T>
245 size_t WriteObject(const T& object) { 249 size_t WriteObject(const T& object) {
246 static_assert(!std::is_pointer<T>::value, "Given object is a pointer"); 250 static_assert(!std::is_pointer_v<T>, "WriteObject arguments must not be a pointer");
247 return WriteArray(&object, 1); 251 return WriteArray(&object, 1);
248 } 252 }
249 253
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) {
28 */ 28 */
29template <typename T> 29template <typename T>
30static inline u64 ComputeStructHash64(const T& data) { 30static inline u64 ComputeStructHash64(const T& data) {
31 static_assert(std::is_trivially_copyable<T>(), 31 static_assert(std::is_trivially_copyable_v<T>,
32 "Type passed to ComputeStructHash64 must be trivially copyable"); 32 "Type passed to ComputeStructHash64 must be trivially copyable");
33 return ComputeHash64(&data, sizeof(data)); 33 return ComputeHash64(&data, sizeof(data));
34} 34}
@@ -38,7 +38,7 @@ template <typename T>
38struct HashableStruct { 38struct HashableStruct {
39 // In addition to being trivially copyable, T must also have a trivial default constructor, 39 // In addition to being trivially copyable, T must also have a trivial default constructor,
40 // because any member initialization would be overridden by memset 40 // because any member initialization would be overridden by memset
41 static_assert(std::is_trivial<T>(), "Type passed to HashableStruct must be trivial"); 41 static_assert(std::is_trivial_v<T>, "Type passed to HashableStruct must be trivial");
42 /* 42 /*
43 * We use a union because "implicitly-defined copy/move constructor for a union X copies the 43 * We use a union because "implicitly-defined copy/move constructor for a union X copies the
44 * object representation of X." and "implicitly-defined copy assignment operator for a union X 44 * object representation of X." and "implicitly-defined copy assignment operator for a union X
diff --git a/src/common/logging/backend.cpp b/src/common/logging/backend.cpp
index 355abd682..e80784c3c 100644
--- a/src/common/logging/backend.cpp
+++ b/src/common/logging/backend.cpp
@@ -171,15 +171,21 @@ void FileBackend::Write(const Entry& entry) {
171 SUB(Service, ARP) \ 171 SUB(Service, ARP) \
172 SUB(Service, BCAT) \ 172 SUB(Service, BCAT) \
173 SUB(Service, BPC) \ 173 SUB(Service, BPC) \
174 SUB(Service, BTDRV) \
174 SUB(Service, BTM) \ 175 SUB(Service, BTM) \
175 SUB(Service, Capture) \ 176 SUB(Service, Capture) \
177 SUB(Service, ERPT) \
178 SUB(Service, ETicket) \
179 SUB(Service, EUPLD) \
176 SUB(Service, Fatal) \ 180 SUB(Service, Fatal) \
177 SUB(Service, FGM) \ 181 SUB(Service, FGM) \
178 SUB(Service, Friend) \ 182 SUB(Service, Friend) \
179 SUB(Service, FS) \ 183 SUB(Service, FS) \
184 SUB(Service, GRC) \
180 SUB(Service, HID) \ 185 SUB(Service, HID) \
181 SUB(Service, LBL) \ 186 SUB(Service, LBL) \
182 SUB(Service, LDN) \ 187 SUB(Service, LDN) \
188 SUB(Service, LDR) \
183 SUB(Service, LM) \ 189 SUB(Service, LM) \
184 SUB(Service, Migration) \ 190 SUB(Service, Migration) \
185 SUB(Service, Mii) \ 191 SUB(Service, Mii) \
@@ -188,11 +194,13 @@ void FileBackend::Write(const Entry& entry) {
188 SUB(Service, NFC) \ 194 SUB(Service, NFC) \
189 SUB(Service, NFP) \ 195 SUB(Service, NFP) \
190 SUB(Service, NIFM) \ 196 SUB(Service, NIFM) \
197 SUB(Service, NIM) \
191 SUB(Service, NS) \ 198 SUB(Service, NS) \
192 SUB(Service, NVDRV) \ 199 SUB(Service, NVDRV) \
193 SUB(Service, PCIE) \ 200 SUB(Service, PCIE) \
194 SUB(Service, PCTL) \ 201 SUB(Service, PCTL) \
195 SUB(Service, PCV) \ 202 SUB(Service, PCV) \
203 SUB(Service, PM) \
196 SUB(Service, PREPO) \ 204 SUB(Service, PREPO) \
197 SUB(Service, PSC) \ 205 SUB(Service, PSC) \
198 SUB(Service, SET) \ 206 SUB(Service, SET) \
diff --git a/src/common/logging/log.h b/src/common/logging/log.h
index a889ebefa..e12f47f8f 100644
--- a/src/common/logging/log.h
+++ b/src/common/logging/log.h
@@ -58,15 +58,21 @@ enum class Class : ClassType {
58 Service_Audio, ///< The Audio (Audio control) service 58 Service_Audio, ///< The Audio (Audio control) service
59 Service_BCAT, ///< The BCAT service 59 Service_BCAT, ///< The BCAT service
60 Service_BPC, ///< The BPC service 60 Service_BPC, ///< The BPC service
61 Service_BTDRV, ///< The Bluetooth driver service
61 Service_BTM, ///< The BTM service 62 Service_BTM, ///< The BTM service
62 Service_Capture, ///< The capture service 63 Service_Capture, ///< The capture service
64 Service_ERPT, ///< The error reporting service
65 Service_ETicket, ///< The ETicket service
66 Service_EUPLD, ///< The error upload service
63 Service_Fatal, ///< The Fatal service 67 Service_Fatal, ///< The Fatal service
64 Service_FGM, ///< The FGM service 68 Service_FGM, ///< The FGM service
65 Service_Friend, ///< The friend service 69 Service_Friend, ///< The friend service
66 Service_FS, ///< The FS (Filesystem) service 70 Service_FS, ///< The FS (Filesystem) service
71 Service_GRC, ///< The game recording service
67 Service_HID, ///< The HID (Human interface device) service 72 Service_HID, ///< The HID (Human interface device) service
68 Service_LBL, ///< The LBL (LCD backlight) service 73 Service_LBL, ///< The LBL (LCD backlight) service
69 Service_LDN, ///< The LDN (Local domain network) service 74 Service_LDN, ///< The LDN (Local domain network) service
75 Service_LDR, ///< The loader service
70 Service_LM, ///< The LM (Logger) service 76 Service_LM, ///< The LM (Logger) service
71 Service_Migration, ///< The migration service 77 Service_Migration, ///< The migration service
72 Service_Mii, ///< The Mii service 78 Service_Mii, ///< The Mii service
@@ -75,11 +81,13 @@ enum class Class : ClassType {
75 Service_NFC, ///< The NFC (Near-field communication) service 81 Service_NFC, ///< The NFC (Near-field communication) service
76 Service_NFP, ///< The NFP service 82 Service_NFP, ///< The NFP service
77 Service_NIFM, ///< The NIFM (Network interface) service 83 Service_NIFM, ///< The NIFM (Network interface) service
84 Service_NIM, ///< The NIM service
78 Service_NS, ///< The NS services 85 Service_NS, ///< The NS services
79 Service_NVDRV, ///< The NVDRV (Nvidia driver) service 86 Service_NVDRV, ///< The NVDRV (Nvidia driver) service
80 Service_PCIE, ///< The PCIe service 87 Service_PCIE, ///< The PCIe service
81 Service_PCTL, ///< The PCTL (Parental control) service 88 Service_PCTL, ///< The PCTL (Parental control) service
82 Service_PCV, ///< The PCV service 89 Service_PCV, ///< The PCV service
90 Service_PM, ///< The PM service
83 Service_PREPO, ///< The PREPO (Play report) service 91 Service_PREPO, ///< The PREPO (Play report) service
84 Service_PSC, ///< The PSC service 92 Service_PSC, ///< The PSC service
85 Service_SET, ///< The SET (Settings) service 93 Service_SET, ///< The SET (Settings) service
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>
43class Vec4; 43class Vec4;
44 44
45template <typename T> 45template <typename T>
46static inline Vec2<T> MakeVec(const T& x, const T& y);
47template <typename T>
48static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z);
49template <typename T>
50static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w);
51
52template <typename T>
53class Vec2 { 46class Vec2 {
54public: 47public:
55 T x{}; 48 T x{};
56 T y{}; 49 T y{};
57 50
58 Vec2() = default; 51 constexpr Vec2() = default;
59 Vec2(const T& _x, const T& _y) : x(_x), y(_y) {} 52 constexpr Vec2(const T& x_, const T& y_) : x(x_), y(y_) {}
60 53
61 template <typename T2> 54 template <typename T2>
62 Vec2<T2> Cast() const { 55 constexpr Vec2<T2> Cast() const {
63 return Vec2<T2>((T2)x, (T2)y); 56 return Vec2<T2>(static_cast<T2>(x), static_cast<T2>(y));
64 } 57 }
65 58
66 static Vec2 AssignToAll(const T& f) { 59 static constexpr Vec2 AssignToAll(const T& f) {
67 return Vec2<T>(f, f); 60 return Vec2{f, f};
68 } 61 }
69 62
70 Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const { 63 constexpr Vec2<decltype(T{} + T{})> operator+(const Vec2& other) const {
71 return MakeVec(x + other.x, y + other.y); 64 return {x + other.x, y + other.y};
72 } 65 }
73 void operator+=(const Vec2& other) { 66 constexpr Vec2& operator+=(const Vec2& other) {
74 x += other.x; 67 x += other.x;
75 y += other.y; 68 y += other.y;
69 return *this;
76 } 70 }
77 Vec2<decltype(T{} - T{})> operator-(const Vec2& other) const { 71 constexpr Vec2<decltype(T{} - T{})> operator-(const Vec2& other) const {
78 return MakeVec(x - other.x, y - other.y); 72 return {x - other.x, y - other.y};
79 } 73 }
80 void operator-=(const Vec2& other) { 74 constexpr Vec2& operator-=(const Vec2& other) {
81 x -= other.x; 75 x -= other.x;
82 y -= other.y; 76 y -= other.y;
77 return *this;
83 } 78 }
84 79
85 template <typename U = T> 80 template <typename U = T>
86 Vec2<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { 81 constexpr Vec2<std::enable_if_t<std::is_signed_v<U>, U>> operator-() const {
87 return MakeVec(-x, -y); 82 return {-x, -y};
88 } 83 }
89 Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const { 84 constexpr Vec2<decltype(T{} * T{})> operator*(const Vec2& other) const {
90 return MakeVec(x * other.x, y * other.y); 85 return {x * other.x, y * other.y};
91 } 86 }
87
92 template <typename V> 88 template <typename V>
93 Vec2<decltype(T{} * V{})> operator*(const V& f) const { 89 constexpr Vec2<decltype(T{} * V{})> operator*(const V& f) const {
94 return MakeVec(x * f, y * f); 90 return {x * f, y * f};
95 } 91 }
92
96 template <typename V> 93 template <typename V>
97 void operator*=(const V& f) { 94 constexpr Vec2& operator*=(const V& f) {
98 *this = *this * f; 95 *this = *this * f;
96 return *this;
99 } 97 }
98
100 template <typename V> 99 template <typename V>
101 Vec2<decltype(T{} / V{})> operator/(const V& f) const { 100 constexpr Vec2<decltype(T{} / V{})> operator/(const V& f) const {
102 return MakeVec(x / f, y / f); 101 return {x / f, y / f};
103 } 102 }
103
104 template <typename V> 104 template <typename V>
105 void operator/=(const V& f) { 105 constexpr Vec2& operator/=(const V& f) {
106 *this = *this / f; 106 *this = *this / f;
107 return *this;
107 } 108 }
108 109
109 T Length2() const { 110 constexpr T Length2() const {
110 return x * x + y * y; 111 return x * x + y * y;
111 } 112 }
112 113
113 // Only implemented for T=float 114 // Only implemented for T=float
114 float Length() const; 115 float Length() const;
115 void SetLength(const float l);
116 Vec2 WithLength(const float l) const;
117 float Distance2To(Vec2& other);
118 Vec2 Normalized() const;
119 float Normalize(); // returns the previous length, which is often useful 116 float Normalize(); // returns the previous length, which is often useful
120 117
121 T& operator[](int i) // allow vector[1] = 3 (vector.y=3) 118 constexpr T& operator[](std::size_t i) {
122 {
123 return *((&x) + i); 119 return *((&x) + i);
124 } 120 }
125 T operator[](const int i) const { 121 constexpr const T& operator[](std::size_t i) const {
126 return *((&x) + i); 122 return *((&x) + i);
127 } 123 }
128 124
129 void SetZero() { 125 constexpr void SetZero() {
130 x = 0; 126 x = 0;
131 y = 0; 127 y = 0;
132 } 128 }
133 129
134 // Common aliases: UV (texel coordinates), ST (texture coordinates) 130 // Common aliases: UV (texel coordinates), ST (texture coordinates)
135 T& u() { 131 constexpr T& u() {
136 return x; 132 return x;
137 } 133 }
138 T& v() { 134 constexpr T& v() {
139 return y; 135 return y;
140 } 136 }
141 T& s() { 137 constexpr T& s() {
142 return x; 138 return x;
143 } 139 }
144 T& t() { 140 constexpr T& t() {
145 return y; 141 return y;
146 } 142 }
147 143
148 const T& u() const { 144 constexpr const T& u() const {
149 return x; 145 return x;
150 } 146 }
151 const T& v() const { 147 constexpr const T& v() const {
152 return y; 148 return y;
153 } 149 }
154 const T& s() const { 150 constexpr const T& s() const {
155 return x; 151 return x;
156 } 152 }
157 const T& t() const { 153 constexpr const T& t() const {
158 return y; 154 return y;
159 } 155 }
160 156
161 // swizzlers - create a subvector of specific components 157 // swizzlers - create a subvector of specific components
162 const Vec2 yx() const { 158 constexpr Vec2 yx() const {
163 return Vec2(y, x); 159 return Vec2(y, x);
164 } 160 }
165 const Vec2 vu() const { 161 constexpr Vec2 vu() const {
166 return Vec2(y, x); 162 return Vec2(y, x);
167 } 163 }
168 const Vec2 ts() const { 164 constexpr Vec2 ts() const {
169 return Vec2(y, x); 165 return Vec2(y, x);
170 } 166 }
171}; 167};
172 168
173template <typename T, typename V> 169template <typename T, typename V>
174Vec2<T> operator*(const V& f, const Vec2<T>& vec) { 170constexpr Vec2<T> operator*(const V& f, const Vec2<T>& vec) {
175 return Vec2<T>(f * vec.x, f * vec.y); 171 return Vec2<T>(f * vec.x, f * vec.y);
176} 172}
177 173
178typedef Vec2<float> Vec2f; 174using Vec2f = Vec2<float>;
179 175
180template <> 176template <>
181inline float Vec2<float>::Length() const { 177inline float Vec2<float>::Length() const {
@@ -196,147 +192,151 @@ public:
196 T y{}; 192 T y{};
197 T z{}; 193 T z{};
198 194
199 Vec3() = default; 195 constexpr Vec3() = default;
200 Vec3(const T& _x, const T& _y, const T& _z) : x(_x), y(_y), z(_z) {} 196 constexpr Vec3(const T& x_, const T& y_, const T& z_) : x(x_), y(y_), z(z_) {}
201 197
202 template <typename T2> 198 template <typename T2>
203 Vec3<T2> Cast() const { 199 constexpr Vec3<T2> Cast() const {
204 return MakeVec<T2>((T2)x, (T2)y, (T2)z); 200 return Vec3<T2>(static_cast<T2>(x), static_cast<T2>(y), static_cast<T2>(z));
205 } 201 }
206 202
207 // Only implemented for T=int and T=float 203 static constexpr Vec3 AssignToAll(const T& f) {
208 static Vec3 FromRGB(unsigned int rgb); 204 return Vec3(f, f, f);
209 unsigned int ToRGB() const; // alpha bits set to zero
210
211 static Vec3 AssignToAll(const T& f) {
212 return MakeVec(f, f, f);
213 } 205 }
214 206
215 Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const { 207 constexpr Vec3<decltype(T{} + T{})> operator+(const Vec3& other) const {
216 return MakeVec(x + other.x, y + other.y, z + other.z); 208 return {x + other.x, y + other.y, z + other.z};
217 } 209 }
218 void operator+=(const Vec3& other) { 210
211 constexpr Vec3& operator+=(const Vec3& other) {
219 x += other.x; 212 x += other.x;
220 y += other.y; 213 y += other.y;
221 z += other.z; 214 z += other.z;
215 return *this;
222 } 216 }
223 Vec3<decltype(T{} - T{})> operator-(const Vec3& other) const { 217
224 return MakeVec(x - other.x, y - other.y, z - other.z); 218 constexpr Vec3<decltype(T{} - T{})> operator-(const Vec3& other) const {
219 return {x - other.x, y - other.y, z - other.z};
225 } 220 }
226 void operator-=(const Vec3& other) { 221
222 constexpr Vec3& operator-=(const Vec3& other) {
227 x -= other.x; 223 x -= other.x;
228 y -= other.y; 224 y -= other.y;
229 z -= other.z; 225 z -= other.z;
226 return *this;
230 } 227 }
231 228
232 template <typename U = T> 229 template <typename U = T>
233 Vec3<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { 230 constexpr Vec3<std::enable_if_t<std::is_signed_v<U>, U>> operator-() const {
234 return MakeVec(-x, -y, -z); 231 return {-x, -y, -z};
235 } 232 }
236 Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const { 233
237 return MakeVec(x * other.x, y * other.y, z * other.z); 234 constexpr Vec3<decltype(T{} * T{})> operator*(const Vec3& other) const {
235 return {x * other.x, y * other.y, z * other.z};
238 } 236 }
237
239 template <typename V> 238 template <typename V>
240 Vec3<decltype(T{} * V{})> operator*(const V& f) const { 239 constexpr Vec3<decltype(T{} * V{})> operator*(const V& f) const {
241 return MakeVec(x * f, y * f, z * f); 240 return {x * f, y * f, z * f};
242 } 241 }
242
243 template <typename V> 243 template <typename V>
244 void operator*=(const V& f) { 244 constexpr Vec3& operator*=(const V& f) {
245 *this = *this * f; 245 *this = *this * f;
246 return *this;
246 } 247 }
247 template <typename V> 248 template <typename V>
248 Vec3<decltype(T{} / V{})> operator/(const V& f) const { 249 constexpr Vec3<decltype(T{} / V{})> operator/(const V& f) const {
249 return MakeVec(x / f, y / f, z / f); 250 return {x / f, y / f, z / f};
250 } 251 }
252
251 template <typename V> 253 template <typename V>
252 void operator/=(const V& f) { 254 constexpr Vec3& operator/=(const V& f) {
253 *this = *this / f; 255 *this = *this / f;
256 return *this;
254 } 257 }
255 258
256 T Length2() const { 259 constexpr T Length2() const {
257 return x * x + y * y + z * z; 260 return x * x + y * y + z * z;
258 } 261 }
259 262
260 // Only implemented for T=float 263 // Only implemented for T=float
261 float Length() const; 264 float Length() const;
262 void SetLength(const float l);
263 Vec3 WithLength(const float l) const;
264 float Distance2To(Vec3& other);
265 Vec3 Normalized() const; 265 Vec3 Normalized() const;
266 float Normalize(); // returns the previous length, which is often useful 266 float Normalize(); // returns the previous length, which is often useful
267 267
268 T& operator[](int i) // allow vector[2] = 3 (vector.z=3) 268 constexpr T& operator[](std::size_t i) {
269 {
270 return *((&x) + i); 269 return *((&x) + i);
271 } 270 }
272 T operator[](const int i) const { 271
272 constexpr const T& operator[](std::size_t i) const {
273 return *((&x) + i); 273 return *((&x) + i);
274 } 274 }
275 275
276 void SetZero() { 276 constexpr void SetZero() {
277 x = 0; 277 x = 0;
278 y = 0; 278 y = 0;
279 z = 0; 279 z = 0;
280 } 280 }
281 281
282 // Common aliases: UVW (texel coordinates), RGB (colors), STQ (texture coordinates) 282 // Common aliases: UVW (texel coordinates), RGB (colors), STQ (texture coordinates)
283 T& u() { 283 constexpr T& u() {
284 return x; 284 return x;
285 } 285 }
286 T& v() { 286 constexpr T& v() {
287 return y; 287 return y;
288 } 288 }
289 T& w() { 289 constexpr T& w() {
290 return z; 290 return z;
291 } 291 }
292 292
293 T& r() { 293 constexpr T& r() {
294 return x; 294 return x;
295 } 295 }
296 T& g() { 296 constexpr T& g() {
297 return y; 297 return y;
298 } 298 }
299 T& b() { 299 constexpr T& b() {
300 return z; 300 return z;
301 } 301 }
302 302
303 T& s() { 303 constexpr T& s() {
304 return x; 304 return x;
305 } 305 }
306 T& t() { 306 constexpr T& t() {
307 return y; 307 return y;
308 } 308 }
309 T& q() { 309 constexpr T& q() {
310 return z; 310 return z;
311 } 311 }
312 312
313 const T& u() const { 313 constexpr const T& u() const {
314 return x; 314 return x;
315 } 315 }
316 const T& v() const { 316 constexpr const T& v() const {
317 return y; 317 return y;
318 } 318 }
319 const T& w() const { 319 constexpr const T& w() const {
320 return z; 320 return z;
321 } 321 }
322 322
323 const T& r() const { 323 constexpr const T& r() const {
324 return x; 324 return x;
325 } 325 }
326 const T& g() const { 326 constexpr const T& g() const {
327 return y; 327 return y;
328 } 328 }
329 const T& b() const { 329 constexpr const T& b() const {
330 return z; 330 return z;
331 } 331 }
332 332
333 const T& s() const { 333 constexpr const T& s() const {
334 return x; 334 return x;
335 } 335 }
336 const T& t() const { 336 constexpr const T& t() const {
337 return y; 337 return y;
338 } 338 }
339 const T& q() const { 339 constexpr const T& q() const {
340 return z; 340 return z;
341 } 341 }
342 342
@@ -345,7 +345,7 @@ public:
345// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all 345// _DEFINE_SWIZZLER2 defines a single such function, DEFINE_SWIZZLER2 defines all of them for all
346// component names (x<->r) and permutations (xy<->yx) 346// component names (x<->r) and permutations (xy<->yx)
347#define _DEFINE_SWIZZLER2(a, b, name) \ 347#define _DEFINE_SWIZZLER2(a, b, name) \
348 const Vec2<T> name() const { \ 348 constexpr Vec2<T> name() const { \
349 return Vec2<T>(a, b); \ 349 return Vec2<T>(a, b); \
350 } 350 }
351#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \ 351#define DEFINE_SWIZZLER2(a, b, a2, b2, a3, b3, a4, b4) \
@@ -366,7 +366,7 @@ public:
366}; 366};
367 367
368template <typename T, typename V> 368template <typename T, typename V>
369Vec3<T> operator*(const V& f, const Vec3<T>& vec) { 369constexpr Vec3<T> operator*(const V& f, const Vec3<T>& vec) {
370 return Vec3<T>(f * vec.x, f * vec.y, f * vec.z); 370 return Vec3<T>(f * vec.x, f * vec.y, f * vec.z);
371} 371}
372 372
@@ -387,7 +387,7 @@ inline float Vec3<float>::Normalize() {
387 return length; 387 return length;
388} 388}
389 389
390typedef Vec3<float> Vec3f; 390using Vec3f = Vec3<float>;
391 391
392template <typename T> 392template <typename T>
393class Vec4 { 393class Vec4 {
@@ -397,86 +397,88 @@ public:
397 T z{}; 397 T z{};
398 T w{}; 398 T w{};
399 399
400 Vec4() = default; 400 constexpr Vec4() = default;
401 Vec4(const T& _x, const T& _y, const T& _z, const T& _w) : x(_x), y(_y), z(_z), w(_w) {} 401 constexpr Vec4(const T& x_, const T& y_, const T& z_, const T& w_)
402 : x(x_), y(y_), z(z_), w(w_) {}
402 403
403 template <typename T2> 404 template <typename T2>
404 Vec4<T2> Cast() const { 405 constexpr Vec4<T2> Cast() const {
405 return Vec4<T2>((T2)x, (T2)y, (T2)z, (T2)w); 406 return Vec4<T2>(static_cast<T2>(x), static_cast<T2>(y), static_cast<T2>(z),
407 static_cast<T2>(w));
406 } 408 }
407 409
408 // Only implemented for T=int and T=float 410 static constexpr Vec4 AssignToAll(const T& f) {
409 static Vec4 FromRGBA(unsigned int rgba); 411 return Vec4(f, f, f, f);
410 unsigned int ToRGBA() const;
411
412 static Vec4 AssignToAll(const T& f) {
413 return Vec4<T>(f, f, f, f);
414 } 412 }
415 413
416 Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const { 414 constexpr Vec4<decltype(T{} + T{})> operator+(const Vec4& other) const {
417 return MakeVec(x + other.x, y + other.y, z + other.z, w + other.w); 415 return {x + other.x, y + other.y, z + other.z, w + other.w};
418 } 416 }
419 void operator+=(const Vec4& other) { 417
418 constexpr Vec4& operator+=(const Vec4& other) {
420 x += other.x; 419 x += other.x;
421 y += other.y; 420 y += other.y;
422 z += other.z; 421 z += other.z;
423 w += other.w; 422 w += other.w;
423 return *this;
424 } 424 }
425 Vec4<decltype(T{} - T{})> operator-(const Vec4& other) const { 425
426 return MakeVec(x - other.x, y - other.y, z - other.z, w - other.w); 426 constexpr Vec4<decltype(T{} - T{})> operator-(const Vec4& other) const {
427 return {x - other.x, y - other.y, z - other.z, w - other.w};
427 } 428 }
428 void operator-=(const Vec4& other) { 429
430 constexpr Vec4& operator-=(const Vec4& other) {
429 x -= other.x; 431 x -= other.x;
430 y -= other.y; 432 y -= other.y;
431 z -= other.z; 433 z -= other.z;
432 w -= other.w; 434 w -= other.w;
435 return *this;
433 } 436 }
434 437
435 template <typename U = T> 438 template <typename U = T>
436 Vec4<std::enable_if_t<std::is_signed<U>::value, U>> operator-() const { 439 constexpr Vec4<std::enable_if_t<std::is_signed_v<U>, U>> operator-() const {
437 return MakeVec(-x, -y, -z, -w); 440 return {-x, -y, -z, -w};
438 } 441 }
439 Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const { 442
440 return MakeVec(x * other.x, y * other.y, z * other.z, w * other.w); 443 constexpr Vec4<decltype(T{} * T{})> operator*(const Vec4& other) const {
444 return {x * other.x, y * other.y, z * other.z, w * other.w};
441 } 445 }
446
442 template <typename V> 447 template <typename V>
443 Vec4<decltype(T{} * V{})> operator*(const V& f) const { 448 constexpr Vec4<decltype(T{} * V{})> operator*(const V& f) const {
444 return MakeVec(x * f, y * f, z * f, w * f); 449 return {x * f, y * f, z * f, w * f};
445 } 450 }
451
446 template <typename V> 452 template <typename V>
447 void operator*=(const V& f) { 453 constexpr Vec4& operator*=(const V& f) {
448 *this = *this * f; 454 *this = *this * f;
455 return *this;
449 } 456 }
457
450 template <typename V> 458 template <typename V>
451 Vec4<decltype(T{} / V{})> operator/(const V& f) const { 459 constexpr Vec4<decltype(T{} / V{})> operator/(const V& f) const {
452 return MakeVec(x / f, y / f, z / f, w / f); 460 return {x / f, y / f, z / f, w / f};
453 } 461 }
462
454 template <typename V> 463 template <typename V>
455 void operator/=(const V& f) { 464 constexpr Vec4& operator/=(const V& f) {
456 *this = *this / f; 465 *this = *this / f;
466 return *this;
457 } 467 }
458 468
459 T Length2() const { 469 constexpr T Length2() const {
460 return x * x + y * y + z * z + w * w; 470 return x * x + y * y + z * z + w * w;
461 } 471 }
462 472
463 // Only implemented for T=float 473 constexpr T& operator[](std::size_t i) {
464 float Length() const;
465 void SetLength(const float l);
466 Vec4 WithLength(const float l) const;
467 float Distance2To(Vec4& other);
468 Vec4 Normalized() const;
469 float Normalize(); // returns the previous length, which is often useful
470
471 T& operator[](int i) // allow vector[2] = 3 (vector.z=3)
472 {
473 return *((&x) + i); 474 return *((&x) + i);
474 } 475 }
475 T operator[](const int i) const { 476
477 constexpr const T& operator[](std::size_t i) const {
476 return *((&x) + i); 478 return *((&x) + i);
477 } 479 }
478 480
479 void SetZero() { 481 constexpr void SetZero() {
480 x = 0; 482 x = 0;
481 y = 0; 483 y = 0;
482 z = 0; 484 z = 0;
@@ -484,29 +486,29 @@ public:
484 } 486 }
485 487
486 // Common alias: RGBA (colors) 488 // Common alias: RGBA (colors)
487 T& r() { 489 constexpr T& r() {
488 return x; 490 return x;
489 } 491 }
490 T& g() { 492 constexpr T& g() {
491 return y; 493 return y;
492 } 494 }
493 T& b() { 495 constexpr T& b() {
494 return z; 496 return z;
495 } 497 }
496 T& a() { 498 constexpr T& a() {
497 return w; 499 return w;
498 } 500 }
499 501
500 const T& r() const { 502 constexpr const T& r() const {
501 return x; 503 return x;
502 } 504 }
503 const T& g() const { 505 constexpr const T& g() const {
504 return y; 506 return y;
505 } 507 }
506 const T& b() const { 508 constexpr const T& b() const {
507 return z; 509 return z;
508 } 510 }
509 const T& a() const { 511 constexpr const T& a() const {
510 return w; 512 return w;
511 } 513 }
512 514
@@ -518,7 +520,7 @@ public:
518// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and 520// DEFINE_SWIZZLER2_COMP2 defines two component functions for all component names (x<->r) and
519// permutations (xy<->yx) 521// permutations (xy<->yx)
520#define _DEFINE_SWIZZLER2(a, b, name) \ 522#define _DEFINE_SWIZZLER2(a, b, name) \
521 const Vec2<T> name() const { \ 523 constexpr Vec2<T> name() const { \
522 return Vec2<T>(a, b); \ 524 return Vec2<T>(a, b); \
523 } 525 }
524#define DEFINE_SWIZZLER2_COMP1(a, a2) \ 526#define DEFINE_SWIZZLER2_COMP1(a, a2) \
@@ -545,7 +547,7 @@ public:
545#undef _DEFINE_SWIZZLER2 547#undef _DEFINE_SWIZZLER2
546 548
547#define _DEFINE_SWIZZLER3(a, b, c, name) \ 549#define _DEFINE_SWIZZLER3(a, b, c, name) \
548 const Vec3<T> name() const { \ 550 constexpr Vec3<T> name() const { \
549 return Vec3<T>(a, b, c); \ 551 return Vec3<T>(a, b, c); \
550 } 552 }
551#define DEFINE_SWIZZLER3_COMP1(a, a2) \ 553#define DEFINE_SWIZZLER3_COMP1(a, a2) \
@@ -579,51 +581,51 @@ public:
579}; 581};
580 582
581template <typename T, typename V> 583template <typename T, typename V>
582Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) { 584constexpr Vec4<decltype(V{} * T{})> operator*(const V& f, const Vec4<T>& vec) {
583 return MakeVec(f * vec.x, f * vec.y, f * vec.z, f * vec.w); 585 return {f * vec.x, f * vec.y, f * vec.z, f * vec.w};
584} 586}
585 587
586typedef Vec4<float> Vec4f; 588using Vec4f = Vec4<float>;
587 589
588template <typename T> 590template <typename T>
589static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) { 591constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec2<T>& a, const Vec2<T>& b) {
590 return a.x * b.x + a.y * b.y; 592 return a.x * b.x + a.y * b.y;
591} 593}
592 594
593template <typename T> 595template <typename T>
594static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) { 596constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec3<T>& a, const Vec3<T>& b) {
595 return a.x * b.x + a.y * b.y + a.z * b.z; 597 return a.x * b.x + a.y * b.y + a.z * b.z;
596} 598}
597 599
598template <typename T> 600template <typename T>
599static inline decltype(T{} * T{} + T{} * T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) { 601constexpr decltype(T{} * T{} + T{} * T{}) Dot(const Vec4<T>& a, const Vec4<T>& b) {
600 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; 602 return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w;
601} 603}
602 604
603template <typename T> 605template <typename T>
604static inline Vec3<decltype(T{} * T{} - T{} * T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) { 606constexpr Vec3<decltype(T{} * T{} - T{} * T{})> Cross(const Vec3<T>& a, const Vec3<T>& b) {
605 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); 607 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};
606} 608}
607 609
608// linear interpolation via float: 0.0=begin, 1.0=end 610// linear interpolation via float: 0.0=begin, 1.0=end
609template <typename X> 611template <typename X>
610static inline decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end, 612constexpr decltype(X{} * float{} + X{} * float{}) Lerp(const X& begin, const X& end,
611 const float t) { 613 const float t) {
612 return begin * (1.f - t) + end * t; 614 return begin * (1.f - t) + end * t;
613} 615}
614 616
615// linear interpolation via int: 0=begin, base=end 617// linear interpolation via int: 0=begin, base=end
616template <typename X, int base> 618template <typename X, int base>
617static inline decltype((X{} * int{} + X{} * int{}) / base) LerpInt(const X& begin, const X& end, 619constexpr decltype((X{} * int{} + X{} * int{}) / base) LerpInt(const X& begin, const X& end,
618 const int t) { 620 const int t) {
619 return (begin * (base - t) + end * t) / base; 621 return (begin * (base - t) + end * t) / base;
620} 622}
621 623
622// bilinear interpolation. s is for interpolating x00-x01 and x10-x11, and t is for the second 624// bilinear interpolation. s is for interpolating x00-x01 and x10-x11, and t is for the second
623// interpolation. 625// interpolation.
624template <typename X> 626template <typename X>
625inline auto BilinearInterp(const X& x00, const X& x01, const X& x10, const X& x11, const float s, 627constexpr auto BilinearInterp(const X& x00, const X& x01, const X& x10, const X& x11, const float s,
626 const float t) { 628 const float t) {
627 auto y0 = Lerp(x00, x01, s); 629 auto y0 = Lerp(x00, x01, s);
628 auto y1 = Lerp(x10, x11, s); 630 auto y1 = Lerp(x10, x11, s);
629 return Lerp(y0, y1, t); 631 return Lerp(y0, y1, t);
@@ -631,42 +633,42 @@ inline auto BilinearInterp(const X& x00, const X& x01, const X& x10, const X& x1
631 633
632// Utility vector factories 634// Utility vector factories
633template <typename T> 635template <typename T>
634static inline Vec2<T> MakeVec(const T& x, const T& y) { 636constexpr Vec2<T> MakeVec(const T& x, const T& y) {
635 return Vec2<T>{x, y}; 637 return Vec2<T>{x, y};
636} 638}
637 639
638template <typename T> 640template <typename T>
639static inline Vec3<T> MakeVec(const T& x, const T& y, const T& z) { 641constexpr Vec3<T> MakeVec(const T& x, const T& y, const T& z) {
640 return Vec3<T>{x, y, z}; 642 return Vec3<T>{x, y, z};
641} 643}
642 644
643template <typename T> 645template <typename T>
644static inline Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) { 646constexpr Vec4<T> MakeVec(const T& x, const T& y, const Vec2<T>& zw) {
645 return MakeVec(x, y, zw[0], zw[1]); 647 return MakeVec(x, y, zw[0], zw[1]);
646} 648}
647 649
648template <typename T> 650template <typename T>
649static inline Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) { 651constexpr Vec3<T> MakeVec(const Vec2<T>& xy, const T& z) {
650 return MakeVec(xy[0], xy[1], z); 652 return MakeVec(xy[0], xy[1], z);
651} 653}
652 654
653template <typename T> 655template <typename T>
654static inline Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) { 656constexpr Vec3<T> MakeVec(const T& x, const Vec2<T>& yz) {
655 return MakeVec(x, yz[0], yz[1]); 657 return MakeVec(x, yz[0], yz[1]);
656} 658}
657 659
658template <typename T> 660template <typename T>
659static inline Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) { 661constexpr Vec4<T> MakeVec(const T& x, const T& y, const T& z, const T& w) {
660 return Vec4<T>{x, y, z, w}; 662 return Vec4<T>{x, y, z, w};
661} 663}
662 664
663template <typename T> 665template <typename T>
664static inline Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) { 666constexpr Vec4<T> MakeVec(const Vec2<T>& xy, const T& z, const T& w) {
665 return MakeVec(xy[0], xy[1], z, w); 667 return MakeVec(xy[0], xy[1], z, w);
666} 668}
667 669
668template <typename T> 670template <typename T>
669static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) { 671constexpr Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) {
670 return MakeVec(x, yz[0], yz[1], w); 672 return MakeVec(x, yz[0], yz[1], w);
671} 673}
672 674
@@ -674,17 +676,17 @@ static inline Vec4<T> MakeVec(const T& x, const Vec2<T>& yz, const T& w) {
674// Even if someone wanted to use an odd object like Vec2<Vec2<T>>, the compiler would error 676// Even if someone wanted to use an odd object like Vec2<Vec2<T>>, the compiler would error
675// out soon enough due to misuse of the returned structure. 677// out soon enough due to misuse of the returned structure.
676template <typename T> 678template <typename T>
677static inline Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) { 679constexpr Vec4<T> MakeVec(const Vec2<T>& xy, const Vec2<T>& zw) {
678 return MakeVec(xy[0], xy[1], zw[0], zw[1]); 680 return MakeVec(xy[0], xy[1], zw[0], zw[1]);
679} 681}
680 682
681template <typename T> 683template <typename T>
682static inline Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) { 684constexpr Vec4<T> MakeVec(const Vec3<T>& xyz, const T& w) {
683 return MakeVec(xyz[0], xyz[1], xyz[2], w); 685 return MakeVec(xyz[0], xyz[1], xyz[2], w);
684} 686}
685 687
686template <typename T> 688template <typename T>
687static inline Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) { 689constexpr Vec4<T> MakeVec(const T& x, const Vec3<T>& yzw) {
688 return MakeVec(x, yzw[0], yzw[1], yzw[2]); 690 return MakeVec(x, yzw[0], yzw[1], yzw[2]);
689} 691}
690 692
diff --git a/src/common/x64/xbyak_util.h b/src/common/x64/xbyak_util.h
index 0f52f704b..ec76e0a47 100644
--- a/src/common/x64/xbyak_util.h
+++ b/src/common/x64/xbyak_util.h
@@ -34,7 +34,7 @@ inline bool IsWithin2G(const Xbyak::CodeGenerator& code, uintptr_t target) {
34 34
35template <typename T> 35template <typename T>
36inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) { 36inline void CallFarFunction(Xbyak::CodeGenerator& code, const T f) {
37 static_assert(std::is_pointer<T>(), "Argument must be a (function) pointer."); 37 static_assert(std::is_pointer_v<T>, "Argument must be a (function) pointer.");
38 size_t addr = reinterpret_cast<size_t>(f); 38 size_t addr = reinterpret_cast<size_t>(f);
39 if (IsWithin2G(code, addr)) { 39 if (IsWithin2G(code, addr)) {
40 code.call(f); 40 code.call(f);