From 37e5e940b0ba077c7c8285d301803eb7f401031b Mon Sep 17 00:00:00 2001 From: Jan Date: Mon, 23 Jun 2025 18:50:21 +0100 Subject: [PATCH] refactor: update IW5 loading code for x64 support --- src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp | 53 +++++++++++++++---- src/ZoneLoading/Game/IW5/ContentLoaderIW5.h | 1 + 2 files changed, 44 insertions(+), 10 deletions(-) diff --git a/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp index c524d3b1..ada66414 100644 --- a/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp +++ b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.cpp @@ -49,6 +49,7 @@ using namespace IW5; ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream) : ContentLoaderBase(zone, stream), + varXAssetList(nullptr), varXAsset(nullptr), varScriptStringList(nullptr) { @@ -56,16 +57,17 @@ ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream) void ContentLoader::LoadScriptStringList(const bool atStreamStart) { - m_stream.PushBlock(XFILE_BLOCK_VIRTUAL); - - if (atStreamStart) - m_stream.Load(varScriptStringList); + assert(!atStreamStart); if (varScriptStringList->strings != nullptr) { assert(GetZonePointerType(varScriptStringList->strings) == ZonePointerType::FOLLOWING); - varScriptStringList->strings = m_stream.Alloc(alignof(const char*)); +#ifdef ARCH_x86 + varScriptStringList->strings = m_stream.Alloc(4); +#else + varScriptStringList->strings = m_stream.AllocOutOfBlock(4, varScriptStringList->count); +#endif varXString = varScriptStringList->strings; LoadXStringArray(true, varScriptStringList->count); @@ -73,8 +75,6 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart) m_zone.m_script_strings.InitializeForExistingZone(varScriptStringList->strings, static_cast(varScriptStringList->count)); } - m_stream.PopBlock(); - assert(m_zone.m_script_strings.Count() <= SCR_STRING_MAX + 1); } @@ -154,21 +154,50 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count assert(count == 0 || varXAsset != nullptr); if (atStreamStart) + { +#ifdef ARCH_x86 m_stream.Load(varXAsset, count); +#else + const auto fill = m_stream.LoadWithFill(8u * count); + + for (size_t index = 0; index < count; index++) + { + fill.Fill(varXAsset[index].type, 8u * index); + fill.FillPtr(varXAsset[index].header.data, 8u * index + 4u); + m_stream.AddPointerLookup(&varXAsset[index].header.data, fill.BlockBuffer(8u * index + 4u)); + } +#endif + } for (size_t index = 0; index < count; index++) { LoadXAsset(false); varXAsset++; + +#ifdef DEBUG_OFFSETS + m_stream.DebugOffsets(index); +#endif } } void ContentLoader::Load() { - m_stream.PushBlock(XFILE_BLOCK_VIRTUAL); - XAssetList assetList{}; + varXAssetList = &assetList; + +#ifdef ARCH_x86 m_stream.LoadDataRaw(&assetList, sizeof(assetList)); +#else + const auto fillAccessor = m_stream.LoadWithFill(16u); + varScriptStringList = &varXAssetList->stringList; + fillAccessor.Fill(varScriptStringList->count, 0u); + fillAccessor.FillPtr(varScriptStringList->strings, 4u); + + fillAccessor.Fill(varXAssetList->assetCount, 8u); + fillAccessor.FillPtr(varXAssetList->assets, 12u); +#endif + + m_stream.PushBlock(XFILE_BLOCK_VIRTUAL); varScriptStringList = &assetList.stringList; LoadScriptStringList(false); @@ -177,7 +206,11 @@ void ContentLoader::Load() { assert(GetZonePointerType(assetList.assets) == ZonePointerType::FOLLOWING); - assetList.assets = m_stream.Alloc(alignof(XAsset)); +#ifdef ARCH_x86 + assetList.assets = m_stream.Alloc(4); +#else + assetList.assets = m_stream.AllocOutOfBlock(4, assetList.assetCount); +#endif varXAsset = assetList.assets; LoadXAssetArray(true, assetList.assetCount); } diff --git a/src/ZoneLoading/Game/IW5/ContentLoaderIW5.h b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.h index e618f44f..3c3f9d93 100644 --- a/src/ZoneLoading/Game/IW5/ContentLoaderIW5.h +++ b/src/ZoneLoading/Game/IW5/ContentLoaderIW5.h @@ -18,6 +18,7 @@ namespace IW5 void LoadXAsset(bool atStreamStart) const; void LoadXAssetArray(bool atStreamStart, size_t count); + XAssetList* varXAssetList; XAsset* varXAsset; ScriptStringList* varScriptStringList; };