diff --git a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp index f4ac70e2..a13a0077 100644 --- a/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp +++ b/src/ZoneCodeGeneratorLib/Generating/Templates/ZoneLoadTemplate.cpp @@ -369,7 +369,8 @@ namespace { if (reusable) { - LINEF("if (*{0} == PTR_FOLLOWING)", MakeTypePtrVarName(def)) + LINEF("const auto zonePtrType = GetZonePointerType(*{0});", MakeTypePtrVarName(def)) + LINEF("if (zonePtrType == ZonePointerType::FOLLOWING)", MakeTypePtrVarName(def)) LINE("{") m_intendation++; @@ -805,7 +806,7 @@ namespace { LINE("") LINEF("{0}** toInsert = nullptr;", member->m_member->m_type_declaration->m_type->GetFullName()) - LINE("if (ptr == PTR_INSERT)") + LINE("if (zonePtrType == ZonePointerType::INSERT)") m_intendation++; LINEF("toInsert = m_stream.InsertPointerNative<{0}>();", member->m_member->m_type_declaration->m_type->GetFullName()) m_intendation--; @@ -850,10 +851,12 @@ namespace return; } + LINEF("const auto zonePtrType = GetZonePointerType({0});", MakeMemberAccess(info, member, modifier)) + const MemberComputations computations(member); if (computations.IsInTempBlock()) { - LINEF("if ({0} == PTR_FOLLOWING || {0} == PTR_INSERT)", MakeMemberAccess(info, member, modifier)) + LINE("if (zonePtrType == ZonePointerType::FOLLOWING || zonePtrType == ZonePointerType::INSERT)") LINE("{") m_intendation++; @@ -872,7 +875,7 @@ namespace } else { - LINEF("if ({0} == PTR_FOLLOWING)", MakeMemberAccess(info, member, modifier)) + LINE("if (zonePtrType == ZonePointerType::FOLLOWING)") LINE("{") m_intendation++; @@ -1213,13 +1216,14 @@ namespace LINE("{") m_intendation++; + LINEF("const auto zonePtrType = GetZonePointerType(*{0});", MakeTypePtrVarName(info->m_definition)) if (inTemp) { - LINEF("if (*{0} == PTR_FOLLOWING || *{0} == PTR_INSERT)", MakeTypePtrVarName(info->m_definition)) + LINEF("if (zonePtrType == ZonePointerType::FOLLOWING || zonePtrType == ZonePointerType::INSERT)", MakeTypePtrVarName(info->m_definition)) } else { - LINEF("if (*{0} == PTR_FOLLOWING)", MakeTypePtrVarName(info->m_definition)) + LINEF("if (zonePtrType == ZonePointerType::FOLLOWING)", MakeTypePtrVarName(info->m_definition)) } LINE("{") m_intendation++; @@ -1237,7 +1241,7 @@ namespace { LINE("") LINEF("{0}** toInsert = nullptr;", info->m_definition->GetFullName()) - LINE("if (ptr == PTR_INSERT)") + LINE("if (zonePtrType == ZonePointerType::INSERT)") m_intendation++; LINEF("toInsert = m_stream.InsertPointerNative<{0}>();", info->m_definition->GetFullName()) m_intendation--; diff --git a/src/ZoneLoading/Game/IW3/ContentLoaderIW3.cpp b/src/ZoneLoading/Game/IW3/ContentLoaderIW3.cpp index 8ad2b90a..02f9c444 100644 --- a/src/ZoneLoading/Game/IW3/ContentLoaderIW3.cpp +++ b/src/ZoneLoading/Game/IW3/ContentLoaderIW3.cpp @@ -48,7 +48,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart) if (varScriptStringList->strings != nullptr) { - assert(varScriptStringList->strings == PTR_FOLLOWING); + assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING); varScriptStringList->strings = m_stream.Alloc(alignof(const char*)); varXString = varScriptStringList->strings; @@ -146,7 +146,7 @@ void ContentLoader::Load() if (assetList.assets != nullptr) { - assert(assetList.assets == PTR_FOLLOWING); + assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING); assetList.assets = m_stream.Alloc(alignof(XAsset)); varXAsset = assetList.assets; diff --git a/src/ZoneLoading/Game/IW4/ContentLoaderIW4.cpp b/src/ZoneLoading/Game/IW4/ContentLoaderIW4.cpp index 62782ed7..a44b14ee 100644 --- a/src/ZoneLoading/Game/IW4/ContentLoaderIW4.cpp +++ b/src/ZoneLoading/Game/IW4/ContentLoaderIW4.cpp @@ -71,7 +71,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart) if (varScriptStringList->strings != nullptr) { - assert(varScriptStringList->strings == PTR_FOLLOWING); + assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING); varScriptStringList->strings = m_stream.Alloc(4); varXString = varScriptStringList->strings; @@ -179,7 +179,7 @@ void ContentLoader::Load() if (assetList.assets != nullptr) { - assert(assetList.assets == PTR_FOLLOWING); + assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING); assetList.assets = m_stream.Alloc(alignof(XAsset)); varXAsset = assetList.assets; diff --git a/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp index b8430c67..c524d3b1 100644 --- a/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp +++ b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp @@ -63,7 +63,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart) if (varScriptStringList->strings != nullptr) { - assert(varScriptStringList->strings == PTR_FOLLOWING); + assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING); varScriptStringList->strings = m_stream.Alloc(alignof(const char*)); varXString = varScriptStringList->strings; @@ -175,7 +175,7 @@ void ContentLoader::Load() if (assetList.assets != nullptr) { - assert(assetList.assets == PTR_FOLLOWING); + assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING); assetList.assets = m_stream.Alloc(alignof(XAsset)); varXAsset = assetList.assets; diff --git a/src/ZoneLoading/Game/T5/ContentLoaderT5.cpp b/src/ZoneLoading/Game/T5/ContentLoaderT5.cpp index b26734bb..9536f02a 100644 --- a/src/ZoneLoading/Game/T5/ContentLoaderT5.cpp +++ b/src/ZoneLoading/Game/T5/ContentLoaderT5.cpp @@ -55,7 +55,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart) if (varScriptStringList->strings != nullptr) { - assert(varScriptStringList->strings == PTR_FOLLOWING); + assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING); varScriptStringList->strings = m_stream.Alloc(alignof(const char*)); varXString = varScriptStringList->strings; @@ -159,7 +159,7 @@ void ContentLoader::Load() if (assetList.assets != nullptr) { - assert(assetList.assets == PTR_FOLLOWING); + assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING); assetList.assets = m_stream.Alloc(alignof(XAsset)); varXAsset = assetList.assets; diff --git a/src/ZoneLoading/Game/T6/ContentLoaderT6.cpp b/src/ZoneLoading/Game/T6/ContentLoaderT6.cpp index 12c62d4f..b551cd91 100644 --- a/src/ZoneLoading/Game/T6/ContentLoaderT6.cpp +++ b/src/ZoneLoading/Game/T6/ContentLoaderT6.cpp @@ -71,7 +71,7 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart) if (varScriptStringList->strings != nullptr) { - assert(varScriptStringList->strings == PTR_FOLLOWING); + assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING); varScriptStringList->strings = m_stream.Alloc(alignof(const char*)); varXString = varScriptStringList->strings; @@ -188,7 +188,7 @@ void ContentLoader::Load() if (assetList.depends != nullptr) { - assert(assetList.depends == PTR_FOLLOWING); + assert(GetZonePointerType(assetList.depends) == ZonePointerType::FOLLOWING); assetList.depends = m_stream.Alloc(alignof(const char*)); varXString = assetList.depends; @@ -197,7 +197,7 @@ void ContentLoader::Load() if (assetList.assets != nullptr) { - assert(assetList.assets == PTR_FOLLOWING); + assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING); assetList.assets = m_stream.Alloc(alignof(XAsset)); varXAsset = assetList.assets; diff --git a/src/ZoneLoading/Loading/ContentLoaderBase.cpp b/src/ZoneLoading/Loading/ContentLoaderBase.cpp index 45fa3b1a..ae92935a 100644 --- a/src/ZoneLoading/Loading/ContentLoaderBase.cpp +++ b/src/ZoneLoading/Loading/ContentLoaderBase.cpp @@ -1,15 +1,22 @@ #include "ContentLoaderBase.h" #include - -const void* ContentLoaderBase::PTR_FOLLOWING = reinterpret_cast(-1); -const void* ContentLoaderBase::PTR_INSERT = reinterpret_cast(-2); +#include +#include ContentLoaderBase::ContentLoaderBase(Zone& zone, ZoneInputStream& stream) : varXString(nullptr), m_zone(zone), m_memory(zone.Memory()), - m_stream(stream) + m_stream(stream), + + // -1 + m_zone_ptr_following( + reinterpret_cast(std::numeric_limits::max() >> ((sizeof(std::uintptr_t) * 8u) - stream.GetPointerBitCount()))), + + // -2 + m_zone_ptr_insert( + reinterpret_cast((std::numeric_limits::max() >> ((sizeof(std::uintptr_t) * 8u) - stream.GetPointerBitCount())) - 1u)) { } @@ -22,9 +29,9 @@ void ContentLoaderBase::LoadXString(const bool atStreamStart) const if (*varXString != nullptr) { - if (*varXString == PTR_FOLLOWING) + if (GetZonePointerType(varXString) == ZonePointerType::FOLLOWING) { - *varXString = m_stream.Alloc(alignof(const char)); + *varXString = m_stream.Alloc(1); m_stream.LoadNullTerminated(const_cast(*varXString)); } else @@ -39,7 +46,10 @@ void ContentLoaderBase::LoadXStringArray(const bool atStreamStart, const size_t assert(varXString != nullptr); if (atStreamStart) + { + m_stream.LoadWithFill(4u * count); m_stream.Load(varXString, count); + } for (size_t index = 0; index < count; index++) { @@ -47,3 +57,13 @@ void ContentLoaderBase::LoadXStringArray(const bool atStreamStart, const size_t varXString++; } } + +ZonePointerType ContentLoaderBase::GetZonePointerType(const void* zonePtr) const +{ + if (zonePtr == m_zone_ptr_following) + return ZonePointerType::FOLLOWING; + if (zonePtr == m_zone_ptr_insert) + return ZonePointerType::INSERT; + + return ZonePointerType::OFFSET; +} diff --git a/src/ZoneLoading/Loading/ContentLoaderBase.h b/src/ZoneLoading/Loading/ContentLoaderBase.h index 5edddb5e..8093476d 100644 --- a/src/ZoneLoading/Loading/ContentLoaderBase.h +++ b/src/ZoneLoading/Loading/ContentLoaderBase.h @@ -3,12 +3,17 @@ #include "Zone/Stream/ZoneInputStream.h" #include "Zone/Zone.h" +#include + +enum class ZonePointerType : std::uint8_t +{ + FOLLOWING, + INSERT, + OFFSET +}; + class ContentLoaderBase { -protected: - static const void* PTR_FOLLOWING; - static const void* PTR_INSERT; - public: virtual ~ContentLoaderBase() = default; ContentLoaderBase(const ContentLoaderBase& other) = default; @@ -22,9 +27,20 @@ protected: void LoadXString(bool atStreamStart) const; void LoadXStringArray(bool atStreamStart, size_t count); + [[nodiscard]] ZonePointerType GetZonePointerType(const void* zonePtr) const; + + template [[nodiscard]] ZonePointerType GetZonePointerType(T* zonePtr) const + { + return GetZonePointerType(reinterpret_cast(zonePtr)); + } + const char** varXString; Zone& m_zone; MemoryManager& m_memory; ZoneInputStream& m_stream; + +private: + const void* m_zone_ptr_following; + const void* m_zone_ptr_insert; }; diff --git a/src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp b/src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp index 572e8494..675203f8 100644 --- a/src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp +++ b/src/ZoneLoading/Zone/Stream/ZoneInputStream.cpp @@ -45,6 +45,11 @@ namespace m_insert_block = blocks[insertBlock]; } + [[nodiscard]] unsigned GetPointerBitCount() const override + { + return m_pointer_byte_count * 8u; + } + void PushBlock(const block_t block) override { assert(block < static_cast(m_blocks.size())); diff --git a/src/ZoneLoading/Zone/Stream/ZoneInputStream.h b/src/ZoneLoading/Zone/Stream/ZoneInputStream.h index 8c7d0f26..312b29c2 100644 --- a/src/ZoneLoading/Zone/Stream/ZoneInputStream.h +++ b/src/ZoneLoading/Zone/Stream/ZoneInputStream.h @@ -47,6 +47,11 @@ private: class ZoneInputStream : public IZoneStream { public: + /** + * \brief Returns the configured bits that make up a pointer. + */ + [[nodiscard]] virtual unsigned GetPointerBitCount() const = 0; + /** * \brief Retrieves the new read position in the current block by aligning the position with the specified value and then returning the current read * position in the block.