From 96ef7a46fbb50b5c81bcb9692048a764f79de0d8 Mon Sep 17 00:00:00 2001 From: Jan Date: Thu, 20 Jan 2022 23:38:45 +0100 Subject: [PATCH] Convert StructuredDataDef for IW4 --- .../AssetLoaderStructuredDataDefSet.cpp | 166 +++++++++++++++++- .../AssetLoaderStructuredDataDefSet.h | 8 + .../Domain/CommonStructuredDataDefStruct.cpp | 4 +- .../Domain/CommonStructuredDataDefStruct.h | 3 +- .../Domain/CommonStructuredDataDefTypes.cpp | 12 +- .../Domain/CommonStructuredDataDefTypes.h | 2 + .../StructuredDataDefStructScopeSequences.cpp | 9 +- .../StructuredDataDefReader.cpp | 5 +- .../StructuredDataDefReader.h | 2 +- 9 files changed, 194 insertions(+), 17 deletions(-) diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.cpp b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.cpp index b6a5c8e2..62548d9f 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.cpp +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.cpp @@ -22,15 +22,167 @@ bool AssetLoaderStructuredDataDefSet::CanLoadFromRaw() const return true; } +StructuredDataType AssetLoaderStructuredDataDefSet::ConvertType(CommonStructuredDataDefType inputType) +{ + switch (inputType.m_category) + { + case CommonStructuredDataDefTypeCategory::INT: + return {DATA_INT, {0}}; + case CommonStructuredDataDefTypeCategory::BYTE: + return {DATA_BYTE, {0}}; + case CommonStructuredDataDefTypeCategory::BOOL: + return {DATA_BOOL, {0}}; + case CommonStructuredDataDefTypeCategory::FLOAT: + return {DATA_FLOAT, {0}}; + case CommonStructuredDataDefTypeCategory::SHORT: + return {DATA_SHORT, {0}}; + case CommonStructuredDataDefTypeCategory::STRING: + return {DATA_STRING, {inputType.m_info.string_length}}; + case CommonStructuredDataDefTypeCategory::ENUM: + return {DATA_ENUM, {inputType.m_info.type_index}}; + case CommonStructuredDataDefTypeCategory::STRUCT: + return {DATA_STRUCT, {inputType.m_info.type_index}}; + case CommonStructuredDataDefTypeCategory::INDEXED_ARRAY: + return {DATA_INDEXED_ARRAY, {inputType.m_info.type_index}}; + case CommonStructuredDataDefTypeCategory::ENUM_ARRAY: + return {DATA_ENUM_ARRAY, {inputType.m_info.type_index}}; + case CommonStructuredDataDefTypeCategory::UNKNOWN: + default: + assert(false); + return {DATA_INT, {0}}; + } +} + +void AssetLoaderStructuredDataDefSet::ConvertEnum(StructuredDataEnum* outputEnum, const CommonStructuredDataDefEnum* inputEnum, MemoryManager* memory) +{ + outputEnum->entryCount = static_cast(inputEnum->m_entries.size()); + if (inputEnum->m_reserved_entry_count <= 0) + outputEnum->reservedEntryCount = outputEnum->entryCount; + else + outputEnum->reservedEntryCount = inputEnum->m_reserved_entry_count; + outputEnum->reservedEntryCount = static_cast(inputEnum->m_entries.size()); + + if (!inputEnum->m_entries.empty()) + { + outputEnum->entries = static_cast(memory->Alloc(sizeof(StructuredDataEnumEntry) * inputEnum->m_entries.size())); + for (auto entryIndex = 0u; entryIndex < inputEnum->m_entries.size(); entryIndex++) + { + auto& outputEntry = outputEnum->entries[entryIndex]; + const auto& inputEntry = inputEnum->m_entries[entryIndex]; + + outputEntry.string = memory->Dup(inputEntry.m_name.c_str()); + outputEntry.index = static_cast(inputEntry.m_value); + } + } + else + outputEnum->entries = nullptr; +} + +void AssetLoaderStructuredDataDefSet::ConvertStruct(StructuredDataStruct* outputStruct, const CommonStructuredDataDefStruct* inputStruct, MemoryManager* memory) +{ + outputStruct->size = static_cast(inputStruct->m_size); + outputStruct->bitOffset = inputStruct->m_bit_offset; + + outputStruct->propertyCount = static_cast(inputStruct->m_properties.size()); + if (!inputStruct->m_properties.empty()) + { + outputStruct->properties = static_cast(memory->Alloc(sizeof(StructuredDataStructProperty) * inputStruct->m_properties.size())); + for (auto propertyIndex = 0u; propertyIndex < inputStruct->m_properties.size(); propertyIndex++) + { + auto& outputProperty = outputStruct->properties[propertyIndex]; + const auto& inputProperty = inputStruct->m_properties[propertyIndex]; + + outputProperty.name = memory->Dup(inputProperty.m_name.c_str()); + outputProperty.offset = inputProperty.m_offset; + outputProperty.type = ConvertType(inputProperty.m_type); + } + } + else + outputStruct->properties = nullptr; +} + +void AssetLoaderStructuredDataDefSet::ConvertIndexedArray(StructuredDataIndexedArray* outputIndexedArray, const CommonStructuredDataDefIndexedArray* inputIndexedArray, MemoryManager* memory) +{ + outputIndexedArray->arraySize = static_cast(inputIndexedArray->m_array_size); + outputIndexedArray->elementType = ConvertType(inputIndexedArray->m_array_type); + outputIndexedArray->elementSize = inputIndexedArray->m_element_size; +} + +void AssetLoaderStructuredDataDefSet::ConvertEnumedArray(StructuredDataEnumedArray* outputEnumedArray, const CommonStructuredDataDefEnumedArray* inputEnumedArray, MemoryManager* memory) +{ + outputEnumedArray->enumIndex = static_cast(inputEnumedArray->m_enum_index); + outputEnumedArray->elementType = ConvertType(inputEnumedArray->m_array_type); + outputEnumedArray->elementSize = inputEnumedArray->m_element_size; +} + +void AssetLoaderStructuredDataDefSet::ConvertDef(StructuredDataDef* outputDef, const CommonStructuredDataDef* inputDef, MemoryManager* memory) +{ + outputDef->version = inputDef->m_version; + outputDef->formatChecksum = inputDef->m_checksum; + + outputDef->enumCount = static_cast(inputDef->m_enums.size()); + if (!inputDef->m_enums.empty()) + { + outputDef->enums = static_cast(memory->Alloc(sizeof(StructuredDataEnum) * inputDef->m_enums.size())); + for (auto enumIndex = 0u; enumIndex < inputDef->m_enums.size(); enumIndex++) + ConvertEnum(&outputDef->enums[enumIndex], inputDef->m_enums[enumIndex].get(), memory); + } + else + outputDef->enums = nullptr; + + outputDef->structCount = static_cast(inputDef->m_structs.size()); + if (!inputDef->m_structs.empty()) + { + outputDef->structs = static_cast(memory->Alloc(sizeof(StructuredDataStruct) * inputDef->m_structs.size())); + for (auto structIndex = 0u; structIndex < inputDef->m_structs.size(); structIndex++) + ConvertStruct(&outputDef->structs[structIndex], inputDef->m_structs[structIndex].get(), memory); + } + else + outputDef->structs = nullptr; + + outputDef->indexedArrayCount = static_cast(inputDef->m_indexed_arrays.size()); + if (!inputDef->m_indexed_arrays.empty()) + { + outputDef->indexedArrays = static_cast(memory->Alloc(sizeof(StructuredDataIndexedArray) * inputDef->m_indexed_arrays.size())); + for (auto indexedArrayIndex = 0u; indexedArrayIndex < inputDef->m_indexed_arrays.size(); indexedArrayIndex++) + ConvertIndexedArray(&outputDef->indexedArrays[indexedArrayIndex], &inputDef->m_indexed_arrays[indexedArrayIndex], memory); + } + else + outputDef->indexedArrays = nullptr; + + outputDef->enumedArrayCount = static_cast(inputDef->m_enumed_arrays.size()); + if (!inputDef->m_enumed_arrays.empty()) + { + outputDef->enumedArrays = static_cast(memory->Alloc(sizeof(StructuredDataEnumedArray) * inputDef->m_enumed_arrays.size())); + for (auto enumedArrayIndex = 0u; enumedArrayIndex < inputDef->m_enumed_arrays.size(); enumedArrayIndex++) + ConvertEnumedArray(&outputDef->enumedArrays[enumedArrayIndex], &inputDef->m_enumed_arrays[enumedArrayIndex], memory); + } + else + outputDef->enumedArrays = nullptr; + + outputDef->rootType = ConvertType(inputDef->m_root_type); + outputDef->size = inputDef->m_size; +} + +StructuredDataDefSet* AssetLoaderStructuredDataDefSet::ConvertSet(const std::string& assetName, const std::vector>& defs, MemoryManager* memory) +{ + auto* set = memory->Create(); + set->name = memory->Dup(assetName.c_str()); + set->defCount = defs.size(); + set->defs = static_cast(memory->Alloc(sizeof(StructuredDataDef) * defs.size())); + + for (auto defIndex = 0u; defIndex < defs.size(); defIndex++) + ConvertDef(&set->defs[defIndex], defs[defIndex].get(), memory); + + return set; +} + bool AssetLoaderStructuredDataDefSet::LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const { const auto file = searchPath->Open(assetName); if (!file.IsOpen()) return false; - auto* structuredDataDefSet = memory->Create(); - structuredDataDefSet->name = memory->Dup(assetName.c_str()); - StructuredDataDefReader reader(*file.m_stream, assetName, [searchPath](const std::string& filename, const std::string& sourceFile) -> std::unique_ptr { auto foundFileToInclude = searchPath->Open(filename); @@ -40,11 +192,11 @@ bool AssetLoaderStructuredDataDefSet::LoadFromRaw(const std::string& assetName, return std::move(foundFileToInclude.m_stream); }); - const auto defs = reader.ReadStructureDataDefs(); + bool readingDefsSuccessful; + const auto defs = reader.ReadStructureDataDefs(readingDefsSuccessful); - // TODO Convert defs - - manager->AddAsset(ASSET_TYPE_STRUCTURED_DATA_DEF, assetName, structuredDataDefSet); + if (readingDefsSuccessful) + manager->AddAsset(ASSET_TYPE_STRUCTURED_DATA_DEF, assetName, ConvertSet(assetName, defs, memory)); return true; } diff --git a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.h b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.h index 6155bf63..23787bc3 100644 --- a/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.h +++ b/src/ObjLoading/Game/IW4/AssetLoaders/AssetLoaderStructuredDataDefSet.h @@ -2,6 +2,7 @@ #include "Game/IW4/IW4.h" #include "AssetLoading/BasicAssetLoader.h" +#include "Parsing/StructuredDataDef/Domain/CommonStructuredDataDef.h" #include "SearchPath/ISearchPath.h" namespace IW4 @@ -11,6 +12,13 @@ namespace IW4 public: _NODISCARD void* CreateEmptyAsset(const std::string& assetName, MemoryManager* memory) override; _NODISCARD bool CanLoadFromRaw() const override; + static StructuredDataType ConvertType(CommonStructuredDataDefType inputType); + static void ConvertEnum(StructuredDataEnum* outputEnum, const CommonStructuredDataDefEnum* inputEnum, MemoryManager* memory); + static void ConvertStruct(StructuredDataStruct* outputStruct, const CommonStructuredDataDefStruct* inputStruct, MemoryManager* memory); + static void ConvertIndexedArray(StructuredDataIndexedArray* outputIndexedArray, const CommonStructuredDataDefIndexedArray* inputIndexedArray, MemoryManager* memory); + static void ConvertEnumedArray(StructuredDataEnumedArray* outputEnumedArray, const CommonStructuredDataDefEnumedArray* inputEnumedArray, MemoryManager* memory); + static void ConvertDef(StructuredDataDef* outputDef, const CommonStructuredDataDef* inputDef, MemoryManager* memory); + static StructuredDataDefSet* ConvertSet(const std::string& assetName, const std::vector>& defs, MemoryManager* memory); bool LoadFromRaw(const std::string& assetName, ISearchPath* searchPath, MemoryManager* memory, IAssetLoadingManager* manager, Zone* zone) const override; }; } diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.cpp index 93427303..77a7bda6 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.cpp +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.cpp @@ -19,12 +19,14 @@ CommonStructuredDataDefStructEntry::CommonStructuredDataDefStructEntry(std::stri } CommonStructuredDataDefStruct::CommonStructuredDataDefStruct() - : m_size(0u) + : m_bit_offset(0u), + m_size(0u) { } CommonStructuredDataDefStruct::CommonStructuredDataDefStruct(std::string name) : m_name(std::move(name)), + m_bit_offset(0u), m_size(0u) { } diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.h b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.h index f68b0bfd..48693df5 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.h +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefStruct.h @@ -19,7 +19,8 @@ struct CommonStructuredDataDefStructEntry struct CommonStructuredDataDefStruct { std::string m_name; - std::vector m_entries; + std::vector m_properties; + size_t m_bit_offset; size_t m_size; CommonStructuredDataDefStruct(); diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.cpp index 39af7a47..f291cf74 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.cpp +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.cpp @@ -43,13 +43,15 @@ bool operator>=(const CommonStructuredDataDefType& lhs, const CommonStructuredDa } CommonStructuredDataDefIndexedArray::CommonStructuredDataDefIndexedArray() - : m_array_size(0u) + : m_array_size(0u), + m_element_size(0u) { } CommonStructuredDataDefIndexedArray::CommonStructuredDataDefIndexedArray(const CommonStructuredDataDefType type, const size_t arraySize) : m_array_type(type), - m_array_size(arraySize) + m_array_size(arraySize), + m_element_size(0u) { } @@ -78,13 +80,15 @@ bool operator>=(const CommonStructuredDataDefIndexedArray& lhs, const CommonStru } CommonStructuredDataDefEnumedArray::CommonStructuredDataDefEnumedArray() - : m_enum_index(0u) + : m_enum_index(0u), + m_element_size(0u) { } CommonStructuredDataDefEnumedArray::CommonStructuredDataDefEnumedArray(const CommonStructuredDataDefType type, const size_t enumIndex) : m_array_type(type), - m_enum_index(enumIndex) + m_enum_index(enumIndex), + m_element_size(0u) { } diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.h b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.h index 140ad7b7..030ffeed 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.h +++ b/src/ObjLoading/Parsing/StructuredDataDef/Domain/CommonStructuredDataDefTypes.h @@ -42,6 +42,7 @@ struct CommonStructuredDataDefIndexedArray { CommonStructuredDataDefType m_array_type; size_t m_array_size; + size_t m_element_size; CommonStructuredDataDefIndexedArray(); CommonStructuredDataDefIndexedArray(CommonStructuredDataDefType type, size_t arraySize); @@ -56,6 +57,7 @@ struct CommonStructuredDataDefEnumedArray { CommonStructuredDataDefType m_array_type; size_t m_enum_index; + size_t m_element_size; CommonStructuredDataDefEnumedArray(); CommonStructuredDataDefEnumedArray(CommonStructuredDataDefType type, size_t enumIndex); diff --git a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.cpp b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.cpp index 0b23142e..5e97d4e5 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.cpp +++ b/src/ObjLoading/Parsing/StructuredDataDef/Sequence/StructuredDataDefStructScopeSequences.cpp @@ -1,5 +1,7 @@ #include "StructuredDataDefStructScopeSequences.h" +#include + #include "Parsing/Simple/Matcher/SimpleMatcherFactory.h" namespace sdd::struct_scope_sequences @@ -169,7 +171,7 @@ namespace sdd::struct_scope_sequences currentType = ProcessArray(state, result, currentType); // TODO: Calculate offset - state->m_current_struct->m_entries.emplace_back(result.NextCapture(CAPTURE_ENTRY_NAME).IdentifierValue(), currentType, 0); + state->m_current_struct->m_properties.emplace_back(result.NextCapture(CAPTURE_ENTRY_NAME).IdentifierValue(), currentType, 0); } }; @@ -191,6 +193,11 @@ namespace sdd::struct_scope_sequences { assert(state->m_current_struct != nullptr); + std::sort(state->m_current_struct->m_properties.begin(), state->m_current_struct->m_properties.end(), + [](const CommonStructuredDataDefStructEntry& e1, const CommonStructuredDataDefStructEntry& e2) + { + return e1.m_name < e2.m_name; + }); state->m_current_struct = nullptr; } }; diff --git a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.cpp b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.cpp index 8c08b05f..43096e83 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.cpp +++ b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.cpp @@ -42,7 +42,7 @@ void StructuredDataDefReader::SetupStreamProxies() m_stream = m_open_streams.back().get(); } -std::vector> StructuredDataDefReader::ReadStructureDataDefs() +std::vector> StructuredDataDefReader::ReadStructureDataDefs(bool& success) { SimpleLexer::Config lexerConfig; lexerConfig.m_emit_new_line_tokens = false; @@ -52,7 +52,8 @@ std::vector> StructuredDataDefReader::R const auto parser = std::make_unique(lexer.get()); - if (parser->Parse()) + success = parser->Parse(); + if (success) return parser->GetDefs(); std::cout << "Parsing structured data def file \"" << m_file_name << "\" failed!" << std::endl; diff --git a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.h b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.h index b2411b11..bc4c2d1e 100644 --- a/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.h +++ b/src/ObjLoading/Parsing/StructuredDataDef/StructuredDataDefReader.h @@ -24,5 +24,5 @@ public: StructuredDataDefReader(std::istream& stream, std::string fileName); StructuredDataDefReader(std::istream& stream, std::string fileName, include_callback_t includeCallback); - std::vector> ReadStructureDataDefs(); + std::vector> ReadStructureDataDefs(bool& success); };