feat: make base content loader for iw4 and iw5 support both 32 and 64 zones

This commit is contained in:
Jan Laupetin committed 2026-10-22 20:01:06 +02:00
1 parent 89a6172acf
commit 49cebf0f0e
6 files changed
+113 -42

No files matched your search

+45 -16
View File
@@ -1,6 +1,7 @@
#include "ContentLoaderIW4.h"
#include "Game/IW4/AssetLoader_iw4_pc32.h"
#include "Game/IW4/AssetLoader_iw4_pc64.h"
#include "Game/IW4/IW4.h"
#include "Loading/Exception/UnsupportedAssetTypeException.h"
@@ -27,7 +28,10 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
#ifdef ARCH_x86
varScriptStringList->strings = m_stream.Alloc<const char*>(4);
#else
varScriptStringList->strings = m_stream.AllocOutOfBlock<const char*>(4, varScriptStringList->count);
if (m_word_size == GameWordSize::ARCH_64)
varScriptStringList->strings = m_stream.Alloc<const char*>(4);
else
varScriptStringList->strings = m_stream.AllocOutOfBlock<const char*>(4, varScriptStringList->count);
#endif
varXString = varScriptStringList->strings;
LoadXStringArray(true, varScriptStringList->count);
@@ -44,8 +48,16 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
#define LOAD_ASSET(type_index, typeName, headerEntry) \
case type_index: \
{ \
Loader_##typeName##_pc32 loader(m_zone, m_stream); \
loader.Load(&varXAsset->header.headerEntry); \
if (m_word_size == GameWordSize::ARCH_64) \
{ \
Loader_##typeName##_pc64 loader(m_zone, m_stream); \
loader.Load(&varXAsset->header.headerEntry); \
} \
else \
{ \
Loader_##typeName##_pc32 loader(m_zone, m_stream); \
loader.Load(&varXAsset->header.headerEntry); \
} \
break; \
}
#define SKIP_ASSET(type_index, typeName, headerEntry) \
@@ -115,13 +127,20 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
#ifdef ARCH_x86
m_stream.Load<XAsset>(varXAsset, count);
#else
const auto fill = m_stream.LoadWithFill(8u * count);
for (size_t index = 0; index < count; index++)
if (m_word_size == GameWordSize::ARCH_64)
{
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));
m_stream.Load<XAsset>(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
}
@@ -145,13 +164,20 @@ void ContentLoader::Load()
#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);
if (m_word_size == GameWordSize::ARCH_64)
{
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);
fillAccessor.Fill(varXAssetList->assetCount, 8u);
fillAccessor.FillPtr(varXAssetList->assets, 12u);
}
#endif
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
@@ -166,7 +192,10 @@ void ContentLoader::Load()
#ifdef ARCH_x86
assetList.assets = m_stream.Alloc<XAsset>(4);
#else
assetList.assets = m_stream.AllocOutOfBlock<XAsset>(4, assetList.assetCount);
if (m_word_size == GameWordSize::ARCH_64)
assetList.assets = m_stream.Alloc<XAsset>(4);
else
assetList.assets = m_stream.AllocOutOfBlock<XAsset>(4, assetList.assetCount);
#endif
varXAsset = assetList.assets;
LoadXAssetArray(true, assetList.assetCount);
@@ -327,8 +327,10 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
if (!inspectResult)
return nullptr;
const auto* variant = GameVariant::GetVariantById(inspectResult->m_generic_result.m_variant_id);
// Create new zone
auto zone = std::make_unique<Zone>(fileName, 0, inspectResult->m_generic_result.m_variant_id);
auto zone = std::make_unique<Zone>(fileName, 0, variant->GetId());
auto* zonePtr = zone.get();
zone->m_language = GameLanguage::LANGUAGE_NONE;
@@ -361,7 +363,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
zoneLoader->AddLoadingStep(step::CreateStepSkipBytes(1));
}
if (inspectResult->m_generic_result.m_variant_id != GameVariantId::IW4_XBOX)
if (variant->GetPlatform() == GamePlatform::PC)
{
// Start of the XFile struct
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneSizes());
@@ -373,7 +375,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
{
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
variant->GetWordSize() == GameWordSize::ARCH_64 ? 64u : 32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr,
+45 -16
View File
@@ -1,6 +1,7 @@
#include "ContentLoaderIW5.h"
#include "Game/IW5/AssetLoader_iw5_pc32.h"
#include "Game/IW5/AssetLoader_iw5_pc64.h"
#include "Game/IW5/IW5.h"
#include "Loading/Exception/UnsupportedAssetTypeException.h"
@@ -27,7 +28,10 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
#ifdef ARCH_x86
varScriptStringList->strings = m_stream.Alloc<const char*>(4);
#else
varScriptStringList->strings = m_stream.AllocOutOfBlock<const char*>(4, varScriptStringList->count);
if (m_word_size == GameWordSize::ARCH_64)
varScriptStringList->strings = m_stream.Alloc<const char*>(4);
else
varScriptStringList->strings = m_stream.AllocOutOfBlock<const char*>(4, varScriptStringList->count);
#endif
varXString = varScriptStringList->strings;
LoadXStringArray(true, varScriptStringList->count);
@@ -44,8 +48,16 @@ void ContentLoader::LoadXAsset(const bool atStreamStart) const
#define LOAD_ASSET(type_index, typeName, headerEntry) \
case type_index: \
{ \
Loader_##typeName##_pc32 loader(m_zone, m_stream); \
loader.Load(&varXAsset->header.headerEntry); \
if (m_word_size == GameWordSize::ARCH_64) \
{ \
Loader_##typeName##_pc64 loader(m_zone, m_stream); \
loader.Load(&varXAsset->header.headerEntry); \
} \
else \
{ \
Loader_##typeName##_pc32 loader(m_zone, m_stream); \
loader.Load(&varXAsset->header.headerEntry); \
} \
break; \
}
#define SKIP_ASSET(type_index) \
@@ -119,13 +131,20 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
#ifdef ARCH_x86
m_stream.Load<XAsset>(varXAsset, count);
#else
const auto fill = m_stream.LoadWithFill(8u * count);
for (size_t index = 0; index < count; index++)
if (m_word_size == GameWordSize::ARCH_64)
{
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));
m_stream.Load<XAsset>(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
}
@@ -149,13 +168,20 @@ void ContentLoader::Load()
#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);
if (m_word_size == GameWordSize::ARCH_64)
{
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);
fillAccessor.Fill(varXAssetList->assetCount, 8u);
fillAccessor.FillPtr(varXAssetList->assets, 12u);
}
#endif
m_stream.PushBlock(XFILE_BLOCK_VIRTUAL);
@@ -170,7 +196,10 @@ void ContentLoader::Load()
#ifdef ARCH_x86
assetList.assets = m_stream.Alloc<XAsset>(4);
#else
assetList.assets = m_stream.AllocOutOfBlock<XAsset>(4, assetList.assetCount);
if (m_word_size == GameWordSize::ARCH_64)
assetList.assets = m_stream.Alloc<XAsset>(4);
else
assetList.assets = m_stream.AllocOutOfBlock<XAsset>(4, assetList.assetCount);
#endif
varXAsset = assetList.assets;
LoadXAssetArray(true, assetList.assetCount);
@@ -240,8 +240,10 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
if (!inspectResult)
return nullptr;
const auto* variant = GameVariant::GetVariantById(inspectResult->m_variant_id);
// Create new zone
auto zone = std::make_unique<Zone>(fileName, 0, inspectResult->m_variant_id);
auto zone = std::make_unique<Zone>(fileName, 0, variant->GetId());
auto* zonePtr = zone.get();
zone->m_language = GameLanguage::LANGUAGE_NONE;
@@ -274,7 +276,7 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneDataPee
{
return std::make_unique<ContentLoader>(*zonePtr, stream);
},
32u,
variant->GetWordSize() == GameWordSize::ARCH_64 ? 64u : 32u,
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
ZoneConstants::INSERT_BLOCK,
zonePtr,
+13 -5
View File
@@ -7,6 +7,7 @@
ContentLoaderBase::ContentLoaderBase(Zone& zone, ZoneInputStream& stream)
: varXString(nullptr),
m_zone(zone),
m_word_size(GameVariant::GetVariantById(zone.m_variant_id)->GetWordSize()),
m_memory(zone.Memory()),
m_stream(stream),
@@ -51,12 +52,19 @@ void ContentLoaderBase::LoadXStringArray(const bool atStreamStart, const size_t
#else
if (atStreamStart)
{
const auto fill = m_stream.LoadWithFill(4u * count);
for (size_t index = 0; index < count; index++)
if (m_word_size == GameWordSize::ARCH_64)
{
fill.FillPtr(varXString[index], 4u * index);
m_stream.AddPointerLookup(&varXString[index], fill.BlockBuffer(4u * index));
m_stream.Load<const char*>(varXString, count);
}
else
{
const auto fill = m_stream.LoadWithFill(4u * count);
for (size_t index = 0; index < count; index++)
{
fill.FillPtr(varXString[index], 4u * index);
m_stream.AddPointerLookup(&varXString[index], fill.BlockBuffer(4u * index));
}
}
}
#endif
@@ -37,6 +37,7 @@ protected:
const char** varXString;
Zone& m_zone;
GameWordSize m_word_size;
MemoryManager& m_memory;
ZoneInputStream& m_stream;