diff --git a/include/helpers.hpp b/include/helpers.hpp index ee1a1dac..25c2ef2d 100644 --- a/include/helpers.hpp +++ b/include/helpers.hpp @@ -141,6 +141,28 @@ constexpr size_t operator""_GB(unsigned long long int x) { return 1024_MB * x; } +// Utility user-literal/metaprogramming-type for turning four-character-codes +// into 32-bit integers at compile-time +// Ex: "BLAH"_u32, "HEAD"_u32, "END "_u32 +template <std::size_t N> +struct FourCC { + u32 value; + + constexpr FourCC(const char (&identifier)[N]) : value(0) { + static_assert(N == 5, "FourCC must be 4 characters"); + if constexpr (std::endian::native == std::endian::big) { + value = ((identifier[3] << 0) | (identifier[2] << 8) | (identifier[1] << 16) | (identifier[0] << 24)); + } else { + value = ((identifier[3] << 24) | (identifier[2] << 16) | (identifier[1] << 8) | (identifier[0] << 0)); + } + } +}; + +template <FourCC code> +constexpr std::uint32_t operator""_u32() { + return code.value; +} + // useful macros // likely/unlikely #ifdef __GNUC__ diff --git a/src/core/loader/ncch.cpp b/src/core/loader/ncch.cpp index c3dd8d2e..6eb4506c 100644 --- a/src/core/loader/ncch.cpp +++ b/src/core/loader/ncch.cpp @@ -5,7 +5,7 @@ #include "memory.hpp" bool NCCH::loadFromHeader(u8* header, IOFile& file) { - if (header[0x100] != 'N' || header[0x101] != 'C' || header[0x102] != 'C' || header[0x103] != 'H') { + if (*(u32*)&header[0x100] != "NCCH"_u32) { printf("Invalid header on NCCH\n"); return false; } diff --git a/src/core/loader/ncsd.cpp b/src/core/loader/ncsd.cpp index bf93f490..cc311eba 100644 --- a/src/core/loader/ncsd.cpp +++ b/src/core/loader/ncsd.cpp @@ -17,7 +17,7 @@ std::optional<NCSD> Memory::loadNCSD(const std::filesystem::path& path) { return std::nullopt; } - if (magic[0] != 'N' || magic[1] != 'C' || magic[2] != 'S' || magic[3] != 'D') { + if (*(u32*)&magic[0] != "NCSD"_u32) { printf("NCSD with wrong magic value\n"); return std::nullopt; }