diff --git a/src/ObjWriting/Dumping/StructuredDataDef/StructuredDataDefDumper.cpp b/src/ObjWriting/Dumping/StructuredDataDef/StructuredDataDefDumper.cpp index f9192d6c..8ef7b075 100644 --- a/src/ObjWriting/Dumping/StructuredDataDef/StructuredDataDefDumper.cpp +++ b/src/ObjWriting/Dumping/StructuredDataDef/StructuredDataDefDumper.cpp @@ -4,7 +4,9 @@ StructuredDataDefDumper::StructuredDataDefDumper(std::ostream& stream) : AbstractTextDumper(stream), - m_flags{} + m_block(Block::BLOCK_NONE), + m_flags{}, + m_enum_size(0u) { } @@ -16,15 +18,12 @@ void StructuredDataDefDumper::BeginVersion(const int version) if (m_flags.m_empty_line_before_version) m_stream << "\n"; - else - m_flags.m_empty_line_before_version = true; Indent(); m_stream << "version " << version << "\n"; Indent(); m_stream << "{\n"; - IncIndent(); m_flags.m_in_version = true; @@ -40,4 +39,105 @@ void StructuredDataDefDumper::EndVersion() 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::BeginEnum(const std::string& enumName, const size_t enumEntryCount) +{ + 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(); + m_stream << "enum " << enumName << "\n"; + + Indent(); + m_stream << "{\n"; + IncIndent(); + + m_block = Block::BLOCK_ENUM; + + m_enum_entries.resize(enumEntryCount); + m_enum_size = 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; +} + +void StructuredDataDefDumper::WriteEnumEntry(const std::string& entryName, const size_t entryValue) +{ + assert(m_block == Block::BLOCK_ENUM); + assert(entryValue < m_enum_size); + + if (m_block != Block::BLOCK_ENUM || entryValue >= m_enum_size) + return; + + m_enum_entries[entryValue] = entryName; +} + +void StructuredDataDefDumper::BeginStruct(const std::string& structName) +{ + 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(); + 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; + + DecIndent(); + Indent(); + m_stream << "};\n"; + m_block = Block::BLOCK_NONE; + m_flags.m_empty_line_before_block = true; } diff --git a/src/ObjWriting/Dumping/StructuredDataDef/StructuredDataDefDumper.h b/src/ObjWriting/Dumping/StructuredDataDef/StructuredDataDefDumper.h index 52bc9b58..0cb4293c 100644 --- a/src/ObjWriting/Dumping/StructuredDataDef/StructuredDataDefDumper.h +++ b/src/ObjWriting/Dumping/StructuredDataDef/StructuredDataDefDumper.h @@ -1,18 +1,38 @@ #pragma once +#include + #include "Dumping/AbstractTextDumper.h" class StructuredDataDefDumper : AbstractTextDumper { + enum class Block + { + BLOCK_NONE = 0, + BLOCK_ENUM = 1, + BLOCK_STRUCT = 2 + } 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 m_enum_entries; + size_t m_enum_size; + public: explicit StructuredDataDefDumper(std::ostream& stream); void BeginVersion(int version); void EndVersion(); + + void BeginEnum(const std::string& enumName, size_t enumEntryCount); + void EndEnum(); + void WriteEnumEntry(const std::string& entryName, size_t entryValue); + + void BeginStruct(const std::string& structName); + void EndStruct(); }; diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperStructuredDataDefSet.cpp b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperStructuredDataDefSet.cpp index 11c80a88..c1760bf4 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperStructuredDataDefSet.cpp +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperStructuredDataDefSet.cpp @@ -1,5 +1,8 @@ #include "AssetDumperStructuredDataDefSet.h" +#include +#include + #include "Dumping/StructuredDataDef/StructuredDataDefDumper.h" using namespace IW4; @@ -9,6 +12,30 @@ bool AssetDumperStructuredDataDefSet::ShouldDump(XAssetInfoentries || _enum->entryCount <= 0) + return; + + std::ostringstream ss; + ss << "ENUM_" << enumIndex; + + dumper.BeginEnum(ss.str(), static_cast(_enum->entryCount)); + + 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(); +} + void AssetDumperStructuredDataDefSet::DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) { const auto* set = asset->Asset(); @@ -25,6 +52,9 @@ void AssetDumperStructuredDataDefSet::DumpAsset(AssetDumpingContext& context, XA dumper.BeginVersion(def.version); + for (auto enumIndex = 0; enumIndex < def.enumCount; enumIndex++) + DumpEnum(dumper, enumIndex, &def.enums[enumIndex]); + // TODO dumper.EndVersion(); diff --git a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperStructuredDataDefSet.h b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperStructuredDataDefSet.h index dfaa9c7a..d1d9506a 100644 --- a/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperStructuredDataDefSet.h +++ b/src/ObjWriting/Game/IW4/AssetDumpers/AssetDumperStructuredDataDefSet.h @@ -1,12 +1,15 @@ #pragma once #include "Dumping/AbstractAssetDumper.h" +#include "Dumping/StructuredDataDef/StructuredDataDefDumper.h" #include "Game/IW4/IW4.h" namespace IW4 { class AssetDumperStructuredDataDefSet final : public AbstractAssetDumper { + static void DumpEnum(StructuredDataDefDumper& dumper, int enumIndex, const StructuredDataEnum* _enum); + protected: bool ShouldDump(XAssetInfo* asset) override; void DumpAsset(AssetDumpingContext& context, XAssetInfo* asset) override;