mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-01-19 15:01:49 +00:00
Merge pull request #648 from Laupetin/feature/x64-zone-writing
feat: x64 zone writing
This commit is contained in:
@@ -2594,8 +2594,8 @@ namespace IW3
|
|||||||
|
|
||||||
union entryInternalData
|
union entryInternalData
|
||||||
{
|
{
|
||||||
int op;
|
|
||||||
Operand operand;
|
Operand operand;
|
||||||
|
int op;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum expressionEntryType : int
|
enum expressionEntryType : int
|
||||||
|
|||||||
@@ -2044,8 +2044,8 @@ namespace IW4
|
|||||||
|
|
||||||
union entryInternalData
|
union entryInternalData
|
||||||
{
|
{
|
||||||
int op;
|
|
||||||
Operand operand;
|
Operand operand;
|
||||||
|
int op;
|
||||||
};
|
};
|
||||||
|
|
||||||
enum expressionEntryType : int
|
enum expressionEntryType : int
|
||||||
|
|||||||
@@ -2608,8 +2608,8 @@ namespace IW5
|
|||||||
|
|
||||||
union entryInternalData
|
union entryInternalData
|
||||||
{
|
{
|
||||||
int op;
|
|
||||||
Operand operand;
|
Operand operand;
|
||||||
|
int op;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct expressionEntry
|
struct expressionEntry
|
||||||
|
|||||||
@@ -198,16 +198,22 @@ ZoneCode.Assets = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function ZoneCode:outputForAssets(assetList)
|
function ZoneCode:outputForAssets(assetList)
|
||||||
|
buildoutputs {
|
||||||
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/AssetLoader%{file.basename}.h",
|
||||||
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/AssetMarker%{file.basename}.h",
|
||||||
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/AssetWriter%{file.basename}.h",
|
||||||
|
}
|
||||||
|
|
||||||
for i = 1, #assetList do
|
for i = 1, #assetList do
|
||||||
local assetNameLower = string.lower(assetList[i])
|
local assetNameLower = string.lower(assetList[i])
|
||||||
buildoutputs {
|
buildoutputs {
|
||||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_load_db.cpp",
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_%{string.lower(file.basename)}_load_db.cpp",
|
||||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_load_db.h",
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_%{string.lower(file.basename)}_load_db.h",
|
||||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_mark_db.cpp",
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_%{string.lower(file.basename)}_mark_db.cpp",
|
||||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_mark_db.h",
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_%{string.lower(file.basename)}_mark_db.h",
|
||||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_write_db.cpp",
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_%{string.lower(file.basename)}_write_db.cpp",
|
||||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_write_db.h",
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_%{string.lower(file.basename)}_write_db.h",
|
||||||
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_struct_test.cpp",
|
"%{wks.location}/src/ZoneCode/Game/%{file.basename}/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_%{string.lower(file.basename)}_struct_test.cpp",
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -216,9 +222,11 @@ function ZoneCode:allTestFiles()
|
|||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
for game, assets in pairs(self.Assets) do
|
for game, assets in pairs(self.Assets) do
|
||||||
|
local gameLower = string.lower(game)
|
||||||
|
|
||||||
for i, assetName in ipairs(assets) do
|
for i, assetName in ipairs(assets) do
|
||||||
local assetNameLower = string.lower(assetName)
|
local assetNameLower = string.lower(assetName)
|
||||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_struct_test.cpp")
|
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_struct_test.cpp")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -229,12 +237,13 @@ function ZoneCode:allMarkFiles()
|
|||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
for game, assets in pairs(self.Assets) do
|
for game, assets in pairs(self.Assets) do
|
||||||
|
local gameLower = string.lower(game)
|
||||||
|
|
||||||
-- PerAsset
|
-- PerAsset
|
||||||
for i, assetName in ipairs(assets) do
|
for i, assetName in ipairs(assets) do
|
||||||
local assetNameLower = string.lower(assetName)
|
local assetNameLower = string.lower(assetName)
|
||||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_mark_db.cpp")
|
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_mark_db.cpp")
|
||||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_mark_db.h")
|
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_mark_db.h")
|
||||||
end
|
end
|
||||||
|
|
||||||
-- PerTemplate
|
-- PerTemplate
|
||||||
@@ -248,11 +257,17 @@ function ZoneCode:allLoadFiles()
|
|||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
for game, assets in pairs(self.Assets) do
|
for game, assets in pairs(self.Assets) do
|
||||||
|
local gameLower = string.lower(game)
|
||||||
|
|
||||||
|
-- PerAsset
|
||||||
for i, assetName in ipairs(assets) do
|
for i, assetName in ipairs(assets) do
|
||||||
local assetNameLower = string.lower(assetName)
|
local assetNameLower = string.lower(assetName)
|
||||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_load_db.cpp")
|
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_load_db.cpp")
|
||||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_load_db.h")
|
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_load_db.h")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- PerTemplate
|
||||||
|
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/AssetLoader" .. game .. ".h")
|
||||||
end
|
end
|
||||||
|
|
||||||
return result
|
return result
|
||||||
@@ -262,11 +277,17 @@ function ZoneCode:allWriteFiles()
|
|||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
for game, assets in pairs(self.Assets) do
|
for game, assets in pairs(self.Assets) do
|
||||||
|
local gameLower = string.lower(game)
|
||||||
|
|
||||||
|
-- PerAsset
|
||||||
for i, assetName in ipairs(assets) do
|
for i, assetName in ipairs(assets) do
|
||||||
local assetNameLower = string.lower(assetName)
|
local assetNameLower = string.lower(assetName)
|
||||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_write_db.cpp")
|
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_write_db.cpp")
|
||||||
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_write_db.h")
|
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/XAssets/" .. assetNameLower .. "/" .. assetNameLower .. "_" .. gameLower .. "_write_db.h")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- PerTemplate
|
||||||
|
table.insert(result, "%{wks.location}/src/ZoneCode/Game/" .. game .. "/AssetWriter" .. game .. ".h")
|
||||||
end
|
end
|
||||||
|
|
||||||
return result
|
return result
|
||||||
|
|||||||
@@ -27,6 +27,11 @@ use MaterialShaderArgument;
|
|||||||
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
||||||
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
||||||
set reusable u::literalConst;
|
set reusable u::literalConst;
|
||||||
|
set condition u::codeConst type == MTL_ARG_CODE_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_CODE_PIXEL_CONST;
|
||||||
|
set condition u::codeSampler type == MTL_ARG_CODE_PIXEL_SAMPLER;
|
||||||
|
set condition u::nameHash type == MTL_ARG_MATERIAL_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_MATERIAL_PIXEL_CONST || type == MTL_ARG_MATERIAL_PIXEL_SAMPLER;
|
||||||
|
|
||||||
// MaterialPixelShader
|
// MaterialPixelShader
|
||||||
set string MaterialPixelShader::name;
|
set string MaterialPixelShader::name;
|
||||||
|
|||||||
@@ -24,3 +24,8 @@ use MaterialShaderArgument;
|
|||||||
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
||||||
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
||||||
set reusable u::literalConst;
|
set reusable u::literalConst;
|
||||||
|
set condition u::codeConst type == MTL_ARG_CODE_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_CODE_PIXEL_CONST;
|
||||||
|
set condition u::codeSampler type == MTL_ARG_CODE_PIXEL_SAMPLER;
|
||||||
|
set condition u::nameHash type == MTL_ARG_MATERIAL_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_MATERIAL_PIXEL_CONST || type == MTL_ARG_MATERIAL_PIXEL_SAMPLER;
|
||||||
@@ -24,3 +24,8 @@ use MaterialShaderArgument;
|
|||||||
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
||||||
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
||||||
set reusable u::literalConst;
|
set reusable u::literalConst;
|
||||||
|
set condition u::codeConst type == MTL_ARG_CODE_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_CODE_PIXEL_CONST;
|
||||||
|
set condition u::codeSampler type == MTL_ARG_CODE_PIXEL_SAMPLER;
|
||||||
|
set condition u::nameHash type == MTL_ARG_MATERIAL_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_MATERIAL_PIXEL_CONST || type == MTL_ARG_MATERIAL_PIXEL_SAMPLER;
|
||||||
@@ -47,3 +47,8 @@ use MaterialShaderArgument;
|
|||||||
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
||||||
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
||||||
set reusable u::literalConst;
|
set reusable u::literalConst;
|
||||||
|
set condition u::codeConst type == MTL_ARG_CODE_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_CODE_PIXEL_CONST;
|
||||||
|
set condition u::codeSampler type == MTL_ARG_CODE_PIXEL_SAMPLER;
|
||||||
|
set condition u::nameHash type == MTL_ARG_MATERIAL_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_MATERIAL_PIXEL_CONST || type == MTL_ARG_MATERIAL_PIXEL_SAMPLER;
|
||||||
@@ -52,3 +52,8 @@ use MaterialShaderArgument;
|
|||||||
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
set condition u::literalConst type == MTL_ARG_LITERAL_VERTEX_CONST
|
||||||
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
|| type == MTL_ARG_LITERAL_PIXEL_CONST;
|
||||||
set reusable u::literalConst;
|
set reusable u::literalConst;
|
||||||
|
set condition u::codeConst type == MTL_ARG_CODE_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_CODE_PIXEL_CONST;
|
||||||
|
set condition u::codeSampler type == MTL_ARG_CODE_PIXEL_SAMPLER;
|
||||||
|
set condition u::nameHash type == MTL_ARG_MATERIAL_VERTEX_CONST
|
||||||
|
|| type == MTL_ARG_MATERIAL_PIXEL_CONST || type == MTL_ARG_MATERIAL_PIXEL_SAMPLER;
|
||||||
@@ -189,15 +189,15 @@ bool MemberComputations::IsInRuntimeBlock() const
|
|||||||
return m_info->m_fast_file_block != nullptr && m_info->m_fast_file_block->m_type == FastFileBlockType::RUNTIME;
|
return m_info->m_fast_file_block != nullptr && m_info->m_fast_file_block->m_type == FastFileBlockType::RUNTIME;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemberComputations::IsFirstUsedMember() const
|
bool MemberComputations::IsFirstUsedMember(const bool includeLeafs) const
|
||||||
{
|
{
|
||||||
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
|
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers(includeLeafs);
|
||||||
return !parentUsedMembers.empty() && parentUsedMembers[0] == m_info;
|
return !parentUsedMembers.empty() && parentUsedMembers[0] == m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MemberComputations::IsLastUsedMember() const
|
bool MemberComputations::IsLastUsedMember(const bool includeLeafs) const
|
||||||
{
|
{
|
||||||
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers();
|
const auto parentUsedMembers = StructureComputations(m_info->m_parent).GetUsedMembers(includeLeafs);
|
||||||
return !parentUsedMembers.empty() && parentUsedMembers[parentUsedMembers.size() - 1] == m_info;
|
return !parentUsedMembers.empty() && parentUsedMembers[parentUsedMembers.size() - 1] == m_info;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ public:
|
|||||||
[[nodiscard]] bool IsNotInDefaultNormalBlock() const;
|
[[nodiscard]] bool IsNotInDefaultNormalBlock() const;
|
||||||
[[nodiscard]] bool IsInTempBlock() const;
|
[[nodiscard]] bool IsInTempBlock() const;
|
||||||
[[nodiscard]] bool IsInRuntimeBlock() const;
|
[[nodiscard]] bool IsInRuntimeBlock() const;
|
||||||
[[nodiscard]] bool IsFirstUsedMember() const;
|
[[nodiscard]] bool IsFirstUsedMember(bool includeLeafs) const;
|
||||||
[[nodiscard]] bool IsLastUsedMember() const;
|
[[nodiscard]] bool IsLastUsedMember(bool includeLeafs) const;
|
||||||
[[nodiscard]] bool HasDynamicArraySize() const;
|
[[nodiscard]] bool HasDynamicArraySize() const;
|
||||||
[[nodiscard]] bool IsDynamicMember() const;
|
[[nodiscard]] bool IsDynamicMember() const;
|
||||||
[[nodiscard]] bool IsAfterPartialLoad() const;
|
[[nodiscard]] bool IsAfterPartialLoad() const;
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ bool StructureComputations::HasNonDynamicMember() const
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<MemberInformation*> StructureComputations::GetUsedMembers() const
|
std::vector<MemberInformation*> StructureComputations::GetUsedMembers(const bool includeLeafs) const
|
||||||
{
|
{
|
||||||
std::vector<MemberInformation*> members;
|
std::vector<MemberInformation*> members;
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ std::vector<MemberInformation*> StructureComputations::GetUsedMembers() const
|
|||||||
{
|
{
|
||||||
for (const auto& member : m_info->m_ordered_members)
|
for (const auto& member : m_info->m_ordered_members)
|
||||||
{
|
{
|
||||||
if (!member->m_is_leaf && !MemberComputations(member.get()).ShouldIgnore())
|
if ((includeLeafs || !member->m_is_leaf) && !MemberComputations(member.get()).ShouldIgnore())
|
||||||
members.push_back(member.get());
|
members.push_back(member.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ public:
|
|||||||
[[nodiscard]] bool IsAsset() const;
|
[[nodiscard]] bool IsAsset() const;
|
||||||
[[nodiscard]] MemberInformation* GetDynamicMember() const;
|
[[nodiscard]] MemberInformation* GetDynamicMember() const;
|
||||||
[[nodiscard]] bool HasNonDynamicMember() const;
|
[[nodiscard]] bool HasNonDynamicMember() const;
|
||||||
[[nodiscard]] std::vector<MemberInformation*> GetUsedMembers() const;
|
[[nodiscard]] std::vector<MemberInformation*> GetUsedMembers(bool includeLeafs) const;
|
||||||
[[nodiscard]] bool IsInTempBlock() const;
|
[[nodiscard]] bool IsInTempBlock() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
21
src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.cpp
Normal file
21
src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#include "BaseRenderingContext.h"
|
||||||
|
|
||||||
|
BaseRenderingContext::BaseRenderingContext(std::string game, const Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks)
|
||||||
|
: m_game(std::move(game)),
|
||||||
|
m_architecture_mismatch(gameArchitecture != OWN_ARCHITECTURE),
|
||||||
|
m_pointer_size(GetPointerSizeForArchitecture(gameArchitecture)),
|
||||||
|
m_blocks(std::move(fastFileBlocks)),
|
||||||
|
m_default_normal_block(nullptr),
|
||||||
|
m_default_temp_block(nullptr)
|
||||||
|
{
|
||||||
|
for (const auto* block : m_blocks)
|
||||||
|
{
|
||||||
|
if (block->m_is_default)
|
||||||
|
{
|
||||||
|
if (block->m_type == FastFileBlockType::NORMAL && m_default_normal_block == nullptr)
|
||||||
|
m_default_normal_block = block;
|
||||||
|
else if (block->m_type == FastFileBlockType::TEMP && m_default_temp_block == nullptr)
|
||||||
|
m_default_temp_block = block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
21
src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.h
Normal file
21
src/ZoneCodeGeneratorLib/Generating/BaseRenderingContext.h
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "Persistence/IDataRepository.h"
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class BaseRenderingContext
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
std::string m_game;
|
||||||
|
bool m_architecture_mismatch;
|
||||||
|
unsigned m_pointer_size;
|
||||||
|
std::vector<const FastFileBlock*> m_blocks;
|
||||||
|
|
||||||
|
const FastFileBlock* m_default_normal_block;
|
||||||
|
const FastFileBlock* m_default_temp_block;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
BaseRenderingContext(std::string game, Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks);
|
||||||
|
};
|
||||||
@@ -21,14 +21,9 @@ RenderingUsedType::RenderingUsedType(const DataDefinition* type, StructureInform
|
|||||||
OncePerAssetRenderingContext::OncePerAssetRenderingContext(std::string game,
|
OncePerAssetRenderingContext::OncePerAssetRenderingContext(std::string game,
|
||||||
const Architecture gameArchitecture,
|
const Architecture gameArchitecture,
|
||||||
std::vector<const FastFileBlock*> fastFileBlocks)
|
std::vector<const FastFileBlock*> fastFileBlocks)
|
||||||
: m_game(std::move(game)),
|
: BaseRenderingContext(std::move(game), gameArchitecture, std::move(fastFileBlocks)),
|
||||||
m_architecture_mismatch(gameArchitecture != OWN_ARCHITECTURE),
|
|
||||||
m_pointer_size(GetPointerSizeForArchitecture(gameArchitecture)),
|
|
||||||
m_blocks(std::move(fastFileBlocks)),
|
|
||||||
m_asset(nullptr),
|
m_asset(nullptr),
|
||||||
m_has_actions(false),
|
m_has_actions(false)
|
||||||
m_default_normal_block(nullptr),
|
|
||||||
m_default_temp_block(nullptr)
|
|
||||||
{
|
{
|
||||||
for (const auto* block : m_blocks)
|
for (const auto* block : m_blocks)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "BaseRenderingContext.h"
|
||||||
#include "Domain/Computations/MemberComputations.h"
|
#include "Domain/Computations/MemberComputations.h"
|
||||||
#include "Domain/Information/StructureInformation.h"
|
#include "Domain/Information/StructureInformation.h"
|
||||||
#include "Persistence/IDataRepository.h"
|
#include "Persistence/IDataRepository.h"
|
||||||
@@ -24,16 +25,11 @@ public:
|
|||||||
bool m_pointer_array_reference_is_reusable;
|
bool m_pointer_array_reference_is_reusable;
|
||||||
};
|
};
|
||||||
|
|
||||||
class OncePerAssetRenderingContext
|
class OncePerAssetRenderingContext : public BaseRenderingContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<OncePerAssetRenderingContext> BuildContext(const IDataRepository* repository, StructureInformation* asset);
|
static std::unique_ptr<OncePerAssetRenderingContext> BuildContext(const IDataRepository* repository, StructureInformation* asset);
|
||||||
|
|
||||||
std::string m_game;
|
|
||||||
bool m_architecture_mismatch;
|
|
||||||
unsigned m_pointer_size;
|
|
||||||
std::vector<const FastFileBlock*> m_blocks;
|
|
||||||
|
|
||||||
StructureInformation* m_asset;
|
StructureInformation* m_asset;
|
||||||
|
|
||||||
std::vector<RenderingUsedType*> m_used_types;
|
std::vector<RenderingUsedType*> m_used_types;
|
||||||
@@ -41,9 +37,6 @@ public:
|
|||||||
std::vector<RenderingUsedType*> m_referenced_assets;
|
std::vector<RenderingUsedType*> m_referenced_assets;
|
||||||
bool m_has_actions;
|
bool m_has_actions;
|
||||||
|
|
||||||
const FastFileBlock* m_default_normal_block;
|
|
||||||
const FastFileBlock* m_default_temp_block;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OncePerAssetRenderingContext(std::string game, Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks);
|
OncePerAssetRenderingContext(std::string game, Architecture gameArchitecture, std::vector<const FastFileBlock*> fastFileBlocks);
|
||||||
|
|
||||||
|
|||||||
@@ -8,13 +8,8 @@ OncePerTemplateRenderingContext::OncePerTemplateRenderingContext(std::string gam
|
|||||||
const Architecture gameArchitecture,
|
const Architecture gameArchitecture,
|
||||||
std::vector<const FastFileBlock*> fastFileBlocks,
|
std::vector<const FastFileBlock*> fastFileBlocks,
|
||||||
std::vector<StructureInformation*> assets)
|
std::vector<StructureInformation*> assets)
|
||||||
: m_game(std::move(game)),
|
: BaseRenderingContext(std::move(game), gameArchitecture, std::move(fastFileBlocks)),
|
||||||
m_architecture_mismatch(gameArchitecture != OWN_ARCHITECTURE),
|
m_assets(std::move(assets))
|
||||||
m_pointer_size(GetPointerSizeForArchitecture(gameArchitecture)),
|
|
||||||
m_blocks(std::move(fastFileBlocks)),
|
|
||||||
m_assets(std::move(assets)),
|
|
||||||
m_default_normal_block(nullptr),
|
|
||||||
m_default_temp_block(nullptr)
|
|
||||||
{
|
{
|
||||||
for (const auto* block : m_blocks)
|
for (const auto* block : m_blocks)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,24 +1,18 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "BaseRenderingContext.h"
|
||||||
#include "Persistence/IDataRepository.h"
|
#include "Persistence/IDataRepository.h"
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
class OncePerTemplateRenderingContext
|
class OncePerTemplateRenderingContext : public BaseRenderingContext
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::unique_ptr<OncePerTemplateRenderingContext> BuildContext(const IDataRepository* repository);
|
static std::unique_ptr<OncePerTemplateRenderingContext> BuildContext(const IDataRepository* repository);
|
||||||
|
|
||||||
std::string m_game;
|
|
||||||
bool m_architecture_mismatch;
|
|
||||||
unsigned m_pointer_size;
|
|
||||||
std::vector<const FastFileBlock*> m_blocks;
|
|
||||||
std::vector<StructureInformation*> m_assets;
|
std::vector<StructureInformation*> m_assets;
|
||||||
|
|
||||||
const FastFileBlock* m_default_normal_block;
|
|
||||||
const FastFileBlock* m_default_temp_block;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
OncePerTemplateRenderingContext(std::string game,
|
OncePerTemplateRenderingContext(std::string game,
|
||||||
Architecture gameArchitecture,
|
Architecture gameArchitecture,
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PerAsset(std::ostream& stream, const OncePerAssetRenderingContext& context)
|
PerAsset(std::ostream& stream, const OncePerAssetRenderingContext& context)
|
||||||
: BaseTemplate(stream),
|
: BaseTemplate(stream, context),
|
||||||
m_env(context)
|
m_env(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -87,7 +87,10 @@ std::vector<CodeTemplateFile> AssetStructTestsTemplate::GetFilesToRenderOncePerA
|
|||||||
auto assetName = context.m_asset->m_definition->m_name;
|
auto assetName = context.m_asset->m_definition->m_name;
|
||||||
utils::MakeStringLowerCase(assetName);
|
utils::MakeStringLowerCase(assetName);
|
||||||
|
|
||||||
files.emplace_back(std::format("XAssets/{0}/{0}_struct_test.cpp", assetName), TAG_SOURCE);
|
auto gameName = context.m_game;
|
||||||
|
utils::MakeStringLowerCase(gameName);
|
||||||
|
|
||||||
|
files.emplace_back(std::format("XAssets/{0}/{0}_{1}_struct_test.cpp", assetName, gameName), TAG_SOURCE);
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
#include "BaseTemplate.h"
|
#include "BaseTemplate.h"
|
||||||
|
|
||||||
#include "Domain/Computations/MemberComputations.h"
|
#include "Domain/Computations/MemberComputations.h"
|
||||||
|
#include "Domain/Computations/StructureComputations.h"
|
||||||
#include "Domain/Definition/ArrayDeclarationModifier.h"
|
#include "Domain/Definition/ArrayDeclarationModifier.h"
|
||||||
|
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
BaseTemplate::BaseTemplate(std::ostream& stream)
|
BaseTemplate::BaseTemplate(std::ostream& stream, const BaseRenderingContext& context)
|
||||||
: m_out(stream),
|
: m_out(stream),
|
||||||
m_intendation(0u)
|
m_intendation(0u),
|
||||||
|
m_env(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,13 +63,6 @@ void BaseTemplate::MakeTypeVarNameInternal(const DataDefinition* def, std::ostri
|
|||||||
MakeSafeTypeNameInternal(def, str);
|
MakeSafeTypeNameInternal(def, str);
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseTemplate::MakeTypeWrittenVarNameInternal(const DataDefinition* def, std::ostringstream& str)
|
|
||||||
{
|
|
||||||
str << "var";
|
|
||||||
MakeSafeTypeNameInternal(def, str);
|
|
||||||
str << "Written";
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseTemplate::MakeTypePtrVarNameInternal(const DataDefinition* def, std::ostringstream& str)
|
void BaseTemplate::MakeTypePtrVarNameInternal(const DataDefinition* def, std::ostringstream& str)
|
||||||
{
|
{
|
||||||
str << "var";
|
str << "var";
|
||||||
@@ -75,13 +70,6 @@ void BaseTemplate::MakeTypePtrVarNameInternal(const DataDefinition* def, std::os
|
|||||||
str << "Ptr";
|
str << "Ptr";
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseTemplate::MakeTypeWrittenPtrVarNameInternal(const DataDefinition* def, std::ostringstream& str)
|
|
||||||
{
|
|
||||||
str << "var";
|
|
||||||
MakeSafeTypeNameInternal(def, str);
|
|
||||||
str << "PtrWritten";
|
|
||||||
}
|
|
||||||
|
|
||||||
void BaseTemplate::MakeArrayIndicesInternal(const DeclarationModifierComputations& modifierComputations, std::ostringstream& str)
|
void BaseTemplate::MakeArrayIndicesInternal(const DeclarationModifierComputations& modifierComputations, std::ostringstream& str)
|
||||||
{
|
{
|
||||||
for (const auto index : modifierComputations.GetArrayIndices())
|
for (const auto index : modifierComputations.GetArrayIndices())
|
||||||
@@ -97,13 +85,6 @@ std::string BaseTemplate::MakeTypeVarName(const DataDefinition* def)
|
|||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseTemplate::MakeTypeWrittenVarName(const DataDefinition* def)
|
|
||||||
{
|
|
||||||
std::ostringstream str;
|
|
||||||
MakeTypeWrittenVarNameInternal(def, str);
|
|
||||||
return str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string BaseTemplate::MakeTypePtrVarName(const DataDefinition* def)
|
std::string BaseTemplate::MakeTypePtrVarName(const DataDefinition* def)
|
||||||
{
|
{
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
@@ -111,13 +92,6 @@ std::string BaseTemplate::MakeTypePtrVarName(const DataDefinition* def)
|
|||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string BaseTemplate::MakeTypeWrittenPtrVarName(const DataDefinition* def)
|
|
||||||
{
|
|
||||||
std::ostringstream str;
|
|
||||||
MakeTypeWrittenPtrVarNameInternal(def, str);
|
|
||||||
return str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string BaseTemplate::MakeSafeTypeName(const DataDefinition* def)
|
std::string BaseTemplate::MakeSafeTypeName(const DataDefinition* def)
|
||||||
{
|
{
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
@@ -135,17 +109,6 @@ std::string BaseTemplate::MakeMemberAccess(const StructureInformation* info, con
|
|||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string
|
|
||||||
BaseTemplate::MakeWrittenMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier)
|
|
||||||
{
|
|
||||||
std::ostringstream str;
|
|
||||||
MakeTypeWrittenVarNameInternal(info->m_definition, str);
|
|
||||||
str << "->" << member->m_member->m_name;
|
|
||||||
MakeArrayIndicesInternal(modifier, str);
|
|
||||||
|
|
||||||
return str.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string BaseTemplate::MakeTypeDecl(const TypeDeclaration* decl)
|
std::string BaseTemplate::MakeTypeDecl(const TypeDeclaration* decl)
|
||||||
{
|
{
|
||||||
std::ostringstream str;
|
std::ostringstream str;
|
||||||
@@ -299,3 +262,52 @@ std::string BaseTemplate::MakeEvaluation(const IEvaluation* evaluation)
|
|||||||
MakeEvaluationInternal(evaluation, str);
|
MakeEvaluationInternal(evaluation, str);
|
||||||
return str.str();
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool BaseTemplate::ShouldGenerateFillMethod(const RenderingUsedType& type)
|
||||||
|
{
|
||||||
|
const auto isNotForeignAsset = type.m_is_context_asset || !type.m_info || !StructureComputations(type.m_info).IsAsset();
|
||||||
|
const auto hasMismatchingStructure = type.m_info && type.m_type == type.m_info->m_definition && !type.m_info->m_has_matching_cross_platform_structure;
|
||||||
|
const auto isEmbeddedDynamic = type.m_info && type.m_info->m_embedded_reference_exists && StructureComputations(type.m_info).GetDynamicMember();
|
||||||
|
|
||||||
|
return isNotForeignAsset && (hasMismatchingStructure || isEmbeddedDynamic);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BaseTemplate::SizeForDeclModifierLevel(const MemberInformation& memberInfo, const size_t level) const
|
||||||
|
{
|
||||||
|
const auto& declModifiers = memberInfo.m_member->m_type_declaration->m_declaration_modifiers;
|
||||||
|
if (declModifiers.empty())
|
||||||
|
return memberInfo.m_member->m_type_declaration->GetSize();
|
||||||
|
|
||||||
|
if (level == 0)
|
||||||
|
return memberInfo.m_member->m_type_declaration->GetSize();
|
||||||
|
|
||||||
|
size_t currentSize = memberInfo.m_member->m_type_declaration->m_type->GetSize();
|
||||||
|
const auto end = declModifiers.rbegin() + (declModifiers.size() - level);
|
||||||
|
for (auto i = declModifiers.rbegin(); i != end; ++i)
|
||||||
|
{
|
||||||
|
if ((*i)->GetType() == DeclarationModifierType::POINTER)
|
||||||
|
currentSize = m_env.m_pointer_size;
|
||||||
|
else
|
||||||
|
currentSize *= dynamic_cast<ArrayDeclarationModifier*>(i->get())->m_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return currentSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t BaseTemplate::OffsetForMemberModifier(const MemberInformation& memberInfo,
|
||||||
|
const DeclarationModifierComputations& modifier,
|
||||||
|
const size_t nestedBaseOffset) const
|
||||||
|
{
|
||||||
|
size_t curOffset = memberInfo.m_member->m_offset;
|
||||||
|
|
||||||
|
auto curLevel = 0u;
|
||||||
|
for (const auto index : modifier.GetArrayIndices())
|
||||||
|
{
|
||||||
|
if (index > 0)
|
||||||
|
curOffset += index * SizeForDeclModifierLevel(memberInfo, curLevel + 1);
|
||||||
|
|
||||||
|
curLevel++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return curOffset + nestedBaseOffset;
|
||||||
|
}
|
||||||
|
|||||||
@@ -5,6 +5,8 @@
|
|||||||
#include "Domain/Evaluation/OperandDynamic.h"
|
#include "Domain/Evaluation/OperandDynamic.h"
|
||||||
#include "Domain/Evaluation/OperandStatic.h"
|
#include "Domain/Evaluation/OperandStatic.h"
|
||||||
#include "Domain/Evaluation/Operation.h"
|
#include "Domain/Evaluation/Operation.h"
|
||||||
|
#include "Generating/BaseRenderingContext.h"
|
||||||
|
#include "Generating/OncePerAssetRenderingContext.h"
|
||||||
|
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
@@ -14,7 +16,7 @@ class BaseTemplate
|
|||||||
protected:
|
protected:
|
||||||
static constexpr auto INTENDATION = " ";
|
static constexpr auto INTENDATION = " ";
|
||||||
|
|
||||||
explicit BaseTemplate(std::ostream& stream);
|
explicit BaseTemplate(std::ostream& stream, const BaseRenderingContext& context);
|
||||||
|
|
||||||
void DoIntendation() const;
|
void DoIntendation() const;
|
||||||
|
|
||||||
@@ -23,13 +25,9 @@ protected:
|
|||||||
static std::string Upper(std::string str);
|
static std::string Upper(std::string str);
|
||||||
static std::string Lower(std::string str);
|
static std::string Lower(std::string str);
|
||||||
static std::string MakeTypeVarName(const DataDefinition* def);
|
static std::string MakeTypeVarName(const DataDefinition* def);
|
||||||
static std::string MakeTypeWrittenVarName(const DataDefinition* def);
|
|
||||||
static std::string MakeTypePtrVarName(const DataDefinition* def);
|
static std::string MakeTypePtrVarName(const DataDefinition* def);
|
||||||
static std::string MakeTypeWrittenPtrVarName(const DataDefinition* def);
|
|
||||||
static std::string MakeSafeTypeName(const DataDefinition* def);
|
static std::string MakeSafeTypeName(const DataDefinition* def);
|
||||||
static std::string MakeMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier);
|
static std::string MakeMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier);
|
||||||
static std::string
|
|
||||||
MakeWrittenMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier);
|
|
||||||
static std::string MakeTypeDecl(const TypeDeclaration* decl);
|
static std::string MakeTypeDecl(const TypeDeclaration* decl);
|
||||||
static std::string MakeFollowingReferences(const std::vector<DeclarationModifier*>& modifiers);
|
static std::string MakeFollowingReferences(const std::vector<DeclarationModifier*>& modifiers);
|
||||||
static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations);
|
static std::string MakeArrayIndices(const DeclarationModifierComputations& modifierComputations);
|
||||||
@@ -37,20 +35,27 @@ protected:
|
|||||||
static std::string MakeArrayCount(const ArrayDeclarationModifier* arrayModifier);
|
static std::string MakeArrayCount(const ArrayDeclarationModifier* arrayModifier);
|
||||||
static std::string MakeEvaluation(const IEvaluation* evaluation);
|
static std::string MakeEvaluation(const IEvaluation* evaluation);
|
||||||
|
|
||||||
|
static bool ShouldGenerateFillMethod(const RenderingUsedType& type);
|
||||||
|
|
||||||
|
static void MakeSafeTypeNameInternal(const DataDefinition* def, std::ostringstream& str);
|
||||||
|
static void MakeArrayIndicesInternal(const DeclarationModifierComputations& modifierComputations, std::ostringstream& str);
|
||||||
|
|
||||||
|
[[nodiscard]] size_t SizeForDeclModifierLevel(const MemberInformation& memberInfo, size_t level) const;
|
||||||
|
[[nodiscard]] size_t
|
||||||
|
OffsetForMemberModifier(const MemberInformation& memberInfo, const DeclarationModifierComputations& modifier, size_t nestedBaseOffset) const;
|
||||||
|
|
||||||
std::ostream& m_out;
|
std::ostream& m_out;
|
||||||
unsigned m_intendation;
|
unsigned m_intendation;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void MakeSafeTypeNameInternal(const DataDefinition* def, std::ostringstream& str);
|
|
||||||
static void MakeTypeVarNameInternal(const DataDefinition* def, std::ostringstream& str);
|
static void MakeTypeVarNameInternal(const DataDefinition* def, std::ostringstream& str);
|
||||||
static void MakeTypeWrittenVarNameInternal(const DataDefinition* def, std::ostringstream& str);
|
|
||||||
static void MakeTypePtrVarNameInternal(const DataDefinition* def, std::ostringstream& str);
|
static void MakeTypePtrVarNameInternal(const DataDefinition* def, std::ostringstream& str);
|
||||||
static void MakeTypeWrittenPtrVarNameInternal(const DataDefinition* def, std::ostringstream& str);
|
|
||||||
static void MakeArrayIndicesInternal(const DeclarationModifierComputations& modifierComputations, std::ostringstream& str);
|
|
||||||
static void MakeOperandStatic(const OperandStatic* op, std::ostringstream& str);
|
static void MakeOperandStatic(const OperandStatic* op, std::ostringstream& str);
|
||||||
static void MakeOperandDynamic(const OperandDynamic* op, std::ostringstream& str);
|
static void MakeOperandDynamic(const OperandDynamic* op, std::ostringstream& str);
|
||||||
static void MakeOperation(const Operation* operation, std::ostringstream& str);
|
static void MakeOperation(const Operation* operation, std::ostringstream& str);
|
||||||
static void MakeEvaluationInternal(const IEvaluation* evaluation, std::ostringstream& str);
|
static void MakeEvaluationInternal(const IEvaluation* evaluation, std::ostringstream& str);
|
||||||
|
|
||||||
|
const BaseRenderingContext& m_env;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define LINE(x) \
|
#define LINE(x) \
|
||||||
|
|||||||
@@ -12,12 +12,39 @@ namespace
|
|||||||
{
|
{
|
||||||
constexpr int TAG_HEADER = 1;
|
constexpr int TAG_HEADER = 1;
|
||||||
constexpr int TAG_SOURCE = 2;
|
constexpr int TAG_SOURCE = 2;
|
||||||
|
constexpr int TAG_ALL_LOADERS = 3;
|
||||||
|
|
||||||
|
class PerTemplate final : BaseTemplate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PerTemplate(std::ostream& stream, const OncePerTemplateRenderingContext& context)
|
||||||
|
: BaseTemplate(stream, context),
|
||||||
|
m_env(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AllLoaders() const
|
||||||
|
{
|
||||||
|
AddGeneratedHint();
|
||||||
|
|
||||||
|
LINE("#pragma once")
|
||||||
|
LINE("")
|
||||||
|
|
||||||
|
for (const auto* asset : m_env.m_assets)
|
||||||
|
{
|
||||||
|
LINEF("#include \"Game/{0}/XAssets/{1}/{1}_{2}_load_db.h\"", m_env.m_game, Lower(asset->m_definition->m_name), Lower(m_env.m_game))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const OncePerTemplateRenderingContext& m_env;
|
||||||
|
};
|
||||||
|
|
||||||
class PerAsset final : BaseTemplate
|
class PerAsset final : BaseTemplate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PerAsset(std::ostream& stream, const OncePerAssetRenderingContext& context)
|
PerAsset(std::ostream& stream, const OncePerAssetRenderingContext& context)
|
||||||
: BaseTemplate(stream),
|
: BaseTemplate(stream, context),
|
||||||
m_env(context)
|
m_env(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -135,7 +162,7 @@ namespace
|
|||||||
{
|
{
|
||||||
AddGeneratedHint();
|
AddGeneratedHint();
|
||||||
|
|
||||||
LINEF("#include \"{0}_load_db.h\"", Lower(m_env.m_asset->m_definition->m_name))
|
LINEF("#include \"{0}_{1}_load_db.h\"", Lower(m_env.m_asset->m_definition->m_name), Lower(m_env.m_game))
|
||||||
LINE("")
|
LINE("")
|
||||||
LINEF("#include \"Game/{0}/AssetMarker{0}.h\"", m_env.m_game)
|
LINEF("#include \"Game/{0}/AssetMarker{0}.h\"", m_env.m_game)
|
||||||
LINE("")
|
LINE("")
|
||||||
@@ -147,7 +174,7 @@ namespace
|
|||||||
LINE("// Referenced Assets:")
|
LINE("// Referenced Assets:")
|
||||||
for (const auto* type : m_env.m_referenced_assets)
|
for (const auto* type : m_env.m_referenced_assets)
|
||||||
{
|
{
|
||||||
LINEF("#include \"../{0}/{0}_load_db.h\"", Lower(type->m_type->m_name))
|
LINEF("#include \"../{0}/{0}_{1}_load_db.h\"", Lower(type->m_type->m_name), Lower(m_env.m_game))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -240,16 +267,6 @@ namespace
|
|||||||
return std::format("{0}** var{1}Ptr;", def->GetFullName(), MakeSafeTypeName(def));
|
return std::format("{0}** var{1}Ptr;", def->GetFullName(), MakeSafeTypeName(def));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ShouldGenerateFillMethod(const RenderingUsedType& type)
|
|
||||||
{
|
|
||||||
const auto isNotForeignAsset = type.m_is_context_asset || !type.m_info || !StructureComputations(type.m_info).IsAsset();
|
|
||||||
const auto hasMismatchingStructure =
|
|
||||||
type.m_info && type.m_type == type.m_info->m_definition && !type.m_info->m_has_matching_cross_platform_structure;
|
|
||||||
const auto isEmbeddedDynamic = type.m_info && type.m_info->m_embedded_reference_exists && StructureComputations(type.m_info).GetDynamicMember();
|
|
||||||
|
|
||||||
return isNotForeignAsset && (hasMismatchingStructure || isEmbeddedDynamic);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintFillStructMethodDeclaration(const StructureInformation* info) const
|
void PrintFillStructMethodDeclaration(const StructureInformation* info) const
|
||||||
{
|
{
|
||||||
LINEF("void FillStruct_{0}(const ZoneStreamFillReadAccessor& fillAccessor);", MakeSafeTypeName(info->m_definition))
|
LINEF("void FillStruct_{0}(const ZoneStreamFillReadAccessor& fillAccessor);", MakeSafeTypeName(info->m_definition))
|
||||||
@@ -328,7 +345,8 @@ namespace
|
|||||||
|
|
||||||
for (const auto* type : m_env.m_used_types)
|
for (const auto* type : m_env.m_used_types)
|
||||||
{
|
{
|
||||||
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
|
if (type->m_info && !type->m_info->m_definition->m_anonymous
|
||||||
|
&& (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset())
|
||||||
{
|
{
|
||||||
PrintVariableInitialization(type->m_type);
|
PrintVariableInitialization(type->m_type);
|
||||||
}
|
}
|
||||||
@@ -345,47 +363,6 @@ namespace
|
|||||||
LINE("}")
|
LINE("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
[[nodiscard]] size_t SizeForDeclModifierLevel(const MemberInformation& memberInfo, const size_t level) const
|
|
||||||
{
|
|
||||||
const auto& declModifiers = memberInfo.m_member->m_type_declaration->m_declaration_modifiers;
|
|
||||||
if (declModifiers.empty())
|
|
||||||
return memberInfo.m_member->m_type_declaration->GetSize();
|
|
||||||
|
|
||||||
if (level == 0)
|
|
||||||
return memberInfo.m_member->m_type_declaration->GetSize();
|
|
||||||
|
|
||||||
size_t currentSize = memberInfo.m_member->m_type_declaration->m_type->GetSize();
|
|
||||||
const auto end = declModifiers.rbegin() + (declModifiers.size() - level);
|
|
||||||
for (auto i = declModifiers.rbegin(); i != end; ++i)
|
|
||||||
{
|
|
||||||
if ((*i)->GetType() == DeclarationModifierType::POINTER)
|
|
||||||
currentSize = m_env.m_pointer_size;
|
|
||||||
else
|
|
||||||
currentSize *= dynamic_cast<ArrayDeclarationModifier*>(i->get())->m_size;
|
|
||||||
}
|
|
||||||
|
|
||||||
return currentSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
[[nodiscard]] size_t
|
|
||||||
OffsetForMemberModifier(const MemberInformation& memberInfo, const DeclarationModifierComputations& modifier, const size_t nestedBaseOffset) const
|
|
||||||
{
|
|
||||||
size_t curOffset = memberInfo.m_member->m_offset;
|
|
||||||
|
|
||||||
const auto& declModifiers = memberInfo.m_member->m_type_declaration->m_declaration_modifiers;
|
|
||||||
auto curDeclModifier = declModifiers.begin();
|
|
||||||
auto curLevel = 0u;
|
|
||||||
for (const auto index : modifier.GetArrayIndices())
|
|
||||||
{
|
|
||||||
if (index > 0)
|
|
||||||
curOffset += index * SizeForDeclModifierLevel(memberInfo, curLevel + 1);
|
|
||||||
|
|
||||||
curLevel++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return curOffset + nestedBaseOffset;
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintFillStruct_Member_DynamicArray(const StructureInformation& structInfo,
|
void PrintFillStruct_Member_DynamicArray(const StructureInformation& structInfo,
|
||||||
const MemberInformation& memberInfo,
|
const MemberInformation& memberInfo,
|
||||||
const DeclarationModifierComputations& modifier,
|
const DeclarationModifierComputations& modifier,
|
||||||
@@ -619,7 +596,7 @@ namespace
|
|||||||
{
|
{
|
||||||
const MemberComputations computations(&member);
|
const MemberComputations computations(&member);
|
||||||
|
|
||||||
if (computations.IsFirstUsedMember())
|
if (computations.IsFirstUsedMember(true))
|
||||||
{
|
{
|
||||||
if (member.m_condition)
|
if (member.m_condition)
|
||||||
{
|
{
|
||||||
@@ -637,7 +614,7 @@ namespace
|
|||||||
PrintFillStruct_Member(structInfo, member, DeclarationModifierComputations(&member), 0u);
|
PrintFillStruct_Member(structInfo, member, DeclarationModifierComputations(&member), 0u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (computations.IsLastUsedMember())
|
else if (computations.IsLastUsedMember(true))
|
||||||
{
|
{
|
||||||
if (member.m_condition)
|
if (member.m_condition)
|
||||||
{
|
{
|
||||||
@@ -691,35 +668,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
const auto* dynamicMember = StructureComputations(&info).GetDynamicMember();
|
const auto* dynamicMember = StructureComputations(&info).GetDynamicMember();
|
||||||
|
if (info.m_definition->GetType() == DataDefinitionType::UNION)
|
||||||
if (dynamicMember)
|
|
||||||
{
|
|
||||||
if (info.m_definition->GetType() == DataDefinitionType::UNION)
|
|
||||||
{
|
|
||||||
for (const auto& member : info.m_ordered_members)
|
|
||||||
{
|
|
||||||
const MemberComputations computations(member.get());
|
|
||||||
if (computations.ShouldIgnore())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PrintFillStruct_Member_Condition_Union(info, *member);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (const auto& member : info.m_ordered_members)
|
|
||||||
{
|
|
||||||
const MemberComputations computations(member.get());
|
|
||||||
if (computations.ShouldIgnore() || member.get() == dynamicMember)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
PrintFillStruct_Member(info, *member, DeclarationModifierComputations(member.get()), 0u);
|
|
||||||
}
|
|
||||||
|
|
||||||
PrintFillStruct_Member_Condition_Struct(info, *dynamicMember);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
for (const auto& member : info.m_ordered_members)
|
for (const auto& member : info.m_ordered_members)
|
||||||
{
|
{
|
||||||
@@ -727,8 +676,22 @@ namespace
|
|||||||
if (computations.ShouldIgnore())
|
if (computations.ShouldIgnore())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
PrintFillStruct_Member_Condition_Union(info, *member);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto& member : info.m_ordered_members)
|
||||||
|
{
|
||||||
|
const MemberComputations computations(member.get());
|
||||||
|
if (computations.ShouldIgnore() || member.get() == dynamicMember)
|
||||||
|
continue;
|
||||||
|
|
||||||
PrintFillStruct_Member(info, *member, DeclarationModifierComputations(member.get()), 0u);
|
PrintFillStruct_Member(info, *member, DeclarationModifierComputations(member.get()), 0u);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dynamicMember)
|
||||||
|
PrintFillStruct_Member_Condition_Struct(info, *dynamicMember);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -833,7 +796,7 @@ namespace
|
|||||||
if (computations.ShouldIgnore())
|
if (computations.ShouldIgnore())
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (computations.IsFirstUsedMember())
|
if (computations.IsFirstUsedMember(false))
|
||||||
{
|
{
|
||||||
LINE("")
|
LINE("")
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
@@ -852,7 +815,7 @@ namespace
|
|||||||
PrintDynamicOversize_DynamicMember(info, *member);
|
PrintDynamicOversize_DynamicMember(info, *member);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (computations.IsLastUsedMember())
|
else if (computations.IsLastUsedMember(false))
|
||||||
{
|
{
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
{
|
{
|
||||||
@@ -1811,7 +1774,7 @@ namespace
|
|||||||
{
|
{
|
||||||
const MemberComputations computations(member);
|
const MemberComputations computations(member);
|
||||||
|
|
||||||
if (computations.IsFirstUsedMember())
|
if (computations.IsFirstUsedMember(false))
|
||||||
{
|
{
|
||||||
LINE("")
|
LINE("")
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
@@ -1830,7 +1793,7 @@ namespace
|
|||||||
LoadMember_Reference(info, member, DeclarationModifierComputations(member));
|
LoadMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (computations.IsLastUsedMember())
|
else if (computations.IsLastUsedMember(false))
|
||||||
{
|
{
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
{
|
{
|
||||||
@@ -2192,6 +2155,23 @@ namespace
|
|||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
std::vector<CodeTemplateFile> ZoneLoadTemplate::GetFilesToRenderOncePerTemplate(const OncePerTemplateRenderingContext& context)
|
||||||
|
{
|
||||||
|
std::vector<CodeTemplateFile> files;
|
||||||
|
|
||||||
|
files.emplace_back(std::format("AssetLoader{0}.h", context.m_game), TAG_ALL_LOADERS);
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneLoadTemplate::RenderOncePerTemplateFile(std::ostream& stream, const CodeTemplateFileTag fileTag, const OncePerTemplateRenderingContext& context)
|
||||||
|
{
|
||||||
|
assert(fileTag == TAG_ALL_LOADERS);
|
||||||
|
|
||||||
|
const PerTemplate t(stream, context);
|
||||||
|
t.AllLoaders();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<CodeTemplateFile> ZoneLoadTemplate::GetFilesToRenderOncePerAsset(const OncePerAssetRenderingContext& context)
|
std::vector<CodeTemplateFile> ZoneLoadTemplate::GetFilesToRenderOncePerAsset(const OncePerAssetRenderingContext& context)
|
||||||
{
|
{
|
||||||
std::vector<CodeTemplateFile> files;
|
std::vector<CodeTemplateFile> files;
|
||||||
@@ -2199,8 +2179,11 @@ std::vector<CodeTemplateFile> ZoneLoadTemplate::GetFilesToRenderOncePerAsset(con
|
|||||||
auto assetName = context.m_asset->m_definition->m_name;
|
auto assetName = context.m_asset->m_definition->m_name;
|
||||||
utils::MakeStringLowerCase(assetName);
|
utils::MakeStringLowerCase(assetName);
|
||||||
|
|
||||||
files.emplace_back(std::format("XAssets/{0}/{0}_load_db.h", assetName), TAG_HEADER);
|
auto gameName = context.m_game;
|
||||||
files.emplace_back(std::format("XAssets/{0}/{0}_load_db.cpp", assetName), TAG_SOURCE);
|
utils::MakeStringLowerCase(gameName);
|
||||||
|
|
||||||
|
files.emplace_back(std::format("XAssets/{0}/{0}_{1}_load_db.h", assetName, gameName), TAG_HEADER);
|
||||||
|
files.emplace_back(std::format("XAssets/{0}/{0}_{1}_load_db.cpp", assetName, gameName), TAG_SOURCE);
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
class ZoneLoadTemplate final : public ICodeTemplate
|
class ZoneLoadTemplate final : public ICodeTemplate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
std::vector<CodeTemplateFile> GetFilesToRenderOncePerTemplate(const OncePerTemplateRenderingContext& context) override;
|
||||||
|
void RenderOncePerTemplateFile(std::ostream& stream, CodeTemplateFileTag fileTag, const OncePerTemplateRenderingContext& context) override;
|
||||||
|
|
||||||
std::vector<CodeTemplateFile> GetFilesToRenderOncePerAsset(const OncePerAssetRenderingContext& context) override;
|
std::vector<CodeTemplateFile> GetFilesToRenderOncePerAsset(const OncePerAssetRenderingContext& context) override;
|
||||||
void RenderOncePerAssetFile(std::ostream& stream, CodeTemplateFileTag fileTag, const OncePerAssetRenderingContext& context) override;
|
void RenderOncePerAssetFile(std::ostream& stream, CodeTemplateFileTag fileTag, const OncePerAssetRenderingContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ namespace
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PerTemplate(std::ostream& stream, const OncePerTemplateRenderingContext& context)
|
PerTemplate(std::ostream& stream, const OncePerTemplateRenderingContext& context)
|
||||||
: BaseTemplate(stream),
|
: BaseTemplate(stream, context),
|
||||||
m_env(context)
|
m_env(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -32,10 +32,7 @@ namespace
|
|||||||
|
|
||||||
for (const auto* asset : m_env.m_assets)
|
for (const auto* asset : m_env.m_assets)
|
||||||
{
|
{
|
||||||
auto lowerAssetName = asset->m_definition->m_name;
|
LINEF("#include \"Game/{0}/XAssets/{1}/{1}_{2}_mark_db.h\"", m_env.m_game, Lower(asset->m_definition->m_name), Lower(m_env.m_game))
|
||||||
utils::MakeStringLowerCase(lowerAssetName);
|
|
||||||
|
|
||||||
LINEF("#include \"Game/{0}/XAssets/{1}/{1}_mark_db.h\"", m_env.m_game, lowerAssetName)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -47,7 +44,7 @@ namespace
|
|||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PerAsset(std::ostream& stream, const OncePerAssetRenderingContext& context)
|
PerAsset(std::ostream& stream, const OncePerAssetRenderingContext& context)
|
||||||
: BaseTemplate(stream),
|
: BaseTemplate(stream, context),
|
||||||
m_env(context)
|
m_env(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -142,7 +139,7 @@ namespace
|
|||||||
{
|
{
|
||||||
AddGeneratedHint();
|
AddGeneratedHint();
|
||||||
|
|
||||||
LINEF("#include \"{0}_mark_db.h\"", Lower(m_env.m_asset->m_definition->m_name))
|
LINEF("#include \"{0}_{1}_mark_db.h\"", Lower(m_env.m_asset->m_definition->m_name), Lower(m_env.m_game))
|
||||||
|
|
||||||
if (!m_env.m_referenced_assets.empty())
|
if (!m_env.m_referenced_assets.empty())
|
||||||
{
|
{
|
||||||
@@ -150,7 +147,7 @@ namespace
|
|||||||
LINE("// Referenced Assets:")
|
LINE("// Referenced Assets:")
|
||||||
for (const auto* type : m_env.m_referenced_assets)
|
for (const auto* type : m_env.m_referenced_assets)
|
||||||
{
|
{
|
||||||
LINEF("#include \"../{0}/{0}_mark_db.h\"", Lower(type->m_type->m_name))
|
LINEF("#include \"../{0}/{0}_{1}_mark_db.h\"", Lower(type->m_type->m_name), Lower(m_env.m_game))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LINE("")
|
LINE("")
|
||||||
@@ -673,7 +670,7 @@ namespace
|
|||||||
{
|
{
|
||||||
const MemberComputations computations(member);
|
const MemberComputations computations(member);
|
||||||
|
|
||||||
if (computations.IsFirstUsedMember())
|
if (computations.IsFirstUsedMember(false))
|
||||||
{
|
{
|
||||||
LINE("")
|
LINE("")
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
@@ -692,7 +689,7 @@ namespace
|
|||||||
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
MarkMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (computations.IsLastUsedMember())
|
else if (computations.IsLastUsedMember(false))
|
||||||
{
|
{
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
{
|
{
|
||||||
@@ -802,7 +799,7 @@ void ZoneMarkTemplate::RenderOncePerTemplateFile(std::ostream& stream, const Cod
|
|||||||
{
|
{
|
||||||
assert(fileTag == TAG_ALL_MARKERS);
|
assert(fileTag == TAG_ALL_MARKERS);
|
||||||
|
|
||||||
PerTemplate t(stream, context);
|
const PerTemplate t(stream, context);
|
||||||
t.AllMarkers();
|
t.AllMarkers();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -813,8 +810,11 @@ std::vector<CodeTemplateFile> ZoneMarkTemplate::GetFilesToRenderOncePerAsset(con
|
|||||||
auto assetName = context.m_asset->m_definition->m_name;
|
auto assetName = context.m_asset->m_definition->m_name;
|
||||||
utils::MakeStringLowerCase(assetName);
|
utils::MakeStringLowerCase(assetName);
|
||||||
|
|
||||||
files.emplace_back(std::format("XAssets/{0}/{0}_mark_db.h", assetName), TAG_HEADER);
|
auto gameName = context.m_game;
|
||||||
files.emplace_back(std::format("XAssets/{0}/{0}_mark_db.cpp", assetName), TAG_SOURCE);
|
utils::MakeStringLowerCase(gameName);
|
||||||
|
|
||||||
|
files.emplace_back(std::format("XAssets/{0}/{0}_{1}_mark_db.h", assetName, gameName), TAG_HEADER);
|
||||||
|
files.emplace_back(std::format("XAssets/{0}/{0}_{1}_mark_db.cpp", assetName, gameName), TAG_SOURCE);
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
#include "Domain/Computations/StructureComputations.h"
|
#include "Domain/Computations/StructureComputations.h"
|
||||||
#include "Internal/BaseTemplate.h"
|
#include "Internal/BaseTemplate.h"
|
||||||
|
#include "Utils/StringUtils.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@@ -11,12 +12,39 @@ namespace
|
|||||||
{
|
{
|
||||||
constexpr CodeTemplateFileTag TAG_HEADER = 1;
|
constexpr CodeTemplateFileTag TAG_HEADER = 1;
|
||||||
constexpr CodeTemplateFileTag TAG_SOURCE = 2;
|
constexpr CodeTemplateFileTag TAG_SOURCE = 2;
|
||||||
|
constexpr CodeTemplateFileTag TAG_ALL_WRITERS = 3;
|
||||||
|
|
||||||
|
class PerTemplate final : BaseTemplate
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PerTemplate(std::ostream& stream, const OncePerTemplateRenderingContext& context)
|
||||||
|
: BaseTemplate(stream, context),
|
||||||
|
m_env(context)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void AllWriters() const
|
||||||
|
{
|
||||||
|
AddGeneratedHint();
|
||||||
|
|
||||||
|
LINE("#pragma once")
|
||||||
|
LINE("")
|
||||||
|
|
||||||
|
for (const auto* asset : m_env.m_assets)
|
||||||
|
{
|
||||||
|
LINEF("#include \"Game/{0}/XAssets/{1}/{1}_{2}_write_db.h\"", m_env.m_game, Lower(asset->m_definition->m_name), Lower(m_env.m_game))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
const OncePerTemplateRenderingContext& m_env;
|
||||||
|
};
|
||||||
|
|
||||||
class PerAsset final : BaseTemplate
|
class PerAsset final : BaseTemplate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
PerAsset(std::ostream& stream, const OncePerAssetRenderingContext& context)
|
PerAsset(std::ostream& stream, const OncePerAssetRenderingContext& context)
|
||||||
: BaseTemplate(stream),
|
: BaseTemplate(stream, context),
|
||||||
m_env(context)
|
m_env(context)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
@@ -51,6 +79,16 @@ namespace
|
|||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
// Method Declarations
|
// Method Declarations
|
||||||
|
if (m_env.m_architecture_mismatch)
|
||||||
|
{
|
||||||
|
for (const auto* type : m_env.m_used_types)
|
||||||
|
{
|
||||||
|
if (ShouldGenerateFillMethod(*type))
|
||||||
|
{
|
||||||
|
PrintFillStructMethodDeclaration(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)
|
||||||
@@ -78,27 +116,35 @@ namespace
|
|||||||
LINE("")
|
LINE("")
|
||||||
|
|
||||||
LINE(VariableDecl(m_env.m_asset->m_definition))
|
LINE(VariableDecl(m_env.m_asset->m_definition))
|
||||||
LINE(WrittenVariableDecl(m_env.m_asset->m_definition))
|
|
||||||
LINE(PointerVariableDecl(m_env.m_asset->m_definition))
|
LINE(PointerVariableDecl(m_env.m_asset->m_definition))
|
||||||
|
LINE(WrittenVariableDecl(m_env.m_asset->m_definition))
|
||||||
LINE(WrittenPointerVariableDecl(m_env.m_asset->m_definition))
|
LINE(WrittenPointerVariableDecl(m_env.m_asset->m_definition))
|
||||||
LINE("")
|
LINE("")
|
||||||
|
|
||||||
// Variable Declarations: type varType;
|
// Variable Declarations: type varType;
|
||||||
for (const auto* type : m_env.m_used_types)
|
for (const auto* type : m_env.m_used_types)
|
||||||
{
|
{
|
||||||
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
|
if (type->m_info && !type->m_info->m_definition->m_anonymous
|
||||||
{
|
&& (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset())
|
||||||
LINE(VariableDecl(type->m_type))
|
LINE(VariableDecl(type->m_type))
|
||||||
LINE(WrittenVariableDecl(type->m_type))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
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 && !type->m_is_context_asset)
|
if (type->m_pointer_array_reference_exists && !type->m_is_context_asset)
|
||||||
{
|
|
||||||
LINE(PointerVariableDecl(type->m_type))
|
LINE(PointerVariableDecl(type->m_type))
|
||||||
|
}
|
||||||
|
|
||||||
|
LINE("")
|
||||||
|
|
||||||
|
for (const auto* type : m_env.m_used_types)
|
||||||
|
{
|
||||||
|
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
|
||||||
|
LINE(WrittenVariableDecl(type->m_type))
|
||||||
|
}
|
||||||
|
for (const auto* type : m_env.m_used_types)
|
||||||
|
{
|
||||||
|
if (type->m_pointer_array_reference_exists && !type->m_is_context_asset)
|
||||||
LINE(WrittenPointerVariableDecl(type->m_type))
|
LINE(WrittenPointerVariableDecl(type->m_type))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
@@ -111,7 +157,7 @@ namespace
|
|||||||
{
|
{
|
||||||
AddGeneratedHint();
|
AddGeneratedHint();
|
||||||
|
|
||||||
LINEF("#include \"{0}_write_db.h\"", Lower(m_env.m_asset->m_definition->m_name))
|
LINEF("#include \"{0}_{1}_write_db.h\"", Lower(m_env.m_asset->m_definition->m_name), Lower(m_env.m_game))
|
||||||
|
|
||||||
if (!m_env.m_referenced_assets.empty())
|
if (!m_env.m_referenced_assets.empty())
|
||||||
{
|
{
|
||||||
@@ -119,7 +165,7 @@ namespace
|
|||||||
LINE("// Referenced Assets:")
|
LINE("// Referenced Assets:")
|
||||||
for (const auto* type : m_env.m_referenced_assets)
|
for (const auto* type : m_env.m_referenced_assets)
|
||||||
{
|
{
|
||||||
LINEF("#include \"../{0}/{0}_write_db.h\"", Lower(type->m_type->m_name))
|
LINEF("#include \"../{0}/{0}_{1}_write_db.h\"", Lower(type->m_type->m_name), Lower(m_env.m_game))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,6 +178,17 @@ namespace
|
|||||||
LINE("")
|
LINE("")
|
||||||
PrintMainWriteMethod();
|
PrintMainWriteMethod();
|
||||||
|
|
||||||
|
if (m_env.m_architecture_mismatch)
|
||||||
|
{
|
||||||
|
for (const auto* type : m_env.m_used_types)
|
||||||
|
{
|
||||||
|
if (ShouldGenerateFillMethod(*type))
|
||||||
|
{
|
||||||
|
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)
|
||||||
@@ -185,7 +242,7 @@ namespace
|
|||||||
|
|
||||||
static std::string WrittenVariableDecl(const DataDefinition* def)
|
static std::string WrittenVariableDecl(const DataDefinition* def)
|
||||||
{
|
{
|
||||||
return std::format("{0}* var{1}Written;", def->GetFullName(), MakeSafeTypeName(def));
|
return std::format("ZoneOutputOffset var{0}Written;", MakeSafeTypeName(def));
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string PointerVariableDecl(const DataDefinition* def)
|
static std::string PointerVariableDecl(const DataDefinition* def)
|
||||||
@@ -195,7 +252,12 @@ namespace
|
|||||||
|
|
||||||
static std::string WrittenPointerVariableDecl(const DataDefinition* def)
|
static std::string WrittenPointerVariableDecl(const DataDefinition* def)
|
||||||
{
|
{
|
||||||
return std::format("{0}** var{1}PtrWritten;", def->GetFullName(), MakeSafeTypeName(def));
|
return std::format("ZoneOutputOffset var{0}PtrWritten;", MakeSafeTypeName(def));
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintFillStructMethodDeclaration(const StructureInformation* info) const
|
||||||
|
{
|
||||||
|
LINEF("void FillStruct_{0}(const ZoneStreamFillWriteAccessor& fillAccessor);", MakeSafeTypeName(info->m_definition))
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderPtrArrayWriteMethodDeclaration(const DataDefinition* def) const
|
void PrintHeaderPtrArrayWriteMethodDeclaration(const DataDefinition* def) const
|
||||||
@@ -220,12 +282,12 @@ namespace
|
|||||||
|
|
||||||
void PrintHeaderMainWriteMethodDeclaration(const StructureInformation* info) const
|
void PrintHeaderMainWriteMethodDeclaration(const StructureInformation* info) const
|
||||||
{
|
{
|
||||||
LINEF("void Write({0}** pAsset);", info->m_definition->GetFullName())
|
LINEF("void Write({0}* pAsset, ZoneOutputOffset pointerWrittenOffset);", info->m_definition->GetFullName())
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintHeaderConstructor() const
|
void PrintHeaderConstructor() const
|
||||||
{
|
{
|
||||||
LINEF("{0}({1}* asset, const Zone& zone, IZoneOutputStream& stream);", WriterClassName(m_env.m_asset), m_env.m_asset->m_definition->GetFullName())
|
LINEF("{0}({1}* asset, const Zone& zone, ZoneOutputStream& stream);", WriterClassName(m_env.m_asset), m_env.m_asset->m_definition->GetFullName())
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintVariableInitialization(const DataDefinition* def) const
|
void PrintVariableInitialization(const DataDefinition* def) const
|
||||||
@@ -233,25 +295,66 @@ namespace
|
|||||||
LINEF("var{0} = nullptr;", def->m_name)
|
LINEF("var{0} = nullptr;", def->m_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintWrittenVariableInitialization(const DataDefinition* def) const
|
|
||||||
{
|
|
||||||
LINEF("var{0}Written = nullptr;", def->m_name)
|
|
||||||
}
|
|
||||||
|
|
||||||
void PrintPointerVariableInitialization(const DataDefinition* def) const
|
void PrintPointerVariableInitialization(const DataDefinition* def) const
|
||||||
{
|
{
|
||||||
LINEF("var{0}Ptr = nullptr;", def->m_name)
|
LINEF("var{0}Ptr = nullptr;", def->m_name)
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintWrittenPointerVariableInitialization(const DataDefinition* def) const
|
static void MakeTypeWrittenPtrVarNameInternal(const DataDefinition* def, std::ostringstream& str)
|
||||||
{
|
{
|
||||||
LINEF("var{0}PtrWritten = nullptr;", def->m_name)
|
str << "var";
|
||||||
|
MakeSafeTypeNameInternal(def, str);
|
||||||
|
str << "PtrWritten";
|
||||||
|
}
|
||||||
|
|
||||||
|
static void MakeTypeWrittenVarNameInternal(const DataDefinition* def, std::ostringstream& str)
|
||||||
|
{
|
||||||
|
str << "var";
|
||||||
|
MakeSafeTypeNameInternal(def, str);
|
||||||
|
str << "Written";
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string MakeTypeWrittenVarName(const DataDefinition* def)
|
||||||
|
{
|
||||||
|
std::ostringstream str;
|
||||||
|
MakeTypeWrittenVarNameInternal(def, str);
|
||||||
|
return str.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::string MakeTypeWrittenPtrVarName(const DataDefinition* def)
|
||||||
|
{
|
||||||
|
std::ostringstream str;
|
||||||
|
MakeTypeWrittenPtrVarNameInternal(def, str);
|
||||||
|
return str.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string
|
||||||
|
MakeWrittenMemberAccess(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
||||||
|
{
|
||||||
|
std::ostringstream str;
|
||||||
|
MakeTypeWrittenVarNameInternal(info->m_definition, str);
|
||||||
|
str << ".AtOffset(";
|
||||||
|
|
||||||
|
if (m_env.m_architecture_mismatch)
|
||||||
|
{
|
||||||
|
str << OffsetForMemberModifier(*member, modifier, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
str << "offsetof(" << info->m_definition->GetFullName() << ", " << member->m_member->m_name;
|
||||||
|
MakeArrayIndicesInternal(modifier, str);
|
||||||
|
str << ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
str << ')';
|
||||||
|
|
||||||
|
return str.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintConstructorMethod()
|
void PrintConstructorMethod()
|
||||||
{
|
{
|
||||||
LINEF(
|
LINEF(
|
||||||
"{0}::{0}({1}* asset, const Zone& zone, IZoneOutputStream& stream)", WriterClassName(m_env.m_asset), m_env.m_asset->m_definition->GetFullName())
|
"{0}::{0}({1}* asset, const Zone& zone, ZoneOutputStream& stream)", WriterClassName(m_env.m_asset), m_env.m_asset->m_definition->GetFullName())
|
||||||
|
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
LINEF(": AssetWriter(zone.m_pools->GetAssetOrAssetReference({0}::EnumEntry, NonReferenceAssetName(AssetName<{0}>(*asset))), zone, stream)",
|
LINEF(": AssetWriter(zone.m_pools->GetAssetOrAssetReference({0}::EnumEntry, NonReferenceAssetName(AssetName<{0}>(*asset))), zone, stream)",
|
||||||
@@ -262,26 +365,19 @@ namespace
|
|||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
PrintVariableInitialization(m_env.m_asset->m_definition);
|
PrintVariableInitialization(m_env.m_asset->m_definition);
|
||||||
PrintWrittenVariableInitialization(m_env.m_asset->m_definition);
|
|
||||||
PrintPointerVariableInitialization(m_env.m_asset->m_definition);
|
PrintPointerVariableInitialization(m_env.m_asset->m_definition);
|
||||||
PrintWrittenPointerVariableInitialization(m_env.m_asset->m_definition);
|
|
||||||
LINE("")
|
LINE("")
|
||||||
|
|
||||||
for (const auto* type : m_env.m_used_types)
|
for (const auto* type : m_env.m_used_types)
|
||||||
{
|
{
|
||||||
if (type->m_info && !type->m_info->m_definition->m_anonymous && !type->m_info->m_is_leaf && !StructureComputations(type->m_info).IsAsset())
|
if (type->m_info && !type->m_info->m_definition->m_anonymous
|
||||||
{
|
&& (!type->m_info->m_is_leaf || !type->m_info->m_has_matching_cross_platform_structure) && !StructureComputations(type->m_info).IsAsset())
|
||||||
PrintVariableInitialization(type->m_type);
|
PrintVariableInitialization(type->m_type);
|
||||||
PrintWrittenVariableInitialization(type->m_type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
for (const auto* type : m_env.m_used_types)
|
for (const auto* type : m_env.m_used_types)
|
||||||
{
|
{
|
||||||
if (type->m_info && type->m_pointer_array_reference_exists && !type->m_is_context_asset)
|
if (type->m_info && type->m_pointer_array_reference_exists && !type->m_is_context_asset)
|
||||||
{
|
|
||||||
PrintPointerVariableInitialization(type->m_type);
|
PrintPointerVariableInitialization(type->m_type);
|
||||||
PrintWrittenPointerVariableInitialization(type->m_type);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
@@ -301,12 +397,13 @@ namespace
|
|||||||
}
|
}
|
||||||
else if (writeType == MemberWriteType::EMBEDDED_ARRAY)
|
else if (writeType == MemberWriteType::EMBEDDED_ARRAY)
|
||||||
{
|
{
|
||||||
|
LINEF("varScriptString = {0};", MakeMemberAccess(info, member, modifier))
|
||||||
LINEF("varScriptStringWritten = {0};", MakeWrittenMemberAccess(info, member, modifier))
|
LINEF("varScriptStringWritten = {0};", MakeWrittenMemberAccess(info, member, modifier))
|
||||||
LINEF("WriteScriptStringArray(false, {0});", MakeArrayCount(dynamic_cast<ArrayDeclarationModifier*>(modifier.GetDeclarationModifier())))
|
LINEF("WriteScriptStringArray(false, {0});", MakeArrayCount(dynamic_cast<ArrayDeclarationModifier*>(modifier.GetDeclarationModifier())))
|
||||||
}
|
}
|
||||||
else if (writeType == MemberWriteType::EMBEDDED)
|
else if (writeType == MemberWriteType::EMBEDDED)
|
||||||
{
|
{
|
||||||
LINEF("{0} = UseScriptString({1});", MakeWrittenMemberAccess(info, member, modifier), MakeMemberAccess(info, member, modifier))
|
LINEF("UseScriptString({0}, {1});", MakeMemberAccess(info, member, modifier), MakeWrittenMemberAccess(info, member, modifier))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -323,7 +420,7 @@ namespace
|
|||||||
if (writeType == MemberWriteType::SINGLE_POINTER)
|
if (writeType == MemberWriteType::SINGLE_POINTER)
|
||||||
{
|
{
|
||||||
LINEF("{0} writer({1}, m_zone, *m_stream);", WriterClassName(member->m_type), MakeMemberAccess(info, member, modifier))
|
LINEF("{0} writer({1}, m_zone, *m_stream);", WriterClassName(member->m_type), MakeMemberAccess(info, member, modifier))
|
||||||
LINEF("writer.Write(&{0});", MakeWrittenMemberAccess(info, member, modifier))
|
LINEF("writer.Write({0}, {1});", MakeMemberAccess(info, member, modifier), MakeWrittenMemberAccess(info, member, modifier))
|
||||||
}
|
}
|
||||||
else if (writeType == MemberWriteType::POINTER_ARRAY)
|
else if (writeType == MemberWriteType::POINTER_ARRAY)
|
||||||
{
|
{
|
||||||
@@ -345,18 +442,20 @@ namespace
|
|||||||
{
|
{
|
||||||
if (member->m_member->m_type_declaration->m_is_const)
|
if (member->m_member->m_type_declaration->m_is_const)
|
||||||
{
|
{
|
||||||
LINEF("varXStringWritten = &{0};", MakeWrittenMemberAccess(info, member, modifier))
|
LINEF("varXString = &{0};", MakeMemberAccess(info, member, modifier))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LINEF("varXStringWritten = const_cast<const char**>(&{0});", MakeWrittenMemberAccess(info, member, modifier))
|
LINEF("varXString = const_cast<const char**>(&{0});", MakeMemberAccess(info, member, modifier))
|
||||||
}
|
}
|
||||||
|
LINEF("varXStringWritten = {0};", MakeWrittenMemberAccess(info, member, modifier))
|
||||||
LINE("WriteXString(false);")
|
LINE("WriteXString(false);")
|
||||||
}
|
}
|
||||||
else if (writeType == MemberWriteType::POINTER_ARRAY)
|
else if (writeType == MemberWriteType::POINTER_ARRAY)
|
||||||
{
|
{
|
||||||
if (modifier.IsArray())
|
if (modifier.IsArray())
|
||||||
{
|
{
|
||||||
|
LINEF("varXString = {0};", MakeMemberAccess(info, member, modifier))
|
||||||
LINEF("varXStringWritten = {0};", MakeWrittenMemberAccess(info, member, modifier))
|
LINEF("varXStringWritten = {0};", MakeWrittenMemberAccess(info, member, modifier))
|
||||||
LINEF("WriteXStringArray(false, {0});", modifier.GetArraySize())
|
LINEF("WriteXStringArray(false, {0});", modifier.GetArraySize())
|
||||||
}
|
}
|
||||||
@@ -374,7 +473,7 @@ namespace
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteMember_ArrayPointer(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier) const
|
void WriteMember_ArrayPointer(const StructureInformation* info, const MemberInformation* member, const DeclarationModifierComputations& modifier)
|
||||||
{
|
{
|
||||||
const MemberComputations computations(member);
|
const MemberComputations computations(member);
|
||||||
LINEF("m_stream->MarkFollowing({0});", MakeWrittenMemberAccess(info, member, modifier))
|
LINEF("m_stream->MarkFollowing({0});", MakeWrittenMemberAccess(info, member, modifier))
|
||||||
@@ -385,6 +484,27 @@ namespace
|
|||||||
MakeSafeTypeName(member->m_member->m_type_declaration->m_type),
|
MakeSafeTypeName(member->m_member->m_type_declaration->m_type),
|
||||||
MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
|
MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
|
||||||
}
|
}
|
||||||
|
else if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure)
|
||||||
|
{
|
||||||
|
LINEF("const auto fillArraySize = static_cast<size_t>({0});", MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
|
||||||
|
if (!computations.IsInRuntimeBlock())
|
||||||
|
{
|
||||||
|
LINEF("const auto fill = m_stream->WriteWithFill({0} * fillArraySize);", member->m_member->m_type_declaration->m_type->GetSize())
|
||||||
|
LINE("for (auto i = 0uz; i < fillArraySize; i++)")
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
LINEF("{0} = &{1}[i];", MakeTypeVarName(member->m_type->m_definition), MakeMemberAccess(info, member, modifier))
|
||||||
|
LINEF("FillStruct_{0}(fill.AtOffset(i * {1}));",
|
||||||
|
MakeSafeTypeName(member->m_type->m_definition),
|
||||||
|
member->m_member->m_type_declaration->m_type->GetSize())
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINEF("m_stream->IncBlockPos({0} * fillArraySize);", member->m_member->m_type_declaration->m_type->GetSize())
|
||||||
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LINEF("m_stream->Write<{0}{1}>({2}, {3});",
|
LINEF("m_stream->Write<{0}{1}>({2}, {3});",
|
||||||
@@ -479,7 +599,7 @@ namespace
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
LINEF("{0} = &{1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
LINEF("{0} = &{1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
||||||
LINEF("{0} = &{1};", MakeTypeWrittenVarName(member->m_member->m_type_declaration->m_type), MakeWrittenMemberAccess(info, member, modifier))
|
LINEF("{0} = {1};", MakeTypeWrittenVarName(member->m_member->m_type_declaration->m_type), MakeWrittenMemberAccess(info, member, modifier))
|
||||||
LINEF("Write_{0}(false);", MakeSafeTypeName(member->m_member->m_type_declaration->m_type))
|
LINEF("Write_{0}(false);", MakeSafeTypeName(member->m_member->m_type_declaration->m_type))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -501,6 +621,13 @@ namespace
|
|||||||
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
||||||
LINEF("Write_{0}(true);", MakeSafeTypeName(member->m_type->m_definition))
|
LINEF("Write_{0}(true);", MakeSafeTypeName(member->m_type->m_definition))
|
||||||
}
|
}
|
||||||
|
else if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure)
|
||||||
|
{
|
||||||
|
LINEF("{0} = {1};", MakeTypeVarName(member->m_member->m_type_declaration->m_type), MakeMemberAccess(info, member, modifier))
|
||||||
|
LINEF("FillStruct_{0}(m_stream->WriteWithFill({1}));",
|
||||||
|
MakeSafeTypeName(member->m_member->m_type_declaration->m_type),
|
||||||
|
member->m_member->m_type_declaration->m_type->GetSize())
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LINEF("m_stream->Write<{0}{1}>({2});",
|
LINEF("m_stream->Write<{0}{1}>({2});",
|
||||||
@@ -513,7 +640,7 @@ namespace
|
|||||||
void WriteMember_TypeCheck(const StructureInformation* info,
|
void WriteMember_TypeCheck(const StructureInformation* info,
|
||||||
const MemberInformation* member,
|
const MemberInformation* member,
|
||||||
const DeclarationModifierComputations& modifier,
|
const DeclarationModifierComputations& modifier,
|
||||||
const MemberWriteType writeType) const
|
const MemberWriteType writeType)
|
||||||
{
|
{
|
||||||
if (member->m_is_string)
|
if (member->m_is_string)
|
||||||
{
|
{
|
||||||
@@ -597,7 +724,7 @@ namespace
|
|||||||
void WriteMember_InsertReuse(const StructureInformation* info,
|
void WriteMember_InsertReuse(const StructureInformation* info,
|
||||||
const MemberInformation* member,
|
const MemberInformation* member,
|
||||||
const DeclarationModifierComputations& modifier,
|
const DeclarationModifierComputations& modifier,
|
||||||
const MemberWriteType writeType) const
|
const MemberWriteType writeType)
|
||||||
{
|
{
|
||||||
if (!WriteMember_ShouldMakeInsertReuse(member, modifier, writeType))
|
if (!WriteMember_ShouldMakeInsertReuse(member, modifier, writeType))
|
||||||
{
|
{
|
||||||
@@ -605,31 +732,37 @@ namespace
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LINE_STARTF("m_stream->ReusableAddOffset({0}", MakeMemberAccess(info, member, modifier))
|
||||||
|
|
||||||
if (writeType == MemberWriteType::ARRAY_POINTER)
|
if (writeType == MemberWriteType::ARRAY_POINTER)
|
||||||
{
|
{
|
||||||
LINEF("m_stream->ReusableAddOffset({0}, {1});",
|
if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure)
|
||||||
MakeMemberAccess(info, member, modifier),
|
{
|
||||||
MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
|
LINE_MIDDLEF(", {0}", member->m_type->m_definition->GetSize())
|
||||||
|
}
|
||||||
|
|
||||||
|
LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetArrayPointerCountEvaluation()))
|
||||||
}
|
}
|
||||||
else if (writeType == MemberWriteType::POINTER_ARRAY)
|
else if (writeType == MemberWriteType::POINTER_ARRAY)
|
||||||
{
|
{
|
||||||
|
if (member->m_type && !member->m_type->m_has_matching_cross_platform_structure)
|
||||||
|
{
|
||||||
|
LINE_MIDDLEF(", {0}", m_env.m_pointer_size)
|
||||||
|
}
|
||||||
|
|
||||||
const auto* evaluation = modifier.GetPointerArrayCountEvaluation();
|
const auto* evaluation = modifier.GetPointerArrayCountEvaluation();
|
||||||
|
|
||||||
if (evaluation)
|
if (evaluation)
|
||||||
{
|
{
|
||||||
LINEF("m_stream->ReusableAddOffset({0}, {1});",
|
LINE_MIDDLEF(", {0}", MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
|
||||||
MakeMemberAccess(info, member, modifier),
|
|
||||||
MakeEvaluation(modifier.GetPointerArrayCountEvaluation()))
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LINEF("m_stream->ReusableAddOffset({0}, {1});", MakeMemberAccess(info, member, modifier), modifier.GetArraySize())
|
LINE_MIDDLEF(", {0}", modifier.GetArraySize())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
LINE_END(");")
|
||||||
LINEF("m_stream->ReusableAddOffset({0});", MakeMemberAccess(info, member, modifier))
|
|
||||||
}
|
|
||||||
|
|
||||||
WriteMember_TypeCheck(info, member, modifier, writeType);
|
WriteMember_TypeCheck(info, member, modifier, writeType);
|
||||||
}
|
}
|
||||||
@@ -663,7 +796,7 @@ namespace
|
|||||||
void WriteMember_Align(const StructureInformation* info,
|
void WriteMember_Align(const StructureInformation* info,
|
||||||
const MemberInformation* member,
|
const MemberInformation* member,
|
||||||
const DeclarationModifierComputations& modifier,
|
const DeclarationModifierComputations& modifier,
|
||||||
const MemberWriteType writeType) const
|
const MemberWriteType writeType)
|
||||||
{
|
{
|
||||||
if (!WriteMember_ShouldMakeAlign(member, modifier, writeType))
|
if (!WriteMember_ShouldMakeAlign(member, modifier, writeType))
|
||||||
{
|
{
|
||||||
@@ -702,6 +835,14 @@ namespace
|
|||||||
return member->m_is_reusable;
|
return member->m_is_reusable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string MakeReusableInnerOffset(const DataDefinition* dataDefinition, const Variable* member) const
|
||||||
|
{
|
||||||
|
if (m_env.m_architecture_mismatch)
|
||||||
|
return std::to_string(member->m_offset);
|
||||||
|
|
||||||
|
return std::format("offsetof({0}, {1})", dataDefinition->GetFullName(), member->m_name);
|
||||||
|
}
|
||||||
|
|
||||||
void WriteMember_Reuse(const StructureInformation* info,
|
void WriteMember_Reuse(const StructureInformation* info,
|
||||||
const MemberInformation* member,
|
const MemberInformation* member,
|
||||||
const DeclarationModifierComputations& modifier,
|
const DeclarationModifierComputations& modifier,
|
||||||
@@ -713,7 +854,10 @@ namespace
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
LINEF("if (m_stream->ReusableShouldWrite(&{0}))", MakeWrittenMemberAccess(info, member, modifier))
|
LINEF("if (m_stream->ReusableShouldWrite({0}, {1}.AtOffset({2})))",
|
||||||
|
MakeMemberAccess(info, member, modifier),
|
||||||
|
MakeTypeWrittenVarName(info->m_definition),
|
||||||
|
MakeReusableInnerOffset(info->m_definition, member->m_member))
|
||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
@@ -867,7 +1011,7 @@ namespace
|
|||||||
{
|
{
|
||||||
const MemberComputations computations(member);
|
const MemberComputations computations(member);
|
||||||
|
|
||||||
if (computations.IsFirstUsedMember())
|
if (computations.IsFirstUsedMember(false))
|
||||||
{
|
{
|
||||||
LINE("")
|
LINE("")
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
@@ -886,7 +1030,7 @@ namespace
|
|||||||
WriteMember_Reference(info, member, DeclarationModifierComputations(member));
|
WriteMember_Reference(info, member, DeclarationModifierComputations(member));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (computations.IsLastUsedMember())
|
else if (computations.IsLastUsedMember(false))
|
||||||
{
|
{
|
||||||
if (member->m_condition)
|
if (member->m_condition)
|
||||||
{
|
{
|
||||||
@@ -961,29 +1105,42 @@ namespace
|
|||||||
if (!(info->m_definition->GetType() == DataDefinitionType::UNION && dynamicMember))
|
if (!(info->m_definition->GetType() == DataDefinitionType::UNION && dynamicMember))
|
||||||
{
|
{
|
||||||
LINE("if (atStreamStart)")
|
LINE("if (atStreamStart)")
|
||||||
m_intendation++;
|
|
||||||
|
|
||||||
if (dynamicMember == nullptr)
|
if (info->m_has_matching_cross_platform_structure)
|
||||||
{
|
{
|
||||||
LINEF("{0} = m_stream->Write<{1}>({2}); // Size: {3}",
|
m_intendation++;
|
||||||
MakeTypeWrittenVarName(info->m_definition),
|
if (dynamicMember == nullptr)
|
||||||
info->m_definition->GetFullName(),
|
{
|
||||||
MakeTypeVarName(info->m_definition),
|
LINEF("{0} = m_stream->Write<{1}>({2}); // Size: {3}",
|
||||||
info->m_definition->GetSize())
|
MakeTypeWrittenVarName(info->m_definition),
|
||||||
|
info->m_definition->GetFullName(),
|
||||||
|
MakeTypeVarName(info->m_definition),
|
||||||
|
info->m_definition->GetSize())
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINEF("{0} = m_stream->WritePartial({1}, offsetof({2}, {3}));",
|
||||||
|
MakeTypeWrittenVarName(info->m_definition),
|
||||||
|
MakeTypeVarName(info->m_definition),
|
||||||
|
info->m_definition->GetFullName(),
|
||||||
|
dynamicMember->m_member->m_name)
|
||||||
|
}
|
||||||
|
m_intendation--;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
LINEF("{0} = m_stream->WritePartial<{1}>({2}, offsetof({1}, {3}));",
|
LINE("{")
|
||||||
MakeTypeWrittenVarName(info->m_definition),
|
m_intendation++;
|
||||||
info->m_definition->GetFullName(),
|
LINEF("const auto fillAccessor = m_stream->WriteWithFill({0});",
|
||||||
MakeTypeVarName(info->m_definition),
|
dynamicMember == nullptr ? info->m_definition->GetSize() : dynamicMember->m_member->m_offset)
|
||||||
dynamicMember->m_member->m_name)
|
LINEF("{0} = fillAccessor.Offset();", MakeTypeWrittenVarName(info->m_definition))
|
||||||
|
LINEF("FillStruct_{0}(fillAccessor);", MakeSafeTypeName(info->m_definition))
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
}
|
}
|
||||||
|
|
||||||
m_intendation--;
|
|
||||||
|
|
||||||
LINE("")
|
LINE("")
|
||||||
LINEF("assert({0} != nullptr);", MakeTypeWrittenVarName(info->m_definition))
|
LINEF("assert({0}.Offset() != nullptr);", MakeTypeWrittenVarName(info->m_definition))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1028,14 +1185,11 @@ namespace
|
|||||||
|
|
||||||
LINE("if (atStreamStart)")
|
LINE("if (atStreamStart)")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
LINEF("{0} = m_stream->Write<{1}*>({2});",
|
LINEF("{0} = m_stream->WriteWithFill(m_stream->GetPointerByteCount()).Offset();", MakeTypeWrittenPtrVarName(info->m_definition))
|
||||||
MakeTypeWrittenPtrVarName(info->m_definition),
|
|
||||||
info->m_definition->GetFullName(),
|
|
||||||
MakeTypePtrVarName(info->m_definition))
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
|
|
||||||
LINE("")
|
LINE("")
|
||||||
LINEF("assert({0} != nullptr);", MakeTypeWrittenPtrVarName(info->m_definition))
|
LINEF("assert({0}.Offset() != nullptr);", MakeTypeWrittenPtrVarName(info->m_definition))
|
||||||
|
|
||||||
LINE("")
|
LINE("")
|
||||||
if (inTemp)
|
if (inTemp)
|
||||||
@@ -1043,7 +1197,7 @@ namespace
|
|||||||
LINEF("m_stream->PushBlock({0});", m_env.m_default_temp_block->m_name)
|
LINEF("m_stream->PushBlock({0});", m_env.m_default_temp_block->m_name)
|
||||||
LINE("")
|
LINE("")
|
||||||
}
|
}
|
||||||
LINEF("if (m_stream->ReusableShouldWrite({0}))", MakeTypeWrittenPtrVarName(info->m_definition))
|
LINEF("if (m_stream->ReusableShouldWrite(*{0}, {1}))", MakeTypePtrVarName(info->m_definition), MakeTypeWrittenPtrVarName(info->m_definition))
|
||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
@@ -1061,7 +1215,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
LINE("")
|
LINE("")
|
||||||
LINEF("m_stream->MarkFollowing(*{0});", MakeTypeWrittenPtrVarName(info->m_definition))
|
LINEF("m_stream->MarkFollowing({0});", MakeTypeWrittenPtrVarName(info->m_definition))
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
LINE("}")
|
LINE("}")
|
||||||
@@ -1078,7 +1232,9 @@ namespace
|
|||||||
|
|
||||||
void PrintMainWriteMethod()
|
void PrintMainWriteMethod()
|
||||||
{
|
{
|
||||||
LINEF("void {0}::Write({1}** pAsset)", WriterClassName(m_env.m_asset), m_env.m_asset->m_definition->GetFullName())
|
LINEF("void {0}::Write({1}* pAsset, const ZoneOutputOffset pointerWrittenOffset)",
|
||||||
|
WriterClassName(m_env.m_asset),
|
||||||
|
m_env.m_asset->m_definition->GetFullName())
|
||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
@@ -1088,9 +1244,233 @@ namespace
|
|||||||
LINE("")
|
LINE("")
|
||||||
LINEF("auto* zoneAsset = static_cast<{0}*>(m_asset->m_ptr);", m_env.m_asset->m_definition->GetFullName())
|
LINEF("auto* zoneAsset = static_cast<{0}*>(m_asset->m_ptr);", m_env.m_asset->m_definition->GetFullName())
|
||||||
LINEF("{0} = &zoneAsset;", MakeTypePtrVarName(m_env.m_asset->m_definition))
|
LINEF("{0} = &zoneAsset;", MakeTypePtrVarName(m_env.m_asset->m_definition))
|
||||||
LINEF("{0} = &zoneAsset;", MakeTypeWrittenPtrVarName(m_env.m_asset->m_definition))
|
LINEF("{0} = pointerWrittenOffset;", MakeTypeWrittenPtrVarName(m_env.m_asset->m_definition))
|
||||||
LINEF("WritePtr_{0}(false);", MakeSafeTypeName(m_env.m_asset->m_definition))
|
LINEF("WritePtr_{0}(false);", MakeSafeTypeName(m_env.m_asset->m_definition))
|
||||||
LINE("*pAsset = zoneAsset;")
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintFillStruct_Member_EmbeddedArray(const StructureInformation& structInfo,
|
||||||
|
const MemberInformation& memberInfo,
|
||||||
|
const DeclarationModifierComputations& modifier,
|
||||||
|
const size_t nestedBaseOffset)
|
||||||
|
{
|
||||||
|
if (memberInfo.m_type && !memberInfo.m_type->m_has_matching_cross_platform_structure)
|
||||||
|
{
|
||||||
|
LINEF("for (auto i = 0u; i < std::extent_v<decltype({0}::{1})>; i++)", structInfo.m_definition->m_name, memberInfo.m_member->m_name)
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
LINEF("{0} = &{1}[i];", MakeTypeVarName(memberInfo.m_member->m_type_declaration->m_type), MakeMemberAccess(&structInfo, &memberInfo, modifier))
|
||||||
|
LINEF("FillStruct_{0}(fillAccessor.AtOffset({1} + i * {2}));",
|
||||||
|
MakeSafeTypeName(memberInfo.m_member->m_type_declaration->m_type),
|
||||||
|
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset),
|
||||||
|
memberInfo.m_member->m_type_declaration->m_type->GetSize())
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINEF("fillAccessor.FillArray({0}, {1});",
|
||||||
|
MakeMemberAccess(&structInfo, &memberInfo, modifier),
|
||||||
|
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintFillStruct_Member_Embedded(const StructureInformation& structInfo,
|
||||||
|
const MemberInformation& memberInfo,
|
||||||
|
const DeclarationModifierComputations& modifier,
|
||||||
|
const size_t nestedBaseOffset)
|
||||||
|
{
|
||||||
|
const auto hasAnonymousType = memberInfo.m_type && memberInfo.m_type->m_definition->m_anonymous;
|
||||||
|
|
||||||
|
if (!hasAnonymousType)
|
||||||
|
{
|
||||||
|
const auto hasMismatchingStructure = memberInfo.m_type && !memberInfo.m_type->m_has_matching_cross_platform_structure;
|
||||||
|
const auto hasDynamicMember = memberInfo.m_type && StructureComputations(memberInfo.m_type).GetDynamicMember();
|
||||||
|
if (hasMismatchingStructure || hasDynamicMember)
|
||||||
|
{
|
||||||
|
LINEF("{0} = &{1};", MakeTypeVarName(memberInfo.m_member->m_type_declaration->m_type), MakeMemberAccess(&structInfo, &memberInfo, modifier))
|
||||||
|
LINEF("FillStruct_{0}(fillAccessor.AtOffset({1}));",
|
||||||
|
MakeSafeTypeName(memberInfo.m_member->m_type_declaration->m_type),
|
||||||
|
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset))
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINEF("fillAccessor.Fill({0}, {1});",
|
||||||
|
MakeMemberAccess(&structInfo, &memberInfo, modifier),
|
||||||
|
OffsetForMemberModifier(memberInfo, modifier, nestedBaseOffset))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (memberInfo.m_member->m_name.empty())
|
||||||
|
{
|
||||||
|
const auto anonymousMemberOffset = memberInfo.m_member->m_offset + nestedBaseOffset;
|
||||||
|
for (const auto& anonymousMember : memberInfo.m_type->m_ordered_members)
|
||||||
|
{
|
||||||
|
PrintFillStruct_Member(structInfo, *anonymousMember, DeclarationModifierComputations(anonymousMember.get()), anonymousMemberOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINEF("#error Unsupported anonymous struct with name: {0}", memberInfo.m_member->m_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintFillStruct_Member_ReferenceArray(const StructureInformation& info,
|
||||||
|
const MemberInformation& member,
|
||||||
|
const DeclarationModifierComputations& modifier,
|
||||||
|
const size_t nestedBaseOffset)
|
||||||
|
{
|
||||||
|
for (const auto& entry : modifier.GetArrayEntries())
|
||||||
|
{
|
||||||
|
PrintFillStruct_Member(info, member, entry, nestedBaseOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool ShouldFillMember(const DeclarationModifierComputations& modifier)
|
||||||
|
{
|
||||||
|
return !modifier.HasPointerModifier();
|
||||||
|
}
|
||||||
|
|
||||||
|
// nestedBaseOffset: Base offset in case member is part of a nested anonymous sub-struct
|
||||||
|
void PrintFillStruct_Member(const StructureInformation& structInfo,
|
||||||
|
const MemberInformation& memberInfo,
|
||||||
|
const DeclarationModifierComputations& modifier,
|
||||||
|
const size_t nestedBaseOffset)
|
||||||
|
{
|
||||||
|
if (!ShouldFillMember(modifier))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (modifier.IsDynamicArray())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else if (modifier.IsArray() && modifier.GetNextDeclarationModifier() == nullptr)
|
||||||
|
{
|
||||||
|
PrintFillStruct_Member_EmbeddedArray(structInfo, memberInfo, modifier, nestedBaseOffset);
|
||||||
|
}
|
||||||
|
else if (modifier.GetDeclarationModifier() == nullptr)
|
||||||
|
{
|
||||||
|
PrintFillStruct_Member_Embedded(structInfo, memberInfo, modifier, nestedBaseOffset);
|
||||||
|
}
|
||||||
|
else if (modifier.IsArray())
|
||||||
|
{
|
||||||
|
PrintFillStruct_Member_ReferenceArray(structInfo, memberInfo, modifier, nestedBaseOffset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
LINEF("#error PrintFillStruct_Member failed @ {0}", memberInfo.m_member->m_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintFillStruct_Member_Condition_Union(const StructureInformation& structInfo,
|
||||||
|
const MemberInformation& member,
|
||||||
|
const DeclarationModifierComputations& modifier)
|
||||||
|
{
|
||||||
|
const MemberComputations computations(&member);
|
||||||
|
|
||||||
|
if (computations.IsFirstUsedMember(true))
|
||||||
|
{
|
||||||
|
if (member.m_condition)
|
||||||
|
{
|
||||||
|
LINEF("if ({0})", MakeEvaluation(member.m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, modifier, 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PrintFillStruct_Member(structInfo, member, modifier, 0u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (computations.IsLastUsedMember(true))
|
||||||
|
{
|
||||||
|
if (member.m_condition)
|
||||||
|
{
|
||||||
|
LINEF("else if ({0})", MakeEvaluation(member.m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, modifier, 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINE("else")
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, modifier, 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (member.m_condition)
|
||||||
|
{
|
||||||
|
LINEF("else if ({0})", MakeEvaluation(member.m_condition.get()))
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Member(structInfo, member, modifier, 0u);
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINEF("#error Middle member of union2 must have condition ({0})", member.m_member->m_name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintFillStruct_Struct(const StructureInformation& info)
|
||||||
|
{
|
||||||
|
const auto* dynamicMember = StructureComputations(&info).GetDynamicMember();
|
||||||
|
if (info.m_definition->GetType() == DataDefinitionType::UNION)
|
||||||
|
{
|
||||||
|
for (const auto& member : info.m_ordered_members)
|
||||||
|
{
|
||||||
|
const MemberComputations computations(member.get());
|
||||||
|
if (computations.ShouldIgnore())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DeclarationModifierComputations modifier(member.get());
|
||||||
|
PrintFillStruct_Member_Condition_Union(info, *member, modifier);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (const auto& member : info.m_ordered_members)
|
||||||
|
{
|
||||||
|
const MemberComputations computations(member.get());
|
||||||
|
if (computations.ShouldIgnore() || member.get() == dynamicMember)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
DeclarationModifierComputations modifier(member.get());
|
||||||
|
PrintFillStruct_Member(info, *member, modifier, 0u);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PrintFillStructMethod(const StructureInformation* info)
|
||||||
|
{
|
||||||
|
LINEF("void {0}::FillStruct_{1}(const ZoneStreamFillWriteAccessor& fillAccessor)",
|
||||||
|
WriterClassName(m_env.m_asset),
|
||||||
|
MakeSafeTypeName(info->m_definition))
|
||||||
|
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
PrintFillStruct_Struct(*info);
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
LINE("}")
|
LINE("}")
|
||||||
@@ -1114,7 +1494,7 @@ namespace
|
|||||||
{
|
{
|
||||||
LINEF("m_stream->Write<{0}>(*{1});", def->GetFullName(), MakeTypePtrVarName(def))
|
LINEF("m_stream->Write<{0}>(*{1});", def->GetFullName(), MakeTypePtrVarName(def))
|
||||||
}
|
}
|
||||||
LINEF("m_stream->MarkFollowing(*{0});", MakeTypeWrittenPtrVarName(def))
|
LINEF("m_stream->MarkFollowing(varWritten);")
|
||||||
}
|
}
|
||||||
|
|
||||||
void PrintWritePtrArrayMethod_PointerCheck(const DataDefinition* def, const StructureInformation* info, const bool reusable)
|
void PrintWritePtrArrayMethod_PointerCheck(const DataDefinition* def, const StructureInformation* info, const bool reusable)
|
||||||
@@ -1126,13 +1506,13 @@ namespace
|
|||||||
if (info && StructureComputations(info).IsAsset())
|
if (info && StructureComputations(info).IsAsset())
|
||||||
{
|
{
|
||||||
LINEF("{0} writer(*{1}, m_zone, *m_stream);", WriterClassName(info), MakeTypePtrVarName(def))
|
LINEF("{0} writer(*{1}, m_zone, *m_stream);", WriterClassName(info), MakeTypePtrVarName(def))
|
||||||
LINEF("writer.Write({0});", MakeTypeWrittenPtrVarName(def))
|
LINEF("writer.Write(*{0}, {1});", MakeTypePtrVarName(def), MakeTypeWrittenPtrVarName(def))
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (reusable)
|
if (reusable)
|
||||||
{
|
{
|
||||||
LINEF("if (m_stream->ReusableShouldWrite({0}))", MakeTypeWrittenPtrVarName(def))
|
LINEF("if (m_stream->ReusableShouldWrite(*{0}, {1}))", MakeTypePtrVarName(def), MakeTypeWrittenPtrVarName(def))
|
||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
|
|
||||||
@@ -1162,15 +1542,15 @@ namespace
|
|||||||
|
|
||||||
LINE("if (atStreamStart)")
|
LINE("if (atStreamStart)")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
LINEF("{0} = m_stream->Write<{1}*>({2}, count);", MakeTypeWrittenPtrVarName(def), def->GetFullName(), MakeTypePtrVarName(def))
|
LINEF("{0} = m_stream->WriteWithFill(m_stream->GetPointerByteCount() * count).Offset();", MakeTypeWrittenPtrVarName(def))
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
|
|
||||||
LINE("")
|
LINE("")
|
||||||
LINEF("assert({0} != nullptr);", MakeTypeWrittenPtrVarName(def))
|
LINEF("assert({0}.Offset() != nullptr);", MakeTypeWrittenPtrVarName(def))
|
||||||
|
|
||||||
LINE("")
|
LINE("")
|
||||||
LINEF("{0}** var = {1};", def->GetFullName(), MakeTypePtrVarName(def))
|
LINEF("{0}** var = {1};", def->GetFullName(), MakeTypePtrVarName(def))
|
||||||
LINEF("{0}** varWritten = {1};", def->GetFullName(), MakeTypeWrittenPtrVarName(def))
|
LINEF("ZoneOutputOffset varWritten = {1};", def->GetFullName(), MakeTypeWrittenPtrVarName(def))
|
||||||
LINE("for (size_t index = 0; index < count; index++)")
|
LINE("for (size_t index = 0; index < count; index++)")
|
||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
@@ -1180,7 +1560,7 @@ namespace
|
|||||||
PrintWritePtrArrayMethod_PointerCheck(def, info, reusable);
|
PrintWritePtrArrayMethod_PointerCheck(def, info, reusable);
|
||||||
LINE("")
|
LINE("")
|
||||||
LINE("var++;")
|
LINE("var++;")
|
||||||
LINE("varWritten++;")
|
LINE("varWritten.Inc(m_stream->GetPointerByteCount());")
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
LINE("}")
|
LINE("}")
|
||||||
@@ -1197,16 +1577,45 @@ namespace
|
|||||||
LINEF("assert({0} != nullptr);", MakeTypeVarName(def))
|
LINEF("assert({0} != nullptr);", MakeTypeVarName(def))
|
||||||
LINE("")
|
LINE("")
|
||||||
LINE("if (atStreamStart)")
|
LINE("if (atStreamStart)")
|
||||||
m_intendation++;
|
|
||||||
LINEF("{0} = m_stream->Write<{1}>({2}, count);", MakeTypeWrittenVarName(def), def->GetFullName(), MakeTypeVarName(def))
|
if (info->m_has_matching_cross_platform_structure)
|
||||||
m_intendation--;
|
{
|
||||||
|
m_intendation++;
|
||||||
|
LINEF("{0} = m_stream->Write<{1}>({2}, count);", MakeTypeWrittenVarName(def), def->GetFullName(), MakeTypeVarName(def))
|
||||||
|
m_intendation--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
LINEF("const auto arrayFill = m_stream->WriteWithFill({0} * count);", def->GetSize())
|
||||||
|
LINEF("{0} = arrayFill.Offset();", MakeTypeWrittenVarName(def))
|
||||||
|
LINEF("auto* arrayStart = {0};", MakeTypeVarName(def))
|
||||||
|
LINEF("auto* var = {0};", MakeTypeVarName(def))
|
||||||
|
LINE("for (size_t index = 0; index < count; index++)")
|
||||||
|
LINE("{")
|
||||||
|
m_intendation++;
|
||||||
|
|
||||||
|
LINEF("{0} = var;", MakeTypeVarName(info->m_definition))
|
||||||
|
LINEF("FillStruct_{0}(arrayFill.AtOffset(0 + {1} * index));", info->m_definition->m_name, def->GetSize())
|
||||||
|
LINE("var++;")
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
|
||||||
|
LINEF("{0} = arrayStart;", MakeTypeVarName(def))
|
||||||
|
|
||||||
|
m_intendation--;
|
||||||
|
LINE("}")
|
||||||
|
}
|
||||||
|
|
||||||
LINE("")
|
LINE("")
|
||||||
LINEF("assert({0} != nullptr);", MakeTypeWrittenVarName(def))
|
LINEF("assert({0}.Offset() != nullptr);", MakeTypeWrittenVarName(def))
|
||||||
|
|
||||||
LINE("")
|
LINE("")
|
||||||
LINEF("{0}* var = {1};", def->GetFullName(), MakeTypeVarName(def))
|
LINEF("{0}* var = {1};", def->GetFullName(), MakeTypeVarName(def))
|
||||||
LINEF("{0}* varWritten = {1};", def->GetFullName(), MakeTypeWrittenVarName(def))
|
LINEF("ZoneOutputOffset varWritten = {1};", def->GetFullName(), MakeTypeWrittenVarName(def))
|
||||||
LINE("for (size_t index = 0; index < count; index++)")
|
LINE("for (size_t index = 0; index < count; index++)")
|
||||||
LINE("{")
|
LINE("{")
|
||||||
m_intendation++;
|
m_intendation++;
|
||||||
@@ -1215,7 +1624,7 @@ namespace
|
|||||||
LINEF("{0} = varWritten;", MakeTypeWrittenVarName(info->m_definition))
|
LINEF("{0} = varWritten;", MakeTypeWrittenVarName(info->m_definition))
|
||||||
LINEF("Write_{0}(false);", info->m_definition->m_name)
|
LINEF("Write_{0}(false);", info->m_definition->m_name)
|
||||||
LINE("var++;")
|
LINE("var++;")
|
||||||
LINE("varWritten++;")
|
LINEF("varWritten.Inc({0});", def->GetSize())
|
||||||
|
|
||||||
m_intendation--;
|
m_intendation--;
|
||||||
LINE("}")
|
LINE("}")
|
||||||
@@ -1228,16 +1637,35 @@ namespace
|
|||||||
};
|
};
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
|
std::vector<CodeTemplateFile> ZoneWriteTemplate::GetFilesToRenderOncePerTemplate(const OncePerTemplateRenderingContext& context)
|
||||||
|
{
|
||||||
|
std::vector<CodeTemplateFile> files;
|
||||||
|
|
||||||
|
files.emplace_back(std::format("AssetWriter{0}.h", context.m_game), TAG_ALL_WRITERS);
|
||||||
|
|
||||||
|
return files;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneWriteTemplate::RenderOncePerTemplateFile(std::ostream& stream, const CodeTemplateFileTag fileTag, const OncePerTemplateRenderingContext& context)
|
||||||
|
{
|
||||||
|
assert(fileTag == TAG_ALL_WRITERS);
|
||||||
|
|
||||||
|
const PerTemplate t(stream, context);
|
||||||
|
t.AllWriters();
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<CodeTemplateFile> ZoneWriteTemplate::GetFilesToRenderOncePerAsset(const OncePerAssetRenderingContext& context)
|
std::vector<CodeTemplateFile> ZoneWriteTemplate::GetFilesToRenderOncePerAsset(const OncePerAssetRenderingContext& context)
|
||||||
{
|
{
|
||||||
std::vector<CodeTemplateFile> files;
|
std::vector<CodeTemplateFile> files;
|
||||||
|
|
||||||
auto assetName = context.m_asset->m_definition->m_name;
|
auto assetName = context.m_asset->m_definition->m_name;
|
||||||
for (auto& c : assetName)
|
utils::MakeStringLowerCase(assetName);
|
||||||
c = static_cast<char>(tolower(c));
|
|
||||||
|
|
||||||
files.emplace_back(std::format("XAssets/{0}/{0}_write_db.h", assetName), TAG_HEADER);
|
auto gameName = context.m_game;
|
||||||
files.emplace_back(std::format("XAssets/{0}/{0}_write_db.cpp", assetName), TAG_SOURCE);
|
utils::MakeStringLowerCase(gameName);
|
||||||
|
|
||||||
|
files.emplace_back(std::format("XAssets/{0}/{0}_{1}_write_db.h", assetName, gameName), TAG_HEADER);
|
||||||
|
files.emplace_back(std::format("XAssets/{0}/{0}_{1}_write_db.cpp", assetName, gameName), TAG_SOURCE);
|
||||||
|
|
||||||
return files;
|
return files;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,9 @@
|
|||||||
class ZoneWriteTemplate final : public ICodeTemplate
|
class ZoneWriteTemplate final : public ICodeTemplate
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
std::vector<CodeTemplateFile> GetFilesToRenderOncePerTemplate(const OncePerTemplateRenderingContext& context) override;
|
||||||
|
void RenderOncePerTemplateFile(std::ostream& stream, CodeTemplateFileTag fileTag, const OncePerTemplateRenderingContext& context) override;
|
||||||
|
|
||||||
std::vector<CodeTemplateFile> GetFilesToRenderOncePerAsset(const OncePerAssetRenderingContext& context) override;
|
std::vector<CodeTemplateFile> GetFilesToRenderOncePerAsset(const OncePerAssetRenderingContext& context) override;
|
||||||
void RenderOncePerAssetFile(std::ostream& stream, CodeTemplateFileTag fileTag, const OncePerAssetRenderingContext& context) override;
|
void RenderOncePerAssetFile(std::ostream& stream, CodeTemplateFileTag fileTag, const OncePerAssetRenderingContext& context) override;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ size_t XChunkProcessorInflate::Process(unsigned streamNumber, const uint8_t* inp
|
|||||||
ret = inflate(&stream, Z_FULL_FLUSH);
|
ret = inflate(&stream, Z_FULL_FLUSH);
|
||||||
if (ret != Z_STREAM_END)
|
if (ret != Z_STREAM_END)
|
||||||
{
|
{
|
||||||
con::error("inflate of stream failed with error code {}: {}", streamNumber, ret, stream.msg);
|
con::error("inflate of stream {} failed with error code {}: {}", streamNumber, ret, stream.msg);
|
||||||
throw XChunkException(std::format("Zone has invalid or unsupported compression: {}", stream.msg));
|
throw XChunkException(std::format("Zone has invalid or unsupported compression: {}", stream.msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,31 +1,7 @@
|
|||||||
#include "ContentLoaderIW3.h"
|
#include "ContentLoaderIW3.h"
|
||||||
|
|
||||||
|
#include "Game/IW3/AssetLoaderIW3.h"
|
||||||
#include "Game/IW3/IW3.h"
|
#include "Game/IW3/IW3.h"
|
||||||
#include "Game/IW3/XAssets/clipmap_t/clipmap_t_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/comworld/comworld_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/font_s/font_s_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/fxeffectdef/fxeffectdef_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/fximpacttable/fximpacttable_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gameworldmp/gameworldmp_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gameworldsp/gameworldsp_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gfximage/gfximage_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gfxlightdef/gfxlightdef_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gfxworld/gfxworld_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/loadedsound/loadedsound_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/localizeentry/localizeentry_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/mapents/mapents_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/material/material_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/materialtechniqueset/materialtechniqueset_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/menudef_t/menudef_t_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/menulist/menulist_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/physpreset/physpreset_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/rawfile/rawfile_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/snd_alias_list_t/snd_alias_list_t_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/sndcurve/sndcurve_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/stringtable/stringtable_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/weapondef/weapondef_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/xanimparts/xanimparts_load_db.h"
|
|
||||||
#include "Game/IW3/XAssets/xmodel/xmodel_load_db.h"
|
|
||||||
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|||||||
@@ -1,41 +1,7 @@
|
|||||||
#include "ContentLoaderIW4.h"
|
#include "ContentLoaderIW4.h"
|
||||||
|
|
||||||
|
#include "Game/IW4/AssetLoaderIW4.h"
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "Game/IW4/XAssets/addonmapents/addonmapents_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/clipmap_t/clipmap_t_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/comworld/comworld_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/font_s/font_s_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/fxeffectdef/fxeffectdef_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/fximpacttable/fximpacttable_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/fxworld/fxworld_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gameworldmp/gameworldmp_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gameworldsp/gameworldsp_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gfximage/gfximage_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gfxlightdef/gfxlightdef_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gfxworld/gfxworld_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/leaderboarddef/leaderboarddef_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/loadedsound/loadedsound_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/localizeentry/localizeentry_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/mapents/mapents_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/material/material_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/materialpixelshader/materialpixelshader_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/materialtechniqueset/materialtechniqueset_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/materialvertexdeclaration/materialvertexdeclaration_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/materialvertexshader/materialvertexshader_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/menudef_t/menudef_t_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/menulist/menulist_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/physcollmap/physcollmap_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/physpreset/physpreset_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/rawfile/rawfile_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/snd_alias_list_t/snd_alias_list_t_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/sndcurve/sndcurve_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/stringtable/stringtable_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/structureddatadefset/structureddatadefset_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/tracerdef/tracerdef_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/vehicledef/vehicledef_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/weaponcompletedef/weaponcompletedef_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/xanimparts/xanimparts_load_db.h"
|
|
||||||
#include "Game/IW4/XAssets/xmodel/xmodel_load_db.h"
|
|
||||||
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|||||||
@@ -1,46 +1,7 @@
|
|||||||
#include "ContentLoaderIW5.h"
|
#include "ContentLoaderIW5.h"
|
||||||
|
|
||||||
|
#include "Game/IW5/AssetLoaderIW5.h"
|
||||||
#include "Game/IW5/IW5.h"
|
#include "Game/IW5/IW5.h"
|
||||||
#include "Game/IW5/XAssets/addonmapents/addonmapents_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/clipmap_t/clipmap_t_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/comworld/comworld_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/font_s/font_s_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/fxeffectdef/fxeffectdef_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/fximpacttable/fximpacttable_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/fxworld/fxworld_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/gfximage/gfximage_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/gfxlightdef/gfxlightdef_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/gfxworld/gfxworld_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/glassworld/glassworld_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/leaderboarddef/leaderboarddef_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/loadedsound/loadedsound_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/localizeentry/localizeentry_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/mapents/mapents_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/material/material_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/materialpixelshader/materialpixelshader_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/materialtechniqueset/materialtechniqueset_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/materialvertexdeclaration/materialvertexdeclaration_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/materialvertexshader/materialvertexshader_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/menudef_t/menudef_t_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/menulist/menulist_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/pathdata/pathdata_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/physcollmap/physcollmap_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/physpreset/physpreset_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/rawfile/rawfile_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/scriptfile/scriptfile_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/snd_alias_list_t/snd_alias_list_t_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/sndcurve/sndcurve_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/stringtable/stringtable_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/structureddatadefset/structureddatadefset_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/surfacefxtable/surfacefxtable_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/tracerdef/tracerdef_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/vehicledef/vehicledef_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/vehicletrack/vehicletrack_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/weaponattachment/weaponattachment_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/weaponcompletedef/weaponcompletedef_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/xanimparts/xanimparts_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/xmodel/xmodel_load_db.h"
|
|
||||||
#include "Game/IW5/XAssets/xmodelsurfs/xmodelsurfs_load_db.h"
|
|
||||||
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|||||||
@@ -1,38 +1,7 @@
|
|||||||
#include "ContentLoaderT5.h"
|
#include "ContentLoaderT5.h"
|
||||||
|
|
||||||
|
#include "Game/T5/AssetLoaderT5.h"
|
||||||
#include "Game/T5/T5.h"
|
#include "Game/T5/T5.h"
|
||||||
#include "Game/T5/XAssets/clipmap_t/clipmap_t_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/comworld/comworld_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/ddlroot_t/ddlroot_t_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/destructibledef/destructibledef_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/emblemset/emblemset_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/font_s/font_s_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/fxeffectdef/fxeffectdef_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/fximpacttable/fximpacttable_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/gameworldmp/gameworldmp_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/gameworldsp/gameworldsp_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/gfximage/gfximage_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/gfxlightdef/gfxlightdef_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/gfxworld/gfxworld_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/glasses/glasses_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/localizeentry/localizeentry_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/mapents/mapents_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/material/material_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/materialtechniqueset/materialtechniqueset_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/menudef_t/menudef_t_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/menulist/menulist_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/packindex/packindex_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/physconstraints/physconstraints_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/physpreset/physpreset_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/rawfile/rawfile_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/sndbank/sndbank_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/snddriverglobals/snddriverglobals_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/sndpatch/sndpatch_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/stringtable/stringtable_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/weaponvariantdef/weaponvariantdef_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/xanimparts/xanimparts_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/xglobals/xglobals_load_db.h"
|
|
||||||
#include "Game/T5/XAssets/xmodel/xmodel_load_db.h"
|
|
||||||
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|||||||
@@ -1,54 +1,7 @@
|
|||||||
#include "ContentLoaderT6.h"
|
#include "ContentLoaderT6.h"
|
||||||
|
|
||||||
|
#include "Game/T6/AssetLoaderT6.h"
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Game/T6/XAssets/addonmapents/addonmapents_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/clipmap_t/clipmap_t_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/comworld/comworld_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/ddlroot_t/ddlroot_t_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/destructibledef/destructibledef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/emblemset/emblemset_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/font_s/font_s_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/fonticon/fonticon_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/footstepfxtabledef/footstepfxtabledef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/footsteptabledef/footsteptabledef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/fxeffectdef/fxeffectdef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/fximpacttable/fximpacttable_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/gameworldmp/gameworldmp_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/gameworldsp/gameworldsp_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/gfximage/gfximage_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/gfxlightdef/gfxlightdef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/gfxworld/gfxworld_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/glasses/glasses_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/keyvaluepairs/keyvaluepairs_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/leaderboarddef/leaderboarddef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/localizeentry/localizeentry_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/mapents/mapents_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/material/material_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/materialtechniqueset/materialtechniqueset_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/memoryblock/memoryblock_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/menudef_t/menudef_t_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/menulist/menulist_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/physconstraints/physconstraints_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/physpreset/physpreset_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/qdb/qdb_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/rawfile/rawfile_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/scriptparsetree/scriptparsetree_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/skinnedvertsdef/skinnedvertsdef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/slug/slug_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/sndbank/sndbank_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/snddriverglobals/snddriverglobals_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/sndpatch/sndpatch_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/stringtable/stringtable_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/tracerdef/tracerdef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/vehicledef/vehicledef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/weaponattachment/weaponattachment_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/weaponattachmentunique/weaponattachmentunique_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/weaponcamo/weaponcamo_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/weaponvariantdef/weaponvariantdef_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/xanimparts/xanimparts_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/xglobals/xglobals_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/xmodel/xmodel_load_db.h"
|
|
||||||
#include "Game/T6/XAssets/zbarrierdef/zbarrierdef_load_db.h"
|
|
||||||
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
#include "Loading/Exception/UnsupportedAssetTypeException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <format>
|
#include <format>
|
||||||
|
|
||||||
InvalidLookupPositionException::InvalidLookupPositionException(block_t block, size_t offset)
|
InvalidLookupPositionException::InvalidLookupPositionException(const block_t block, const size_t offset)
|
||||||
: m_block(block),
|
: m_block(block),
|
||||||
m_offset(offset)
|
m_offset(offset)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ namespace
|
|||||||
{
|
{
|
||||||
const auto blockCount = static_cast<unsigned>(zoneLoader.m_blocks.size());
|
const auto blockCount = static_cast<unsigned>(zoneLoader.m_blocks.size());
|
||||||
|
|
||||||
const auto blockSizes = std::make_unique<xblock_size_t[]>(blockCount);
|
std::vector<xblock_size_t> blockSizes(blockCount);
|
||||||
stream.Load(blockSizes.get(), sizeof(xblock_size_t) * blockCount);
|
stream.Load(blockSizes.data(), sizeof(xblock_size_t) * blockCount);
|
||||||
|
|
||||||
uint64_t totalMemory = 0;
|
uint64_t totalMemory = 0;
|
||||||
for (unsigned int block = 0; block < blockCount; block++)
|
for (unsigned int block = 0; block < blockCount; block++)
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ namespace
|
|||||||
MemoryManager& memory,
|
MemoryManager& memory,
|
||||||
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
|
std::optional<std::unique_ptr<ProgressCallback>> progressCallback)
|
||||||
: m_blocks(blocks),
|
: m_blocks(blocks),
|
||||||
|
m_block_offsets(blocks.size()),
|
||||||
m_stream(stream),
|
m_stream(stream),
|
||||||
m_memory(memory),
|
m_memory(memory),
|
||||||
m_pointer_byte_count(pointerBitCount / 8u),
|
m_pointer_byte_count(pointerBitCount / 8u),
|
||||||
@@ -67,9 +68,7 @@ namespace
|
|||||||
assert(pointerBitCount % 8u == 0u);
|
assert(pointerBitCount % 8u == 0u);
|
||||||
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
||||||
|
|
||||||
const auto blockCount = static_cast<unsigned>(blocks.size());
|
std::memset(m_block_offsets.data(), 0, sizeof(decltype(m_block_offsets)::value_type) * m_block_offsets.size());
|
||||||
m_block_offsets = std::make_unique<size_t[]>(blockCount);
|
|
||||||
std::memset(m_block_offsets.get(), 0, sizeof(size_t) * blockCount);
|
|
||||||
|
|
||||||
m_insert_block = blocks[insertBlock];
|
m_insert_block = blocks[insertBlock];
|
||||||
|
|
||||||
@@ -488,7 +487,7 @@ namespace
|
|||||||
}
|
}
|
||||||
|
|
||||||
std::vector<XBlock*>& m_blocks;
|
std::vector<XBlock*>& m_blocks;
|
||||||
std::unique_ptr<size_t[]> m_block_offsets;
|
std::vector<size_t> m_block_offsets;
|
||||||
|
|
||||||
std::stack<XBlock*> m_block_stack;
|
std::stack<XBlock*> m_block_stack;
|
||||||
std::stack<size_t> m_temp_offsets;
|
std::stack<size_t> m_temp_offsets;
|
||||||
|
|||||||
@@ -7,7 +7,9 @@
|
|||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <format>
|
#include <format>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
using namespace std::string_literals;
|
||||||
namespace fs = std::filesystem;
|
namespace fs = std::filesystem;
|
||||||
|
|
||||||
result::Expected<std::unique_ptr<Zone>, std::string> ZoneLoading::LoadZone(const std::string& path,
|
result::Expected<std::unique_ptr<Zone>, std::string> ZoneLoading::LoadZone(const std::string& path,
|
||||||
@@ -41,5 +43,9 @@ result::Expected<std::unique_ptr<Zone>, std::string> ZoneLoading::LoadZone(const
|
|||||||
auto loadedZone = zoneLoader->LoadZone(file);
|
auto loadedZone = zoneLoader->LoadZone(file);
|
||||||
|
|
||||||
file.close();
|
file.close();
|
||||||
|
|
||||||
|
if (!loadedZone)
|
||||||
|
return result::Unexpected("Loading zone failed."s);
|
||||||
|
|
||||||
return std::move(loadedZone);
|
return std::move(loadedZone);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,30 +1,6 @@
|
|||||||
#include "ContentWriterIW3.h"
|
#include "ContentWriterIW3.h"
|
||||||
|
|
||||||
#include "Game/IW3/XAssets/clipmap_t/clipmap_t_write_db.h"
|
#include "Game/IW3/AssetWriterIW3.h"
|
||||||
#include "Game/IW3/XAssets/comworld/comworld_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/font_s/font_s_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/fxeffectdef/fxeffectdef_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/fximpacttable/fximpacttable_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gameworldmp/gameworldmp_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gameworldsp/gameworldsp_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gfximage/gfximage_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gfxlightdef/gfxlightdef_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/gfxworld/gfxworld_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/loadedsound/loadedsound_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/localizeentry/localizeentry_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/mapents/mapents_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/material/material_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/materialtechniqueset/materialtechniqueset_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/menudef_t/menudef_t_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/menulist/menulist_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/physpreset/physpreset_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/rawfile/rawfile_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/snd_alias_list_t/snd_alias_list_t_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/sndcurve/sndcurve_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/stringtable/stringtable_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/weapondef/weapondef_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/xanimparts/xanimparts_write_db.h"
|
|
||||||
#include "Game/IW3/XAssets/xmodel/xmodel_write_db.h"
|
|
||||||
#include "Writing/WritingException.h"
|
#include "Writing/WritingException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -81,30 +57,31 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo
|
|||||||
|
|
||||||
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
assert(!atStreamStart);
|
||||||
|
|
||||||
if (atStreamStart)
|
|
||||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
|
||||||
|
|
||||||
if (varScriptStringList->strings != nullptr)
|
if (varScriptStringList->strings != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(const char*));
|
m_stream->Align(4);
|
||||||
varXString = varScriptStringList->strings;
|
varXString = varScriptStringList->strings;
|
||||||
WriteXStringArray(true, varScriptStringList->count);
|
WriteXStringArray(true, varScriptStringList->count);
|
||||||
|
|
||||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAsset, header.data) == 4u);
|
||||||
|
#endif
|
||||||
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
||||||
case type_index: \
|
case type_index: \
|
||||||
{ \
|
{ \
|
||||||
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
||||||
writer.Write(&varXAsset->header.headerEntry); \
|
writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
#define SKIP_ASSET(type_index, typeName, headerEntry) \
|
#define SKIP_ASSET(type_index, typeName, headerEntry) \
|
||||||
@@ -114,7 +91,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
|||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset);
|
varXAssetWritten = m_stream->Write(varXAsset);
|
||||||
|
|
||||||
switch (varXAsset->type)
|
switch (varXAsset->type)
|
||||||
{
|
{
|
||||||
@@ -160,38 +137,75 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun
|
|||||||
{
|
{
|
||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAsset) == 8u);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset, count);
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||||
|
#else
|
||||||
|
const auto fill = m_stream->WriteWithFill(8u * count);
|
||||||
|
varXAssetWritten = fill.Offset();
|
||||||
|
|
||||||
|
for (size_t index = 0; index < count; index++)
|
||||||
|
fill.Fill(varXAsset[index].type, 8u * index);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t index = 0; index < count; index++)
|
for (size_t index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
WriteXAsset(false);
|
WriteXAsset(false);
|
||||||
varXAsset++;
|
varXAsset++;
|
||||||
|
varXAssetWritten.Inc(8u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteContent(IZoneOutputStream& stream)
|
void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
m_stream = &stream;
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
|
||||||
|
|
||||||
MemoryManager memory;
|
MemoryManager memory;
|
||||||
XAssetList assetList{};
|
XAssetList assetList{};
|
||||||
|
|
||||||
CreateXAssetList(assetList, memory);
|
CreateXAssetList(assetList, memory);
|
||||||
|
|
||||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
varXAssetList = &assetList;
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAssetList) == 16);
|
||||||
|
static_assert(offsetof(XAssetList, assetCount) == 8u);
|
||||||
|
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||||
|
#else
|
||||||
|
const auto fillAccessor = m_stream->WriteWithFill(16u);
|
||||||
|
varXAssetListWritten = fillAccessor.Offset();
|
||||||
|
|
||||||
varScriptStringList = &varXAssetList->stringList;
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
fillAccessor.Fill(varScriptStringList->count, 0u);
|
||||||
|
|
||||||
|
fillAccessor.Fill(varXAssetList->assetCount, 8u);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||||
|
#endif
|
||||||
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
varScriptStringListWritten = varXAssetListWritten.AtOffset(0);
|
||||||
WriteScriptStringList(false);
|
WriteScriptStringList(false);
|
||||||
|
|
||||||
if (varXAssetList->assets != nullptr)
|
if (varXAssetList->assets != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(XAsset));
|
m_stream->Align(4);
|
||||||
varXAsset = varXAssetList->assets;
|
varXAsset = varXAssetList->assets;
|
||||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||||
m_stream->MarkFollowing(varXAssetList->assets);
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, assets) == 12u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
m_stream->PopBlock();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Game/IW3/IW3.h"
|
#include "Game/IW3/IW3.h"
|
||||||
#include "Writing/ContentWriterBase.h"
|
#include "Writing/ContentWriterBase.h"
|
||||||
#include "Writing/IContentWritingEntryPoint.h"
|
#include "Writing/IContentWritingEntryPoint.h"
|
||||||
@@ -10,7 +11,7 @@ namespace IW3
|
|||||||
public:
|
public:
|
||||||
explicit ContentWriter(const Zone& zone);
|
explicit ContentWriter(const Zone& zone);
|
||||||
|
|
||||||
void WriteContent(IZoneOutputStream& stream) override;
|
void WriteContent(ZoneOutputStream& stream) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
||||||
@@ -23,5 +24,9 @@ namespace IW3
|
|||||||
XAssetList* varXAssetList;
|
XAssetList* varXAssetList;
|
||||||
XAsset* varXAsset;
|
XAsset* varXAsset;
|
||||||
ScriptStringList* varScriptStringList;
|
ScriptStringList* varScriptStringList;
|
||||||
|
|
||||||
|
ZoneOutputOffset varXAssetListWritten;
|
||||||
|
ZoneOutputOffset varXAssetWritten;
|
||||||
|
ZoneOutputOffset varScriptStringListWritten;
|
||||||
};
|
};
|
||||||
} // namespace IW3
|
} // namespace IW3
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
|
|||||||
SetupBlocks(*writer);
|
SetupBlocks(*writer);
|
||||||
|
|
||||||
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
||||||
std::make_unique<ContentWriter>(zone), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
||||||
auto* contentInMemoryPtr = contentInMemory.get();
|
auto* contentInMemoryPtr = contentInMemory.get();
|
||||||
writer->AddWritingStep(std::move(contentInMemory));
|
writer->AddWritingStep(std::move(contentInMemory));
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +1,6 @@
|
|||||||
#include "ContentWriterIW4.h"
|
#include "ContentWriterIW4.h"
|
||||||
|
|
||||||
#include "Game/IW4/XAssets/addonmapents/addonmapents_write_db.h"
|
#include "Game/IW4/AssetWriterIW4.h"
|
||||||
#include "Game/IW4/XAssets/clipmap_t/clipmap_t_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/comworld/comworld_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/font_s/font_s_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/fxeffectdef/fxeffectdef_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/fximpacttable/fximpacttable_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/fxworld/fxworld_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gameworldmp/gameworldmp_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gameworldsp/gameworldsp_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gfximage/gfximage_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gfxlightdef/gfxlightdef_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/gfxworld/gfxworld_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/leaderboarddef/leaderboarddef_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/loadedsound/loadedsound_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/localizeentry/localizeentry_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/mapents/mapents_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/material/material_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/materialpixelshader/materialpixelshader_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/materialtechniqueset/materialtechniqueset_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/materialvertexdeclaration/materialvertexdeclaration_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/materialvertexshader/materialvertexshader_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/menudef_t/menudef_t_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/menulist/menulist_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/physcollmap/physcollmap_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/physpreset/physpreset_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/rawfile/rawfile_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/snd_alias_list_t/snd_alias_list_t_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/sndcurve/sndcurve_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/stringtable/stringtable_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/structureddatadefset/structureddatadefset_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/tracerdef/tracerdef_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/vehicledef/vehicledef_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/weaponcompletedef/weaponcompletedef_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/xanimparts/xanimparts_write_db.h"
|
|
||||||
#include "Game/IW4/XAssets/xmodel/xmodel_write_db.h"
|
|
||||||
#include "Writing/WritingException.h"
|
#include "Writing/WritingException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -91,30 +57,31 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo
|
|||||||
|
|
||||||
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
assert(!atStreamStart);
|
||||||
|
|
||||||
if (atStreamStart)
|
|
||||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
|
||||||
|
|
||||||
if (varScriptStringList->strings != nullptr)
|
if (varScriptStringList->strings != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(const char*));
|
m_stream->Align(4);
|
||||||
varXString = varScriptStringList->strings;
|
varXString = varScriptStringList->strings;
|
||||||
WriteXStringArray(true, varScriptStringList->count);
|
WriteXStringArray(true, varScriptStringList->count);
|
||||||
|
|
||||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAsset, header.data) == 4u);
|
||||||
|
#endif
|
||||||
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
||||||
case type_index: \
|
case type_index: \
|
||||||
{ \
|
{ \
|
||||||
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
||||||
writer.Write(&varXAsset->header.headerEntry); \
|
writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
#define SKIP_ASSET(type_index, typeName, headerEntry) \
|
#define SKIP_ASSET(type_index, typeName, headerEntry) \
|
||||||
@@ -124,7 +91,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
|||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset);
|
varXAssetWritten = m_stream->Write(varXAsset);
|
||||||
|
|
||||||
switch (varXAsset->type)
|
switch (varXAsset->type)
|
||||||
{
|
{
|
||||||
@@ -180,38 +147,75 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun
|
|||||||
{
|
{
|
||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAsset) == 8u);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset, count);
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||||
|
#else
|
||||||
|
const auto fill = m_stream->WriteWithFill(8u * count);
|
||||||
|
varXAssetWritten = fill.Offset();
|
||||||
|
|
||||||
|
for (size_t index = 0; index < count; index++)
|
||||||
|
fill.Fill(varXAsset[index].type, 8u * index);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t index = 0; index < count; index++)
|
for (size_t index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
WriteXAsset(false);
|
WriteXAsset(false);
|
||||||
varXAsset++;
|
varXAsset++;
|
||||||
|
varXAssetWritten.Inc(8u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteContent(IZoneOutputStream& stream)
|
void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
m_stream = &stream;
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
|
||||||
|
|
||||||
MemoryManager memory;
|
MemoryManager memory;
|
||||||
XAssetList assetList{};
|
XAssetList assetList{};
|
||||||
|
|
||||||
CreateXAssetList(assetList, memory);
|
CreateXAssetList(assetList, memory);
|
||||||
|
|
||||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
varXAssetList = &assetList;
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAssetList) == 16);
|
||||||
|
static_assert(offsetof(XAssetList, assetCount) == 8u);
|
||||||
|
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||||
|
#else
|
||||||
|
const auto fillAccessor = m_stream->WriteWithFill(16u);
|
||||||
|
varXAssetListWritten = fillAccessor.Offset();
|
||||||
|
|
||||||
varScriptStringList = &varXAssetList->stringList;
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
fillAccessor.Fill(varScriptStringList->count, 0u);
|
||||||
|
|
||||||
|
fillAccessor.Fill(varXAssetList->assetCount, 8u);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||||
|
#endif
|
||||||
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
varScriptStringListWritten = varXAssetListWritten.AtOffset(0);
|
||||||
WriteScriptStringList(false);
|
WriteScriptStringList(false);
|
||||||
|
|
||||||
if (varXAssetList->assets != nullptr)
|
if (varXAssetList->assets != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(XAsset));
|
m_stream->Align(4);
|
||||||
varXAsset = varXAssetList->assets;
|
varXAsset = varXAssetList->assets;
|
||||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||||
m_stream->MarkFollowing(varXAssetList->assets);
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, assets) == 12u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
m_stream->PopBlock();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "Writing/ContentWriterBase.h"
|
#include "Writing/ContentWriterBase.h"
|
||||||
#include "Writing/IContentWritingEntryPoint.h"
|
#include "Writing/IContentWritingEntryPoint.h"
|
||||||
@@ -10,7 +11,7 @@ namespace IW4
|
|||||||
public:
|
public:
|
||||||
explicit ContentWriter(const Zone& zone);
|
explicit ContentWriter(const Zone& zone);
|
||||||
|
|
||||||
void WriteContent(IZoneOutputStream& stream) override;
|
void WriteContent(ZoneOutputStream& stream) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
||||||
@@ -23,5 +24,9 @@ namespace IW4
|
|||||||
XAssetList* varXAssetList;
|
XAssetList* varXAssetList;
|
||||||
XAsset* varXAsset;
|
XAsset* varXAsset;
|
||||||
ScriptStringList* varScriptStringList;
|
ScriptStringList* varScriptStringList;
|
||||||
|
|
||||||
|
ZoneOutputOffset varXAssetListWritten;
|
||||||
|
ZoneOutputOffset varXAssetWritten;
|
||||||
|
ZoneOutputOffset varScriptStringListWritten;
|
||||||
};
|
};
|
||||||
} // namespace IW4
|
} // namespace IW4
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
|
|||||||
SetupBlocks(*writer);
|
SetupBlocks(*writer);
|
||||||
|
|
||||||
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
||||||
std::make_unique<ContentWriter>(zone), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
||||||
auto* contentInMemoryPtr = contentInMemory.get();
|
auto* contentInMemoryPtr = contentInMemory.get();
|
||||||
writer->AddWritingStep(std::move(contentInMemory));
|
writer->AddWritingStep(std::move(contentInMemory));
|
||||||
|
|
||||||
|
|||||||
@@ -1,45 +1,6 @@
|
|||||||
#include "ContentWriterIW5.h"
|
#include "ContentWriterIW5.h"
|
||||||
|
|
||||||
#include "Game/IW5/XAssets/addonmapents/addonmapents_write_db.h"
|
#include "Game/IW5/AssetWriterIW5.h"
|
||||||
#include "Game/IW5/XAssets/clipmap_t/clipmap_t_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/comworld/comworld_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/font_s/font_s_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/fxeffectdef/fxeffectdef_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/fximpacttable/fximpacttable_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/fxworld/fxworld_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/gfximage/gfximage_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/gfxlightdef/gfxlightdef_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/gfxworld/gfxworld_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/glassworld/glassworld_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/leaderboarddef/leaderboarddef_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/loadedsound/loadedsound_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/localizeentry/localizeentry_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/mapents/mapents_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/material/material_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/materialpixelshader/materialpixelshader_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/materialtechniqueset/materialtechniqueset_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/materialvertexdeclaration/materialvertexdeclaration_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/materialvertexshader/materialvertexshader_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/menudef_t/menudef_t_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/menulist/menulist_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/pathdata/pathdata_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/physcollmap/physcollmap_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/physpreset/physpreset_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/rawfile/rawfile_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/scriptfile/scriptfile_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/snd_alias_list_t/snd_alias_list_t_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/sndcurve/sndcurve_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/stringtable/stringtable_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/structureddatadefset/structureddatadefset_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/surfacefxtable/surfacefxtable_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/tracerdef/tracerdef_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/vehicledef/vehicledef_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/vehicletrack/vehicletrack_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/weaponattachment/weaponattachment_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/weaponcompletedef/weaponcompletedef_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/xanimparts/xanimparts_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/xmodel/xmodel_write_db.h"
|
|
||||||
#include "Game/IW5/XAssets/xmodelsurfs/xmodelsurfs_write_db.h"
|
|
||||||
#include "Writing/WritingException.h"
|
#include "Writing/WritingException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -96,30 +57,31 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo
|
|||||||
|
|
||||||
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
assert(!atStreamStart);
|
||||||
|
|
||||||
if (atStreamStart)
|
|
||||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
|
||||||
|
|
||||||
if (varScriptStringList->strings != nullptr)
|
if (varScriptStringList->strings != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(const char*));
|
m_stream->Align(4);
|
||||||
varXString = varScriptStringList->strings;
|
varXString = varScriptStringList->strings;
|
||||||
WriteXStringArray(true, varScriptStringList->count);
|
WriteXStringArray(true, varScriptStringList->count);
|
||||||
|
|
||||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAsset, header.data) == 4u);
|
||||||
|
#endif
|
||||||
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
||||||
case type_index: \
|
case type_index: \
|
||||||
{ \
|
{ \
|
||||||
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
||||||
writer.Write(&varXAsset->header.headerEntry); \
|
writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
#define SKIP_ASSET(type_index, typeName, headerEntry) \
|
#define SKIP_ASSET(type_index, typeName, headerEntry) \
|
||||||
@@ -129,7 +91,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
|||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset);
|
varXAssetWritten = m_stream->Write(varXAsset);
|
||||||
|
|
||||||
switch (varXAsset->type)
|
switch (varXAsset->type)
|
||||||
{
|
{
|
||||||
@@ -188,38 +150,75 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun
|
|||||||
{
|
{
|
||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAsset) == 8u);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset, count);
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||||
|
#else
|
||||||
|
const auto fill = m_stream->WriteWithFill(8u * count);
|
||||||
|
varXAssetWritten = fill.Offset();
|
||||||
|
|
||||||
|
for (size_t index = 0; index < count; index++)
|
||||||
|
fill.Fill(varXAsset[index].type, 8u * index);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t index = 0; index < count; index++)
|
for (size_t index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
WriteXAsset(false);
|
WriteXAsset(false);
|
||||||
varXAsset++;
|
varXAsset++;
|
||||||
|
varXAssetWritten.Inc(8u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteContent(IZoneOutputStream& stream)
|
void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
m_stream = &stream;
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
|
||||||
|
|
||||||
MemoryManager memory;
|
MemoryManager memory;
|
||||||
XAssetList assetList{};
|
XAssetList assetList{};
|
||||||
|
|
||||||
CreateXAssetList(assetList, memory);
|
CreateXAssetList(assetList, memory);
|
||||||
|
|
||||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
varXAssetList = &assetList;
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAssetList) == 16);
|
||||||
|
static_assert(offsetof(XAssetList, assetCount) == 8u);
|
||||||
|
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||||
|
#else
|
||||||
|
const auto fillAccessor = m_stream->WriteWithFill(16u);
|
||||||
|
varXAssetListWritten = fillAccessor.Offset();
|
||||||
|
|
||||||
varScriptStringList = &varXAssetList->stringList;
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
fillAccessor.Fill(varScriptStringList->count, 0u);
|
||||||
|
|
||||||
|
fillAccessor.Fill(varXAssetList->assetCount, 8u);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||||
|
#endif
|
||||||
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
varScriptStringListWritten = varXAssetListWritten.AtOffset(0);
|
||||||
WriteScriptStringList(false);
|
WriteScriptStringList(false);
|
||||||
|
|
||||||
if (varXAssetList->assets != nullptr)
|
if (varXAssetList->assets != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(XAsset));
|
m_stream->Align(4);
|
||||||
varXAsset = varXAssetList->assets;
|
varXAsset = varXAssetList->assets;
|
||||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||||
m_stream->MarkFollowing(varXAssetList->assets);
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, assets) == 12u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
m_stream->PopBlock();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Game/IW5/IW5.h"
|
#include "Game/IW5/IW5.h"
|
||||||
#include "Writing/ContentWriterBase.h"
|
#include "Writing/ContentWriterBase.h"
|
||||||
#include "Writing/IContentWritingEntryPoint.h"
|
#include "Writing/IContentWritingEntryPoint.h"
|
||||||
@@ -10,7 +11,7 @@ namespace IW5
|
|||||||
public:
|
public:
|
||||||
explicit ContentWriter(const Zone& zone);
|
explicit ContentWriter(const Zone& zone);
|
||||||
|
|
||||||
void WriteContent(IZoneOutputStream& stream) override;
|
void WriteContent(ZoneOutputStream& stream) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
||||||
@@ -23,5 +24,9 @@ namespace IW5
|
|||||||
XAssetList* varXAssetList;
|
XAssetList* varXAssetList;
|
||||||
XAsset* varXAsset;
|
XAsset* varXAsset;
|
||||||
ScriptStringList* varScriptStringList;
|
ScriptStringList* varScriptStringList;
|
||||||
|
|
||||||
|
ZoneOutputOffset varXAssetListWritten;
|
||||||
|
ZoneOutputOffset varXAssetWritten;
|
||||||
|
ZoneOutputOffset varScriptStringListWritten;
|
||||||
};
|
};
|
||||||
} // namespace IW5
|
} // namespace IW5
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
|
|||||||
SetupBlocks(*writer);
|
SetupBlocks(*writer);
|
||||||
|
|
||||||
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
||||||
std::make_unique<ContentWriter>(zone), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
||||||
auto* contentInMemoryPtr = contentInMemory.get();
|
auto* contentInMemoryPtr = contentInMemory.get();
|
||||||
writer->AddWritingStep(std::move(contentInMemory));
|
writer->AddWritingStep(std::move(contentInMemory));
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,6 @@
|
|||||||
#include "ContentWriterT5.h"
|
#include "ContentWriterT5.h"
|
||||||
|
|
||||||
#include "Game/T5/XAssets/clipmap_t/clipmap_t_write_db.h"
|
#include "Game/T5/AssetWriterT5.h"
|
||||||
#include "Game/T5/XAssets/comworld/comworld_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/ddlroot_t/ddlroot_t_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/destructibledef/destructibledef_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/emblemset/emblemset_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/font_s/font_s_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/fxeffectdef/fxeffectdef_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/fximpacttable/fximpacttable_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/gameworldmp/gameworldmp_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/gameworldsp/gameworldsp_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/gfximage/gfximage_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/gfxlightdef/gfxlightdef_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/gfxworld/gfxworld_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/glasses/glasses_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/localizeentry/localizeentry_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/mapents/mapents_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/material/material_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/materialtechniqueset/materialtechniqueset_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/menudef_t/menudef_t_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/menulist/menulist_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/packindex/packindex_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/physconstraints/physconstraints_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/physpreset/physpreset_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/rawfile/rawfile_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/sndbank/sndbank_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/snddriverglobals/snddriverglobals_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/sndpatch/sndpatch_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/stringtable/stringtable_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/weaponvariantdef/weaponvariantdef_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/xanimparts/xanimparts_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/xglobals/xglobals_write_db.h"
|
|
||||||
#include "Game/T5/XAssets/xmodel/xmodel_write_db.h"
|
|
||||||
#include "Writing/WritingException.h"
|
#include "Writing/WritingException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -88,30 +57,31 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo
|
|||||||
|
|
||||||
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
assert(!atStreamStart);
|
||||||
|
|
||||||
if (atStreamStart)
|
|
||||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
|
||||||
|
|
||||||
if (varScriptStringList->strings != nullptr)
|
if (varScriptStringList->strings != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(const char*));
|
m_stream->Align(4);
|
||||||
varXString = varScriptStringList->strings;
|
varXString = varScriptStringList->strings;
|
||||||
WriteXStringArray(true, varScriptStringList->count);
|
WriteXStringArray(true, varScriptStringList->count);
|
||||||
|
|
||||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAsset, header.data) == 4u);
|
||||||
|
#endif
|
||||||
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
||||||
case type_index: \
|
case type_index: \
|
||||||
{ \
|
{ \
|
||||||
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
||||||
writer.Write(&varXAsset->header.headerEntry); \
|
writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
#define SKIP_ASSET(type_index, typeName, headerEntry) \
|
#define SKIP_ASSET(type_index, typeName, headerEntry) \
|
||||||
@@ -121,7 +91,7 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
|||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset);
|
varXAssetWritten = m_stream->Write(varXAsset);
|
||||||
|
|
||||||
switch (varXAsset->type)
|
switch (varXAsset->type)
|
||||||
{
|
{
|
||||||
@@ -173,38 +143,75 @@ void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t coun
|
|||||||
{
|
{
|
||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAsset) == 8u);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset, count);
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||||
|
#else
|
||||||
|
const auto fill = m_stream->WriteWithFill(8u * count);
|
||||||
|
varXAssetWritten = fill.Offset();
|
||||||
|
|
||||||
|
for (size_t index = 0; index < count; index++)
|
||||||
|
fill.Fill(varXAsset[index].type, 8u * index);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t index = 0; index < count; index++)
|
for (size_t index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
WriteXAsset(false);
|
WriteXAsset(false);
|
||||||
varXAsset++;
|
varXAsset++;
|
||||||
|
varXAssetWritten.Inc(8u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteContent(IZoneOutputStream& stream)
|
void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
m_stream = &stream;
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
|
||||||
|
|
||||||
MemoryManager memory;
|
MemoryManager memory;
|
||||||
XAssetList assetList{};
|
XAssetList assetList{};
|
||||||
|
|
||||||
CreateXAssetList(assetList, memory);
|
CreateXAssetList(assetList, memory);
|
||||||
|
|
||||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
varXAssetList = &assetList;
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAssetList) == 16);
|
||||||
|
static_assert(offsetof(XAssetList, assetCount) == 8u);
|
||||||
|
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||||
|
#else
|
||||||
|
const auto fillAccessor = m_stream->WriteWithFill(16u);
|
||||||
|
varXAssetListWritten = fillAccessor.Offset();
|
||||||
|
|
||||||
varScriptStringList = &varXAssetList->stringList;
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
fillAccessor.Fill(varScriptStringList->count, 0u);
|
||||||
|
|
||||||
|
fillAccessor.Fill(varXAssetList->assetCount, 8u);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||||
|
#endif
|
||||||
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
varScriptStringListWritten = varXAssetListWritten.AtOffset(0);
|
||||||
WriteScriptStringList(false);
|
WriteScriptStringList(false);
|
||||||
|
|
||||||
if (varXAssetList->assets != nullptr)
|
if (varXAssetList->assets != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(XAsset));
|
m_stream->Align(4);
|
||||||
varXAsset = varXAssetList->assets;
|
varXAsset = varXAssetList->assets;
|
||||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||||
m_stream->MarkFollowing(varXAssetList->assets);
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, assets) == 12u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
m_stream->PopBlock();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Game/T5/T5.h"
|
#include "Game/T5/T5.h"
|
||||||
#include "Writing/ContentWriterBase.h"
|
#include "Writing/ContentWriterBase.h"
|
||||||
#include "Writing/IContentWritingEntryPoint.h"
|
#include "Writing/IContentWritingEntryPoint.h"
|
||||||
@@ -8,9 +9,9 @@ namespace T5
|
|||||||
class ContentWriter final : public ContentWriterBase, public IContentWritingEntryPoint
|
class ContentWriter final : public ContentWriterBase, public IContentWritingEntryPoint
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
ContentWriter(const Zone& zone);
|
explicit ContentWriter(const Zone& zone);
|
||||||
|
|
||||||
void WriteContent(IZoneOutputStream& stream) override;
|
void WriteContent(ZoneOutputStream& stream) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
||||||
@@ -23,5 +24,9 @@ namespace T5
|
|||||||
XAssetList* varXAssetList;
|
XAssetList* varXAssetList;
|
||||||
XAsset* varXAsset;
|
XAsset* varXAsset;
|
||||||
ScriptStringList* varScriptStringList;
|
ScriptStringList* varScriptStringList;
|
||||||
|
|
||||||
|
ZoneOutputOffset varXAssetListWritten;
|
||||||
|
ZoneOutputOffset varXAssetWritten;
|
||||||
|
ZoneOutputOffset varScriptStringListWritten;
|
||||||
};
|
};
|
||||||
} // namespace T5
|
} // namespace T5
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
|
|||||||
SetupBlocks(*writer);
|
SetupBlocks(*writer);
|
||||||
|
|
||||||
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
||||||
std::make_unique<ContentWriter>(zone), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
||||||
auto* contentInMemoryPtr = contentInMemory.get();
|
auto* contentInMemoryPtr = contentInMemory.get();
|
||||||
writer->AddWritingStep(std::move(contentInMemory));
|
writer->AddWritingStep(std::move(contentInMemory));
|
||||||
|
|
||||||
|
|||||||
@@ -1,53 +1,6 @@
|
|||||||
#include "ContentWriterT6.h"
|
#include "ContentWriterT6.h"
|
||||||
|
|
||||||
#include "Game/T6/XAssets/addonmapents/addonmapents_write_db.h"
|
#include "Game/T6/AssetWriterT6.h"
|
||||||
#include "Game/T6/XAssets/clipmap_t/clipmap_t_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/comworld/comworld_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/ddlroot_t/ddlroot_t_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/destructibledef/destructibledef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/emblemset/emblemset_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/font_s/font_s_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/fonticon/fonticon_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/footstepfxtabledef/footstepfxtabledef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/footsteptabledef/footsteptabledef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/fxeffectdef/fxeffectdef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/fximpacttable/fximpacttable_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/gameworldmp/gameworldmp_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/gameworldsp/gameworldsp_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/gfximage/gfximage_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/gfxlightdef/gfxlightdef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/gfxworld/gfxworld_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/glasses/glasses_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/keyvaluepairs/keyvaluepairs_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/leaderboarddef/leaderboarddef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/localizeentry/localizeentry_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/mapents/mapents_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/material/material_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/materialtechniqueset/materialtechniqueset_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/memoryblock/memoryblock_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/menudef_t/menudef_t_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/menulist/menulist_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/physconstraints/physconstraints_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/physpreset/physpreset_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/qdb/qdb_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/rawfile/rawfile_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/scriptparsetree/scriptparsetree_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/skinnedvertsdef/skinnedvertsdef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/slug/slug_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/sndbank/sndbank_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/snddriverglobals/snddriverglobals_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/sndpatch/sndpatch_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/stringtable/stringtable_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/tracerdef/tracerdef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/vehicledef/vehicledef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/weaponattachment/weaponattachment_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/weaponattachmentunique/weaponattachmentunique_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/weaponcamo/weaponcamo_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/weaponvariantdef/weaponvariantdef_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/xanimparts/xanimparts_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/xglobals/xglobals_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/xmodel/xmodel_write_db.h"
|
|
||||||
#include "Game/T6/XAssets/zbarrierdef/zbarrierdef_write_db.h"
|
|
||||||
#include "Writing/WritingException.h"
|
#include "Writing/WritingException.h"
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
@@ -107,37 +60,38 @@ void ContentWriter::CreateXAssetList(XAssetList& xAssetList, MemoryManager& memo
|
|||||||
|
|
||||||
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
void ContentWriter::WriteScriptStringList(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
assert(!atStreamStart);
|
||||||
|
|
||||||
if (atStreamStart)
|
|
||||||
varScriptStringList = m_stream->Write(varScriptStringList);
|
|
||||||
|
|
||||||
if (varScriptStringList->strings != nullptr)
|
if (varScriptStringList->strings != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(const char*));
|
m_stream->Align(4);
|
||||||
varXString = varScriptStringList->strings;
|
varXString = varScriptStringList->strings;
|
||||||
WriteXStringArray(true, varScriptStringList->count);
|
WriteXStringArray(true, varScriptStringList->count);
|
||||||
|
|
||||||
m_stream->MarkFollowing(varScriptStringList->strings);
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(ScriptStringList, strings) == 4u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varScriptStringListWritten.AtOffset(4));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
void ContentWriter::WriteXAsset(const bool atStreamStart)
|
||||||
{
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAsset, header.data) == 4u);
|
||||||
|
#endif
|
||||||
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
#define WRITE_ASSET(type_index, typeName, headerEntry) \
|
||||||
case type_index: \
|
case type_index: \
|
||||||
{ \
|
{ \
|
||||||
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
Writer_##typeName writer(varXAsset->header.headerEntry, m_zone, *m_stream); \
|
||||||
writer.Write(&varXAsset->header.headerEntry); \
|
writer.Write(varXAsset->header.headerEntry, varXAssetWritten.AtOffset(4)); \
|
||||||
break; \
|
break; \
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset);
|
varXAssetWritten = m_stream->Write(varXAsset);
|
||||||
|
|
||||||
switch (varXAsset->type)
|
switch (varXAsset->type)
|
||||||
{
|
{
|
||||||
@@ -203,47 +157,89 @@ void ContentWriter::WriteXAsset(const bool atStreamStart)
|
|||||||
void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t count)
|
void ContentWriter::WriteXAssetArray(const bool atStreamStart, const size_t count)
|
||||||
{
|
{
|
||||||
assert(varXAsset != nullptr);
|
assert(varXAsset != nullptr);
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAsset) == 8u);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
varXAsset = m_stream->Write(varXAsset, count);
|
{
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
varXAssetWritten = m_stream->Write(varXAsset, count);
|
||||||
|
#else
|
||||||
|
const auto fill = m_stream->WriteWithFill(8u * count);
|
||||||
|
varXAssetWritten = fill.Offset();
|
||||||
|
|
||||||
|
for (size_t index = 0; index < count; index++)
|
||||||
|
fill.Fill(varXAsset[index].type, 8u * index);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
for (size_t index = 0; index < count; index++)
|
for (size_t index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
WriteXAsset(false);
|
WriteXAsset(false);
|
||||||
varXAsset++;
|
varXAsset++;
|
||||||
|
varXAssetWritten.Inc(8u);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriter::WriteContent(IZoneOutputStream& stream)
|
void ContentWriter::WriteContent(ZoneOutputStream& stream)
|
||||||
{
|
{
|
||||||
m_stream = &stream;
|
m_stream = &stream;
|
||||||
|
|
||||||
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
|
||||||
|
|
||||||
MemoryManager memory;
|
MemoryManager memory;
|
||||||
XAssetList assetList{};
|
XAssetList assetList{};
|
||||||
|
|
||||||
CreateXAssetList(assetList, memory);
|
CreateXAssetList(assetList, memory);
|
||||||
|
|
||||||
varXAssetList = static_cast<XAssetList*>(m_stream->WriteDataRaw(&assetList, sizeof(assetList)));
|
varXAssetList = &assetList;
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(sizeof(XAssetList) == 24);
|
||||||
|
static_assert(offsetof(XAssetList, dependCount) == 8u);
|
||||||
|
static_assert(offsetof(XAssetList, assetCount) == 16u);
|
||||||
|
varXAssetListWritten = m_stream->WriteDataRaw(&assetList, sizeof(assetList));
|
||||||
|
#else
|
||||||
|
const auto fillAccessor = m_stream->WriteWithFill(24u);
|
||||||
|
varXAssetListWritten = fillAccessor.Offset();
|
||||||
|
|
||||||
varScriptStringList = &varXAssetList->stringList;
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
fillAccessor.Fill(varScriptStringList->count, 0u);
|
||||||
|
|
||||||
|
fillAccessor.Fill(varXAssetList->dependCount, 8u);
|
||||||
|
fillAccessor.Fill(varXAssetList->assetCount, 16u);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
m_stream->PushBlock(XFILE_BLOCK_VIRTUAL);
|
||||||
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, stringList) == 0u);
|
||||||
|
#endif
|
||||||
|
varScriptStringList = &varXAssetList->stringList;
|
||||||
|
varScriptStringListWritten = varXAssetListWritten.AtOffset(0);
|
||||||
WriteScriptStringList(false);
|
WriteScriptStringList(false);
|
||||||
|
|
||||||
if (varXAssetList->depends != nullptr)
|
if (varXAssetList->depends != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(const char*));
|
m_stream->Align(4);
|
||||||
varXString = varXAssetList->depends;
|
varXString = varXAssetList->depends;
|
||||||
WriteXStringArray(true, varXAssetList->dependCount);
|
WriteXStringArray(true, varXAssetList->dependCount);
|
||||||
m_stream->MarkFollowing(varXAssetList->depends);
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, depends) == 12u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varXAssetListWritten.AtOffset(12));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (varXAssetList->assets != nullptr)
|
if (varXAssetList->assets != nullptr)
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(XAsset));
|
m_stream->Align(4);
|
||||||
varXAsset = varXAssetList->assets;
|
varXAsset = varXAssetList->assets;
|
||||||
WriteXAssetArray(true, varXAssetList->assetCount);
|
WriteXAssetArray(true, varXAssetList->assetCount);
|
||||||
m_stream->MarkFollowing(varXAssetList->assets);
|
|
||||||
|
#ifdef ARCH_x86
|
||||||
|
static_assert(offsetof(XAssetList, assets) == 20u);
|
||||||
|
#endif
|
||||||
|
m_stream->MarkFollowing(varXAssetListWritten.AtOffset(20));
|
||||||
}
|
}
|
||||||
|
|
||||||
m_stream->PopBlock();
|
m_stream->PopBlock();
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Game/T6/T6.h"
|
#include "Game/T6/T6.h"
|
||||||
#include "Writing/ContentWriterBase.h"
|
#include "Writing/ContentWriterBase.h"
|
||||||
#include "Writing/IContentWritingEntryPoint.h"
|
#include "Writing/IContentWritingEntryPoint.h"
|
||||||
@@ -10,7 +11,7 @@ namespace T6
|
|||||||
public:
|
public:
|
||||||
explicit ContentWriter(const Zone& zone);
|
explicit ContentWriter(const Zone& zone);
|
||||||
|
|
||||||
void WriteContent(IZoneOutputStream& stream) override;
|
void WriteContent(ZoneOutputStream& stream) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
void CreateXAssetList(XAssetList& xAssetList, MemoryManager& memory) const;
|
||||||
@@ -23,5 +24,9 @@ namespace T6
|
|||||||
XAssetList* varXAssetList;
|
XAssetList* varXAssetList;
|
||||||
XAsset* varXAsset;
|
XAsset* varXAsset;
|
||||||
ScriptStringList* varScriptStringList;
|
ScriptStringList* varScriptStringList;
|
||||||
|
|
||||||
|
ZoneOutputOffset varXAssetListWritten;
|
||||||
|
ZoneOutputOffset varXAssetWritten;
|
||||||
|
ZoneOutputOffset varScriptStringListWritten;
|
||||||
};
|
};
|
||||||
} // namespace T6
|
} // namespace T6
|
||||||
|
|||||||
@@ -106,7 +106,7 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
|
|||||||
SetupBlocks(*writer);
|
SetupBlocks(*writer);
|
||||||
|
|
||||||
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
auto contentInMemory = std::make_unique<StepWriteZoneContentToMemory>(
|
||||||
std::make_unique<ContentWriter>(zone), zone, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
std::make_unique<ContentWriter>(zone), zone, 32u, ZoneConstants::OFFSET_BLOCK_BIT_COUNT, ZoneConstants::INSERT_BLOCK);
|
||||||
auto* contentInMemoryPtr = contentInMemory.get();
|
auto* contentInMemoryPtr = contentInMemory.get();
|
||||||
writer->AddWritingStep(std::move(contentInMemory));
|
writer->AddWritingStep(std::move(contentInMemory));
|
||||||
|
|
||||||
@@ -119,7 +119,6 @@ std::unique_ptr<ZoneWriter> ZoneWriterFactory::CreateWriter(const Zone& zone) co
|
|||||||
AddXChunkProcessor(*writer, zone, isEncrypted, &dataToSignProvider, &xChunksProcessor);
|
AddXChunkProcessor(*writer, zone, isEncrypted, &dataToSignProvider, &xChunksProcessor);
|
||||||
|
|
||||||
// Start of the XFile struct
|
// Start of the XFile struct
|
||||||
// m_writer->AddWritingStep(std::make_unique<StepSkipBytes>(8)); // Skip size and externalSize fields since they are not interesting for us
|
|
||||||
writer->AddWritingStep(std::make_unique<StepWriteZoneSizes>(contentInMemoryPtr));
|
writer->AddWritingStep(std::make_unique<StepWriteZoneSizes>(contentInMemoryPtr));
|
||||||
writer->AddWritingStep(std::make_unique<StepWriteXBlockSizes>(zone));
|
writer->AddWritingStep(std::make_unique<StepWriteXBlockSizes>(zone));
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
|
||||||
AssetWriter::AssetWriter(XAssetInfoGeneric* asset, const Zone& zone, IZoneOutputStream& stream)
|
AssetWriter::AssetWriter(XAssetInfoGeneric* asset, const Zone& zone, ZoneOutputStream& stream)
|
||||||
: ContentWriterBase(zone, stream),
|
: ContentWriterBase(zone, stream),
|
||||||
m_asset(asset),
|
m_asset(asset),
|
||||||
varScriptString(nullptr),
|
varScriptString(nullptr),
|
||||||
@@ -18,16 +18,16 @@ const char* AssetWriter::NonReferenceAssetName(const char* assetName)
|
|||||||
return assetName;
|
return assetName;
|
||||||
}
|
}
|
||||||
|
|
||||||
scr_string_t AssetWriter::UseScriptString(const scr_string_t scrString) const
|
void AssetWriter::UseScriptString(const scr_string_t scrString, const ZoneOutputOffset written) const
|
||||||
{
|
{
|
||||||
assert(scrString < m_asset->m_zone->m_script_strings.Count());
|
assert(scrString < m_asset->m_zone->m_script_strings.Count());
|
||||||
|
|
||||||
if (m_asset->m_zone == &m_zone)
|
if (m_asset->m_zone == &m_zone)
|
||||||
return scrString;
|
return;
|
||||||
|
|
||||||
// The asset comes from a different zone, we need to translate it
|
// The asset comes from a different zone, we need to translate it
|
||||||
const auto strValue = m_asset->m_zone->m_script_strings.CValue(scrString);
|
const auto strValue = m_asset->m_zone->m_script_strings.CValue(scrString);
|
||||||
return m_zone.m_script_strings.GetScriptString(strValue);
|
*static_cast<scr_string_t*>(written.Offset()) = m_zone.m_script_strings.GetScriptString(strValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AssetWriter::WriteScriptStringArray(const bool atStreamStart, const size_t count)
|
void AssetWriter::WriteScriptStringArray(const bool atStreamStart, const size_t count)
|
||||||
@@ -38,12 +38,13 @@ void AssetWriter::WriteScriptStringArray(const bool atStreamStart, const size_t
|
|||||||
varScriptStringWritten = m_stream->Write<scr_string_t>(varScriptString, count);
|
varScriptStringWritten = m_stream->Write<scr_string_t>(varScriptString, count);
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(varScriptStringWritten != nullptr);
|
assert(varScriptStringWritten.Offset() != nullptr);
|
||||||
|
|
||||||
auto* ptr = varScriptStringWritten;
|
|
||||||
for (size_t index = 0; index < count; index++)
|
for (size_t index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
*ptr = UseScriptString(*ptr);
|
UseScriptString(*varScriptString, varScriptStringWritten);
|
||||||
ptr++;
|
|
||||||
|
varScriptString++;
|
||||||
|
varScriptStringWritten.Inc(sizeof(scr_string_t));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,21 +2,20 @@
|
|||||||
|
|
||||||
#include "ContentWriterBase.h"
|
#include "ContentWriterBase.h"
|
||||||
#include "Pool/XAssetInfo.h"
|
#include "Pool/XAssetInfo.h"
|
||||||
#include "Utils/ClassUtils.h"
|
|
||||||
#include "Zone/Zone.h"
|
#include "Zone/Zone.h"
|
||||||
#include "Zone/ZoneTypes.h"
|
#include "Zone/ZoneTypes.h"
|
||||||
|
|
||||||
class AssetWriter : public ContentWriterBase
|
class AssetWriter : public ContentWriterBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
AssetWriter(XAssetInfoGeneric* asset, const Zone& zone, IZoneOutputStream& stream);
|
AssetWriter(XAssetInfoGeneric* asset, const Zone& zone, ZoneOutputStream& stream);
|
||||||
|
|
||||||
[[nodiscard]] static const char* NonReferenceAssetName(const char* assetName);
|
[[nodiscard]] static const char* NonReferenceAssetName(const char* assetName);
|
||||||
[[nodiscard]] scr_string_t UseScriptString(scr_string_t scrString) const;
|
void UseScriptString(scr_string_t scrString, ZoneOutputOffset written) const;
|
||||||
void WriteScriptStringArray(bool atStreamStart, size_t count);
|
void WriteScriptStringArray(bool atStreamStart, size_t count);
|
||||||
|
|
||||||
XAssetInfoGeneric* m_asset;
|
XAssetInfoGeneric* m_asset;
|
||||||
|
|
||||||
scr_string_t* varScriptString;
|
scr_string_t* varScriptString;
|
||||||
scr_string_t* varScriptStringWritten;
|
ZoneOutputOffset varScriptStringWritten;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ ContentWriterBase::ContentWriterBase(const Zone& zone)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
ContentWriterBase::ContentWriterBase(const Zone& zone, IZoneOutputStream& stream)
|
ContentWriterBase::ContentWriterBase(const Zone& zone, ZoneOutputStream& stream)
|
||||||
: m_zone(zone),
|
: m_zone(zone),
|
||||||
m_stream(&stream),
|
m_stream(&stream),
|
||||||
varXString(nullptr),
|
varXString(nullptr),
|
||||||
@@ -23,34 +23,36 @@ void ContentWriterBase::WriteXString(const bool atStreamStart)
|
|||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
{
|
{
|
||||||
assert(varXString != nullptr);
|
assert(varXString != nullptr);
|
||||||
varXStringWritten = m_stream->Write<const char*>(varXString);
|
varXStringWritten = m_stream->WriteWithFill(m_stream->GetPointerByteCount()).Offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(varXStringWritten != nullptr);
|
assert(varXStringWritten.Offset() != nullptr);
|
||||||
|
|
||||||
if (m_stream->ReusableShouldWrite(varXStringWritten))
|
if (m_stream->ReusableShouldWrite(*varXString, varXStringWritten))
|
||||||
{
|
{
|
||||||
m_stream->Align(alignof(const char));
|
m_stream->Align(1);
|
||||||
m_stream->ReusableAddOffset(*varXStringWritten);
|
m_stream->ReusableAddOffset(*varXString);
|
||||||
m_stream->WriteNullTerminated(*varXStringWritten);
|
m_stream->WriteNullTerminated(*varXString);
|
||||||
|
|
||||||
m_stream->MarkFollowing(*varXStringWritten);
|
m_stream->MarkFollowing(varXStringWritten);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ContentWriterBase::WriteXStringArray(const bool atStreamStart, const size_t count)
|
void ContentWriterBase::WriteXStringArray(const bool atStreamStart, const size_t count)
|
||||||
{
|
{
|
||||||
|
const auto pointerByteCount = m_stream->GetPointerByteCount();
|
||||||
if (atStreamStart)
|
if (atStreamStart)
|
||||||
{
|
{
|
||||||
assert(varXString != nullptr);
|
assert(varXString != nullptr);
|
||||||
varXStringWritten = m_stream->Write<const char*>(varXString, count);
|
varXStringWritten = m_stream->WriteWithFill(pointerByteCount * count).Offset();
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(varXStringWritten != nullptr);
|
assert(varXStringWritten.Offset() != nullptr);
|
||||||
|
|
||||||
for (size_t index = 0; index < count; index++)
|
for (size_t index = 0; index < count; index++)
|
||||||
{
|
{
|
||||||
WriteXString(false);
|
WriteXString(false);
|
||||||
varXStringWritten++;
|
varXString++;
|
||||||
|
varXStringWritten.Inc(pointerByteCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Zone/Stream/IZoneOutputStream.h"
|
#include "Zone/Stream/ZoneOutputStream.h"
|
||||||
#include "Zone/Zone.h"
|
#include "Zone/Zone.h"
|
||||||
|
|
||||||
class ContentWriterBase
|
class ContentWriterBase
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
explicit ContentWriterBase(const Zone& zone);
|
explicit ContentWriterBase(const Zone& zone);
|
||||||
ContentWriterBase(const Zone& zone, IZoneOutputStream& stream);
|
ContentWriterBase(const Zone& zone, ZoneOutputStream& stream);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~ContentWriterBase() = default;
|
virtual ~ContentWriterBase() = default;
|
||||||
@@ -21,8 +21,8 @@ protected:
|
|||||||
void WriteXStringArray(bool atStreamStart, size_t count);
|
void WriteXStringArray(bool atStreamStart, size_t count);
|
||||||
|
|
||||||
const Zone& m_zone;
|
const Zone& m_zone;
|
||||||
IZoneOutputStream* m_stream;
|
ZoneOutputStream* m_stream;
|
||||||
|
|
||||||
const char** varXString;
|
const char** varXString;
|
||||||
const char** varXStringWritten;
|
ZoneOutputOffset varXStringWritten;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Zone/Stream/IZoneOutputStream.h"
|
#include "Zone/Stream/ZoneOutputStream.h"
|
||||||
|
|
||||||
class IContentWritingEntryPoint
|
class IContentWritingEntryPoint
|
||||||
{
|
{
|
||||||
@@ -12,5 +12,5 @@ public:
|
|||||||
IContentWritingEntryPoint& operator=(const IContentWritingEntryPoint& other) = default;
|
IContentWritingEntryPoint& operator=(const IContentWritingEntryPoint& other) = default;
|
||||||
IContentWritingEntryPoint& operator=(IContentWritingEntryPoint&& other) noexcept = default;
|
IContentWritingEntryPoint& operator=(IContentWritingEntryPoint&& other) noexcept = default;
|
||||||
|
|
||||||
virtual void WriteContent(IZoneOutputStream& stream) = 0;
|
virtual void WriteContent(ZoneOutputStream& stream) = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
#include "StepWriteZoneContentToMemory.h"
|
#include "StepWriteZoneContentToMemory.h"
|
||||||
|
|
||||||
#include "Zone/Stream/Impl/InMemoryZoneOutputStream.h"
|
#include "Zone/Stream/ZoneOutputStream.h"
|
||||||
|
|
||||||
StepWriteZoneContentToMemory::StepWriteZoneContentToMemory(std::unique_ptr<IContentWritingEntryPoint> entryPoint,
|
StepWriteZoneContentToMemory::StepWriteZoneContentToMemory(std::unique_ptr<IContentWritingEntryPoint> entryPoint,
|
||||||
const Zone& zone,
|
const Zone& zone,
|
||||||
const int offsetBlockBitCount,
|
const unsigned pointerBitCount,
|
||||||
|
const unsigned offsetBlockBitCount,
|
||||||
const block_t insertBlock)
|
const block_t insertBlock)
|
||||||
: m_content_loader(std::move(entryPoint)),
|
: m_content_loader(std::move(entryPoint)),
|
||||||
m_zone_data(std::make_unique<InMemoryZoneData>()),
|
m_zone_data(std::make_unique<InMemoryZoneData>()),
|
||||||
m_zone(zone),
|
m_zone(zone),
|
||||||
|
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,12 +18,11 @@ StepWriteZoneContentToMemory::StepWriteZoneContentToMemory(std::unique_ptr<ICont
|
|||||||
|
|
||||||
void StepWriteZoneContentToMemory::PerformStep(ZoneWriter* zoneWriter, IWritingStream* stream)
|
void StepWriteZoneContentToMemory::PerformStep(ZoneWriter* zoneWriter, IWritingStream* stream)
|
||||||
{
|
{
|
||||||
std::vector<XBlock*> blocks;
|
m_blocks.reserve(zoneWriter->m_blocks.size());
|
||||||
blocks.reserve(zoneWriter->m_blocks.size());
|
|
||||||
for (const auto& block : zoneWriter->m_blocks)
|
for (const auto& block : zoneWriter->m_blocks)
|
||||||
blocks.emplace_back(block.get());
|
m_blocks.emplace_back(block.get());
|
||||||
|
|
||||||
const auto zoneOutputStream = std::make_unique<InMemoryZoneOutputStream>(m_zone_data.get(), std::move(blocks), m_offset_block_bit_count, m_insert_block);
|
const auto zoneOutputStream = ZoneOutputStream::Create(m_pointer_bit_count, m_offset_block_bit_count, m_blocks, m_insert_block, *m_zone_data);
|
||||||
m_content_loader->WriteContent(*zoneOutputStream);
|
m_content_loader->WriteContent(*zoneOutputStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,14 +2,15 @@
|
|||||||
|
|
||||||
#include "Writing/IContentWritingEntryPoint.h"
|
#include "Writing/IContentWritingEntryPoint.h"
|
||||||
#include "Writing/IWritingStep.h"
|
#include "Writing/IWritingStep.h"
|
||||||
#include "Writing/InMemoryZoneData.h"
|
#include "Zone/Stream/InMemoryZoneData.h"
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
class StepWriteZoneContentToMemory final : public IWritingStep
|
class StepWriteZoneContentToMemory final : public IWritingStep
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
StepWriteZoneContentToMemory(std::unique_ptr<IContentWritingEntryPoint> entryPoint, const Zone& zone, int offsetBlockBitCount, block_t insertBlock);
|
StepWriteZoneContentToMemory(
|
||||||
|
std::unique_ptr<IContentWritingEntryPoint> entryPoint, const Zone& zone, unsigned pointerBitCount, unsigned offsetBlockBitCount, block_t insertBlock);
|
||||||
|
|
||||||
void PerformStep(ZoneWriter* zoneWriter, IWritingStream* stream) override;
|
void PerformStep(ZoneWriter* zoneWriter, IWritingStream* stream) override;
|
||||||
[[nodiscard]] InMemoryZoneData* GetData() const;
|
[[nodiscard]] InMemoryZoneData* GetData() const;
|
||||||
@@ -18,6 +19,9 @@ private:
|
|||||||
std::unique_ptr<IContentWritingEntryPoint> m_content_loader;
|
std::unique_ptr<IContentWritingEntryPoint> m_content_loader;
|
||||||
std::unique_ptr<InMemoryZoneData> m_zone_data;
|
std::unique_ptr<InMemoryZoneData> m_zone_data;
|
||||||
const Zone& m_zone;
|
const Zone& m_zone;
|
||||||
int m_offset_block_bit_count;
|
std::vector<XBlock*> m_blocks;
|
||||||
|
|
||||||
|
unsigned m_pointer_bit_count;
|
||||||
|
unsigned m_offset_block_bit_count;
|
||||||
block_t m_insert_block;
|
block_t m_insert_block;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#include "StepWriteZoneSizes.h"
|
#include "StepWriteZoneSizes.h"
|
||||||
|
|
||||||
|
#include <cstdint>
|
||||||
|
|
||||||
StepWriteZoneSizes::StepWriteZoneSizes(StepWriteZoneContentToMemory* memory)
|
StepWriteZoneSizes::StepWriteZoneSizes(StepWriteZoneContentToMemory* memory)
|
||||||
: m_memory(memory)
|
: m_memory(memory)
|
||||||
{
|
{
|
||||||
@@ -7,8 +9,8 @@ StepWriteZoneSizes::StepWriteZoneSizes(StepWriteZoneContentToMemory* memory)
|
|||||||
|
|
||||||
void StepWriteZoneSizes::PerformStep(ZoneWriter* zoneWriter, IWritingStream* stream)
|
void StepWriteZoneSizes::PerformStep(ZoneWriter* zoneWriter, IWritingStream* stream)
|
||||||
{
|
{
|
||||||
auto totalSize = static_cast<size_t>(m_memory->GetData()->m_total_size);
|
const auto totalSize = static_cast<uint32_t>(m_memory->GetData()->m_total_size);
|
||||||
size_t externalSize = 0;
|
constexpr uint32_t externalSize = 0;
|
||||||
|
|
||||||
stream->Write(&totalSize, sizeof(totalSize));
|
stream->Write(&totalSize, sizeof(totalSize));
|
||||||
stream->Write(&externalSize, sizeof(externalSize));
|
stream->Write(&externalSize, sizeof(externalSize));
|
||||||
|
|||||||
@@ -1,60 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Zone/Stream/IZoneStream.h"
|
|
||||||
|
|
||||||
#include <cstddef>
|
|
||||||
#include <typeindex>
|
|
||||||
#include <typeinfo>
|
|
||||||
|
|
||||||
class IZoneOutputStream : public IZoneStream
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
inline static void* const PTR_FOLLOWING = reinterpret_cast<void*>(-1);
|
|
||||||
inline static void* const PTR_INSERT = reinterpret_cast<void*>(-2);
|
|
||||||
|
|
||||||
virtual void Align(int alignTo) = 0;
|
|
||||||
|
|
||||||
virtual void* WriteDataRaw(const void* dst, size_t size) = 0;
|
|
||||||
virtual void* WriteDataInBlock(const void* dst, size_t size) = 0;
|
|
||||||
virtual void IncBlockPos(size_t size) = 0;
|
|
||||||
virtual void WriteNullTerminated(const void* dst) = 0;
|
|
||||||
|
|
||||||
virtual bool ReusableShouldWrite(void** pPtr, size_t size, std::type_index type) = 0;
|
|
||||||
virtual void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) = 0;
|
|
||||||
virtual void MarkFollowing(void** pPtr) = 0;
|
|
||||||
|
|
||||||
template<typename T> bool ReusableShouldWrite(T** pPtr)
|
|
||||||
{
|
|
||||||
return ReusableShouldWrite(reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(pPtr)), sizeof(T), std::type_index(typeid(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> void ReusableAddOffset(T* ptr)
|
|
||||||
{
|
|
||||||
ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), 1, std::type_index(typeid(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> void ReusableAddOffset(T* ptr, const size_t count)
|
|
||||||
{
|
|
||||||
ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), count, std::type_index(typeid(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> T* Write(T* dst)
|
|
||||||
{
|
|
||||||
return static_cast<T*>(WriteDataInBlock(reinterpret_cast<const void*>(dst), sizeof(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> T* Write(T* dst, const size_t count)
|
|
||||||
{
|
|
||||||
return static_cast<T*>(WriteDataInBlock(reinterpret_cast<const void*>(dst), count * sizeof(T)));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> T* WritePartial(T* dst, const size_t size)
|
|
||||||
{
|
|
||||||
return static_cast<T*>(WriteDataInBlock(reinterpret_cast<const void*>(dst), size));
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T> void MarkFollowing(T*& ptr)
|
|
||||||
{
|
|
||||||
MarkFollowing(reinterpret_cast<void**>(reinterpret_cast<uintptr_t>(&ptr)));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
@@ -1,218 +0,0 @@
|
|||||||
#include "InMemoryZoneOutputStream.h"
|
|
||||||
|
|
||||||
#include <cassert>
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
InMemoryZoneOutputStream::InMemoryZoneOutputStream(InMemoryZoneData* zoneData, std::vector<XBlock*> blocks, const int blockBitCount, const block_t insertBlock)
|
|
||||||
: m_zone_data(zoneData),
|
|
||||||
m_blocks(std::move(blocks)),
|
|
||||||
m_block_bit_count(blockBitCount),
|
|
||||||
m_insert_block(m_blocks[insertBlock])
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
InMemoryZoneOutputStream::ReusableEntry::ReusableEntry(void* startPtr, const size_t entrySize, const size_t entryCount, const uintptr_t startZonePtr)
|
|
||||||
: m_start_ptr(startPtr),
|
|
||||||
m_end_ptr(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(startPtr) + entrySize * entryCount)),
|
|
||||||
m_start_zone_ptr(startZonePtr),
|
|
||||||
m_entry_size(entrySize),
|
|
||||||
m_entry_count(entryCount)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void InMemoryZoneOutputStream::PushBlock(const block_t block)
|
|
||||||
{
|
|
||||||
assert(block >= 0 && block < static_cast<block_t>(m_blocks.size()));
|
|
||||||
|
|
||||||
auto* newBlock = m_blocks[block];
|
|
||||||
|
|
||||||
assert(newBlock->m_index == block);
|
|
||||||
|
|
||||||
m_block_stack.push(newBlock);
|
|
||||||
|
|
||||||
if (newBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
|
||||||
{
|
|
||||||
if (m_temp_sizes.empty())
|
|
||||||
m_temp_sizes.push(0);
|
|
||||||
else
|
|
||||||
m_temp_sizes.push(m_temp_sizes.top());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
block_t InMemoryZoneOutputStream::PopBlock()
|
|
||||||
{
|
|
||||||
assert(!m_block_stack.empty());
|
|
||||||
|
|
||||||
if (m_block_stack.empty())
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
auto* poppedBlock = m_block_stack.top();
|
|
||||||
m_block_stack.pop();
|
|
||||||
|
|
||||||
// If temp block is popped, see if its size is bigger than the current maximum temp size
|
|
||||||
if (poppedBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
|
||||||
{
|
|
||||||
const auto tempSize = m_temp_sizes.top();
|
|
||||||
m_temp_sizes.pop();
|
|
||||||
|
|
||||||
if (tempSize > poppedBlock->m_buffer_size)
|
|
||||||
poppedBlock->m_buffer_size = tempSize;
|
|
||||||
}
|
|
||||||
|
|
||||||
return poppedBlock->m_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InMemoryZoneOutputStream::Align(const int align)
|
|
||||||
{
|
|
||||||
assert(!m_block_stack.empty());
|
|
||||||
|
|
||||||
if (align > 1)
|
|
||||||
{
|
|
||||||
auto* block = m_block_stack.top();
|
|
||||||
|
|
||||||
if (block->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
|
||||||
m_temp_sizes.top() = (m_temp_sizes.top() + align - 1) / align * align;
|
|
||||||
else
|
|
||||||
block->m_buffer_size = (block->m_buffer_size + align - 1) / align * align;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void* InMemoryZoneOutputStream::WriteDataRaw(const void* src, const size_t size)
|
|
||||||
{
|
|
||||||
auto* result = m_zone_data->GetBufferOfSize(size);
|
|
||||||
memcpy(result, src, size);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void* InMemoryZoneOutputStream::WriteDataInBlock(const void* src, const size_t size)
|
|
||||||
{
|
|
||||||
assert(!m_block_stack.empty());
|
|
||||||
|
|
||||||
if (m_block_stack.empty())
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
auto* block = m_block_stack.top();
|
|
||||||
|
|
||||||
void* result = nullptr;
|
|
||||||
switch (block->m_type)
|
|
||||||
{
|
|
||||||
case XBlockType::BLOCK_TYPE_TEMP:
|
|
||||||
case XBlockType::BLOCK_TYPE_NORMAL:
|
|
||||||
result = m_zone_data->GetBufferOfSize(size);
|
|
||||||
memcpy(result, src, size);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XBlockType::BLOCK_TYPE_RUNTIME:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case XBlockType::BLOCK_TYPE_DELAY:
|
|
||||||
assert(false);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
IncBlockPos(size);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InMemoryZoneOutputStream::IncBlockPos(const size_t size)
|
|
||||||
{
|
|
||||||
assert(!m_block_stack.empty());
|
|
||||||
|
|
||||||
if (m_block_stack.empty())
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto* block = m_block_stack.top();
|
|
||||||
if (block->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
|
||||||
{
|
|
||||||
m_temp_sizes.top() += size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
block->m_buffer_size += size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void InMemoryZoneOutputStream::WriteNullTerminated(const void* src)
|
|
||||||
{
|
|
||||||
const auto len = strlen(static_cast<const char*>(src));
|
|
||||||
WriteDataInBlock(src, len + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t InMemoryZoneOutputStream::GetCurrentZonePointer()
|
|
||||||
{
|
|
||||||
assert(!m_block_stack.empty());
|
|
||||||
assert(m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_NORMAL);
|
|
||||||
|
|
||||||
uintptr_t ptr = 0;
|
|
||||||
ptr |= static_cast<uintptr_t>(m_block_stack.top()->m_index) << (sizeof(uintptr_t) * 8 - m_block_bit_count);
|
|
||||||
ptr |= m_block_stack.top()->m_buffer_size & (UINTPTR_MAX >> m_block_bit_count);
|
|
||||||
ptr++;
|
|
||||||
|
|
||||||
return ptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
uintptr_t InMemoryZoneOutputStream::InsertPointer()
|
|
||||||
{
|
|
||||||
PushBlock(m_insert_block->m_index);
|
|
||||||
|
|
||||||
Align(sizeof(uintptr_t));
|
|
||||||
const auto result = GetCurrentZonePointer();
|
|
||||||
IncBlockPos(sizeof(uintptr_t));
|
|
||||||
|
|
||||||
PopBlock();
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InMemoryZoneOutputStream::MarkFollowing(void** pPtr)
|
|
||||||
{
|
|
||||||
assert(!m_block_stack.empty());
|
|
||||||
assert(pPtr != nullptr);
|
|
||||||
*pPtr = m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP ? PTR_INSERT : PTR_FOLLOWING;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool InMemoryZoneOutputStream::ReusableShouldWrite(void** pPtr, const size_t entrySize, const std::type_index type)
|
|
||||||
{
|
|
||||||
assert(!m_block_stack.empty());
|
|
||||||
assert(pPtr != nullptr);
|
|
||||||
|
|
||||||
if (*pPtr == nullptr)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
const auto foundEntriesForType = m_reusable_entries.find(type);
|
|
||||||
if (foundEntriesForType == m_reusable_entries.end())
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const auto& entry : foundEntriesForType->second)
|
|
||||||
{
|
|
||||||
if (*pPtr >= entry.m_start_ptr && *pPtr < entry.m_end_ptr)
|
|
||||||
{
|
|
||||||
assert((reinterpret_cast<uintptr_t>(*pPtr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)) % entrySize == 0);
|
|
||||||
*pPtr = reinterpret_cast<void*>(entry.m_start_zone_ptr + (reinterpret_cast<uintptr_t>(*pPtr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)));
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void InMemoryZoneOutputStream::ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type)
|
|
||||||
{
|
|
||||||
assert(!m_block_stack.empty());
|
|
||||||
|
|
||||||
const auto inTemp = m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP;
|
|
||||||
auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer();
|
|
||||||
const auto foundEntriesForType = m_reusable_entries.find(type);
|
|
||||||
if (foundEntriesForType == m_reusable_entries.end())
|
|
||||||
{
|
|
||||||
std::vector<ReusableEntry> entries;
|
|
||||||
entries.emplace_back(ptr, size, count, zoneOffset);
|
|
||||||
m_reusable_entries.emplace(std::make_pair(type, std::move(entries)));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
foundEntriesForType->second.emplace_back(ptr, size, count, zoneOffset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include "Writing/InMemoryZoneData.h"
|
|
||||||
#include "Zone/Stream/IZoneOutputStream.h"
|
|
||||||
#include "Zone/XBlock.h"
|
|
||||||
|
|
||||||
#include <stack>
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class InMemoryZoneOutputStream final : public IZoneOutputStream
|
|
||||||
{
|
|
||||||
class ReusableEntry
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
void* m_start_ptr;
|
|
||||||
void* m_end_ptr;
|
|
||||||
uintptr_t m_start_zone_ptr;
|
|
||||||
size_t m_entry_size;
|
|
||||||
size_t m_entry_count;
|
|
||||||
|
|
||||||
ReusableEntry(void* startPtr, size_t entrySize, size_t entryCount, uintptr_t startZonePtr);
|
|
||||||
};
|
|
||||||
|
|
||||||
InMemoryZoneData* m_zone_data;
|
|
||||||
std::vector<XBlock*> m_blocks;
|
|
||||||
|
|
||||||
std::stack<XBlock*> m_block_stack;
|
|
||||||
std::stack<size_t> m_temp_sizes;
|
|
||||||
|
|
||||||
int m_block_bit_count;
|
|
||||||
XBlock* m_insert_block;
|
|
||||||
|
|
||||||
std::unordered_map<std::type_index, std::vector<ReusableEntry>> m_reusable_entries;
|
|
||||||
|
|
||||||
uintptr_t GetCurrentZonePointer();
|
|
||||||
uintptr_t InsertPointer();
|
|
||||||
|
|
||||||
public:
|
|
||||||
InMemoryZoneOutputStream(InMemoryZoneData* zoneData, std::vector<XBlock*> blocks, int blockBitCount, block_t insertBlock);
|
|
||||||
|
|
||||||
void PushBlock(block_t block) override;
|
|
||||||
block_t PopBlock() override;
|
|
||||||
void Align(int align) override;
|
|
||||||
void* WriteDataRaw(const void* src, size_t size) override;
|
|
||||||
void* WriteDataInBlock(const void* src, size_t size) override;
|
|
||||||
void IncBlockPos(size_t size) override;
|
|
||||||
void WriteNullTerminated(const void* src) override;
|
|
||||||
void MarkFollowing(void** pPtr) override;
|
|
||||||
bool ReusableShouldWrite(void** pPtr, size_t entrySize, std::type_index type) override;
|
|
||||||
void ReusableAddOffset(void* ptr, size_t size, size_t count, std::type_index type) override;
|
|
||||||
};
|
|
||||||
375
src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp
Normal file
375
src/ZoneWriting/Zone/Stream/ZoneOutputStream.cpp
Normal file
@@ -0,0 +1,375 @@
|
|||||||
|
#include "ZoneOutputStream.h"
|
||||||
|
|
||||||
|
#include "InMemoryZoneData.h"
|
||||||
|
#include "Utils/Alignment.h"
|
||||||
|
#include "Zone/XBlock.h"
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstring>
|
||||||
|
#include <stack>
|
||||||
|
#include <type_traits>
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
class ReusableEntry
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ReusableEntry(void* startPtr, const size_t entrySize, const size_t entryCount, const size_t blockSize, const uintptr_t startZonePtr)
|
||||||
|
: m_start_ptr(startPtr),
|
||||||
|
m_end_ptr(reinterpret_cast<void*>(reinterpret_cast<uintptr_t>(startPtr) + entrySize * entryCount)),
|
||||||
|
m_start_zone_ptr(startZonePtr),
|
||||||
|
m_entry_size(entrySize),
|
||||||
|
m_entry_count(entryCount),
|
||||||
|
m_block_size(blockSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void* m_start_ptr;
|
||||||
|
void* m_end_ptr;
|
||||||
|
uintptr_t m_start_zone_ptr;
|
||||||
|
size_t m_entry_size;
|
||||||
|
size_t m_entry_count;
|
||||||
|
size_t m_block_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
class InMemoryZoneOutputStream final : public ZoneOutputStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
InMemoryZoneOutputStream(
|
||||||
|
const unsigned pointerBitCount, const unsigned blockBitCount, std::vector<XBlock*>& blocks, const block_t insertBlock, InMemoryZoneData& zoneData)
|
||||||
|
: m_zone_data(zoneData),
|
||||||
|
m_blocks(blocks),
|
||||||
|
m_block_bit_count(blockBitCount),
|
||||||
|
m_pointer_byte_count(pointerBitCount / 8u),
|
||||||
|
|
||||||
|
// -1
|
||||||
|
m_zone_ptr_following(std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - pointerBitCount)),
|
||||||
|
|
||||||
|
// -2
|
||||||
|
m_zone_ptr_insert((std::numeric_limits<std::uintptr_t>::max() >> ((sizeof(std::uintptr_t) * 8u) - pointerBitCount)) - 1u)
|
||||||
|
{
|
||||||
|
assert(pointerBitCount % 8u == 0u);
|
||||||
|
assert(insertBlock < static_cast<block_t>(blocks.size()));
|
||||||
|
|
||||||
|
m_insert_block = blocks[insertBlock];
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] unsigned GetPointerByteCount() const override
|
||||||
|
{
|
||||||
|
return m_pointer_byte_count;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PushBlock(const block_t block) override
|
||||||
|
{
|
||||||
|
assert(block < static_cast<block_t>(m_blocks.size()));
|
||||||
|
|
||||||
|
auto* newBlock = m_blocks[block];
|
||||||
|
|
||||||
|
assert(newBlock->m_index == block);
|
||||||
|
|
||||||
|
m_block_stack.push(newBlock);
|
||||||
|
|
||||||
|
if (newBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||||
|
{
|
||||||
|
if (m_temp_sizes.empty())
|
||||||
|
m_temp_sizes.push(0);
|
||||||
|
else
|
||||||
|
m_temp_sizes.push(m_temp_sizes.top());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
block_t PopBlock() override
|
||||||
|
{
|
||||||
|
assert(!m_block_stack.empty());
|
||||||
|
|
||||||
|
if (m_block_stack.empty())
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
auto* poppedBlock = m_block_stack.top();
|
||||||
|
m_block_stack.pop();
|
||||||
|
|
||||||
|
// If temp block is popped, see if its size is bigger than the current maximum temp size
|
||||||
|
if (poppedBlock->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||||
|
{
|
||||||
|
const auto tempSize = m_temp_sizes.top();
|
||||||
|
m_temp_sizes.pop();
|
||||||
|
|
||||||
|
poppedBlock->m_buffer_size = std::max(tempSize, poppedBlock->m_buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return poppedBlock->m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Align(const unsigned align) override
|
||||||
|
{
|
||||||
|
assert(!m_block_stack.empty());
|
||||||
|
|
||||||
|
if (align > 1)
|
||||||
|
{
|
||||||
|
auto* block = m_block_stack.top();
|
||||||
|
|
||||||
|
if (block->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||||
|
m_temp_sizes.top() = utils::Align(m_temp_sizes.top(), static_cast<size_t>(align));
|
||||||
|
else
|
||||||
|
block->m_buffer_size = utils::Align(block->m_buffer_size, static_cast<size_t>(align));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneOutputOffset WriteDataRaw(const void* src, const size_t size) override
|
||||||
|
{
|
||||||
|
auto* result = m_zone_data.GetBufferOfSize(size);
|
||||||
|
memcpy(result, src, size);
|
||||||
|
|
||||||
|
return ZoneOutputOffset(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneOutputOffset WriteDataInBlock(const void* src, const size_t size) override
|
||||||
|
{
|
||||||
|
assert(!m_block_stack.empty());
|
||||||
|
|
||||||
|
if (m_block_stack.empty())
|
||||||
|
return ZoneOutputOffset();
|
||||||
|
|
||||||
|
const auto* block = m_block_stack.top();
|
||||||
|
|
||||||
|
void* result = nullptr;
|
||||||
|
switch (block->m_type)
|
||||||
|
{
|
||||||
|
case XBlockType::BLOCK_TYPE_TEMP:
|
||||||
|
case XBlockType::BLOCK_TYPE_NORMAL:
|
||||||
|
result = m_zone_data.GetBufferOfSize(size);
|
||||||
|
memcpy(result, src, size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XBlockType::BLOCK_TYPE_RUNTIME:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XBlockType::BLOCK_TYPE_DELAY:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IncBlockPos(size);
|
||||||
|
|
||||||
|
return ZoneOutputOffset(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IncBlockPos(const size_t size) override
|
||||||
|
{
|
||||||
|
assert(!m_block_stack.empty());
|
||||||
|
|
||||||
|
if (m_block_stack.empty())
|
||||||
|
return;
|
||||||
|
|
||||||
|
auto* block = m_block_stack.top();
|
||||||
|
if (block->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||||
|
{
|
||||||
|
m_temp_sizes.top() += size;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
block->m_buffer_size += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void WriteNullTerminated(const void* src) override
|
||||||
|
{
|
||||||
|
const auto len = strlen(static_cast<const char*>(src));
|
||||||
|
WriteDataInBlock(src, len + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneStreamFillWriteAccessor WriteWithFill(const size_t size) override
|
||||||
|
{
|
||||||
|
// If no block has been pushed, load raw
|
||||||
|
if (!m_block_stack.empty())
|
||||||
|
{
|
||||||
|
const auto* block = m_block_stack.top();
|
||||||
|
|
||||||
|
void* result = nullptr;
|
||||||
|
switch (block->m_type)
|
||||||
|
{
|
||||||
|
case XBlockType::BLOCK_TYPE_TEMP:
|
||||||
|
case XBlockType::BLOCK_TYPE_NORMAL:
|
||||||
|
result = m_zone_data.GetBufferOfSize(size);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case XBlockType::BLOCK_TYPE_RUNTIME:
|
||||||
|
case XBlockType::BLOCK_TYPE_DELAY:
|
||||||
|
assert(false);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
IncBlockPos(size);
|
||||||
|
|
||||||
|
return ZoneStreamFillWriteAccessor(result, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ZoneStreamFillWriteAccessor(m_zone_data.GetBufferOfSize(size), size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void MarkFollowing(const ZoneOutputOffset outputOffset) override
|
||||||
|
{
|
||||||
|
assert(!m_block_stack.empty());
|
||||||
|
|
||||||
|
auto* ptr = static_cast<char*>(outputOffset.Offset());
|
||||||
|
assert(ptr != nullptr);
|
||||||
|
|
||||||
|
if (m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP)
|
||||||
|
{
|
||||||
|
for (auto i = 0u; i < m_pointer_byte_count; i++)
|
||||||
|
ptr[i] = reinterpret_cast<const char*>(&m_zone_ptr_insert)[i];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
for (auto i = 0u; i < m_pointer_byte_count; i++)
|
||||||
|
ptr[i] = reinterpret_cast<const char*>(&m_zone_ptr_following)[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ReusableShouldWrite(void* ptr, const ZoneOutputOffset outputOffset, const size_t entrySize, const std::type_index type) override
|
||||||
|
{
|
||||||
|
assert(!m_block_stack.empty());
|
||||||
|
|
||||||
|
if (ptr == nullptr)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
const auto foundEntriesForType = m_reusable_entries.find(type);
|
||||||
|
if (foundEntriesForType == m_reusable_entries.end())
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const auto& entry : foundEntriesForType->second)
|
||||||
|
{
|
||||||
|
if (ptr >= entry.m_start_ptr && ptr < entry.m_end_ptr)
|
||||||
|
{
|
||||||
|
assert((reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)) % entrySize == 0);
|
||||||
|
|
||||||
|
const auto entryIndex = (reinterpret_cast<uintptr_t>(ptr) - reinterpret_cast<uintptr_t>(entry.m_start_ptr)) / entry.m_entry_size;
|
||||||
|
const auto finalZonePointer = entry.m_start_zone_ptr + entryIndex * entry.m_block_size;
|
||||||
|
auto* writtenPtrOffset = outputOffset.Offset();
|
||||||
|
|
||||||
|
for (auto i = 0u; i < m_pointer_byte_count; i++)
|
||||||
|
static_cast<char*>(writtenPtrOffset)[i] = reinterpret_cast<const char*>(&finalZonePointer)[i];
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ReusableAddOffset(void* ptr, const size_t size, const size_t count, const size_t blockSize, std::type_index type) override
|
||||||
|
{
|
||||||
|
assert(!m_block_stack.empty());
|
||||||
|
|
||||||
|
const auto inTemp = m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_TEMP;
|
||||||
|
auto zoneOffset = inTemp ? InsertPointer() : GetCurrentZonePointer();
|
||||||
|
const auto foundEntriesForType = m_reusable_entries.find(type);
|
||||||
|
if (foundEntriesForType == m_reusable_entries.end())
|
||||||
|
{
|
||||||
|
std::vector<ReusableEntry> entries;
|
||||||
|
entries.emplace_back(ptr, size, count, blockSize, zoneOffset);
|
||||||
|
m_reusable_entries.emplace(std::make_pair(type, std::move(entries)));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
foundEntriesForType->second.emplace_back(ptr, size, count, blockSize, zoneOffset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
uintptr_t GetCurrentZonePointer()
|
||||||
|
{
|
||||||
|
assert(!m_block_stack.empty());
|
||||||
|
assert(m_block_stack.top()->m_type == XBlockType::BLOCK_TYPE_NORMAL);
|
||||||
|
|
||||||
|
uintptr_t ptr = 0;
|
||||||
|
ptr |= static_cast<uintptr_t>(m_block_stack.top()->m_index) << (m_pointer_byte_count * 8 - m_block_bit_count);
|
||||||
|
ptr |= m_block_stack.top()->m_buffer_size & (UINTPTR_MAX >> (m_block_bit_count + (sizeof(uintptr_t) - m_pointer_byte_count) * 8));
|
||||||
|
ptr++;
|
||||||
|
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
uintptr_t InsertPointer()
|
||||||
|
{
|
||||||
|
PushBlock(m_insert_block->m_index);
|
||||||
|
|
||||||
|
Align(m_pointer_byte_count);
|
||||||
|
const auto result = GetCurrentZonePointer();
|
||||||
|
IncBlockPos(m_pointer_byte_count);
|
||||||
|
|
||||||
|
PopBlock();
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
InMemoryZoneData& m_zone_data;
|
||||||
|
std::vector<XBlock*>& m_blocks;
|
||||||
|
|
||||||
|
std::stack<XBlock*> m_block_stack;
|
||||||
|
std::stack<size_t> m_temp_sizes;
|
||||||
|
|
||||||
|
unsigned m_block_bit_count;
|
||||||
|
unsigned m_pointer_byte_count;
|
||||||
|
XBlock* m_insert_block;
|
||||||
|
|
||||||
|
uintptr_t m_zone_ptr_following;
|
||||||
|
uintptr_t m_zone_ptr_insert;
|
||||||
|
|
||||||
|
std::unordered_map<std::type_index, std::vector<ReusableEntry>> m_reusable_entries;
|
||||||
|
};
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
ZoneOutputOffset::ZoneOutputOffset()
|
||||||
|
: m_offset(nullptr)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneOutputOffset::ZoneOutputOffset(void* offset)
|
||||||
|
: m_offset(offset)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneOutputOffset ZoneOutputOffset::AtOffset(const size_t innerOffset) const
|
||||||
|
{
|
||||||
|
return ZoneOutputOffset(static_cast<char*>(m_offset) + innerOffset);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ZoneOutputOffset::Inc(const size_t size)
|
||||||
|
{
|
||||||
|
m_offset = static_cast<void*>(static_cast<char*>(m_offset) + size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void* ZoneOutputOffset::Offset() const
|
||||||
|
{
|
||||||
|
return m_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<ZoneOutputStream>
|
||||||
|
ZoneOutputStream::Create(unsigned pointerBitCount, unsigned blockBitCount, std::vector<XBlock*>& blocks, block_t insertBlock, InMemoryZoneData& zoneData)
|
||||||
|
{
|
||||||
|
return std::make_unique<InMemoryZoneOutputStream>(pointerBitCount, blockBitCount, blocks, insertBlock, zoneData);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneStreamFillWriteAccessor::ZoneStreamFillWriteAccessor(void* blockBuffer, const size_t bufferSize)
|
||||||
|
: m_block_buffer(blockBuffer),
|
||||||
|
m_buffer_size(bufferSize)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneStreamFillWriteAccessor ZoneStreamFillWriteAccessor::AtOffset(const size_t offset) const
|
||||||
|
{
|
||||||
|
assert(m_block_buffer);
|
||||||
|
return ZoneStreamFillWriteAccessor(static_cast<char*>(m_block_buffer) + offset, m_buffer_size - offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneOutputOffset ZoneStreamFillWriteAccessor::Offset() const
|
||||||
|
{
|
||||||
|
assert(m_block_buffer);
|
||||||
|
return ZoneOutputOffset(m_block_buffer);
|
||||||
|
}
|
||||||
148
src/ZoneWriting/Zone/Stream/ZoneOutputStream.h
Normal file
148
src/ZoneWriting/Zone/Stream/ZoneOutputStream.h
Normal file
@@ -0,0 +1,148 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "InMemoryZoneData.h"
|
||||||
|
#include "Zone/Stream/IZoneStream.h"
|
||||||
|
#include "Zone/XBlock.h"
|
||||||
|
|
||||||
|
#include <cassert>
|
||||||
|
#include <cstddef>
|
||||||
|
#include <cstring>
|
||||||
|
#include <memory>
|
||||||
|
#include <typeindex>
|
||||||
|
#include <typeinfo>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
class ZoneOutputOffset
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZoneOutputOffset();
|
||||||
|
explicit ZoneOutputOffset(void* offset);
|
||||||
|
|
||||||
|
[[nodiscard]] ZoneOutputOffset AtOffset(size_t innerOffset) const;
|
||||||
|
void Inc(size_t size);
|
||||||
|
[[nodiscard]] void* Offset() const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* m_offset;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ZoneStreamFillWriteAccessor
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ZoneStreamFillWriteAccessor(void* blockBuffer, size_t bufferSize);
|
||||||
|
|
||||||
|
[[nodiscard]] ZoneStreamFillWriteAccessor AtOffset(size_t offset) const;
|
||||||
|
[[nodiscard]] ZoneOutputOffset Offset() const;
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
requires(sizeof(T) <= sizeof(uintptr_t))
|
||||||
|
void Fill(const T& value, const size_t offset) const
|
||||||
|
{
|
||||||
|
assert(m_block_buffer);
|
||||||
|
assert(offset + sizeof(T) <= m_buffer_size);
|
||||||
|
|
||||||
|
*reinterpret_cast<T*>(static_cast<char*>(m_block_buffer) + offset) = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
requires(sizeof(T) > sizeof(uintptr_t))
|
||||||
|
void Fill(const T& value, const size_t offset) const
|
||||||
|
{
|
||||||
|
assert(m_block_buffer);
|
||||||
|
assert(offset + sizeof(T) <= m_buffer_size);
|
||||||
|
|
||||||
|
std::memcpy(static_cast<char*>(m_block_buffer) + offset, &value, sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T, size_t S> void FillArray(T (&value)[S], const size_t offset) const
|
||||||
|
{
|
||||||
|
assert(m_block_buffer);
|
||||||
|
assert(offset + sizeof(T) * S <= m_buffer_size);
|
||||||
|
|
||||||
|
std::memcpy(static_cast<char*>(m_block_buffer) + offset, value, sizeof(T) * S);
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
void* m_block_buffer;
|
||||||
|
size_t m_buffer_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ZoneOutputStream : public IZoneStream
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
/**
|
||||||
|
* \brief Returns the configured bits that make up a pointer.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] virtual unsigned GetPointerByteCount() const = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Aligns the write position in the current block with the specified value.
|
||||||
|
* \param align The alignment value that the write position is aligned with. This should typically be the alignment of the struct that
|
||||||
|
* should be written afterward.
|
||||||
|
*/
|
||||||
|
virtual void Align(unsigned align) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Write data to the zone data without considering the current block or advancing the block position.
|
||||||
|
* The data is written directly to the specified location instead of block memory.
|
||||||
|
* \param dst The memory location to write data to.
|
||||||
|
* \param size The amount of data to write.
|
||||||
|
*/
|
||||||
|
virtual ZoneOutputOffset WriteDataRaw(const void* dst, size_t size) = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Write data with the current blocks write operation into its block memory.
|
||||||
|
* Depending on the block type, the underlying stream might be written to or not.
|
||||||
|
* The current block position is advanced by the number of bytes written.
|
||||||
|
* The destination must be inside the current block's memory space, otherwise an exception is thrown.
|
||||||
|
* \param dst The destination where the data is written to. Must be inside the current block's memory bounds.
|
||||||
|
* \param size The amount of data to write.
|
||||||
|
*/
|
||||||
|
virtual ZoneOutputOffset WriteDataInBlock(const void* dst, size_t size) = 0;
|
||||||
|
virtual void IncBlockPos(size_t size) = 0;
|
||||||
|
virtual void WriteNullTerminated(const void* dst) = 0;
|
||||||
|
|
||||||
|
virtual ZoneStreamFillWriteAccessor WriteWithFill(size_t size) = 0;
|
||||||
|
|
||||||
|
virtual bool ReusableShouldWrite(void* pPtr, ZoneOutputOffset outputOffset, size_t size, std::type_index type) = 0;
|
||||||
|
virtual void ReusableAddOffset(void* ptr, size_t size, size_t count, size_t blockSize, std::type_index type) = 0;
|
||||||
|
virtual void MarkFollowing(ZoneOutputOffset offset) = 0;
|
||||||
|
|
||||||
|
template<typename T> bool ReusableShouldWrite(T* pPtr, const ZoneOutputOffset outputOffset)
|
||||||
|
{
|
||||||
|
return ReusableShouldWrite(const_cast<void*>(reinterpret_cast<const void*>(pPtr)), outputOffset, sizeof(T), std::type_index(typeid(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void ReusableAddOffset(T* ptr)
|
||||||
|
{
|
||||||
|
ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), 1, sizeof(T), std::type_index(typeid(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void ReusableAddOffset(T* ptr, const size_t count)
|
||||||
|
{
|
||||||
|
ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), count, sizeof(T), std::type_index(typeid(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> void ReusableAddOffset(T* ptr, const size_t blockSize, const size_t count)
|
||||||
|
{
|
||||||
|
ReusableAddOffset(const_cast<void*>(reinterpret_cast<const void*>(ptr)), sizeof(T), count, blockSize, std::type_index(typeid(T)));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> ZoneOutputOffset Write(T* dst)
|
||||||
|
{
|
||||||
|
return WriteDataInBlock(reinterpret_cast<const void*>(dst), sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T> ZoneOutputOffset Write(T* dst, const size_t count)
|
||||||
|
{
|
||||||
|
return WriteDataInBlock(reinterpret_cast<const void*>(dst), count * sizeof(T));
|
||||||
|
}
|
||||||
|
|
||||||
|
ZoneOutputOffset WritePartial(const void* dst, const size_t size)
|
||||||
|
{
|
||||||
|
return WriteDataInBlock(dst, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
static std::unique_ptr<ZoneOutputStream>
|
||||||
|
Create(unsigned pointerBitCount, unsigned blockBitCount, std::vector<XBlock*>& blocks, block_t insertBlock, InMemoryZoneData& zoneData);
|
||||||
|
};
|
||||||
@@ -46,8 +46,6 @@ namespace
|
|||||||
|
|
||||||
REQUIRE(linkerResult);
|
REQUIRE(linkerResult);
|
||||||
|
|
||||||
// x64 for now produces invalid zones, don't try to load them yet
|
|
||||||
#ifdef ARCH_x86
|
|
||||||
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneIW3.ff").string();
|
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneIW3.ff").string();
|
||||||
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
||||||
REQUIRE(maybeZone);
|
REQUIRE(maybeZone);
|
||||||
@@ -60,6 +58,5 @@ namespace
|
|||||||
REQUIRE(zone->m_name == "SimpleZoneIW3");
|
REQUIRE(zone->m_name == "SimpleZoneIW3");
|
||||||
REQUIRE(pools->GetTotalAssetCount() == 1);
|
REQUIRE(pools->GetTotalAssetCount() == 1);
|
||||||
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ namespace
|
|||||||
|
|
||||||
REQUIRE(linkerResult);
|
REQUIRE(linkerResult);
|
||||||
|
|
||||||
// x64 for now produces invalid zones, don't try to load them yet
|
|
||||||
#ifdef ARCH_x86
|
|
||||||
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneIW4.ff").string();
|
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneIW4.ff").string();
|
||||||
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
||||||
REQUIRE(maybeZone);
|
REQUIRE(maybeZone);
|
||||||
@@ -60,6 +58,5 @@ namespace
|
|||||||
REQUIRE(zone->m_name == "SimpleZoneIW4");
|
REQUIRE(zone->m_name == "SimpleZoneIW4");
|
||||||
REQUIRE(pools->GetTotalAssetCount() == 1);
|
REQUIRE(pools->GetTotalAssetCount() == 1);
|
||||||
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ namespace
|
|||||||
|
|
||||||
REQUIRE(linkerResult);
|
REQUIRE(linkerResult);
|
||||||
|
|
||||||
// x64 for now produces invalid zones, don't try to load them yet
|
|
||||||
#ifdef ARCH_x86
|
|
||||||
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneIW5.ff").string();
|
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneIW5.ff").string();
|
||||||
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
||||||
REQUIRE(maybeZone);
|
REQUIRE(maybeZone);
|
||||||
@@ -60,6 +58,5 @@ namespace
|
|||||||
REQUIRE(zone->m_name == "SimpleZoneIW5");
|
REQUIRE(zone->m_name == "SimpleZoneIW5");
|
||||||
REQUIRE(pools->GetTotalAssetCount() == 1);
|
REQUIRE(pools->GetTotalAssetCount() == 1);
|
||||||
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ namespace
|
|||||||
|
|
||||||
REQUIRE(linkerResult);
|
REQUIRE(linkerResult);
|
||||||
|
|
||||||
// x64 for now produces invalid zones, don't try to load them yet
|
|
||||||
#ifdef ARCH_x86
|
|
||||||
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneT5.ff").string();
|
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneT5.ff").string();
|
||||||
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
||||||
REQUIRE(maybeZone);
|
REQUIRE(maybeZone);
|
||||||
@@ -60,6 +58,5 @@ namespace
|
|||||||
REQUIRE(zone->m_name == "SimpleZoneT5");
|
REQUIRE(zone->m_name == "SimpleZoneT5");
|
||||||
REQUIRE(pools->GetTotalAssetCount() == 1);
|
REQUIRE(pools->GetTotalAssetCount() == 1);
|
||||||
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -115,8 +115,6 @@ namespace
|
|||||||
REQUIRE(material->Asset()->techniqueSet->techniques[T6::TECHNIQUE_UNLIT]);
|
REQUIRE(material->Asset()->techniqueSet->techniques[T6::TECHNIQUE_UNLIT]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// x64 for now produces invalid zones, don't try to load them yet
|
|
||||||
#ifdef ARCH_x86
|
|
||||||
TEST_CASE("Extend and dereference(T6)", "[t6][system][simple]")
|
TEST_CASE("Extend and dereference(T6)", "[t6][system][simple]")
|
||||||
{
|
{
|
||||||
const auto testDir = oat::paths::GetSystemTestsDirectory() / "Game/T6/ExtendAndDereference";
|
const auto testDir = oat::paths::GetSystemTestsDirectory() / "Game/T6/ExtendAndDereference";
|
||||||
@@ -126,5 +124,4 @@ namespace
|
|||||||
BuildCombinedZone(testDir, outputPath);
|
BuildCombinedZone(testDir, outputPath);
|
||||||
CheckCombinedZoneContent(outputPath);
|
CheckCombinedZoneContent(outputPath);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -122,8 +122,6 @@ namespace
|
|||||||
REQUIRE(zone->m_script_strings.Value(xmodel->Asset()->boneNames[2]) == "EarRight2");
|
REQUIRE(zone->m_script_strings.Value(xmodel->Asset()->boneNames[2]) == "EarRight2");
|
||||||
}
|
}
|
||||||
|
|
||||||
// x64 for now produces invalid zones, don't try to load them yet
|
|
||||||
#ifdef ARCH_x86
|
|
||||||
TEST_CASE("Reuse assets from global asset pool(T6)", "[t6][system][simple]")
|
TEST_CASE("Reuse assets from global asset pool(T6)", "[t6][system][simple]")
|
||||||
{
|
{
|
||||||
const auto testDir = oat::paths::GetSystemTestsDirectory() / "Game/T6/ReuseGlobalAssetPoolsAssets";
|
const auto testDir = oat::paths::GetSystemTestsDirectory() / "Game/T6/ReuseGlobalAssetPoolsAssets";
|
||||||
@@ -133,5 +131,4 @@ namespace
|
|||||||
BuildTestZone(testDir, outputPath);
|
BuildTestZone(testDir, outputPath);
|
||||||
CheckTestZoneContent(outputPath);
|
CheckTestZoneContent(outputPath);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ namespace
|
|||||||
|
|
||||||
REQUIRE(linkerResult);
|
REQUIRE(linkerResult);
|
||||||
|
|
||||||
// x64 for now produces invalid zones, don't try to load them yet
|
|
||||||
#ifdef ARCH_x86
|
|
||||||
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneT6.ff").string();
|
const auto expectedZonePath = (fs::path(outputPath) / "SimpleZoneT6.ff").string();
|
||||||
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
auto maybeZone = ZoneLoading::LoadZone(expectedZonePath, std::nullopt);
|
||||||
REQUIRE(maybeZone);
|
REQUIRE(maybeZone);
|
||||||
@@ -60,6 +58,5 @@ namespace
|
|||||||
REQUIRE(zone->m_name == "SimpleZoneT6");
|
REQUIRE(zone->m_name == "SimpleZoneT6");
|
||||||
REQUIRE(pools->GetTotalAssetCount() == 1);
|
REQUIRE(pools->GetTotalAssetCount() == 1);
|
||||||
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
REQUIRE(pools->m_raw_file->GetAsset("SimpleZone.txt"));
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
96
test/SystemTests/RebuildVanillaZonesTests.cpp
Normal file
96
test/SystemTests/RebuildVanillaZonesTests.cpp
Normal file
@@ -0,0 +1,96 @@
|
|||||||
|
#include "Game/T6/GameAssetPoolT6.h"
|
||||||
|
#include "OatTestPaths.h"
|
||||||
|
#include "Utils/Logging/Log.h"
|
||||||
|
#include "Utils/StringUtils.h"
|
||||||
|
#include "ZoneLoading.h"
|
||||||
|
#include "ZoneWriting.h"
|
||||||
|
|
||||||
|
#include <catch2/catch_test_macros.hpp>
|
||||||
|
#include <filesystem>
|
||||||
|
#include <format>
|
||||||
|
#include <fstream>
|
||||||
|
#include <memory>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace fs = std::filesystem;
|
||||||
|
using namespace std::literals;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This test is only run when the user defines the environment variable OAT_FASTFILE_DIR containing the path to a folder containing fastfiles.
|
||||||
|
*/
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
void EnsureCanRebuildFastFile(const fs::path& outputPath, const fs::path& fastFilePath)
|
||||||
|
{
|
||||||
|
const auto fastFilePathStr = fastFilePath.string();
|
||||||
|
const auto tempFilePath = outputPath / "temp.ff";
|
||||||
|
const auto tempFilePathStr = tempFilePath.string();
|
||||||
|
|
||||||
|
con::info("Testing for rebuild: {}", fastFilePathStr);
|
||||||
|
|
||||||
|
auto maybeZone = ZoneLoading::LoadZone(fastFilePathStr, std::nullopt);
|
||||||
|
REQUIRE(maybeZone.has_value());
|
||||||
|
|
||||||
|
auto zone = std::move(*maybeZone);
|
||||||
|
zone->m_name = "temp";
|
||||||
|
|
||||||
|
{
|
||||||
|
std::ofstream outStream(tempFilePath, std::ios::out | std::ios::binary);
|
||||||
|
REQUIRE(outStream.is_open());
|
||||||
|
|
||||||
|
const auto linkingResult = ZoneWriting::WriteZone(outStream, *zone);
|
||||||
|
REQUIRE(linkingResult);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto maybeRebuiltZone = ZoneLoading::LoadZone(tempFilePathStr, std::nullopt);
|
||||||
|
REQUIRE(maybeRebuiltZone.has_value());
|
||||||
|
|
||||||
|
auto rebuiltZone = std::move(*maybeRebuiltZone);
|
||||||
|
|
||||||
|
const auto& pools = *zone->m_pools;
|
||||||
|
const auto& rebuiltPools = *rebuiltZone->m_pools;
|
||||||
|
|
||||||
|
const auto totalAssetCount = pools.GetTotalAssetCount();
|
||||||
|
REQUIRE(totalAssetCount == rebuiltPools.GetTotalAssetCount());
|
||||||
|
|
||||||
|
auto zoneIter = pools.begin();
|
||||||
|
auto zoneEnd = pools.end();
|
||||||
|
auto rebuiltZoneIter = rebuiltPools.begin();
|
||||||
|
auto rebuiltZoneEnd = rebuiltPools.end();
|
||||||
|
|
||||||
|
while (zoneIter != zoneEnd)
|
||||||
|
{
|
||||||
|
REQUIRE(rebuiltZoneIter != rebuiltZoneEnd);
|
||||||
|
|
||||||
|
REQUIRE((*zoneIter)->m_type == (*rebuiltZoneIter)->m_type);
|
||||||
|
REQUIRE((*zoneIter)->m_name == (*rebuiltZoneIter)->m_name);
|
||||||
|
|
||||||
|
++zoneIter;
|
||||||
|
++rebuiltZoneIter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("Rebuild vanilla zones", "[custom]")
|
||||||
|
{
|
||||||
|
auto* fastFilePathStr = std::getenv("OAT_FASTFILE_DIR");
|
||||||
|
if (!fastFilePathStr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const auto outputPath = oat::paths::GetTempDirectory("RebuildVanillaZones");
|
||||||
|
const fs::path fastFilePath(fastFilePathStr);
|
||||||
|
|
||||||
|
fs::directory_iterator iterator(fastFilePath);
|
||||||
|
const auto end = fs::end(iterator);
|
||||||
|
for (auto i = fs::begin(iterator); i != end; ++i)
|
||||||
|
{
|
||||||
|
if (!i->is_regular_file())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
const auto path = i->path();
|
||||||
|
auto extension = path.extension().string();
|
||||||
|
utils::MakeStringLowerCase(extension);
|
||||||
|
if (extension == ".ff")
|
||||||
|
EnsureCanRebuildFastFile(outputPath, path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // namespace
|
||||||
Reference in New Issue
Block a user