diff --git a/src/archive_wrapper.hpp b/src/archive_wrapper.hpp new file mode 100644 index 000000000..e615695b9 --- /dev/null +++ b/src/archive_wrapper.hpp @@ -0,0 +1,133 @@ +// DR. ROBOTNIK'S RING RACERS +//----------------------------------------------------------------------------- +// Copyright (C) 2024 by James Robert Roman +// +// This program is free software distributed under the +// terms of the GNU General Public License, version 2. +// See the 'LICENSE' file for more details. +//----------------------------------------------------------------------------- + +#ifndef archive_wrapper_hpp +#define archive_wrapper_hpp + +#include + +#include "typedef.h" + +#include "cxxutil.hpp" +#include "byteptr.h" +#include "doomdef.h" // p_saveg.h +#include "doomtype.h" +#include "m_fixed.h" +#include "p_mobj.h" // p_saveg.h +#include "p_saveg.h" + +namespace srb2 +{ + +struct ArchiveWrapperBase +{ + explicit ArchiveWrapperBase(savebuffer_t* save) : p_(save->p) {} + +protected: + template + void read(U& n) = delete; + + template + void write(const U& n) = delete; + +private: + UINT8*& p_; +}; + +#define READ_SPEC(T, arg) \ + template <> void ArchiveWrapperBase::read(T& arg) + +#define WRITE_SPEC(T, arg) \ + template <> void ArchiveWrapperBase::write(const T& arg) + +#define MACRO_PAIR(T) \ + READ_SPEC(T, n) { n = READ ## T(p_); } \ + WRITE_SPEC(T, n) { WRITE ## T(p_, n); } + +MACRO_PAIR(UINT8) +MACRO_PAIR(SINT8) +MACRO_PAIR(UINT16) +MACRO_PAIR(INT16) +MACRO_PAIR(UINT32) +MACRO_PAIR(INT32) + +READ_SPEC(vector2_t, n) +{ + read(n.x); + read(n.y); +} + +WRITE_SPEC(vector2_t, n) +{ + write(n.x); + write(n.y); +} + +READ_SPEC(vector3_t, n) +{ + read(n.x); + read(n.y); + read(n.z); +} + +WRITE_SPEC(vector3_t, n) +{ + write(n.x); + write(n.y); + write(n.z); +} + +// Specializations for boolean, so it can stored as char +// instead of int. + +template <> +void ArchiveWrapperBase::read(boolean& n) +{ + SRB2_ASSERT(n == true || n == false); + n = READUINT8(p_); +} + +template <> +void ArchiveWrapperBase::write(const boolean& n) +{ + SRB2_ASSERT(n == true || n == false); + WRITEUINT8(p_, n); +} + +#undef MACRO_PAIR +#undef WRITE_SPEC +#undef READ_SPEC + +struct ArchiveWrapper : ArchiveWrapperBase +{ + using ArchiveWrapperBase::ArchiveWrapperBase; + + template + void operator()(const U& n) { write(n); } +}; + +struct UnArchiveWrapper : ArchiveWrapperBase +{ + using ArchiveWrapperBase::ArchiveWrapperBase; + + template + void operator()(U& n) { read(n); } +}; + +template +struct is_archive_wrapper : std::is_base_of {}; + +template +inline constexpr bool is_archive_wrapper_v = is_archive_wrapper::value; + +#define SRB2_ARCHIVE_WRAPPER_CALL(ar, T, var) ((ar). template operator()(var)) + +}; // namespace + +#endif/*archive_wrapper_hpp*/