diff --git a/include/europa/structs/MathTypes.hpp b/include/europa/structs/MathTypes.hpp new file mode 100644 index 0000000..9a496cd --- /dev/null +++ b/include/europa/structs/MathTypes.hpp @@ -0,0 +1,40 @@ +// +// EuropaTools +// +// (C) 2021-2025 modeco80 +// +// SPDX-License-Identifier: MIT +// + +// Math types which are used by mesh I/O code. +// These are not general purpose and are only meant to be +// binary compatible. + +#pragma once + +namespace europa::structs { + + +#ifdef _MSC_VER + #pragma pack(push, 1) +#endif + + struct [[gnu::packed]] Vec3f { + float x; + float y; + float z; + }; + + struct [[gnu::packed]] Uvf { + float u; + float v; + }; + +#ifdef _MSC_VER + #pragma pack(pop) +#endif + + static_assert(sizeof(Vec3f) == 0xc, "Vec3f size is incorrect"); + static_assert(sizeof(Uvf) == 0x8, "Uvf size is incorrect"); + +} \ No newline at end of file diff --git a/include/europa/util/Into.hpp b/include/europa/util/Into.hpp new file mode 100644 index 0000000..3874583 --- /dev/null +++ b/include/europa/util/Into.hpp @@ -0,0 +1,63 @@ +#pragma once + +#include + +namespace europa::util { + + template + struct IntoImpl { + constexpr static To DoInto(const From& from) { + // The default implentation assumes that the To type has a constructor which + // can initalize it from a value of From const&. + return To(from); + } + }; + + /// Into() support for vectors of items. + template + struct IntoImpl, std::vector> { + constexpr static std::vector DoInto(const std::vector& from) { + // FIXME: Ranges could make this less stupid + auto vec = std::vector {}; + vec.resize(from.size()); + + // Feed into existing Into() implementation + for(auto const& item : from) + vec.push_back(Into(item)); + + return vec; + } + }; + + /// Allows a type to be converted. + /// A user is allowed to supply conversions out-of-band. + template + constexpr To Into(const From& from) { + return IntoImpl::DoInto(from); + } + +/// Helper macro to hide away the annoying boilerplate of +/// implementing the IntoImpl struct used for implementing conversion +#define EUROPA_BEGIN_INTO_CONVERSION(To, From) \ + template <> \ + struct ::europa::util::IntoImpl { \ + static To DoInto([[maybe_unused]] const From& from) + +#define EUROPA_END_INTO_CONVERSION } + +#if 0 + // An example of specializing Into(). + // This is a bit iffy, but works. + struct Frob {}; + + EUROPA_BEGIN_INTO_CONVERSION(int, Frob) { + return 42; + } EUROPA_END_INTO_CONVERSION; + + auto a() { + Frob f{}; + int i = Into(f); + } +#endif + +} // namespace europa::util \ No newline at end of file