diff --git a/DataSpec/DNACommon/DNACommon.hpp b/DataSpec/DNACommon/DNACommon.hpp index 2cda9db94..84ea6d2cd 100644 --- a/DataSpec/DNACommon/DNACommon.hpp +++ b/DataSpec/DNACommon/DNACommon.hpp @@ -155,6 +155,7 @@ public: bool operator!=(const UniqueID32& other) const {return m_id != other.m_id;} bool operator==(const UniqueID32& other) const {return m_id == other.m_id;} + bool operator<(const UniqueID32& other) const {return m_id < other.m_id;} uint32_t toUint32() const {return m_id;} uint64_t toUint64() const {return m_id;} std::string toString() const; @@ -219,6 +220,7 @@ public: bool operator!=(const UniqueID64& other) const {return m_id != other.m_id;} bool operator==(const UniqueID64& other) const {return m_id == other.m_id;} + bool operator<(const UniqueID64& other) const {return m_id < other.m_id;} uint64_t toUint64() const {return m_id;} std::string toString() const; void clear() {m_id = 0xffffffffffffffff;} diff --git a/DataSpec/DNACommon/PAK.cpp b/DataSpec/DNACommon/PAK.cpp index 841c9ca1b..b832f3ec2 100644 --- a/DataSpec/DNACommon/PAK.cpp +++ b/DataSpec/DNACommon/PAK.cpp @@ -283,10 +283,7 @@ hecl::ProjectPath PAKRouter::getWorking(const EntryType* entry, const PAKType* pak = m_pak.get(); intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); - if (!pak) - LogDNACommon.report(logvisor::Fatal, - "PAKRouter::enterPAKBridge() must be called before PAKRouter::getWorkingPath()"); - if (pak->m_noShare) + if (pak && pak->m_noShare) { const EntryType* singleSearch = pak->lookupEntry(entry->id); if (singleSearch) @@ -400,10 +397,7 @@ hecl::ProjectPath PAKRouter::getCooked(const EntryType* entry) const const PAKType* pak = m_pak.get(); intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); - if (!pak) - LogDNACommon.report(logvisor::Fatal, - "PAKRouter::enterPAKBridge() must be called before PAKRouter::getCookedPath()"); - if (pak->m_noShare) + if (pak && pak->m_noShare) { const EntryType* singleSearch = pak->lookupEntry(entry->id); if (singleSearch) @@ -761,6 +755,17 @@ hecl::ProjectPath PAKRouter::getAreaLayerCooked(const IDType& areaId return hecl::ProjectPath(); } +template +void PAKRouter::enumerateResources(const std::function& func) +{ + if (!m_bridges) + LogDNACommon.report(logvisor::Fatal, + "PAKRouter::build() must be called before PAKRouter::enumerateResources()"); + for (const auto& entryPair : m_uniqueEntries) + if (!func(entryPair.second.second)) + return; +} + template class PAKRouter; template class PAKRouter; template class PAKRouter; diff --git a/DataSpec/DNACommon/PAK.hpp b/DataSpec/DNACommon/PAK.hpp index 18db4abaa..ce1655ab2 100644 --- a/DataSpec/DNACommon/PAK.hpp +++ b/DataSpec/DNACommon/PAK.hpp @@ -230,6 +230,8 @@ public: hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx, bool& activeOut) const; hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx) const; hecl::ProjectPath getAreaLayerCooked(const IDType& areaId, int layerIdx, bool& activeOut) const; + + void enumerateResources(const std::function& func); }; } diff --git a/DataSpec/SpecMP1.cpp b/DataSpec/SpecMP1.cpp index b7ca1108e..80d70549f 100644 --- a/DataSpec/SpecMP1.cpp +++ b/DataSpec/SpecMP1.cpp @@ -262,6 +262,31 @@ struct SpecMP1 : SpecBase outPath.makeDir(); hecl::ProjectPath mp1OutPath(outPath, _S("MP1")); mp1OutPath.makeDir(); + + /* Generate original ID mapping for MLVL and SCAN entries */ + { + std::vector originalIDs; + m_pakRouter.enumerateResources([&](const DNAMP1::PAK::Entry* ent) -> bool + { + if (ent->type == FOURCC('MLVL') || ent->type == FOURCC('SCAN')) + originalIDs.push_back(ent->id); + return true; + }); + std::sort(originalIDs.begin(), originalIDs.end()); + + athena::io::YAMLDocWriter yamlW("MP1OriginalIDs"); + for (const UniqueID32& id : originalIDs) + { + hecl::ProjectPath path = m_pakRouter.getWorking(id); + yamlW.writeString(id.toString().c_str(), path.getRelativePathUTF8()); + } + hecl::ProjectPath path(m_project.getProjectWorkingPath(), "MP1/original_ids.yaml"); + path.makeDirChain(false); + athena::io::FileWriter fileW(path.getAbsolutePath()); + yamlW.finish(&fileW); + } + + /* Extract non-pak files */ progress(_S("MP1 Root"), _S(""), 3, 0.0); int prog = 0; ctx.progressCB = [&](const std::string& name) { @@ -275,6 +300,7 @@ struct SpecMP1 : SpecBase } progress(_S("MP1 Root"), _S(""), 3, 1.0); + /* Extract unique resources */ std::mutex msgLock; hecl::ClientProcess process; int compIdx = 4;