Add FourCC/_u32 helper function/literals

Portable code for turning string-based four-character-codes like
`"BLAH"_u32` into a 32-bit integer at compile-time.
This commit is contained in:
Wunkolo 2023-06-10 01:42:35 -07:00
parent 75c41a3841
commit 5124b54027
3 changed files with 24 additions and 2 deletions

View file

@ -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__

View file

@ -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;
}

View file

@ -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;
}