mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 08:05:45 +00:00
Remove outdated StructuredDataDef Dumper
This commit is contained in:
parent
f5a72f4fef
commit
9f0852485d
@ -1,270 +0,0 @@
|
|||||||
#include "StructuredDataDefDumper.h"
|
|
||||||
|
|
||||||
#include <algorithm>
|
|
||||||
#include <cassert>
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
StructuredDataDefDumper::StructEntry::StructEntry(std::string stringValue, const size_t offset, const size_t sizeInBits, const size_t alignment)
|
|
||||||
: m_string_value(std::move(stringValue)),
|
|
||||||
m_offset(offset),
|
|
||||||
m_size_in_bits(sizeInBits),
|
|
||||||
m_alignment(alignment)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
StructuredDataDefDumper::StructuredDataDefDumper(std::ostream& stream)
|
|
||||||
: AbstractTextDumper(stream),
|
|
||||||
m_block(Block::BLOCK_NONE),
|
|
||||||
m_flags{},
|
|
||||||
m_enum_entry_count(0u),
|
|
||||||
m_struct_property_count(0u),
|
|
||||||
m_current_property_offset(0u),
|
|
||||||
m_current_property_size_in_bits(0u),
|
|
||||||
m_current_property_alignment(0u)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::BeginVersion(const int version)
|
|
||||||
{
|
|
||||||
assert(!m_flags.m_in_version);
|
|
||||||
if (m_flags.m_in_version)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_flags.m_empty_line_before_version)
|
|
||||||
m_stream << "\n";
|
|
||||||
|
|
||||||
Indent();
|
|
||||||
m_stream << "version " << version << "\n";
|
|
||||||
|
|
||||||
Indent();
|
|
||||||
m_stream << "{\n";
|
|
||||||
IncIndent();
|
|
||||||
|
|
||||||
m_flags.m_in_version = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::EndVersion()
|
|
||||||
{
|
|
||||||
assert(m_flags.m_in_version);
|
|
||||||
if (!m_flags.m_in_version)
|
|
||||||
return;
|
|
||||||
|
|
||||||
DecIndent();
|
|
||||||
Indent();
|
|
||||||
m_stream << "}\n";
|
|
||||||
m_flags.m_in_version = false;
|
|
||||||
m_flags.m_empty_line_before_version = true;
|
|
||||||
m_flags.m_empty_line_before_block = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::WriteLineComment(const std::string& comment) const
|
|
||||||
{
|
|
||||||
Indent();
|
|
||||||
m_stream << "// " << comment << "\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::BeginEnum(const std::string& enumName, const size_t enumEntryCount, size_t enumReservedEntryCount)
|
|
||||||
{
|
|
||||||
assert(m_flags.m_in_version);
|
|
||||||
assert(m_block == Block::BLOCK_NONE);
|
|
||||||
|
|
||||||
if (m_block != Block::BLOCK_NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (m_flags.m_empty_line_before_block)
|
|
||||||
m_stream << "\n";
|
|
||||||
|
|
||||||
Indent();
|
|
||||||
if (enumReservedEntryCount != enumEntryCount)
|
|
||||||
m_stream << "enum(" << enumReservedEntryCount << ") ";
|
|
||||||
else
|
|
||||||
m_stream << "enum ";
|
|
||||||
m_stream << enumName;
|
|
||||||
|
|
||||||
m_stream << "\n";
|
|
||||||
|
|
||||||
Indent();
|
|
||||||
m_stream << "{\n";
|
|
||||||
IncIndent();
|
|
||||||
|
|
||||||
m_block = Block::BLOCK_ENUM;
|
|
||||||
|
|
||||||
m_enum_entries.resize(enumEntryCount);
|
|
||||||
m_enum_entry_count = enumEntryCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::EndEnum()
|
|
||||||
{
|
|
||||||
assert(m_block == Block::BLOCK_ENUM);
|
|
||||||
|
|
||||||
if (m_block != Block::BLOCK_ENUM)
|
|
||||||
return;
|
|
||||||
|
|
||||||
bool firstEntry = true;
|
|
||||||
for (const auto& entry : m_enum_entries)
|
|
||||||
{
|
|
||||||
if (firstEntry)
|
|
||||||
firstEntry = false;
|
|
||||||
else
|
|
||||||
m_stream << ",\n";
|
|
||||||
|
|
||||||
Indent();
|
|
||||||
m_stream << "\"" << entry << "\"";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!firstEntry)
|
|
||||||
m_stream << "\n";
|
|
||||||
|
|
||||||
DecIndent();
|
|
||||||
Indent();
|
|
||||||
m_stream << "};\n";
|
|
||||||
m_block = Block::BLOCK_NONE;
|
|
||||||
m_flags.m_empty_line_before_block = true;
|
|
||||||
m_enum_entries.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::WriteEnumEntry(const std::string& entryName, const size_t entryValue)
|
|
||||||
{
|
|
||||||
assert(m_block == Block::BLOCK_ENUM);
|
|
||||||
assert(entryValue < m_enum_entry_count);
|
|
||||||
|
|
||||||
if (m_block != Block::BLOCK_ENUM || entryValue >= m_enum_entry_count)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_enum_entries[entryValue] = entryName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::BeginStruct(const std::string& structName, const size_t structPropertyCount, const size_t structSizeInBits, const size_t structInitialOffset)
|
|
||||||
{
|
|
||||||
assert(m_flags.m_in_version);
|
|
||||||
assert(m_block == Block::BLOCK_NONE);
|
|
||||||
|
|
||||||
if (m_block != Block::BLOCK_NONE)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_struct_property_count = structPropertyCount;
|
|
||||||
m_struct_size_in_bits = structSizeInBits;
|
|
||||||
m_struct_initial_offset = structInitialOffset;
|
|
||||||
m_struct_properties.reserve(structPropertyCount);
|
|
||||||
|
|
||||||
if (m_flags.m_empty_line_before_block)
|
|
||||||
m_stream << "\n";
|
|
||||||
|
|
||||||
Indent();
|
|
||||||
m_stream << "struct " << structName << "\n";
|
|
||||||
|
|
||||||
Indent();
|
|
||||||
m_stream << "{\n";
|
|
||||||
IncIndent();
|
|
||||||
|
|
||||||
m_block = Block::BLOCK_STRUCT;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::EndStruct()
|
|
||||||
{
|
|
||||||
assert(m_block == Block::BLOCK_STRUCT);
|
|
||||||
|
|
||||||
if (m_block != Block::BLOCK_STRUCT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::sort(m_struct_properties.begin(), m_struct_properties.end(), [](const StructEntry& e1, const StructEntry& e2)
|
|
||||||
{
|
|
||||||
return e1.m_offset < e2.m_offset;
|
|
||||||
});
|
|
||||||
|
|
||||||
auto expectedOffset = m_struct_initial_offset;
|
|
||||||
for (auto& structProperty : m_struct_properties)
|
|
||||||
{
|
|
||||||
if (structProperty.m_alignment > 0)
|
|
||||||
expectedOffset = (expectedOffset + structProperty.m_alignment - 1) / structProperty.m_alignment * structProperty.m_alignment;
|
|
||||||
|
|
||||||
if(expectedOffset != structProperty.m_offset)
|
|
||||||
{
|
|
||||||
assert(structProperty.m_offset > expectedOffset);
|
|
||||||
assert((structProperty.m_offset - expectedOffset) % 8 == 0);
|
|
||||||
Indent();
|
|
||||||
m_stream << "pad(" << (structProperty.m_offset - expectedOffset) << ");\n";
|
|
||||||
expectedOffset = structProperty.m_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
Indent();
|
|
||||||
m_stream << structProperty.m_string_value << ";\n";
|
|
||||||
|
|
||||||
expectedOffset += structProperty.m_size_in_bits;
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedOffset = (expectedOffset + 7) / 8 * 8;
|
|
||||||
if (m_struct_size_in_bits > 0 && expectedOffset != m_struct_size_in_bits)
|
|
||||||
{
|
|
||||||
assert(m_struct_size_in_bits > expectedOffset);
|
|
||||||
assert((m_struct_size_in_bits - expectedOffset) % 8 == 0);
|
|
||||||
Indent();
|
|
||||||
m_stream << "pad(" << (m_struct_size_in_bits - expectedOffset) / 8 << ");\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
DecIndent();
|
|
||||||
Indent();
|
|
||||||
m_stream << "};\n";
|
|
||||||
m_block = Block::BLOCK_NONE;
|
|
||||||
m_flags.m_empty_line_before_block = true;
|
|
||||||
m_struct_properties.clear();
|
|
||||||
m_struct_property_count = 0u;
|
|
||||||
m_struct_initial_offset = 0u;
|
|
||||||
m_struct_size_in_bits = 0u;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::BeginProperty(const std::string& propertyName, const size_t propertyOffset, const size_t propertySizeInBits, const size_t alignment)
|
|
||||||
{
|
|
||||||
assert(m_flags.m_in_version);
|
|
||||||
assert(m_block == Block::BLOCK_STRUCT);
|
|
||||||
|
|
||||||
if (m_block != Block::BLOCK_STRUCT)
|
|
||||||
return;
|
|
||||||
|
|
||||||
m_current_property_name = propertyName;
|
|
||||||
m_current_property_offset = propertyOffset;
|
|
||||||
m_current_property_size_in_bits = propertySizeInBits;
|
|
||||||
m_current_property_alignment = alignment;
|
|
||||||
|
|
||||||
m_block = Block::BLOCK_PROPERTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::AddPropertyArraySpecifier(const std::string& specifierName)
|
|
||||||
{
|
|
||||||
m_current_property_array_specifiers.emplace_back(specifierName);
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::SetPropertyTypeName(const std::string& typeName)
|
|
||||||
{
|
|
||||||
m_current_property_type_name = typeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void StructuredDataDefDumper::EndProperty()
|
|
||||||
{
|
|
||||||
assert(m_block == Block::BLOCK_PROPERTY);
|
|
||||||
|
|
||||||
if (m_block != Block::BLOCK_PROPERTY)
|
|
||||||
return;
|
|
||||||
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << m_current_property_type_name << " " << m_current_property_name;
|
|
||||||
|
|
||||||
for (const auto& arraySpecifierName : m_current_property_array_specifiers)
|
|
||||||
{
|
|
||||||
ss << "[" << arraySpecifierName << "]";
|
|
||||||
}
|
|
||||||
|
|
||||||
ss << " /* Offset: " << m_current_property_offset / 8;
|
|
||||||
|
|
||||||
if (m_current_property_offset % 8 > 0)
|
|
||||||
ss << " + " << m_current_property_offset % 8 << "bit";
|
|
||||||
|
|
||||||
ss << " */ ";
|
|
||||||
m_struct_properties.emplace_back(ss.str(), m_current_property_offset, m_current_property_size_in_bits, m_current_property_alignment);
|
|
||||||
|
|
||||||
m_block = Block::BLOCK_STRUCT;
|
|
||||||
m_current_property_array_specifiers.clear();
|
|
||||||
m_current_property_name = std::string();
|
|
||||||
m_current_property_offset = 0u;
|
|
||||||
m_current_property_type_name = std::string();
|
|
||||||
}
|
|
@ -1,66 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Dumping/AbstractTextDumper.h"
|
|
||||||
|
|
||||||
class StructuredDataDefDumper : AbstractTextDumper
|
|
||||||
{
|
|
||||||
struct StructEntry
|
|
||||||
{
|
|
||||||
std::string m_string_value;
|
|
||||||
size_t m_offset;
|
|
||||||
size_t m_size_in_bits;
|
|
||||||
size_t m_alignment;
|
|
||||||
|
|
||||||
StructEntry(std::string stringValue, size_t offset, size_t sizeInBits, size_t alignment);
|
|
||||||
};
|
|
||||||
|
|
||||||
enum class Block
|
|
||||||
{
|
|
||||||
BLOCK_NONE = 0,
|
|
||||||
BLOCK_ENUM = 1,
|
|
||||||
BLOCK_STRUCT = 2,
|
|
||||||
BLOCK_PROPERTY = 3
|
|
||||||
} m_block;
|
|
||||||
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
bool m_in_version : 1;
|
|
||||||
bool m_empty_line_before_version : 1;
|
|
||||||
bool m_empty_line_before_block : 1;
|
|
||||||
} m_flags;
|
|
||||||
|
|
||||||
std::vector<std::string> m_enum_entries;
|
|
||||||
size_t m_enum_entry_count;
|
|
||||||
|
|
||||||
std::vector<StructEntry> m_struct_properties;
|
|
||||||
size_t m_struct_property_count;
|
|
||||||
size_t m_struct_initial_offset;
|
|
||||||
size_t m_struct_size_in_bits;
|
|
||||||
std::string m_current_property_name;
|
|
||||||
size_t m_current_property_offset;
|
|
||||||
size_t m_current_property_size_in_bits;
|
|
||||||
size_t m_current_property_alignment;
|
|
||||||
std::string m_current_property_type_name;
|
|
||||||
std::vector<std::string> m_current_property_array_specifiers;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit StructuredDataDefDumper(std::ostream& stream);
|
|
||||||
|
|
||||||
void BeginVersion(int version);
|
|
||||||
void EndVersion();
|
|
||||||
|
|
||||||
void WriteLineComment(const std::string& comment) const;
|
|
||||||
|
|
||||||
void BeginEnum(const std::string& enumName, size_t enumEntryCount, size_t enumReservedEntryCount);
|
|
||||||
void EndEnum();
|
|
||||||
void WriteEnumEntry(const std::string& entryName, size_t entryValue);
|
|
||||||
|
|
||||||
void BeginStruct(const std::string& structName, size_t structPropertyCount, size_t structSizeInBits, size_t structInitialOffset);
|
|
||||||
void EndStruct();
|
|
||||||
void BeginProperty(const std::string& propertyName, size_t propertyOffset, size_t propertySizeInBits, size_t alignment);
|
|
||||||
void AddPropertyArraySpecifier(const std::string& specifierName);
|
|
||||||
void SetPropertyTypeName(const std::string& typeName);
|
|
||||||
void EndProperty();
|
|
||||||
};
|
|
@ -4,346 +4,11 @@
|
|||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Dumping/StructuredDataDef/StructuredDataDefDumper.h"
|
|
||||||
#include "StructuredDataDef/StructuredDataDefDumper.h"
|
#include "StructuredDataDef/StructuredDataDefDumper.h"
|
||||||
|
|
||||||
using namespace IW4;
|
using namespace IW4;
|
||||||
using namespace std::string_literals;
|
using namespace std::string_literals;
|
||||||
|
|
||||||
bool AssetDumperStructuredDataDefSet::GetNextHeadValue(const StructuredDataDef* def, const bool isFirstStruct, const std::vector<bool>& structsIncludedInOrder, size_t& nextHeadValue)
|
|
||||||
{
|
|
||||||
if (isFirstStruct
|
|
||||||
&& def->rootType.type == DATA_STRUCT
|
|
||||||
&& def->rootType.u.structIndex >= 0
|
|
||||||
&& def->rootType.u.structIndex < def->structCount)
|
|
||||||
{
|
|
||||||
nextHeadValue = def->rootType.u.structIndex;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto firstNotIncludedStruct = std::find(structsIncludedInOrder.begin(), structsIncludedInOrder.end(), false);
|
|
||||||
assert(firstNotIncludedStruct != structsIncludedInOrder.end());
|
|
||||||
|
|
||||||
if (firstNotIncludedStruct == structsIncludedInOrder.end())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
nextHeadValue = static_cast<size_t>(firstNotIncludedStruct - structsIncludedInOrder.begin());
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
StructuredDataType AssetDumperStructuredDataDefSet::GetBaseType(const StructuredDataDef* def, StructuredDataType type)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
if (type.type == DATA_INDEXED_ARRAY)
|
|
||||||
{
|
|
||||||
if (def->indexedArrays != nullptr && type.u.indexedArrayIndex >= 0 && type.u.indexedArrayIndex < def->indexedArrayCount)
|
|
||||||
type = def->indexedArrays[type.u.indexedArrayIndex].elementType;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (type.type == DATA_ENUM_ARRAY)
|
|
||||||
{
|
|
||||||
if (def->enumedArrays != nullptr && type.u.enumedArrayIndex >= 0 && type.u.enumedArrayIndex < def->enumedArrayCount)
|
|
||||||
type = def->enumedArrays[type.u.enumedArrayIndex].elementType;
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return type;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<size_t> AssetDumperStructuredDataDefSet::CalculateStructDumpingOrder(const StructuredDataDef* def)
|
|
||||||
{
|
|
||||||
if (def->structCount <= 0 || def->structs == nullptr)
|
|
||||||
return {};
|
|
||||||
|
|
||||||
const auto structCount = static_cast<size_t>(def->structCount);
|
|
||||||
|
|
||||||
std::vector<size_t> result;
|
|
||||||
auto resultStructHead = 0u;
|
|
||||||
auto resultStructTail = 0u;
|
|
||||||
|
|
||||||
result.reserve(def->structCount);
|
|
||||||
std::vector<bool> structIncludedInOrder(def->structCount);
|
|
||||||
|
|
||||||
while (resultStructTail < structCount)
|
|
||||||
{
|
|
||||||
size_t nextHeadValue;
|
|
||||||
if (!GetNextHeadValue(def, resultStructHead == 0, structIncludedInOrder, nextHeadValue))
|
|
||||||
return result;
|
|
||||||
result.push_back(nextHeadValue);
|
|
||||||
structIncludedInOrder[nextHeadValue] = true;
|
|
||||||
++resultStructHead;
|
|
||||||
|
|
||||||
while (resultStructHead > resultStructTail)
|
|
||||||
{
|
|
||||||
const auto& currentStruct = def->structs[result[resultStructTail++]];
|
|
||||||
|
|
||||||
if (currentStruct.properties == nullptr)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
for (auto i = 0; i < currentStruct.propertyCount; i++)
|
|
||||||
{
|
|
||||||
const auto baseType = GetBaseType(def, currentStruct.properties[i].type);
|
|
||||||
if (baseType.type == DATA_STRUCT
|
|
||||||
&& baseType.u.structIndex >= 0
|
|
||||||
&& static_cast<size_t>(baseType.u.structIndex) < structCount
|
|
||||||
&& structIncludedInOrder[static_cast<size_t>(baseType.u.structIndex)] == false)
|
|
||||||
{
|
|
||||||
result.push_back(static_cast<size_t>(baseType.u.structIndex));
|
|
||||||
structIncludedInOrder[static_cast<size_t>(baseType.u.structIndex)] = true;
|
|
||||||
++resultStructHead;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool AssetDumperStructuredDataDefSet::ShouldDump(XAssetInfo<StructuredDataDefSet>* asset)
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetDumperStructuredDataDefSet::DumpEnum(StructuredDataDefDumper& dumper, const int enumIndex, const StructuredDataEnum* _enum)
|
|
||||||
{
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << "ENUM_" << enumIndex;
|
|
||||||
|
|
||||||
dumper.BeginEnum(ss.str(), static_cast<size_t>(_enum->entryCount), static_cast<size_t>(_enum->reservedEntryCount));
|
|
||||||
|
|
||||||
if (_enum->entries && _enum->entryCount > 0)
|
|
||||||
{
|
|
||||||
for (auto i = 0; i < _enum->entryCount; i++)
|
|
||||||
{
|
|
||||||
const auto& entry = _enum->entries[i];
|
|
||||||
|
|
||||||
assert(entry.string);
|
|
||||||
if (!entry.string)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
dumper.WriteEnumEntry(entry.string, entry.index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dumper.EndEnum();
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t AssetDumperStructuredDataDefSet::GetPropertySizeInBits(const StructuredDataStructProperty& property, const StructuredDataDef* def)
|
|
||||||
{
|
|
||||||
switch (property.type.type)
|
|
||||||
{
|
|
||||||
case DATA_FLOAT:
|
|
||||||
case DATA_INT:
|
|
||||||
return 32;
|
|
||||||
case DATA_BYTE:
|
|
||||||
return 8;
|
|
||||||
case DATA_BOOL:
|
|
||||||
return 1;
|
|
||||||
case DATA_SHORT:
|
|
||||||
case DATA_ENUM:
|
|
||||||
return 16;
|
|
||||||
case DATA_STRING:
|
|
||||||
return property.type.u.stringDataLength * 8;
|
|
||||||
case DATA_STRUCT:
|
|
||||||
if (property.type.u.structIndex < 0 || property.type.u.structIndex >= def->structCount || def->structs == nullptr)
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return static_cast<size_t>(def->structs[property.type.u.structIndex].size) * 8;
|
|
||||||
case DATA_INDEXED_ARRAY:
|
|
||||||
{
|
|
||||||
if (property.type.u.indexedArrayIndex < 0 || property.type.u.indexedArrayIndex >= def->indexedArrayCount || def->indexedArrays == nullptr)
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
const auto& indexedArray = def->indexedArrays[property.type.u.indexedArrayIndex];
|
|
||||||
const auto elementSize = indexedArray.elementType.type == DATA_BOOL ? 1 : indexedArray.elementSize * 8;
|
|
||||||
return elementSize * static_cast<size_t>(def->indexedArrays[property.type.u.indexedArrayIndex].arraySize);
|
|
||||||
}
|
|
||||||
case DATA_ENUM_ARRAY:
|
|
||||||
{
|
|
||||||
if (property.type.u.enumedArrayIndex < 0 || property.type.u.enumedArrayIndex >= def->enumedArrayCount || def->enumedArrays == nullptr)
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto& enumedArray = def->enumedArrays[property.type.u.enumedArrayIndex];
|
|
||||||
if (enumedArray.enumIndex < 0 || enumedArray.enumIndex >= def->enumCount || def->enums == nullptr)
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
const auto elementSize = enumedArray.elementType.type == DATA_BOOL ? 1 : enumedArray.elementSize * 8;
|
|
||||||
return elementSize * static_cast<size_t>(def->enums[enumedArray.enumIndex].reservedEntryCount);
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
assert(false);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t AssetDumperStructuredDataDefSet::GetPropertyAlign(const StructuredDataStructProperty& property)
|
|
||||||
{
|
|
||||||
return property.type.type == DATA_BOOL ? 0 : 8;
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetDumperStructuredDataDefSet::DumpProperty(StructuredDataDefDumper& dumper, const StructuredDataStructProperty& property, const StructuredDataDef* def, const int rootStructIndex)
|
|
||||||
{
|
|
||||||
dumper.BeginProperty(property.name, property.type.type == DATA_BOOL ? property.offset : property.offset * 8, GetPropertySizeInBits(property, def), GetPropertyAlign(property));
|
|
||||||
|
|
||||||
auto currentType = property.type;
|
|
||||||
auto stopTypeIteration = false;
|
|
||||||
do
|
|
||||||
{
|
|
||||||
switch (currentType.type)
|
|
||||||
{
|
|
||||||
case DATA_INT:
|
|
||||||
dumper.SetPropertyTypeName("int");
|
|
||||||
stopTypeIteration = true;
|
|
||||||
break;
|
|
||||||
case DATA_BYTE:
|
|
||||||
dumper.SetPropertyTypeName("byte");
|
|
||||||
stopTypeIteration = true;
|
|
||||||
break;
|
|
||||||
case DATA_BOOL:
|
|
||||||
dumper.SetPropertyTypeName("bool");
|
|
||||||
stopTypeIteration = true;
|
|
||||||
break;
|
|
||||||
case DATA_FLOAT:
|
|
||||||
dumper.SetPropertyTypeName("float");
|
|
||||||
stopTypeIteration = true;
|
|
||||||
break;
|
|
||||||
case DATA_SHORT:
|
|
||||||
dumper.SetPropertyTypeName("short");
|
|
||||||
stopTypeIteration = true;
|
|
||||||
break;
|
|
||||||
case DATA_STRING:
|
|
||||||
{
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << "string(" << currentType.u.stringDataLength << ")";
|
|
||||||
dumper.SetPropertyTypeName(ss.str());
|
|
||||||
stopTypeIteration = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DATA_ENUM:
|
|
||||||
{
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << "ENUM_" << currentType.u.enumIndex;
|
|
||||||
dumper.SetPropertyTypeName(ss.str());
|
|
||||||
stopTypeIteration = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DATA_STRUCT:
|
|
||||||
{
|
|
||||||
if (currentType.u.structIndex == rootStructIndex)
|
|
||||||
{
|
|
||||||
dumper.SetPropertyTypeName("root");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << "STRUCT_" << currentType.u.enumIndex;
|
|
||||||
dumper.SetPropertyTypeName(ss.str());
|
|
||||||
}
|
|
||||||
stopTypeIteration = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DATA_INDEXED_ARRAY:
|
|
||||||
{
|
|
||||||
if (def->indexedArrays == nullptr
|
|
||||||
|| currentType.u.indexedArrayIndex < 0
|
|
||||||
|| currentType.u.indexedArrayIndex >= def->indexedArrayCount)
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
dumper.SetPropertyTypeName("ERRORTYPE");
|
|
||||||
stopTypeIteration = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto& indexedArray = def->indexedArrays[currentType.u.indexedArrayIndex];
|
|
||||||
dumper.AddPropertyArraySpecifier(std::to_string(indexedArray.arraySize));
|
|
||||||
currentType = indexedArray.elementType;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case DATA_ENUM_ARRAY:
|
|
||||||
{
|
|
||||||
if (def->enumedArrays == nullptr
|
|
||||||
|| currentType.u.enumedArrayIndex < 0
|
|
||||||
|| currentType.u.enumedArrayIndex >= def->enumedArrayCount)
|
|
||||||
{
|
|
||||||
assert(false);
|
|
||||||
dumper.SetPropertyTypeName("ERRORTYPE");
|
|
||||||
stopTypeIteration = true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
const auto& enumedArray = def->enumedArrays[currentType.u.enumedArrayIndex];
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << "ENUM_" << enumedArray.enumIndex;
|
|
||||||
dumper.AddPropertyArraySpecifier(ss.str());
|
|
||||||
currentType = enumedArray.elementType;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
while (!stopTypeIteration);
|
|
||||||
|
|
||||||
dumper.EndProperty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AssetDumperStructuredDataDefSet::DumpStruct(StructuredDataDefDumper& dumper, const size_t structIndex, const StructuredDataStruct* _struct, const StructuredDataDef* def,
|
|
||||||
const int rootStructIndex)
|
|
||||||
{
|
|
||||||
std::string structName;
|
|
||||||
size_t actualStructSize;
|
|
||||||
size_t initialOffset;
|
|
||||||
if (static_cast<int>(structIndex) == rootStructIndex)
|
|
||||||
{
|
|
||||||
structName = "root";
|
|
||||||
actualStructSize = def->size;
|
|
||||||
initialOffset = 64;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
std::ostringstream ss;
|
|
||||||
ss << "STRUCT_" << structIndex;
|
|
||||||
structName = ss.str();
|
|
||||||
actualStructSize = static_cast<size_t>(_struct->size);
|
|
||||||
initialOffset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
dumper.WriteLineComment("BitOffset: "s + std::to_string(_struct->bitOffset));
|
|
||||||
dumper.WriteLineComment("Size: "s + std::to_string(_struct->size));
|
|
||||||
dumper.BeginStruct(structName, static_cast<size_t>(_struct->propertyCount), actualStructSize * 8, initialOffset);
|
|
||||||
|
|
||||||
if (_struct->properties && _struct->propertyCount > 0)
|
|
||||||
{
|
|
||||||
for (auto i = 0; i < _struct->propertyCount; i++)
|
|
||||||
{
|
|
||||||
const auto& property = _struct->properties[i];
|
|
||||||
|
|
||||||
DumpProperty(dumper, property, def, rootStructIndex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dumper.EndStruct();
|
|
||||||
}
|
|
||||||
|
|
||||||
CommonStructuredDataType AssetDumperStructuredDataDefSet::ConvertType(const CommonStructuredDataDef* def, const StructuredDataType in)
|
CommonStructuredDataType AssetDumperStructuredDataDefSet::ConvertType(const CommonStructuredDataDef* def, const StructuredDataType in)
|
||||||
{
|
{
|
||||||
CommonStructuredDataType out;
|
CommonStructuredDataType out;
|
||||||
@ -511,6 +176,11 @@ std::unique_ptr<CommonStructuredDataDef> AssetDumperStructuredDataDefSet::Conver
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AssetDumperStructuredDataDefSet::ShouldDump(XAssetInfo<StructuredDataDefSet>* asset)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void AssetDumperStructuredDataDefSet::DumpAsset(AssetDumpingContext& context, XAssetInfo<StructuredDataDefSet>* asset)
|
void AssetDumperStructuredDataDefSet::DumpAsset(AssetDumpingContext& context, XAssetInfo<StructuredDataDefSet>* asset)
|
||||||
{
|
{
|
||||||
const auto* set = asset->Asset();
|
const auto* set = asset->Asset();
|
||||||
|
@ -1,10 +1,8 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
#include "Dumping/AbstractAssetDumper.h"
|
#include "Dumping/AbstractAssetDumper.h"
|
||||||
#include "Dumping/StructuredDataDef/StructuredDataDefDumper.h"
|
|
||||||
#include "Game/IW4/IW4.h"
|
#include "Game/IW4/IW4.h"
|
||||||
#include "StructuredDataDef/CommonStructuredDataDef.h"
|
#include "StructuredDataDef/CommonStructuredDataDef.h"
|
||||||
|
|
||||||
@ -12,21 +10,13 @@ namespace IW4
|
|||||||
{
|
{
|
||||||
class AssetDumperStructuredDataDefSet final : public AbstractAssetDumper<StructuredDataDefSet>
|
class AssetDumperStructuredDataDefSet final : public AbstractAssetDumper<StructuredDataDefSet>
|
||||||
{
|
{
|
||||||
static bool GetNextHeadValue(const StructuredDataDef* def, bool isFirstStruct, const std::vector<bool>& structsIncludedInOrder, size_t& nextHeadValue);
|
static CommonStructuredDataType ConvertType(const CommonStructuredDataDef* def, StructuredDataType in);
|
||||||
static StructuredDataType GetBaseType(const StructuredDataDef* def, StructuredDataType type);
|
|
||||||
static std::vector<size_t> CalculateStructDumpingOrder(const StructuredDataDef* def);
|
|
||||||
static void DumpEnum(StructuredDataDefDumper& dumper, int enumIndex, const StructuredDataEnum* _enum);
|
|
||||||
static size_t GetPropertySizeInBits(const StructuredDataStructProperty& property, const StructuredDataDef* def);
|
|
||||||
static size_t GetPropertyAlign(const StructuredDataStructProperty& property);
|
|
||||||
static void DumpProperty(StructuredDataDefDumper& dumper, const StructuredDataStructProperty& property, const StructuredDataDef* def, int rootStructIndex);
|
|
||||||
static void DumpStruct(StructuredDataDefDumper& dumper, size_t structIndex, const StructuredDataStruct* _struct, const StructuredDataDef* def, int rootStructIndex);
|
|
||||||
|
|
||||||
static CommonStructuredDataType ConvertType(const CommonStructuredDataDef* def, const StructuredDataType in);
|
|
||||||
static void ConvertEnum(CommonStructuredDataEnum* out, const StructuredDataEnum* in, size_t enumIndex);
|
static void ConvertEnum(CommonStructuredDataEnum* out, const StructuredDataEnum* in, size_t enumIndex);
|
||||||
static void ConvertStruct(const CommonStructuredDataDef* def, const StructuredDataDef* gameDef, CommonStructuredDataStruct* out, const StructuredDataStruct* in, const size_t structIndex);
|
static void ConvertStruct(const CommonStructuredDataDef* def, const StructuredDataDef* gameDef, CommonStructuredDataStruct* out, const StructuredDataStruct* in, size_t structIndex);
|
||||||
static void ConvertIndexedArray(const CommonStructuredDataDef* def, CommonStructuredDataIndexedArray* out, const StructuredDataIndexedArray* in);
|
static void ConvertIndexedArray(const CommonStructuredDataDef* def, CommonStructuredDataIndexedArray* out, const StructuredDataIndexedArray* in);
|
||||||
static void ConvertEnumedArray(const CommonStructuredDataDef* def, CommonStructuredDataEnumedArray* out, const StructuredDataEnumedArray* in);
|
static void ConvertEnumedArray(const CommonStructuredDataDef* def, CommonStructuredDataEnumedArray* out, const StructuredDataEnumedArray* in);
|
||||||
static std::unique_ptr<CommonStructuredDataDef> ConvertDef(const StructuredDataDef* in);
|
static std::unique_ptr<CommonStructuredDataDef> ConvertDef(const StructuredDataDef* in);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ShouldDump(XAssetInfo<StructuredDataDefSet>* asset) override;
|
bool ShouldDump(XAssetInfo<StructuredDataDefSet>* asset) override;
|
||||||
void DumpAsset(AssetDumpingContext& context, XAssetInfo<StructuredDataDefSet>* asset) override;
|
void DumpAsset(AssetDumpingContext& context, XAssetInfo<StructuredDataDefSet>* asset) override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user