diff --git a/include/helpers.hpp b/include/helpers.hpp index 237a333b..853e487b 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -1,6 +1,6 @@ #pragma once -#include #include +#include #include #include #include @@ -8,8 +8,16 @@ #include #include #include + #include "termcolor.hpp" +// We have to detect and special-case AppleClang at the moment since its C++20 support is finicky and doesn't quite support std::bit_cast +#if defined(__clang__) && defined(__apple_build_version__) +#define HELPERS_APPLE_CLANG +#else +#include +#endif + using u8 = std::uint8_t; using u16 = std::uint16_t; using u32 = std::uint32_t; @@ -23,78 +31,74 @@ using s32 = std::int32_t; using s64 = std::int64_t; namespace Helpers { - [[noreturn]] static void panic(const char* fmt, ...) { - std::va_list args; - va_start(args, fmt); - std::cout << termcolor::on_red << "[FATAL] "; - std::vprintf (fmt, args); - std::cout << termcolor::reset << "\n"; - va_end(args); + [[noreturn]] static void panic(const char* fmt, ...) { + std::va_list args; + va_start(args, fmt); + std::cout << termcolor::on_red << "[FATAL] "; + std::vprintf(fmt, args); + std::cout << termcolor::reset << "\n"; + va_end(args); - exit(1); - } + exit(1); + } - static void warn(const char* fmt, ...) { - std::va_list args; - va_start(args, fmt); - std::cout << termcolor::on_red << "[Warning] "; - std::vprintf (fmt, args); - std::cout << termcolor::reset << "\n"; - va_end(args); - } + static void warn(const char* fmt, ...) { + std::va_list args; + va_start(args, fmt); + std::cout << termcolor::on_red << "[Warning] "; + std::vprintf(fmt, args); + std::cout << termcolor::reset << "\n"; + va_end(args); + } - static std::vector loadROM(std::string directory) { - std::ifstream file (directory, std::ios::binary); - if (file.fail()) - panic("Couldn't read %s", directory.c_str()); + static std::vector loadROM(std::string directory) { + std::ifstream file(directory, std::ios::binary); + if (file.fail()) panic("Couldn't read %s", directory.c_str()); - std::vector ROM; + std::vector ROM; - file.unsetf(std::ios::skipws); - ROM.insert(ROM.begin(), - std::istream_iterator(file), - std::istream_iterator()); + file.unsetf(std::ios::skipws); + ROM.insert(ROM.begin(), std::istream_iterator(file), std::istream_iterator()); - file.close(); + file.close(); - printf ("%s loaded successfully\n", directory.c_str()); - return ROM; - } + printf("%s loaded successfully\n", directory.c_str()); + return ROM; + } - static constexpr bool buildingInDebugMode() { - #ifdef NDEBUG - return false; - #endif + static constexpr bool buildingInDebugMode() { +#ifdef NDEBUG + return false; +#endif + return true; + } - return true; - } - - static void debug_printf (const char* fmt, ...) { - if constexpr (buildingInDebugMode()) { - std::va_list args; - va_start(args, fmt); - std::vprintf (fmt, args); - va_end(args); - } - } + static void debug_printf(const char* fmt, ...) { + if constexpr (buildingInDebugMode()) { + std::va_list args; + va_start(args, fmt); + std::vprintf(fmt, args); + va_end(args); + } + } - /// Sign extend an arbitrary-size value to 32 bits - static constexpr u32 inline signExtend32 (u32 value, u32 startingSize) { - auto temp = (s32) value; - auto bitsToShift = 32 - startingSize; - return (u32) (temp << bitsToShift >> bitsToShift); - } + /// Sign extend an arbitrary-size value to 32 bits + static constexpr u32 inline signExtend32(u32 value, u32 startingSize) { + auto temp = (s32)value; + auto bitsToShift = 32 - startingSize; + return (u32)(temp << bitsToShift >> bitsToShift); + } - /// Sign extend an arbitrary-size value to 16 bits - static constexpr u16 signExtend16 (u16 value, u32 startingSize) { - auto temp = (s16) value; - auto bitsToShift = 16 - startingSize; - return (u16) (temp << bitsToShift >> bitsToShift); - } + /// Sign extend an arbitrary-size value to 16 bits + static constexpr u16 signExtend16(u16 value, u32 startingSize) { + auto temp = (s16)value; + auto bitsToShift = 16 - startingSize; + return (u16)(temp << bitsToShift >> bitsToShift); + } /// Create a mask with `count` number of one bits. - template - static constexpr T ones () { + template + static constexpr T ones() { constexpr usize bitsize = CHAR_BIT * sizeof(T); static_assert(count <= bitsize, "count larger than bitsize of T"); @@ -105,74 +109,74 @@ namespace Helpers { } /// Extract bits from an integer-type - template - static constexpr T getBit (T value) { - return (value >> offset) & T(1); + template + static constexpr T getBit(T value) { + return (value >> offset) & T(1); } /// Extract bits from an integer-type - template - static constexpr T getBits (T value) { - return (value >> offset) & ones(); + template + static constexpr T getBits(T value) { + return (value >> offset) & ones(); } - /// Check if a bit "bit" of value is set - static constexpr bool isBitSet (u32 value, int bit) { - return (value >> bit) & 1; - } + /// Check if a bit "bit" of value is set + static constexpr bool isBitSet(u32 value, int bit) { return (value >> bit) & 1; } - /// rotate number right - template - static constexpr T rotr (T value, int bits) { - constexpr auto bitWidth = sizeof(T) * 8; - bits &= bitWidth - 1; - return (value >> bits) | (value << (bitWidth - bits)); - } + /// rotate number right + template + static constexpr T rotr(T value, int bits) { + constexpr auto bitWidth = sizeof(T) * 8; + bits &= bitWidth - 1; + return (value >> bits) | (value << (bitWidth - bits)); + } - // rotate number left - template - static constexpr T rotl (T value, int bits) { - constexpr auto bitWidth = sizeof(T) * 8; - bits &= bitWidth - 1; - return (value << bits) | (value >> (bitWidth - bits)); - } + // rotate number left + template + static constexpr T rotl(T value, int bits) { + constexpr auto bitWidth = sizeof(T) * 8; + bits &= bitWidth - 1; + return (value << bits) | (value >> (bitWidth - bits)); + } - /// Used to make the compiler evaluate beeg loops at compile time for the tablegen - template - static constexpr void static_for_impl( Func&& f, std::integer_sequence ) { - ( f( std::integral_constant{ } ),... ); - } + /// Used to make the compiler evaluate beeg loops at compile time for the tablegen + template + static constexpr void static_for_impl(Func&& f, std::integer_sequence) { + (f(std::integral_constant{}), ...); + } - template - static constexpr void static_for(Func&& f) { - static_for_impl( std::forward(f), std::make_integer_sequence{ } ); - } + template + static constexpr void static_for(Func&& f) { + static_for_impl(std::forward(f), std::make_integer_sequence{}); + } - // For values < 0x99 - static constexpr inline u8 incBCDByte(u8 value) { - return ((value & 0xf) == 0x9) ? value + 7 : value + 1; - } -}; + // For values < 0x99 + static constexpr inline u8 incBCDByte(u8 value) { return ((value & 0xf) == 0x9) ? value + 7 : value + 1; } + +#ifdef HELPERS_APPLE_CLANG + template + constexpr To bit_cast(const From& from) noexcept { + return *reinterpret_cast(&from); + } +#else + template + constexpr To bit_cast(const From& from) noexcept { + return std::bit_cast(from); + } +#endif +}; // namespace Helpers // UDLs for memory size values -constexpr size_t operator""_KB(unsigned long long int x) { - return 1024ULL * x; -} - -constexpr size_t operator""_MB(unsigned long long int x) { - return 1024_KB * x; -} - -constexpr size_t operator""_GB(unsigned long long int x) { - return 1024_MB * x; -} +constexpr size_t operator""_KB(unsigned long long int x) { return 1024ULL * x; } +constexpr size_t operator""_MB(unsigned long long int x) { return 1024_KB * x; } +constexpr size_t operator""_GB(unsigned long long int x) { return 1024_MB * x; } // useful macros // likely/unlikely #ifdef __GNUC__ - #define likely(x) __builtin_expect((x),1) - #define unlikely(x) __builtin_expect((x),0) -#else - #define likely(x) (x) - #define unlikely(x) (x) -#endif \ No newline at end of file +#define likely(x) __builtin_expect((x), 1) +#define unlikely(x) __builtin_expect((x), 0) +#else +#define likely(x) (x) +#define unlikely(x) (x) +#endif diff --git a/src/core/kernel/threads.cpp b/src/core/kernel/threads.cpp index cf6b2cac..c8325031 100644 --- a/src/core/kernel/threads.cpp +++ b/src/core/kernel/threads.cpp @@ -1,3 +1,4 @@ +#include #include #include diff --git a/src/core/services/cfg.cpp b/src/core/services/cfg.cpp index ab969183..6925e3d8 100644 --- a/src/core/services/cfg.cpp +++ b/src/core/services/cfg.cpp @@ -73,7 +73,7 @@ void CFGService::getConfigInfoBlk2(u32 messagePointer) { }; for (int i = 0; i < 8; i++) { - mem.write32(output + i * 4, std::bit_cast(STEREO_CAMERA_SETTINGS[i])); + mem.write32(output + i * 4, Helpers::bit_cast(STEREO_CAMERA_SETTINGS[i])); } } else if (size == 0x1C && blockID == 0xA0000) { // Username writeStringU16(output, u"Pander"); diff --git a/src/core/services/hid.cpp b/src/core/services/hid.cpp index ed7f2afd..7993dc7a 100644 --- a/src/core/services/hid.cpp +++ b/src/core/services/hid.cpp @@ -83,7 +83,7 @@ void HIDService::getGyroscopeCoefficient(u32 messagePointer) { constexpr float gyroscopeCoeff = 14.375f; // Same as retail 3DS mem.write32(messagePointer, IPC::responseHeader(0x15, 2, 0)); mem.write32(messagePointer + 4, Result::Success); - mem.write32(messagePointer + 8, std::bit_cast(gyroscopeCoeff)); + mem.write32(messagePointer + 8, Helpers::bit_cast(gyroscopeCoeff)); } void HIDService::getIPCHandles(u32 messagePointer) {