mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-05-08 05:24:56 +00:00
chore: implement base skeleton for architecture independent zone loading
This commit is contained in:
parent
f802b4e130
commit
9425fe4775
@ -18,8 +18,9 @@ RenderingUsedType::RenderingUsedType(const DataDefinition* type, StructureInform
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderingContext::RenderingContext(std::string game, std::vector<const FastFileBlock*> fastFileBlocks)
|
RenderingContext::RenderingContext(std::string game, const Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks)
|
||||||
: m_game(std::move(game)),
|
: m_game(std::move(game)),
|
||||||
|
m_architecture_mismatch(gameArchitecture != OWN_ARCHITECTURE),
|
||||||
m_blocks(std::move(fastFileBlocks)),
|
m_blocks(std::move(fastFileBlocks)),
|
||||||
m_asset(nullptr),
|
m_asset(nullptr),
|
||||||
m_has_actions(false),
|
m_has_actions(false),
|
||||||
@ -190,7 +191,8 @@ bool RenderingContext::UsedTypeHasActions(const RenderingUsedType* usedType) con
|
|||||||
|
|
||||||
std::unique_ptr<RenderingContext> RenderingContext::BuildContext(const IDataRepository* repository, StructureInformation* asset)
|
std::unique_ptr<RenderingContext> RenderingContext::BuildContext(const IDataRepository* repository, StructureInformation* asset)
|
||||||
{
|
{
|
||||||
auto context = std::make_unique<RenderingContext>(RenderingContext(repository->GetGameName(), repository->GetAllFastFileBlocks()));
|
auto context =
|
||||||
|
std::make_unique<RenderingContext>(RenderingContext(repository->GetGameName(), repository->GetArchitecture(), repository->GetAllFastFileBlocks()));
|
||||||
|
|
||||||
context->MakeAsset(repository, asset);
|
context->MakeAsset(repository, asset);
|
||||||
context->CreateUsedTypeCollections();
|
context->CreateUsedTypeCollections();
|
||||||
|
@ -30,6 +30,7 @@ public:
|
|||||||
static std::unique_ptr<RenderingContext> BuildContext(const IDataRepository* repository, StructureInformation* asset);
|
static std::unique_ptr<RenderingContext> BuildContext(const IDataRepository* repository, StructureInformation* asset);
|
||||||
|
|
||||||
std::string m_game;
|
std::string m_game;
|
||||||
|
bool m_architecture_mismatch;
|
||||||
std::vector<const FastFileBlock*> m_blocks;
|
std::vector<const FastFileBlock*> m_blocks;
|
||||||
|
|
||||||
StructureInformation* m_asset;
|
StructureInformation* m_asset;
|
||||||
@ -43,7 +44,7 @@ public:
|
|||||||
const FastFileBlock* m_default_temp_block;
|
const FastFileBlock* m_default_temp_block;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
RenderingContext(std::string game, std::vector<const FastFileBlock*> fastFileBlocks);
|
RenderingContext(std::string game, Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks);
|
||||||
|
|
||||||
RenderingUsedType* AddUsedType(std::unique_ptr<RenderingUsedType> usedType);
|
RenderingUsedType* AddUsedType(std::unique_ptr<RenderingUsedType> usedType);
|
||||||
RenderingUsedType* GetBaseType(const IDataRepository* repository, MemberComputations* computations, RenderingUsedType* usedType);
|
RenderingUsedType* GetBaseType(const IDataRepository* repository, MemberComputations* computations, RenderingUsedType* usedType);
|
||||||
|
@ -60,6 +60,13 @@ namespace
|
|||||||
|
|
||||||
// Method Declarations
|
// Method Declarations
|
||||||
for (const auto* type : m_env.m_used_types)
|
for (const auto* type : m_env.m_used_types)
|
||||||
|
{
|
||||||
|
if (type->m_info && type->m_type == type->m_info->m_definition && !type->m_info->m_has_matching_cross_platform_structure)
|
||||||
|
{
|
||||||
|
PrintFillStructMethodDeclaration(type->m_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (const auto* type : m_env.m_used_types)
|
||||||
{
|
{
|
||||||
if (type->m_pointer_array_reference_exists)
|
if (type->m_pointer_array_reference_exists)
|
||||||
{
|
{
|
||||||
@ -149,6 +156,14 @@ namespace
|
|||||||
LINE("")
|
LINE("")
|
||||||
PrintMainLoadMethod();
|
PrintMainLoadMethod();
|
||||||
|
|
||||||
|
for (const auto* type : m_env.m_used_types)
|
||||||
|
{
|
||||||
|
if (type->m_info && type->m_type == type->m_info->m_definition && !type->m_info->m_has_matching_cross_platform_structure)
|
||||||
|
{
|
||||||
|
LINE("")
|
||||||
|
PrintFillStructMethod(type->m_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
for (const auto* type : m_env.m_used_types)
|
for (const auto* type : m_env.m_used_types)
|
||||||
{
|
{
|
||||||
if (type->m_pointer_array_reference_exists)
|
if (type->m_pointer_array_reference_exists)
|
||||||
@ -212,6 +227,11 @@ namespace
|
|||||||
return std::format("{0}** var{1}Ptr;", def->GetFullName(), MakeSafeTypeName(def));
|
return std::format("{0}** var{1}Ptr;", def->GetFullName(), MakeSafeTypeName(def));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintFillStructMethodDeclaration(const StructureInformation* info)
|
||||||
|
{
|
||||||
|
LINEF("void FillStruct_{1}(const ZoneStreamFillReadAccessor& fillAccessor);", LoaderClassName(m_env.m_asset), MakeSafeTypeName(info->m_definition))
|
||||||
|
}
|
||||||
|
|
||||||
void PrintHeaderPtrArrayLoadMethodDeclaration(const DataDefinition* def) const
|
void PrintHeaderPtrArrayLoadMethodDeclaration(const DataDefinition* def) const
|
||||||
{
|
{
|
||||||
LINEF("void LoadPtrArray_{0}(bool atStreamStart, size_t count);", MakeSafeTypeName(def))
|
LINEF("void LoadPtrArray_{0}(bool atStreamStart, size_t count);", MakeSafeTypeName(def))
|
||||||
@ -297,6 +317,28 @@ namespace
|
|||||||
LINE("}")
|
LINE("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PrintFillStructMethod(const StructureInformation* info)
|
||||||
|
{
|
||||||
|
LINEF("void {0}::FillStruct_{1}(const ZoneStreamFillReadAccessor& fillAccessor)",
|
||||||
|
LoaderClassName(m_env.m_asset),
|
||||||
|
MakeSafeTypeName(info->m_definition))
|
||||||
|
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
for (const auto& member : info->m_ordered_members)
|
||||||
|
{
|
||||||
|
const MemberComputations computations(member.get());
|
||||||
|
if (computations.ShouldIgnore())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
LINEF("// FillStruct_{0}();", MakeSafeTypeName(member->m_member->m_type_declaration->m_type))
|
||||||
|
}
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
|
||||||
void PrintLoadPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const
|
void PrintLoadPtrArrayMethod_Loading(const DataDefinition* def, const StructureInformation* info) const
|
||||||
{
|
{
|
||||||
LINEF("*{0} = m_stream->Alloc<{1}>({2});", MakeTypePtrVarName(def), def->GetFullName(), def->GetAlignment())
|
LINEF("*{0} = m_stream->Alloc<{1}>({2});", MakeTypePtrVarName(def), def->GetFullName(), def->GetAlignment())
|
||||||
@ -339,7 +381,7 @@ namespace
|
|||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
LINEF("*{0} = m_stream->ConvertOffsetToPointer(*{0});", MakeTypePtrVarName(def))
|
LINEF("*{0} = m_stream->ConvertOffsetToPointerNative(*{0});", MakeTypePtrVarName(def))
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
LINE("}")
|
LINE("}")
|
||||||
@ -765,7 +807,7 @@ namespace
|
|||||||
LINEF("{0}** toInsert = nullptr;", member->m_member->m_type_declaration->m_type->GetFullName())
|
LINEF("{0}** toInsert = nullptr;", member->m_member->m_type_declaration->m_type->GetFullName())
|
||||||
LINE("if (ptr == PTR_INSERT)")
|
LINE("if (ptr == PTR_INSERT)")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
LINEF("toInsert = m_stream->InsertPointer<{0}>();", member->m_member->m_type_declaration->m_type->GetFullName())
|
LINEF("toInsert = m_stream->InsertPointerNative<{0}>();", member->m_member->m_type_declaration->m_type->GetFullName())
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
LINE("")
|
LINE("")
|
||||||
}
|
}
|
||||||
@ -823,7 +865,7 @@ namespace
|
|||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
LINEF("{0} = m_stream->ConvertOffsetToAlias({0});", MakeMemberAccess(info, member, modifier))
|
LINEF("{0} = m_stream->ConvertOffsetToAliasNative({0});", MakeMemberAccess(info, member, modifier))
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
LINE("}")
|
LINE("}")
|
||||||
@ -842,7 +884,7 @@ namespace
|
|||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
LINEF("{0} = m_stream->ConvertOffsetToPointer({0});", MakeMemberAccess(info, member, modifier))
|
LINEF("{0} = m_stream->ConvertOffsetToPointerNative({0});", MakeMemberAccess(info, member, modifier))
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
LINE("}")
|
LINE("}")
|
||||||
@ -1080,6 +1122,9 @@ namespace
|
|||||||
{
|
{
|
||||||
LINE("")
|
LINE("")
|
||||||
LINE("if (atStreamStart)")
|
LINE("if (atStreamStart)")
|
||||||
|
|
||||||
|
if (info->m_has_matching_cross_platform_structure)
|
||||||
|
{
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
if (dynamicMember == nullptr)
|
if (dynamicMember == nullptr)
|
||||||
@ -1100,6 +1145,18 @@ namespace
|
|||||||
m_intendation--;
|
m_intendation--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
LINEF("{0} = m_memory.Alloc<{1}>();", MakeTypeVarName(info->m_definition), info->m_definition->m_name)
|
||||||
|
LINEF("FillStruct_{0}(m_stream->LoadWithFill({1}));", MakeSafeTypeName(info->m_definition), info->m_definition->GetSize())
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
LINE("assert(atStreamStart);")
|
LINE("assert(atStreamStart);")
|
||||||
}
|
}
|
||||||
@ -1182,7 +1239,7 @@ namespace
|
|||||||
LINEF("{0}** toInsert = nullptr;", info->m_definition->GetFullName())
|
LINEF("{0}** toInsert = nullptr;", info->m_definition->GetFullName())
|
||||||
LINE("if (ptr == PTR_INSERT)")
|
LINE("if (ptr == PTR_INSERT)")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
LINEF("toInsert = m_stream->InsertPointer<{0}>();", info->m_definition->GetFullName())
|
LINEF("toInsert = m_stream->InsertPointerNative<{0}>();", info->m_definition->GetFullName())
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1236,11 +1293,11 @@ namespace
|
|||||||
|
|
||||||
if (inTemp)
|
if (inTemp)
|
||||||
{
|
{
|
||||||
LINEF("*{0} = m_stream->ConvertOffsetToAlias(*{0});", MakeTypePtrVarName(info->m_definition))
|
LINEF("*{0} = m_stream->ConvertOffsetToAliasNative(*{0});", MakeTypePtrVarName(info->m_definition))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LINEF("*{0} = m_stream->ConvertOffsetToPointer(*{0});", MakeTypePtrVarName(info->m_definition))
|
LINEF("*{0} = m_stream->ConvertOffsetToPointerNative(*{0});", MakeTypePtrVarName(info->m_definition))
|
||||||
}
|
}
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
|
@ -20,7 +20,7 @@ namespace IW3
|
|||||||
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
||||||
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
||||||
|
|
||||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 4;
|
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 4u;
|
||||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||||
};
|
};
|
||||||
} // namespace IW3
|
} // namespace IW3
|
||||||
|
@ -43,7 +43,7 @@ namespace IW4
|
|||||||
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
||||||
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
||||||
|
|
||||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 4;
|
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 4u;
|
||||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||||
};
|
};
|
||||||
} // namespace IW4
|
} // namespace IW4
|
||||||
|
@ -40,7 +40,7 @@ namespace IW5
|
|||||||
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
||||||
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
||||||
|
|
||||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 4;
|
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 4u;
|
||||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||||
};
|
};
|
||||||
} // namespace IW5
|
} // namespace IW5
|
||||||
|
@ -20,7 +20,7 @@ namespace T5
|
|||||||
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
static constexpr size_t AUTHED_CHUNK_SIZE = 0x2000;
|
||||||
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
static constexpr unsigned AUTHED_CHUNK_COUNT_PER_GROUP = 256;
|
||||||
|
|
||||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 3;
|
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 3u;
|
||||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||||
};
|
};
|
||||||
} // namespace T5
|
} // namespace T5
|
||||||
|
@ -27,7 +27,7 @@ namespace T6
|
|||||||
static constexpr int XCHUNK_SIZE = 0x8000;
|
static constexpr int XCHUNK_SIZE = 0x8000;
|
||||||
static constexpr int XCHUNK_MAX_WRITE_SIZE = XCHUNK_SIZE - 0x40;
|
static constexpr int XCHUNK_MAX_WRITE_SIZE = XCHUNK_SIZE - 0x40;
|
||||||
static constexpr int VANILLA_BUFFER_SIZE = 0x80000;
|
static constexpr int VANILLA_BUFFER_SIZE = 0x80000;
|
||||||
static constexpr int OFFSET_BLOCK_BIT_COUNT = 3;
|
static constexpr unsigned OFFSET_BLOCK_BIT_COUNT = 3u;
|
||||||
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
static constexpr block_t INSERT_BLOCK = XFILE_BLOCK_VIRTUAL;
|
||||||
|
|
||||||
static constexpr size_t FILE_SUFFIX_ZERO_MIN_SIZE = 0x40;
|
static constexpr size_t FILE_SUFFIX_ZERO_MIN_SIZE = 0x40;
|
||||||
|
@ -32,8 +32,8 @@
|
|||||||
|
|
||||||
using namespace IW3;
|
using namespace IW3;
|
||||||
|
|
||||||
ContentLoader::ContentLoader(Zone& zone)
|
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||||
: ContentLoaderBase(zone),
|
: ContentLoaderBase(zone, stream),
|
||||||
varXAsset(nullptr),
|
varXAsset(nullptr),
|
||||||
varScriptStringList(nullptr)
|
varScriptStringList(nullptr)
|
||||||
{
|
{
|
||||||
@ -134,10 +134,8 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLoader::Load(ZoneInputStream& stream)
|
void ContentLoader::Load()
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
XAssetList assetList{};
|
XAssetList assetList{};
|
||||||
|
@ -9,9 +9,8 @@ namespace IW3
|
|||||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ContentLoader(Zone& zone);
|
ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||||
|
void Load() override;
|
||||||
void Load(ZoneInputStream& stream) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadScriptStringList(bool atStreamStart);
|
void LoadScriptStringList(bool atStreamStart);
|
||||||
|
@ -85,8 +85,14 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
|||||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||||
|
|
||||||
// Start of the zone content
|
// Start of the zone content
|
||||||
zoneLoader->AddLoadingStep(
|
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
[&zonePtr](ZoneInputStream& stream)
|
||||||
|
{
|
||||||
|
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||||
|
},
|
||||||
|
32u,
|
||||||
|
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||||
|
ZoneConstants::INSERT_BLOCK));
|
||||||
|
|
||||||
return zoneLoader;
|
return zoneLoader;
|
||||||
}
|
}
|
||||||
|
@ -42,25 +42,38 @@
|
|||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
|
|
||||||
ContentLoader::ContentLoader(Zone& zone)
|
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||||
: ContentLoaderBase(zone),
|
: ContentLoaderBase(zone, stream),
|
||||||
|
varXAssetList(nullptr),
|
||||||
varXAsset(nullptr),
|
varXAsset(nullptr),
|
||||||
varScriptStringList(nullptr)
|
varScriptStringList(nullptr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ContentLoader::FillStruct_XAssetList(const ZoneStreamFillReadAccessor& fillAccessor)
|
||||||
|
{
|
||||||
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
FillStruct_ScriptStringList(fillAccessor.AtOffset(0u));
|
||||||
|
|
||||||
|
fillAccessor.Fill(varXAssetList->assetCount, 8u);
|
||||||
|
fillAccessor.FillPtr(varXAssetList->assets, 12u);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ContentLoader::FillStruct_ScriptStringList(const ZoneStreamFillReadAccessor& fillAccessor) const
|
||||||
|
{
|
||||||
|
fillAccessor.Fill(varScriptStringList->count, 0u);
|
||||||
|
fillAccessor.FillPtr(varScriptStringList->strings, 4u);
|
||||||
|
}
|
||||||
|
|
||||||
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
assert(!atStreamStart);
|
||||||
|
|
||||||
if (atStreamStart)
|
|
||||||
m_stream->Load<ScriptStringList>(varScriptStringList);
|
|
||||||
|
|
||||||
if (varScriptStringList->strings != nullptr)
|
if (varScriptStringList->strings != nullptr)
|
||||||
{
|
{
|
||||||
assert(varScriptStringList->strings == PTR_FOLLOWING);
|
assert(varScriptStringList->strings == PTR_FOLLOWING);
|
||||||
|
|
||||||
varScriptStringList->strings = m_stream->Alloc<const char*>(alignof(const char*));
|
varScriptStringList->strings = m_stream->Alloc<const char*>(4);
|
||||||
varXString = varScriptStringList->strings;
|
varXString = varScriptStringList->strings;
|
||||||
LoadXStringArray(true, varScriptStringList->count);
|
LoadXStringArray(true, varScriptStringList->count);
|
||||||
|
|
||||||
@ -68,8 +81,6 @@ void ContentLoader::LoadScriptStringList(const bool atStreamStart)
|
|||||||
m_zone.m_script_strings.InitializeForExistingZone(varScriptStringList->strings, static_cast<size_t>(varScriptStringList->count));
|
m_zone.m_script_strings.InitializeForExistingZone(varScriptStringList->strings, static_cast<size_t>(varScriptStringList->count));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
|
||||||
|
|
||||||
assert(m_zone.m_script_strings.Count() <= SCR_STRING_MAX + 1);
|
assert(m_zone.m_script_strings.Count() <= SCR_STRING_MAX + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,15 +165,15 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLoader::Load(ZoneInputStream& stream)
|
void ContentLoader::Load()
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
XAssetList assetList{};
|
||||||
|
varXAssetList = &assetList;
|
||||||
|
|
||||||
|
FillStruct_XAssetList(m_stream->LoadWithFill(16u));
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
XAssetList assetList{};
|
|
||||||
m_stream->LoadDataRaw(&assetList, sizeof(assetList));
|
|
||||||
|
|
||||||
varScriptStringList = &assetList.stringList;
|
varScriptStringList = &assetList.stringList;
|
||||||
LoadScriptStringList(false);
|
LoadScriptStringList(false);
|
||||||
|
|
||||||
|
@ -9,16 +9,19 @@ namespace IW4
|
|||||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ContentLoader(Zone& zone);
|
explicit ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||||
|
void Load() override;
|
||||||
void Load(ZoneInputStream& stream) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void FillStruct_XAssetList(const ZoneStreamFillReadAccessor& fillAccessor);
|
||||||
|
void FillStruct_ScriptStringList(const ZoneStreamFillReadAccessor& fillAccessor) const;
|
||||||
|
|
||||||
void LoadScriptStringList(bool atStreamStart);
|
void LoadScriptStringList(bool atStreamStart);
|
||||||
|
|
||||||
void LoadXAsset(bool atStreamStart) const;
|
void LoadXAsset(bool atStreamStart) const;
|
||||||
void LoadXAssetArray(bool atStreamStart, size_t count);
|
void LoadXAssetArray(bool atStreamStart, size_t count);
|
||||||
|
|
||||||
|
XAssetList* varXAssetList;
|
||||||
XAsset* varXAsset;
|
XAsset* varXAsset;
|
||||||
ScriptStringList* varScriptStringList;
|
ScriptStringList* varScriptStringList;
|
||||||
};
|
};
|
||||||
|
@ -207,8 +207,14 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
|||||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||||
|
|
||||||
// Start of the zone content
|
// Start of the zone content
|
||||||
zoneLoader->AddLoadingStep(
|
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
[&zonePtr](ZoneInputStream& stream)
|
||||||
|
{
|
||||||
|
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||||
|
},
|
||||||
|
32u,
|
||||||
|
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||||
|
ZoneConstants::INSERT_BLOCK));
|
||||||
|
|
||||||
return zoneLoader;
|
return zoneLoader;
|
||||||
}
|
}
|
||||||
|
@ -47,8 +47,8 @@
|
|||||||
|
|
||||||
using namespace IW5;
|
using namespace IW5;
|
||||||
|
|
||||||
ContentLoader::ContentLoader(Zone& zone)
|
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||||
: ContentLoaderBase(zone),
|
: ContentLoaderBase(zone, stream),
|
||||||
varXAsset(nullptr),
|
varXAsset(nullptr),
|
||||||
varScriptStringList(nullptr)
|
varScriptStringList(nullptr)
|
||||||
{
|
{
|
||||||
@ -163,10 +163,8 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLoader::Load(ZoneInputStream& stream)
|
void ContentLoader::Load()
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
XAssetList assetList{};
|
XAssetList assetList{};
|
||||||
|
@ -9,9 +9,8 @@ namespace IW5
|
|||||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ContentLoader(Zone& zone);
|
explicit ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||||
|
void Load() override;
|
||||||
void Load(ZoneInputStream& stream) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadScriptStringList(bool atStreamStart);
|
void LoadScriptStringList(bool atStreamStart);
|
||||||
|
@ -184,8 +184,14 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
|||||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||||
|
|
||||||
// Start of the zone content
|
// Start of the zone content
|
||||||
zoneLoader->AddLoadingStep(
|
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
[&zonePtr](ZoneInputStream& stream)
|
||||||
|
{
|
||||||
|
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||||
|
},
|
||||||
|
32u,
|
||||||
|
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||||
|
ZoneConstants::INSERT_BLOCK));
|
||||||
|
|
||||||
return zoneLoader;
|
return zoneLoader;
|
||||||
}
|
}
|
||||||
|
@ -39,8 +39,8 @@
|
|||||||
|
|
||||||
using namespace T5;
|
using namespace T5;
|
||||||
|
|
||||||
ContentLoader::ContentLoader(Zone& zone)
|
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||||
: ContentLoaderBase(zone),
|
: ContentLoaderBase(zone, stream),
|
||||||
varXAsset(nullptr),
|
varXAsset(nullptr),
|
||||||
varScriptStringList(nullptr)
|
varScriptStringList(nullptr)
|
||||||
{
|
{
|
||||||
@ -147,10 +147,8 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLoader::Load(ZoneInputStream& stream)
|
void ContentLoader::Load()
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
XAssetList assetList{};
|
XAssetList assetList{};
|
||||||
|
@ -9,9 +9,8 @@ namespace T5
|
|||||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ContentLoader(Zone& zone);
|
explicit ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||||
|
void Load() override;
|
||||||
void Load(ZoneInputStream& stream) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadScriptStringList(bool atStreamStart);
|
void LoadScriptStringList(bool atStreamStart);
|
||||||
|
@ -85,8 +85,14 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
|||||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||||
|
|
||||||
// Start of the zone content
|
// Start of the zone content
|
||||||
zoneLoader->AddLoadingStep(
|
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
[&zonePtr](ZoneInputStream& stream)
|
||||||
|
{
|
||||||
|
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||||
|
},
|
||||||
|
32u,
|
||||||
|
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||||
|
ZoneConstants::INSERT_BLOCK));
|
||||||
|
|
||||||
return zoneLoader;
|
return zoneLoader;
|
||||||
}
|
}
|
||||||
|
@ -55,8 +55,8 @@
|
|||||||
|
|
||||||
using namespace T6;
|
using namespace T6;
|
||||||
|
|
||||||
ContentLoader::ContentLoader(Zone& zone)
|
ContentLoader::ContentLoader(Zone& zone, ZoneInputStream& stream)
|
||||||
: ContentLoaderBase(zone),
|
: ContentLoaderBase(zone, stream),
|
||||||
varXAsset(nullptr),
|
varXAsset(nullptr),
|
||||||
varScriptStringList(nullptr)
|
varScriptStringList(nullptr)
|
||||||
{
|
{
|
||||||
@ -176,10 +176,8 @@ void ContentLoader::LoadXAssetArray(const bool atStreamStart, const size_t count
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentLoader::Load(ZoneInputStream& stream)
|
void ContentLoader::Load()
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
XAssetList assetList{};
|
XAssetList assetList{};
|
||||||
|
@ -9,9 +9,8 @@ namespace T6
|
|||||||
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
class ContentLoader final : public ContentLoaderBase, public IContentLoadingEntryPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
explicit ContentLoader(Zone& zone);
|
explicit ContentLoader(Zone& zone, ZoneInputStream& stream);
|
||||||
|
void Load() override;
|
||||||
void Load(ZoneInputStream& stream) override;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void LoadScriptStringList(bool atStreamStart);
|
void LoadScriptStringList(bool atStreamStart);
|
||||||
|
@ -203,8 +203,14 @@ std::unique_ptr<ZoneLoader> ZoneLoaderFactory::CreateLoaderForHeader(ZoneHeader&
|
|||||||
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
zoneLoader->AddLoadingStep(step::CreateStepAllocXBlocks());
|
||||||
|
|
||||||
// Start of the zone content
|
// Start of the zone content
|
||||||
zoneLoader->AddLoadingStep(
|
zoneLoader->AddLoadingStep(step::CreateStepLoadZoneContent(
|
||||||
step::CreateStepLoadZoneContent(std::make_unique<ContentLoader>(*zonePtr), ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK));
|
[&zonePtr](ZoneInputStream& stream)
|
||||||
|
{
|
||||||
|
return std::make_unique<ContentLoader>(*zonePtr, stream);
|
||||||
|
},
|
||||||
|
32u,
|
||||||
|
ZoneConstants::OFFSET_BLOCK_BIT_COUNT,
|
||||||
|
ZoneConstants::INSERT_BLOCK));
|
||||||
|
|
||||||
if (isSecure)
|
if (isSecure)
|
||||||
{
|
{
|
||||||
|
@ -5,14 +5,6 @@
|
|||||||
const void* ContentLoaderBase::PTR_FOLLOWING = reinterpret_cast<void*>(-1);
|
const void* ContentLoaderBase::PTR_FOLLOWING = reinterpret_cast<void*>(-1);
|
||||||
const void* ContentLoaderBase::PTR_INSERT = reinterpret_cast<void*>(-2);
|
const void* ContentLoaderBase::PTR_INSERT = reinterpret_cast<void*>(-2);
|
||||||
|
|
||||||
ContentLoaderBase::ContentLoaderBase(Zone& zone)
|
|
||||||
: varXString(nullptr),
|
|
||||||
m_zone(zone),
|
|
||||||
m_memory(zone.Memory()),
|
|
||||||
m_stream(nullptr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
ContentLoaderBase::ContentLoaderBase(Zone& zone, ZoneInputStream& stream)
|
ContentLoaderBase::ContentLoaderBase(Zone& zone, ZoneInputStream& stream)
|
||||||
: varXString(nullptr),
|
: varXString(nullptr),
|
||||||
m_zone(zone),
|
m_zone(zone),
|
||||||
@ -37,7 +29,7 @@ void ContentLoaderBase::LoadXString(const bool atStreamStart) const
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*varXString = m_stream->ConvertOffsetToPointer<const char>(*varXString);
|
*varXString = m_stream->ConvertOffsetToPointerNative<const char>(*varXString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,6 @@ public:
|
|||||||
ContentLoaderBase& operator=(ContentLoaderBase&& other) noexcept = delete;
|
ContentLoaderBase& operator=(ContentLoaderBase&& other) noexcept = delete;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
explicit ContentLoaderBase(Zone& zone);
|
|
||||||
ContentLoaderBase(Zone& zone, ZoneInputStream& stream);
|
ContentLoaderBase(Zone& zone, ZoneInputStream& stream);
|
||||||
|
|
||||||
void LoadXString(bool atStreamStart) const;
|
void LoadXString(bool atStreamStart) const;
|
||||||
@ -27,5 +26,5 @@ protected:
|
|||||||
|
|
||||||
Zone& m_zone;
|
Zone& m_zone;
|
||||||
MemoryManager& m_memory;
|
MemoryManager& m_memory;
|
||||||
ZoneInputStream* m_stream;
|
ZoneInputStream* m_stream; // TODO: Change this to reference
|
||||||
};
|
};
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Zone/Stream/ZoneInputStream.h"
|
|
||||||
|
|
||||||
class IContentLoadingEntryPoint
|
class IContentLoadingEntryPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -12,5 +10,5 @@ public:
|
|||||||
IContentLoadingEntryPoint& operator=(const IContentLoadingEntryPoint& other) = default;
|
IContentLoadingEntryPoint& operator=(const IContentLoadingEntryPoint& other) = default;
|
||||||
IContentLoadingEntryPoint& operator=(IContentLoadingEntryPoint&& other) noexcept = default;
|
IContentLoadingEntryPoint& operator=(IContentLoadingEntryPoint&& other) noexcept = default;
|
||||||
|
|
||||||
virtual void Load(ZoneInputStream& stream) = 0;
|
virtual void Load() = 0;
|
||||||
};
|
};
|
||||||
|
@ -7,8 +7,12 @@ namespace
|
|||||||
class StepLoadZoneContent final : public ILoadingStep
|
class StepLoadZoneContent final : public ILoadingStep
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StepLoadZoneContent(std::unique_ptr<IContentLoadingEntryPoint> entryPoint, const int offsetBlockBitCount, const block_t insertBlock)
|
StepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||||
: m_content_loader(std::move(entryPoint)),
|
const unsigned pointerBitCount,
|
||||||
|
const unsigned offsetBlockBitCount,
|
||||||
|
const block_t insertBlock)
|
||||||
|
: m_entry_point_factory(std::move(entryPointFactory)),
|
||||||
|
m_pointer_bit_count(pointerBitCount),
|
||||||
m_offset_block_bit_count(offsetBlockBitCount),
|
m_offset_block_bit_count(offsetBlockBitCount),
|
||||||
m_insert_block(insertBlock)
|
m_insert_block(insertBlock)
|
||||||
{
|
{
|
||||||
@ -16,23 +20,29 @@ namespace
|
|||||||
|
|
||||||
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
|
void PerformStep(ZoneLoader& zoneLoader, ILoadingStream& stream) override
|
||||||
{
|
{
|
||||||
const auto inputStream = ZoneInputStream::Create(zoneLoader.m_blocks, stream, m_offset_block_bit_count, m_insert_block);
|
const auto inputStream = ZoneInputStream::Create(m_pointer_bit_count, m_offset_block_bit_count, zoneLoader.m_blocks, m_insert_block, stream);
|
||||||
|
|
||||||
m_content_loader->Load(*inputStream);
|
const auto entryPoint = m_entry_point_factory(*inputStream);
|
||||||
|
assert(entryPoint);
|
||||||
|
|
||||||
|
entryPoint->Load();
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::unique_ptr<IContentLoadingEntryPoint> m_content_loader;
|
std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> m_entry_point_factory;
|
||||||
int m_offset_block_bit_count;
|
unsigned m_pointer_bit_count;
|
||||||
|
unsigned m_offset_block_bit_count;
|
||||||
block_t m_insert_block;
|
block_t m_insert_block;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace step
|
namespace step
|
||||||
{
|
{
|
||||||
std::unique_ptr<ILoadingStep>
|
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||||
CreateStepLoadZoneContent(std::unique_ptr<IContentLoadingEntryPoint> entryPoint, const int offsetBlockBitCount, const block_t insertBlock)
|
const unsigned pointerBitCount,
|
||||||
|
const unsigned offsetBlockBitCount,
|
||||||
|
const block_t insertBlock)
|
||||||
{
|
{
|
||||||
return std::make_unique<StepLoadZoneContent>(std::move(entryPoint), offsetBlockBitCount, insertBlock);
|
return std::make_unique<StepLoadZoneContent>(std::move(entryPointFactory), pointerBitCount, offsetBlockBitCount, insertBlock);
|
||||||
}
|
}
|
||||||
} // namespace step
|
} // namespace step
|
||||||
|
@ -2,11 +2,15 @@
|
|||||||
|
|
||||||
#include "Loading/IContentLoadingEntryPoint.h"
|
#include "Loading/IContentLoadingEntryPoint.h"
|
||||||
#include "Loading/ILoadingStep.h"
|
#include "Loading/ILoadingStep.h"
|
||||||
|
#include "Zone/Stream/ZoneInputStream.h"
|
||||||
|
|
||||||
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace step
|
namespace step
|
||||||
{
|
{
|
||||||
std::unique_ptr<ILoadingStep>
|
std::unique_ptr<ILoadingStep> CreateStepLoadZoneContent(std::function<std::unique_ptr<IContentLoadingEntryPoint>(ZoneInputStream&)> entryPointFactory,
|
||||||
CreateStepLoadZoneContent(std::unique_ptr<IContentLoadingEntryPoint> entryPoint, int offsetBlockBitCount, block_t insertBlock);
|
unsigned pointerBitCount,
|
||||||
|
unsigned offsetBlockBitCount,
|
||||||
|
block_t insertBlock);
|
||||||
}
|
}
|
||||||
|
@ -10,22 +10,38 @@
|
|||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
|
||||||
|
ZoneStreamFillReadAccessor::ZoneStreamFillReadAccessor(const void* buffer, const size_t bufferSize, const unsigned pointerByteCount)
|
||||||
|
: m_buffer(buffer),
|
||||||
|
m_buffer_size(bufferSize),
|
||||||
|
m_pointer_byte_count(pointerByteCount)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneStreamFillReadAccessor ZoneStreamFillReadAccessor::AtOffset(const size_t offset) const
|
||||||
|
{
|
||||||
|
assert(offset < m_buffer_size);
|
||||||
|
return ZoneStreamFillReadAccessor(static_cast<const char*>(m_buffer) + offset, m_buffer_size - offset, m_pointer_byte_count);
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
class XBlockInputStream final : public ZoneInputStream
|
class XBlockInputStream final : public ZoneInputStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
XBlockInputStream(std::vector<XBlock*>& blocks, ILoadingStream& stream, const unsigned blockBitCount, const block_t insertBlock)
|
XBlockInputStream(
|
||||||
|
const unsigned pointerBitCount, const unsigned blockBitCount, std::vector<XBlock*>& blocks, const block_t insertBlock, ILoadingStream& stream)
|
||||||
: m_blocks(blocks),
|
: m_blocks(blocks),
|
||||||
m_stream(stream)
|
m_stream(stream),
|
||||||
|
m_pointer_byte_count(pointerBitCount / 8u),
|
||||||
|
m_block_bit_count(blockBitCount)
|
||||||
{
|
{
|
||||||
|
assert(pointerBitCount % 8u == 0u);
|
||||||
|
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
||||||
|
|
||||||
const auto blockCount = static_cast<unsigned>(blocks.size());
|
const auto blockCount = static_cast<unsigned>(blocks.size());
|
||||||
m_block_offsets = std::make_unique<size_t[]>(blockCount);
|
m_block_offsets = std::make_unique<size_t[]>(blockCount);
|
||||||
std::memset(m_block_offsets.get(), 0, sizeof(size_t) * blockCount);
|
std::memset(m_block_offsets.get(), 0, sizeof(size_t) * blockCount);
|
||||||
|
|
||||||
m_block_bit_count = blockBitCount;
|
|
||||||
|
|
||||||
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
|
||||||
m_insert_block = blocks[insertBlock];
|
m_insert_block = blocks[insertBlock];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,11 +103,9 @@ namespace
|
|||||||
|
|
||||||
void LoadDataInBlock(void* dst, const size_t size) override
|
void LoadDataInBlock(void* dst, const size_t size) override
|
||||||
{
|
{
|
||||||
assert(!m_block_stack.empty());
|
// If no block has been pushed, load raw
|
||||||
|
if (!m_block_stack.empty())
|
||||||
if (m_block_stack.empty())
|
{
|
||||||
return;
|
|
||||||
|
|
||||||
auto* block = m_block_stack.top();
|
auto* block = m_block_stack.top();
|
||||||
|
|
||||||
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst)
|
if (block->m_buffer > dst || block->m_buffer + block->m_buffer_size < dst)
|
||||||
@ -111,7 +125,7 @@ namespace
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case XBlock::Type::BLOCK_TYPE_RUNTIME:
|
case XBlock::Type::BLOCK_TYPE_RUNTIME:
|
||||||
memset(dst, 0, size);
|
std::memset(dst, 0, size);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case XBlock::Type::BLOCK_TYPE_DELAY:
|
case XBlock::Type::BLOCK_TYPE_DELAY:
|
||||||
@ -121,16 +135,10 @@ namespace
|
|||||||
|
|
||||||
IncBlockPos(size);
|
IncBlockPos(size);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
void IncBlockPos(const size_t size) override
|
|
||||||
{
|
{
|
||||||
assert(!m_block_stack.empty());
|
m_stream.Load(dst, size);
|
||||||
|
}
|
||||||
if (m_block_stack.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
const auto* block = m_block_stack.top();
|
|
||||||
m_block_offsets[block->m_index] += size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void LoadNullTerminated(void* dst) override
|
void LoadNullTerminated(void* dst) override
|
||||||
@ -162,25 +170,61 @@ namespace
|
|||||||
m_block_offsets[block->m_index] = offset;
|
m_block_offsets[block->m_index] = offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
void** InsertPointer() override
|
ZoneStreamFillReadAccessor LoadWithFill(const size_t size) override
|
||||||
|
{
|
||||||
|
m_fill_buffer.reserve(size);
|
||||||
|
auto* dst = m_fill_buffer.data();
|
||||||
|
|
||||||
|
// If no block has been pushed, load raw
|
||||||
|
if (!m_block_stack.empty())
|
||||||
|
{
|
||||||
|
const auto* block = m_block_stack.top();
|
||||||
|
switch (block->m_type)
|
||||||
|
{
|
||||||
|
case XBlock::Type::BLOCK_TYPE_TEMP:
|
||||||
|
case XBlock::Type::BLOCK_TYPE_NORMAL:
|
||||||
|
m_stream.Load(dst, size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XBlock::Type::BLOCK_TYPE_RUNTIME:
|
||||||
|
std::memset(dst, 0, size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XBlock::Type::BLOCK_TYPE_DELAY:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IncBlockPos(size);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_stream.Load(dst, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZoneStreamFillReadAccessor(dst, size, m_pointer_byte_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* InsertPointer() override
|
||||||
{
|
{
|
||||||
m_block_stack.push(m_insert_block);
|
m_block_stack.push(m_insert_block);
|
||||||
|
|
||||||
Align(alignof(void*));
|
// Alignment of pointer should always be its size
|
||||||
|
Align(m_pointer_byte_count);
|
||||||
|
|
||||||
if (m_block_offsets[m_insert_block->m_index] + sizeof(void*) > m_insert_block->m_buffer_size)
|
if (m_block_offsets[m_insert_block->m_index] + m_pointer_byte_count > m_insert_block->m_buffer_size)
|
||||||
throw BlockOverflowException(m_insert_block);
|
throw BlockOverflowException(m_insert_block);
|
||||||
|
|
||||||
auto* ptr = reinterpret_cast<void**>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
auto* ptr = static_cast<void*>(&m_insert_block->m_buffer[m_block_offsets[m_insert_block->m_index]]);
|
||||||
|
|
||||||
IncBlockPos(sizeof(void*));
|
IncBlockPos(m_pointer_byte_count);
|
||||||
|
|
||||||
m_block_stack.pop();
|
m_block_stack.pop();
|
||||||
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ConvertOffsetToPointer(const void* offset) override
|
void* ConvertOffsetToPointerNative(const void* offset) override
|
||||||
{
|
{
|
||||||
// -1 because otherwise Block 0 Offset 0 would be just 0 which is already used to signalize a nullptr.
|
// -1 because otherwise Block 0 Offset 0 would be just 0 which is already used to signalize a nullptr.
|
||||||
// So all offsets are moved by 1.
|
// So all offsets are moved by 1.
|
||||||
@ -200,7 +244,7 @@ namespace
|
|||||||
return &block->m_buffer[blockOffset];
|
return &block->m_buffer[blockOffset];
|
||||||
}
|
}
|
||||||
|
|
||||||
void* ConvertOffsetToAlias(const void* offset) override
|
void* ConvertOffsetToAliasNative(const void* offset) override
|
||||||
{
|
{
|
||||||
// For details see ConvertOffsetToPointer
|
// For details see ConvertOffsetToPointer
|
||||||
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
const auto offsetInt = reinterpret_cast<uintptr_t>(offset) - 1u;
|
||||||
@ -220,6 +264,17 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void IncBlockPos(const size_t size)
|
||||||
|
{
|
||||||
|
assert(!m_block_stack.empty());
|
||||||
|
|
||||||
|
if (m_block_stack.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto* block = m_block_stack.top();
|
||||||
|
m_block_offsets[block->m_index] += size;
|
||||||
|
}
|
||||||
|
|
||||||
void Align(const unsigned align)
|
void Align(const unsigned align)
|
||||||
{
|
{
|
||||||
assert(!m_block_stack.empty());
|
assert(!m_block_stack.empty());
|
||||||
@ -238,12 +293,16 @@ namespace
|
|||||||
std::stack<size_t> m_temp_offsets;
|
std::stack<size_t> m_temp_offsets;
|
||||||
ILoadingStream& m_stream;
|
ILoadingStream& m_stream;
|
||||||
|
|
||||||
|
unsigned m_pointer_byte_count;
|
||||||
unsigned m_block_bit_count;
|
unsigned m_block_bit_count;
|
||||||
XBlock* m_insert_block;
|
XBlock* m_insert_block;
|
||||||
|
|
||||||
|
std::vector<uint8_t> m_fill_buffer;
|
||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
std::unique_ptr<ZoneInputStream> ZoneInputStream::Create(std::vector<XBlock*>& blocks, ILoadingStream& stream, unsigned blockBitCount, block_t insertBlock)
|
std::unique_ptr<ZoneInputStream> ZoneInputStream::Create(
|
||||||
|
const unsigned pointerBitCount, const unsigned blockBitCount, std::vector<XBlock*>& blocks, const block_t insertBlock, ILoadingStream& stream)
|
||||||
{
|
{
|
||||||
return std::make_unique<XBlockInputStream>(blocks, stream, blockBitCount, insertBlock);
|
return std::make_unique<XBlockInputStream>(pointerBitCount, blockBitCount, blocks, insertBlock, stream);
|
||||||
}
|
}
|
||||||
|
@ -4,23 +4,85 @@
|
|||||||
#include "Zone/Stream/IZoneStream.h"
|
#include "Zone/Stream/IZoneStream.h"
|
||||||
#include "Zone/XBlock.h"
|
#include "Zone/XBlock.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
class ZoneStreamFillReadAccessor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZoneStreamFillReadAccessor(const void* buffer, size_t bufferSize, unsigned pointerByteCount);
|
||||||
|
|
||||||
|
[[nodiscard]] ZoneStreamFillReadAccessor AtOffset(size_t offset) const;
|
||||||
|
|
||||||
|
template<typename T> void Fill(T& value, const size_t offset) const
|
||||||
|
{
|
||||||
|
assert(offset + sizeof(T) <= m_buffer_size);
|
||||||
|
|
||||||
|
value = *reinterpret_cast<const T*>(static_cast<const char*>(m_buffer) + offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void FillArray(T* value, const size_t offset, const size_t arraySize) const
|
||||||
|
{
|
||||||
|
assert(offset + sizeof(T) * arraySize <= m_buffer_size);
|
||||||
|
|
||||||
|
std::memcpy(value, static_cast<const char*>(m_buffer) + offset, sizeof(T) * arraySize);
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void FillPtr(T*& value, const size_t offset) const
|
||||||
|
{
|
||||||
|
assert(offset + m_pointer_byte_count <= m_buffer_size);
|
||||||
|
assert(m_pointer_byte_count <= sizeof(uintptr_t));
|
||||||
|
|
||||||
|
value = nullptr;
|
||||||
|
std::memcpy(&value, static_cast<const char*>(m_buffer) + offset, m_pointer_byte_count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const void* m_buffer;
|
||||||
|
size_t m_buffer_size;
|
||||||
|
unsigned m_pointer_byte_count;
|
||||||
|
};
|
||||||
|
|
||||||
class ZoneInputStream : public IZoneStream
|
class ZoneInputStream : public IZoneStream
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
/**
|
||||||
|
* \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.
|
||||||
|
* \param align The alignment value that the read position is aligned with before being returned. This should typically be the alignment of the struct that
|
||||||
|
* should be read afterward.
|
||||||
|
* \return A pointer to the memory in which following load calls will load data to.
|
||||||
|
*/
|
||||||
virtual void* Alloc(unsigned align) = 0;
|
virtual void* Alloc(unsigned align) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \copydoc ZoneInputStream#Alloc(unsigned)
|
||||||
|
*/
|
||||||
template<typename T> T* Alloc(const unsigned align)
|
template<typename T> T* Alloc(const unsigned align)
|
||||||
{
|
{
|
||||||
return static_cast<T*>(Alloc(align));
|
return static_cast<T*>(Alloc(align));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Loads data from the underlying stream without considering the current block or advancing the block position.
|
||||||
|
* The data is read directly to the specified location instead of block memory.
|
||||||
|
* \param dst The memory location to load data to.
|
||||||
|
* \param size The amount of data to load.
|
||||||
|
*/
|
||||||
virtual void LoadDataRaw(void* dst, size_t size) = 0;
|
virtual void LoadDataRaw(void* dst, size_t size) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Loads data with the current blocks read operation into its block memory.
|
||||||
|
* Depending on the block type, the underlying stream might be read from or not.
|
||||||
|
* The current block position is advanced by the number of bytes read.
|
||||||
|
* The destination must be inside the current block's memory space, otherwise an exception is thrown.
|
||||||
|
* \param dst The destination where the data is loaded to. Must be inside the current block's memory bounds.
|
||||||
|
* \param size The amount of data to load.
|
||||||
|
*/
|
||||||
virtual void LoadDataInBlock(void* dst, size_t size) = 0;
|
virtual void LoadDataInBlock(void* dst, size_t size) = 0;
|
||||||
virtual void IncBlockPos(size_t size) = 0;
|
|
||||||
virtual void LoadNullTerminated(void* dst) = 0;
|
virtual void LoadNullTerminated(void* dst) = 0;
|
||||||
|
virtual ZoneStreamFillReadAccessor LoadWithFill(size_t size) = 0;
|
||||||
|
|
||||||
template<typename T> void Load(T* dst)
|
template<typename T> void Load(T* dst)
|
||||||
{
|
{
|
||||||
@ -37,26 +99,27 @@ public:
|
|||||||
LoadDataInBlock(const_cast<void*>(reinterpret_cast<const void*>(dst)), size);
|
LoadDataInBlock(const_cast<void*>(reinterpret_cast<const void*>(dst)), size);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void** InsertPointer() = 0;
|
virtual void* InsertPointer() = 0;
|
||||||
|
|
||||||
template<typename T> T** InsertPointer()
|
template<typename T> T** InsertPointerNative()
|
||||||
{
|
{
|
||||||
return reinterpret_cast<T**>(InsertPointer());
|
return static_cast<T**>(InsertPointer());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* ConvertOffsetToPointer(const void* offset) = 0;
|
virtual void* ConvertOffsetToPointerNative(const void* offset) = 0;
|
||||||
|
|
||||||
template<typename T> T* ConvertOffsetToPointer(T* offset)
|
template<typename T> T* ConvertOffsetToPointerNative(T* offset)
|
||||||
{
|
{
|
||||||
return static_cast<T*>(ConvertOffsetToPointer(static_cast<const void*>(offset)));
|
return static_cast<T*>(ConvertOffsetToPointerNative(static_cast<const void*>(offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void* ConvertOffsetToAlias(const void* offset) = 0;
|
virtual void* ConvertOffsetToAliasNative(const void* offset) = 0;
|
||||||
|
|
||||||
template<typename T> T* ConvertOffsetToAlias(T* offset)
|
template<typename T> T* ConvertOffsetToAliasNative(T* offset)
|
||||||
{
|
{
|
||||||
return static_cast<T*>(ConvertOffsetToAlias(static_cast<const void*>(offset)));
|
return static_cast<T*>(ConvertOffsetToAliasNative(static_cast<const void*>(offset)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::unique_ptr<ZoneInputStream> Create(std::vector<XBlock*>& blocks, ILoadingStream& stream, unsigned blockBitCount, block_t insertBlock);
|
static std::unique_ptr<ZoneInputStream>
|
||||||
|
Create(unsigned pointerBitCount, unsigned blockBitCount, std::vector<XBlock*>& blocks, block_t insertBlock, ILoadingStream& stream);
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user