mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-04-20 00:02:55 +00:00
Dump structured data def structs
This commit is contained in:
parent
02769fe21d
commit
0aad5a42cb
@ -2031,7 +2031,8 @@ namespace IW4
|
|||||||
DATA_ENUM_ARRAY = 0x7,
|
DATA_ENUM_ARRAY = 0x7,
|
||||||
DATA_FLOAT = 0x8,
|
DATA_FLOAT = 0x8,
|
||||||
DATA_SHORT = 0x9,
|
DATA_SHORT = 0x9,
|
||||||
DATA_COUNT = 0xA,
|
|
||||||
|
DATA_COUNT
|
||||||
};
|
};
|
||||||
|
|
||||||
struct StructuredDataEnumEntry
|
struct StructuredDataEnumEntry
|
||||||
|
@ -83,7 +83,7 @@ void StructuredDataDefDumper::EndEnum()
|
|||||||
m_stream << ",\n";
|
m_stream << ",\n";
|
||||||
|
|
||||||
Indent();
|
Indent();
|
||||||
m_stream << entry;
|
m_stream << "\"" << entry << "\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!firstEntry)
|
if (!firstEntry)
|
||||||
@ -94,6 +94,7 @@ void StructuredDataDefDumper::EndEnum()
|
|||||||
m_stream << "};\n";
|
m_stream << "};\n";
|
||||||
m_block = Block::BLOCK_NONE;
|
m_block = Block::BLOCK_NONE;
|
||||||
m_flags.m_empty_line_before_block = true;
|
m_flags.m_empty_line_before_block = true;
|
||||||
|
m_enum_entries.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void StructuredDataDefDumper::WriteEnumEntry(const std::string& entryName, const size_t entryValue)
|
void StructuredDataDefDumper::WriteEnumEntry(const std::string& entryName, const size_t entryValue)
|
||||||
@ -141,3 +142,50 @@ void StructuredDataDefDumper::EndStruct()
|
|||||||
m_block = Block::BLOCK_NONE;
|
m_block = Block::BLOCK_NONE;
|
||||||
m_flags.m_empty_line_before_block = true;
|
m_flags.m_empty_line_before_block = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void StructuredDataDefDumper::BeginProperty(const std::string& propertyName)
|
||||||
|
{
|
||||||
|
assert(m_flags.m_in_version);
|
||||||
|
assert(m_block == Block::BLOCK_STRUCT);
|
||||||
|
|
||||||
|
if (m_block != Block::BLOCK_STRUCT)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_property_name = propertyName;
|
||||||
|
|
||||||
|
m_block = Block::BLOCK_PROPERTY;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StructuredDataDefDumper::AddPropertyArraySpecifier(const std::string& specifierName)
|
||||||
|
{
|
||||||
|
m_property_array_specifiers.emplace_back(specifierName);
|
||||||
|
}
|
||||||
|
|
||||||
|
void StructuredDataDefDumper::SetPropertyTypeName(const std::string& typeName)
|
||||||
|
{
|
||||||
|
m_property_type_name = typeName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void StructuredDataDefDumper::EndProperty()
|
||||||
|
{
|
||||||
|
assert(m_block == Block::BLOCK_PROPERTY);
|
||||||
|
|
||||||
|
if (m_block != Block::BLOCK_PROPERTY)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Indent();
|
||||||
|
|
||||||
|
m_stream << m_property_type_name << " " << m_property_name;
|
||||||
|
|
||||||
|
for(const auto& arraySpecifierName : m_property_array_specifiers)
|
||||||
|
{
|
||||||
|
m_stream << "[" << arraySpecifierName << "]";
|
||||||
|
}
|
||||||
|
|
||||||
|
m_stream << ";\n";
|
||||||
|
|
||||||
|
m_block = Block::BLOCK_STRUCT;
|
||||||
|
m_property_array_specifiers.clear();
|
||||||
|
m_property_name = std::string();
|
||||||
|
m_property_type_name = std::string();
|
||||||
|
}
|
||||||
|
@ -10,7 +10,8 @@ class StructuredDataDefDumper : AbstractTextDumper
|
|||||||
{
|
{
|
||||||
BLOCK_NONE = 0,
|
BLOCK_NONE = 0,
|
||||||
BLOCK_ENUM = 1,
|
BLOCK_ENUM = 1,
|
||||||
BLOCK_STRUCT = 2
|
BLOCK_STRUCT = 2,
|
||||||
|
BLOCK_PROPERTY = 3
|
||||||
} m_block;
|
} m_block;
|
||||||
|
|
||||||
struct
|
struct
|
||||||
@ -23,6 +24,10 @@ class StructuredDataDefDumper : AbstractTextDumper
|
|||||||
std::vector<std::string> m_enum_entries;
|
std::vector<std::string> m_enum_entries;
|
||||||
size_t m_enum_size;
|
size_t m_enum_size;
|
||||||
|
|
||||||
|
std::string m_property_name;
|
||||||
|
std::string m_property_type_name;
|
||||||
|
std::vector<std::string> m_property_array_specifiers;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit StructuredDataDefDumper(std::ostream& stream);
|
explicit StructuredDataDefDumper(std::ostream& stream);
|
||||||
|
|
||||||
@ -35,4 +40,8 @@ public:
|
|||||||
|
|
||||||
void BeginStruct(const std::string& structName);
|
void BeginStruct(const std::string& structName);
|
||||||
void EndStruct();
|
void EndStruct();
|
||||||
|
void BeginProperty(const std::string& propertyName);
|
||||||
|
void AddPropertyArraySpecifier(const std::string& specifierName);
|
||||||
|
void SetPropertyTypeName(const std::string& typeName);
|
||||||
|
void EndProperty();
|
||||||
};
|
};
|
||||||
|
@ -22,12 +22,12 @@ void AssetDumperStructuredDataDefSet::DumpEnum(StructuredDataDefDumper& dumper,
|
|||||||
|
|
||||||
dumper.BeginEnum(ss.str(), static_cast<size_t>(_enum->entryCount));
|
dumper.BeginEnum(ss.str(), static_cast<size_t>(_enum->entryCount));
|
||||||
|
|
||||||
for(auto i = 0; i < _enum->entryCount; i++)
|
for (auto i = 0; i < _enum->entryCount; i++)
|
||||||
{
|
{
|
||||||
const auto& entry = _enum->entries[i];
|
const auto& entry = _enum->entries[i];
|
||||||
|
|
||||||
assert(entry.string);
|
assert(entry.string);
|
||||||
if(!entry.string)
|
if (!entry.string)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
dumper.WriteEnumEntry(entry.string, entry.index);
|
dumper.WriteEnumEntry(entry.string, entry.index);
|
||||||
@ -36,6 +36,146 @@ void AssetDumperStructuredDataDefSet::DumpEnum(StructuredDataDefDumper& dumper,
|
|||||||
dumper.EndEnum();
|
dumper.EndEnum();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AssetDumperStructuredDataDefSet::DumpProperty(StructuredDataDefDumper& dumper, const StructuredDataStructProperty& property, const StructuredDataDef* def, const int rootStructIndex)
|
||||||
|
{
|
||||||
|
dumper.BeginProperty(property.name);
|
||||||
|
|
||||||
|
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 int structIndex, const StructuredDataStruct* _struct, const StructuredDataDef* def, const bool isRoot)
|
||||||
|
{
|
||||||
|
if (!_struct->properties || _struct->propertyCount <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::string structName;
|
||||||
|
|
||||||
|
if (isRoot)
|
||||||
|
{
|
||||||
|
structName = "root";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::ostringstream ss;
|
||||||
|
ss << "STRUCT_" << structIndex;
|
||||||
|
structName = ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
dumper.BeginStruct(structName);
|
||||||
|
|
||||||
|
const auto rootStructIndex = def->rootType.type == DATA_STRUCT ? def->rootType.u.structIndex : -1;
|
||||||
|
for (auto i = 0; i < _struct->propertyCount; i++)
|
||||||
|
{
|
||||||
|
const auto& property = _struct->properties[i];
|
||||||
|
|
||||||
|
DumpProperty(dumper, property, def, rootStructIndex);
|
||||||
|
}
|
||||||
|
|
||||||
|
dumper.EndStruct();
|
||||||
|
}
|
||||||
|
|
||||||
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();
|
||||||
@ -46,7 +186,7 @@ void AssetDumperStructuredDataDefSet::DumpAsset(AssetDumpingContext& context, XA
|
|||||||
|
|
||||||
StructuredDataDefDumper dumper(*assetFile);
|
StructuredDataDefDumper dumper(*assetFile);
|
||||||
|
|
||||||
for(auto defIndex = 0u; defIndex < set->defCount; defIndex++)
|
for (auto defIndex = 0u; defIndex < set->defCount; defIndex++)
|
||||||
{
|
{
|
||||||
const auto& def = set->defs[defIndex];
|
const auto& def = set->defs[defIndex];
|
||||||
|
|
||||||
@ -55,7 +195,10 @@ void AssetDumperStructuredDataDefSet::DumpAsset(AssetDumpingContext& context, XA
|
|||||||
for (auto enumIndex = 0; enumIndex < def.enumCount; enumIndex++)
|
for (auto enumIndex = 0; enumIndex < def.enumCount; enumIndex++)
|
||||||
DumpEnum(dumper, enumIndex, &def.enums[enumIndex]);
|
DumpEnum(dumper, enumIndex, &def.enums[enumIndex]);
|
||||||
|
|
||||||
// TODO
|
const auto rootStructIndex = def.rootType.type == DATA_STRUCT ? def.rootType.u.structIndex : -1;
|
||||||
|
assert(rootStructIndex >= 0);
|
||||||
|
for (auto structIndex = 0; structIndex < def.structCount; structIndex++)
|
||||||
|
DumpStruct(dumper, structIndex, &def.structs[structIndex], &def, structIndex == rootStructIndex);
|
||||||
|
|
||||||
dumper.EndVersion();
|
dumper.EndVersion();
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,8 @@ namespace IW4
|
|||||||
class AssetDumperStructuredDataDefSet final : public AbstractAssetDumper<StructuredDataDefSet>
|
class AssetDumperStructuredDataDefSet final : public AbstractAssetDumper<StructuredDataDefSet>
|
||||||
{
|
{
|
||||||
static void DumpEnum(StructuredDataDefDumper& dumper, int enumIndex, const StructuredDataEnum* _enum);
|
static void DumpEnum(StructuredDataDefDumper& dumper, int enumIndex, const StructuredDataEnum* _enum);
|
||||||
|
static void DumpProperty(StructuredDataDefDumper& dumper, const StructuredDataStructProperty& property, const StructuredDataDef* def, int rootStructIndex);
|
||||||
|
static void DumpStruct(StructuredDataDefDumper& dumper, int structIndex, const StructuredDataStruct* _struct, const StructuredDataDef* def, bool isRoot);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool ShouldDump(XAssetInfo<StructuredDataDefSet>* asset) override;
|
bool ShouldDump(XAssetInfo<StructuredDataDefSet>* asset) override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user