diff --git a/src/Common/Game/T6/T6_Assets.h b/src/Common/Game/T6/T6_Assets.h index 89394044..95800cf3 100644 --- a/src/Common/Game/T6/T6_Assets.h +++ b/src/Common/Game/T6/T6_Assets.h @@ -2114,7 +2114,7 @@ namespace T6 struct KeyValuePairs { const char* name; - int numVariables; + unsigned int numVariables; KeyValuePair* keyValuePairs; }; @@ -5569,8 +5569,8 @@ namespace T6 struct KeyValuePair { - int keyHash; - int namespaceHash; + unsigned int keyHash; + unsigned int namespaceHash; const char* value; }; diff --git a/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompiler.cpp b/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompiler.cpp deleted file mode 100644 index af02ffd7..00000000 --- a/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompiler.cpp +++ /dev/null @@ -1,74 +0,0 @@ -#include "KeyValuePairsCompiler.h" - -#include "Game/T6/CommonT6.h" -#include "Game/T6/T6.h" - -#include -#include - -using namespace T6; - -KeyValuePairsCompiler::KeyValuePairsCompiler(const Zone& zone, const ZoneDefinition& zoneDefinition) - : m_zone(zone), - m_zone_definition(zoneDefinition) -{ -} - -std::optional KeyValuePairsCompiler::GetHandlingAssetType() const -{ - return std::nullopt; -} - -AssetCreationResult KeyValuePairsCompiler::CreateAsset(const std::string& assetName, AssetCreationContext& context) -{ - return AssetCreationResult::NoAction(); -} - -void KeyValuePairsCompiler::FinalizeZone(AssetCreationContext& context) -{ - std::vector kvpList; - auto& memory = *m_zone.GetMemory(); - - for (const auto& metaData : m_zone_definition.m_properties.m_properties) - { - if (metaData.first.rfind("level.", 0) == 0) - { - const std::string strValue = metaData.first.substr(std::char_traits::length("level.")); - if (strValue.empty()) - continue; - - int keyHash; - if (strValue[0] == '@') - { - char* endPtr; - keyHash = strtol(&strValue[1], &endPtr, 16); - - if (endPtr != &strValue[strValue.size()]) - { - std::cerr << std::format("Could not parse metadata key \"{}\" as hash\n", metaData.first); - continue; - } - } - else - { - keyHash = Common::Com_HashKey(strValue.c_str(), 64); - } - - KeyValuePair kvp{keyHash, Common::Com_HashKey(m_zone.m_name.c_str(), 64), memory.Dup(metaData.second.c_str())}; - kvpList.push_back(kvp); - } - } - - if (!kvpList.empty()) - { - auto* kvps = memory.Create(); - kvps->name = memory.Dup(m_zone.m_name.c_str()); - kvps->numVariables = static_cast(kvpList.size()); - kvps->keyValuePairs = m_zone.GetMemory()->Alloc(kvpList.size()); - - for (auto i = 0u; i < kvpList.size(); i++) - kvps->keyValuePairs[i] = kvpList[i]; - - context.AddAsset(AssetRegistration(m_zone.m_name, kvps)); - } -} diff --git a/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompilerT6.cpp b/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompilerT6.cpp new file mode 100644 index 00000000..11c98ea1 --- /dev/null +++ b/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompilerT6.cpp @@ -0,0 +1,62 @@ +#include "KeyValuePairsCompilerT6.h" + +#include "Game/T6/CommonT6.h" +#include "Game/T6/T6.h" + +#include +#include +#include + +using namespace T6; + +KeyValuePairsCompiler::KeyValuePairsCompiler(MemoryManager& memory, + const Zone& zone, + const ZoneDefinition& zoneDefinition, + ZoneAssetCreationStateContainer& zoneStates) + : m_memory(memory), + m_zone(zone), + m_zone_definition(zoneDefinition), + m_kvp_creator(zoneStates.GetZoneAssetCreationState()) +{ +} + +std::optional KeyValuePairsCompiler::GetHandlingAssetType() const +{ + return std::nullopt; +} + +AssetCreationResult KeyValuePairsCompiler::CreateAsset(const std::string& assetName, AssetCreationContext& context) +{ + return AssetCreationResult::NoAction(); +} + +void KeyValuePairsCompiler::FinalizeZone(AssetCreationContext& context) +{ + m_kvp_creator.Finalize(m_zone_definition); + const auto commonKvps = m_kvp_creator.GetFinalKeyValuePairs(); + if (commonKvps.empty()) + return; + + auto* gameKvps = m_memory.Alloc(); + gameKvps->name = m_memory.Dup(m_zone.m_name.c_str()); + gameKvps->numVariables = commonKvps.size(); + gameKvps->keyValuePairs = m_memory.Alloc(commonKvps.size()); + + const auto namespaceHash = Common::Com_HashKey(m_zone.m_name.c_str(), 64); + for (auto kvpIndex = 0u; kvpIndex < gameKvps->numVariables; kvpIndex++) + { + const auto& commonKvp = commonKvps[kvpIndex]; + auto& gameKvp = gameKvps->keyValuePairs[kvpIndex]; + + assert(commonKvp.m_key_str || commonKvp.m_key_hash); + if (commonKvp.m_key_str) + gameKvp.keyHash = Common::Com_HashKey(commonKvp.m_key_str->c_str(), 64); + else + gameKvp.keyHash = *commonKvp.m_key_hash; + + gameKvp.namespaceHash = namespaceHash; + gameKvp.value = m_memory.Dup(commonKvp.m_value.c_str()); + } + + context.AddAsset(AssetRegistration(m_zone.m_name, gameKvps)); +} diff --git a/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompiler.h b/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompilerT6.h similarity index 63% rename from src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompiler.h rename to src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompilerT6.h index 3ad22b8a..fa5ea50e 100644 --- a/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompiler.h +++ b/src/ObjCompiling/Game/T6/KeyValuePairs/KeyValuePairsCompilerT6.h @@ -2,21 +2,26 @@ #include "Asset/IAssetCreator.h" #include "Game/T6/T6.h" +#include "KeyValuePairs/KeyValuePairsCreator.h" +#include "Utils/MemoryManager.h" #include "Zone/Definition/ZoneDefinition.h" +#include "Zone/Zone.h" namespace T6 { class KeyValuePairsCompiler final : public IAssetCreator { public: - KeyValuePairsCompiler(const Zone& zone, const ZoneDefinition& zoneDefinition); + KeyValuePairsCompiler(MemoryManager& memory, const Zone& zone, const ZoneDefinition& zoneDefinition, ZoneAssetCreationStateContainer& zoneStates); [[nodiscard]] std::optional GetHandlingAssetType() const override; AssetCreationResult CreateAsset(const std::string& assetName, AssetCreationContext& context) override; void FinalizeZone(AssetCreationContext& context) override; private: + MemoryManager& m_memory; const Zone& m_zone; const ZoneDefinition& m_zone_definition; + KeyValuePairsCreator& m_kvp_creator; }; } // namespace T6 diff --git a/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp b/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp index 6b5f1dfe..807f8aae 100644 --- a/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp +++ b/src/ObjCompiling/Game/T6/ObjCompilerT6.cpp @@ -3,7 +3,7 @@ #include "Game/T6/T6.h" #include "Image/ImageIPakPostProcessor.h" #include "Image/ImageIwdPostProcessor.h" -#include "KeyValuePairs/KeyValuePairsCompiler.h" +#include "KeyValuePairs/KeyValuePairsCompilerT6.h" #include @@ -12,11 +12,15 @@ namespace fs = std::filesystem; namespace { - void ConfigureCompilers(AssetCreatorCollection& collection, Zone& zone, const ZoneDefinitionContext& zoneDefinition, ISearchPath& searchPath) + void ConfigureCompilers(AssetCreatorCollection& collection, + Zone& zone, + const ZoneDefinitionContext& zoneDefinition, + ISearchPath& searchPath, + ZoneAssetCreationStateContainer& zoneStates) { auto& memory = *zone.GetMemory(); - collection.AddAssetCreator(std::make_unique(zone, zoneDefinition.m_zone_definition)); + collection.AddAssetCreator(std::make_unique(memory, zone, zoneDefinition.m_zone_definition, zoneStates)); } void ConfigurePostProcessors(AssetCreatorCollection& collection, @@ -45,6 +49,6 @@ void ObjCompiler::ConfigureCreatorCollection(AssetCreatorCollection& collection, const fs::path& outDir, const fs::path& cacheDir) const { - ConfigureCompilers(collection, zone, zoneDefinition, searchPath); + ConfigureCompilers(collection, zone, zoneDefinition, searchPath, zoneStates); ConfigurePostProcessors(collection, zone, zoneDefinition, searchPath, zoneStates, outDir); } diff --git a/src/ObjCompiling/KeyValuePairs/KeyValuePairsCreator.cpp b/src/ObjCompiling/KeyValuePairs/KeyValuePairsCreator.cpp new file mode 100644 index 00000000..eac08bae --- /dev/null +++ b/src/ObjCompiling/KeyValuePairs/KeyValuePairsCreator.cpp @@ -0,0 +1,57 @@ +#include "KeyValuePairsCreator.h" + +#include +#include + +CommonKeyValuePair::CommonKeyValuePair(std::string keyStr, std::string value) + : m_key_str(std::move(keyStr)), + m_value(std::move(value)) +{ +} + +CommonKeyValuePair::CommonKeyValuePair(const unsigned keyHash, std::string value) + : m_key_hash(keyHash), + m_value(std::move(value)) +{ +} + +void KeyValuePairsCreator::AddKeyValuePair(CommonKeyValuePair keyValuePair) +{ + m_key_value_pairs.emplace_back(std::move(keyValuePair)); +} + +void KeyValuePairsCreator::Finalize(const ZoneDefinition& zoneDefinition) +{ + for (const auto& metaData : zoneDefinition.m_properties.m_properties) + { + if (metaData.first.rfind("level.", 0) == 0) + { + std::string strValue = metaData.first.substr(std::char_traits::length("level.")); + if (strValue.empty()) + continue; + + if (strValue[0] == '@') + { + char* endPtr; + const unsigned keyHash = strtoul(&strValue[1], &endPtr, 16); + + if (endPtr != &strValue[strValue.size()]) + { + std::cerr << std::format("Could not parse metadata key \"{}\" as hash\n", metaData.first); + continue; + } + + m_key_value_pairs.emplace_back(keyHash, metaData.second); + } + else + { + m_key_value_pairs.emplace_back(std::move(strValue), metaData.second); + } + } + } +} + +std::vector KeyValuePairsCreator::GetFinalKeyValuePairs() +{ + return std::move(m_key_value_pairs); +} diff --git a/src/ObjCompiling/KeyValuePairs/KeyValuePairsCreator.h b/src/ObjCompiling/KeyValuePairs/KeyValuePairsCreator.h new file mode 100644 index 00000000..16499635 --- /dev/null +++ b/src/ObjCompiling/KeyValuePairs/KeyValuePairsCreator.h @@ -0,0 +1,28 @@ +#pragma once + +#include "Asset/IZoneAssetCreationState.h" +#include "Zone/Definition/ZoneDefinition.h" + +#include + +class CommonKeyValuePair +{ +public: + CommonKeyValuePair(std::string keyStr, std::string value); + CommonKeyValuePair(unsigned keyHash, std::string value); + + std::optional m_key_str; + std::optional m_key_hash; + std::string m_value; +}; + +class KeyValuePairsCreator : public IZoneAssetCreationState +{ +public: + void AddKeyValuePair(CommonKeyValuePair keyValuePair); + void Finalize(const ZoneDefinition& zoneDefinition); + std::vector GetFinalKeyValuePairs(); + +private: + std::vector m_key_value_pairs; +}; diff --git a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp index 59324dda..cbce8c48 100644 --- a/src/ObjLoading/Game/T6/ObjLoaderT6.cpp +++ b/src/ObjLoading/Game/T6/ObjLoaderT6.cpp @@ -252,7 +252,7 @@ namespace T6 for (auto* keyValuePairsEntry : *assetPoolT6->m_key_value_pairs) { const auto* keyValuePairs = keyValuePairsEntry->Asset(); - for (auto variableIndex = 0; variableIndex < keyValuePairs->numVariables; variableIndex++) + for (auto variableIndex = 0u; variableIndex < keyValuePairs->numVariables; variableIndex++) { auto* variable = &keyValuePairs->keyValuePairs[variableIndex]; diff --git a/src/Unlinker/Game/T6/ZoneDefWriterT6.cpp b/src/Unlinker/Game/T6/ZoneDefWriterT6.cpp index ad7b197d..5b50ed8d 100644 --- a/src/Unlinker/Game/T6/ZoneDefWriterT6.cpp +++ b/src/Unlinker/Game/T6/ZoneDefWriterT6.cpp @@ -56,7 +56,7 @@ void ZoneDefWriter::WriteMetaData(ZoneDefinitionOutputStream& stream, const Unli for (const auto* kvpAsset : *assetPoolT6->m_key_value_pairs) { const auto* keyValuePairs = kvpAsset->Asset(); - for (auto varIndex = 0; varIndex < keyValuePairs->numVariables; varIndex++) + for (auto varIndex = 0u; varIndex < keyValuePairs->numVariables; varIndex++) WriteKeyValuePair(stream, keyValuePairs->keyValuePairs[varIndex]); }