diff --git a/DataSpec/DNACommon/MAPA.cpp b/DataSpec/DNACommon/MAPA.cpp index d98d7fd66..1427945f6 100644 --- a/DataSpec/DNACommon/MAPA.cpp +++ b/DataSpec/DNACommon/MAPA.cpp @@ -2,6 +2,7 @@ #include "../DNAMP1/DNAMP1.hpp" #include "../DNAMP2/DNAMP2.hpp" #include "../DNAMP3/DNAMP3.hpp" +#include "zeus/CTransform.hpp" namespace DataSpec { @@ -286,6 +287,18 @@ bool ReadMAPAToBlender(hecl::BlenderConnection& conn, "bpy.context.scene.objects.link(obj)\n" "bm.free()\n"; + const zeus::CMatrix4f* tmpMtx = pakRouter.lookupMAPATransform(entry.id); + const zeus::CMatrix4f& mtx = tmpMtx ? *tmpMtx : zeus::CMatrix4f::skIdentityMatrix4f; + os.format("mtx = Matrix(((%f,%f,%f,%f),(%f,%f,%f,%f),(%f,%f,%f,%f),(0.0,0.0,0.0,1.0)))\n" + "mtxd = mtx.decompose()\n" + "obj.rotation_mode = 'QUATERNION'\n" + "obj.location = mtxd[0]\n" + "obj.rotation_quaternion = mtxd[1]\n" + "obj.scale = mtxd[2]\n", + mtx[0][0], mtx[1][0], mtx[2][0], mtx[3][0], + mtx[0][1], mtx[1][1], mtx[2][1], mtx[3][1], + mtx[0][2], mtx[1][2], mtx[2][2], mtx[3][2]); + /* World background */ hecl::ProjectPath worldBlend(outPath.getParentPath().getParentPath(), "!world.blend"); if (worldBlend.isFile()) diff --git a/DataSpec/DNACommon/MAPA.hpp b/DataSpec/DNACommon/MAPA.hpp index 7ac00e833..479f07c81 100644 --- a/DataSpec/DNACommon/MAPA.hpp +++ b/DataSpec/DNACommon/MAPA.hpp @@ -4,6 +4,7 @@ #include "DNACommon.hpp" #include "GX.hpp" + namespace DataSpec { namespace DNAMAPA diff --git a/DataSpec/DNACommon/PAK.cpp b/DataSpec/DNACommon/PAK.cpp index d1390507b..ed4447edf 100644 --- a/DataSpec/DNACommon/PAK.cpp +++ b/DataSpec/DNACommon/PAK.cpp @@ -202,6 +202,10 @@ void PAKRouter::build(std::vector& bridges, std::functio athena::io::YAMLDocWriter catalogWriter(nullptr); enterPAKBridge(bridge); + + /* Add MAPA transforms to global map */ + bridge.addMAPATransforms(*this, m_mapaTransforms, m_overrideEntries); + const typename BRIDGETYPE::PAKType& pak = bridge.getPAK(); for (const auto& namedEntry : pak.m_nameEntries) { @@ -224,7 +228,7 @@ void PAKRouter::build(std::vector& bridges, std::functio /* Write catalog */ intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); const hecl::ProjectPath& pakPath = m_bridgePaths[curBridgeIdx].first; - hecl::SystemString catalogPath = hecl::ProjectPath(pakPath, "catalog.yaml").getAbsolutePath(); + hecl::SystemString catalogPath = hecl::ProjectPath(pakPath, "!catalog.yaml").getAbsolutePath(); athena::io::FileWriter writer(catalogPath); catalogWriter.finish(&writer); } @@ -274,6 +278,11 @@ hecl::ProjectPath PAKRouter::getWorking(const EntryType* entry, { if (!entry) return hecl::ProjectPath(); + + auto overrideSearch = m_overrideEntries.find(entry->id); + if (overrideSearch != m_overrideEntries.end()) + return overrideSearch->second; + const PAKType* pak = m_pak.get(); intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); if (!pak) @@ -384,6 +393,16 @@ hecl::ProjectPath PAKRouter::getCooked(const EntryType* entry) const { if (!entry) return hecl::ProjectPath(); + + auto overrideSearch = m_overrideEntries.find(entry->id); + if (overrideSearch != m_overrideEntries.end()) + { + return overrideSearch->second.getCookedPath( + *m_dataSpec.overrideDataSpec(overrideSearch->second, + m_dataSpec.getDataSpecEntry(), + hecl::SharedBlenderToken)); + } + const PAKType* pak = m_pak.get(); intptr_t curBridgeIdx = reinterpret_cast(m_curBridgeIdx.get()); if (!pak) @@ -636,6 +655,15 @@ const typename PAKRouter::RigPair* PAKRouter::lookupCMDL return &search->second; } +template +const zeus::CMatrix4f* PAKRouter::lookupMAPATransform(const IDType& id) const +{ + auto search = m_mapaTransforms.find(id); + if (search == m_mapaTransforms.end()) + return nullptr; + return &search->second; +} + template hecl::ProjectPath PAKRouter::getAreaLayerWorking(const IDType& areaId, int layerIdx) const { diff --git a/DataSpec/DNACommon/PAK.hpp b/DataSpec/DNACommon/PAK.hpp index 0b96aabc7..2e29adcae 100644 --- a/DataSpec/DNACommon/PAK.hpp +++ b/DataSpec/DNACommon/PAK.hpp @@ -4,6 +4,7 @@ #include "DNACommon.hpp" #include "boo/ThreadLocalPtr.hpp" #include +#include "zeus/CMatrix4f.hpp" namespace DataSpec { @@ -168,8 +169,10 @@ private: ThreadLocalPtr m_node; std::unordered_map> m_uniqueEntries; std::unordered_map> m_sharedEntries; + std::unordered_map m_overrideEntries; std::unordered_map m_cmdlRigs; std::unordered_map> m_cskrCinfToCharacter; + std::unordered_map m_mapaTransforms; hecl::ProjectPath getCharacterWorking(const EntryType* entry) const; @@ -221,6 +224,7 @@ public: } const RigPair* lookupCMDLRigPair(const IDType& id) const; + const zeus::CMatrix4f* lookupMAPATransform(const IDType& mapaId) const; hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx) const; hecl::ProjectPath getAreaLayerWorking(const IDType& areaId, int layerIdx, bool& activeOut) const; diff --git a/DataSpec/DNAMP1/CMakeLists.txt b/DataSpec/DNAMP1/CMakeLists.txt index 5610179d2..aa88a6608 100644 --- a/DataSpec/DNAMP1/CMakeLists.txt +++ b/DataSpec/DNAMP1/CMakeLists.txt @@ -34,6 +34,7 @@ add_library(DNAMP1 DNAMP1.hpp DNAMP1.cpp ${liblist} PAK.cpp + MLVL.cpp STRG.hpp STRG.cpp AGSC.cpp CSNG.cpp diff --git a/DataSpec/DNAMP1/DNAMP1.cpp b/DataSpec/DNAMP1/DNAMP1.cpp index d2d569a36..2be4d091b 100644 --- a/DataSpec/DNAMP1/DNAMP1.cpp +++ b/DataSpec/DNAMP1/DNAMP1.cpp @@ -147,13 +147,7 @@ void PAKBridge::build() areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0); /* Trim possible trailing whitespace */ -#if HECL_UCS2 - while (areaDeps.name.size() && iswspace(areaDeps.name.back())) - areaDeps.name.pop_back(); -#else - while (areaDeps.name.size() && isspace(areaDeps.name.back())) - areaDeps.name.pop_back(); -#endif + areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name); } if (areaDeps.name.empty()) { @@ -273,6 +267,63 @@ void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, } } +static const atVec4f BottomRow = {0.f, 0.f, 0.f, 1.f}; + +void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, + std::unordered_map& addTo, + std::unordered_map& pathOverrides) const +{ + for (const std::pair& entry : m_pak.m_idMap) + { + if (entry.second->type == FOURCC('MLVL')) + { + MLVL mlvl; + { + PAKEntryReadStream rs = entry.second->beginReadStream(m_node); + mlvl.read(rs); + } + hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath(); + + if (mlvl.worldNameId) + pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml")); + + for (const MLVL::Area& area : mlvl.areas) + { + hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); + if (area.areaNameId) + pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _S("!name.yaml")); + } + + if (mlvl.worldMap) + { + const nod::Node* mapNode; + const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode); + if (mapEntry) + { + PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode); + u32 magic = rs.readUint32Big(); + if (magic == 0xDEADF00D) + { + rs.readUint32Big(); + u32 count = rs.readUint32Big(); + for (u32 i=0 ; i PAKBridge::LookupExtractor(const PAK& pak, const PAK::Entry& entry) { switch (entry.type) diff --git a/DataSpec/DNAMP1/DNAMP1.hpp b/DataSpec/DNAMP1/DNAMP1.hpp index 60b675ecb..8c53521c5 100644 --- a/DataSpec/DNAMP1/DNAMP1.hpp +++ b/DataSpec/DNAMP1/DNAMP1.hpp @@ -3,6 +3,7 @@ #include "../DNACommon/DNACommon.hpp" #include "PAK.hpp" +#include "zeus/CMatrix4f.hpp" namespace DataSpec { @@ -37,6 +38,10 @@ public: void addCMDLRigPairs(PAKRouter& pakRouter, std::unordered_map>& addTo, std::unordered_map>& cskrCinfToAncs) const; + + void addMAPATransforms(PAKRouter& pakRouter, + std::unordered_map& addTo, + std::unordered_map& pathOverrides) const; }; } diff --git a/DataSpec/DNAMP1/MLVL.cpp b/DataSpec/DNAMP1/MLVL.cpp new file mode 100644 index 000000000..da5dbff4d --- /dev/null +++ b/DataSpec/DNAMP1/MLVL.cpp @@ -0,0 +1,93 @@ +#include "MLVL.hpp" +#include "SCLY.hpp" + +namespace DataSpec +{ +namespace DNAMP1 +{ + +bool MLVL::Extract(const SpecBase& dataSpec, + PAKEntryReadStream& rs, + const hecl::ProjectPath& outPath, + PAKRouter& pakRouter, + const PAK::Entry& entry, + bool force, + hecl::BlenderToken& btok, + std::function fileChanged) +{ + MLVL mlvl; + mlvl.read(rs); + athena::io::FileWriter writer(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath()); + mlvl.toYAMLStream(writer, static_cast(&MLVL::writeMeta)); + hecl::BlenderConnection& conn = btok.getBlenderConnection(); + return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, + entry, force, fileChanged); +} + +bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld) +{ + MLVL mlvl = {}; + athena::io::FileReader reader(inPath.getWithExtension(_S(".yaml"), true).getAbsolutePath()); + mlvl.fromYAMLStream(reader, static_cast(&MLVL::readMeta)); + + mlvl.magic = 0xDEAFBABE; + mlvl.version = 0x11; + mlvl.saveWorldId = inPath.ensureAuxInfo(_S(".SAVW")); + + size_t areaIdx = 0; + for (const World::Area& area : wld.areas) + { + if (area.path.getPathType() != hecl::ProjectPath::Type::Directory) + continue; + hecl::DirectoryEnumerator dEnum(area.path.getAbsolutePath(), + hecl::DirectoryEnumerator::Mode::DirsSorted); + bool areaInit = false; + + for (const hecl::DirectoryEnumerator::Entry& e : dEnum) + { + hecl::SystemString layerName; + hecl::SystemChar* endCh = nullptr; + hecl::StrToUl(e.m_name.c_str(), &endCh, 0); + if (!endCh) + layerName = e.m_name; + else + layerName = hecl::StringUtils::TrimWhitespace(hecl::SystemString(endCh)); + + hecl::ProjectPath objectsPath(area.path, e.m_name + _S("/!objects.yaml")); + if (objectsPath.isNone()) + continue; + + SCLY::ScriptLayer layer; + { + athena::io::FileReader freader(objectsPath.getAbsolutePath()); + if (!freader.isOpen()) + continue; + if (!BigYAML::ValidateFromYAMLStream(freader)) + continue; + + athena::io::YAMLDocReader reader; + if (!reader.parse(&freader)) + continue; + + layer.read(reader); + } + + hecl::ProjectPath defActivePath(area.path, e.m_name + _S("/!defaultactive")); + bool active = defActivePath.isNone() ? false : true; + + if (!areaInit) + { + mlvl.areas.emplace_back(); + MLVL::Area& areaOut = mlvl.areas.back(); + areaInit = true; + } + } + ++areaIdx; + } + mlvl.memRelayLinkCount = mlvl.memRelayLinks.size(); + mlvl.areaCount = mlvl.areas.size(); + +} + +} +} diff --git a/DataSpec/DNAMP1/MLVL.hpp b/DataSpec/DNAMP1/MLVL.hpp index 483b02460..16510fb48 100644 --- a/DataSpec/DNAMP1/MLVL.hpp +++ b/DataSpec/DNAMP1/MLVL.hpp @@ -108,8 +108,6 @@ struct MLVL : BigYAML void readMeta(athena::io::YAMLDocReader& __dna_docin) { - /* worldNameId */ - __dna_docin.enumerate("worldNameId", worldNameId); /* worldSkyboxId */ __dna_docin.enumerate("worldSkyboxId", worldSkyboxId); /* audioGroupCount squelched */ @@ -119,8 +117,6 @@ struct MLVL : BigYAML void writeMeta(athena::io::YAMLDocWriter& __dna_docout) const { - /* worldNameId */ - __dna_docout.enumerate("worldNameId", worldNameId); /* worldSkyboxId */ __dna_docout.enumerate("worldSkyboxId", worldSkyboxId); /* audioGroupCount squelched */ @@ -135,16 +131,13 @@ struct MLVL : BigYAML const PAK::Entry& entry, bool force, hecl::BlenderToken& btok, - std::function fileChanged) - { - MLVL mlvl; - mlvl.read(rs); - athena::io::FileWriter writer(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath()); - mlvl.toYAMLStream(writer, static_cast(&MLVL::writeMeta)); - hecl::BlenderConnection& conn = btok.getBlenderConnection(); - return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, - entry, force, fileChanged); - } + std::function fileChanged); + + using World = hecl::BlenderConnection::DataStream::World; + + static bool Cook(const hecl::ProjectPath& outPath, + const hecl::ProjectPath& inPath, + const World& wld); }; } diff --git a/DataSpec/DNAMP1/MREA.cpp b/DataSpec/DNAMP1/MREA.cpp index 55f0ee23e..45478707a 100644 --- a/DataSpec/DNAMP1/MREA.cpp +++ b/DataSpec/DNAMP1/MREA.cpp @@ -262,7 +262,7 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath, false, false, true); for (const hecl::DirectoryEnumerator::Entry& ent : dEnum) { - hecl::ProjectPath layerScriptPath(areaDirPath, ent.m_name + _S("/objects.yaml")); + hecl::ProjectPath layerScriptPath(areaDirPath, ent.m_name + _S("/!objects.yaml")); if (layerScriptPath.isFile()) layerScriptPaths.push_back(std::move(layerScriptPath)); } diff --git a/DataSpec/DNAMP1/SCLY.cpp b/DataSpec/DNAMP1/SCLY.cpp index 60a2b4882..bb019dc18 100644 --- a/DataSpec/DNAMP1/SCLY.cpp +++ b/DataSpec/DNAMP1/SCLY.cpp @@ -51,7 +51,7 @@ void SCLY::exportToLayerDirectories(const PAK::Entry& entry, PAKRouter& pakRouter, } } +static const atVec4f BottomRow = {0.f, 0.f, 0.f, 1.f}; + +void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, + std::unordered_map& addTo, + std::unordered_map& pathOverrides) const +{ + for (const std::pair& entry : m_pak.m_idMap) + { + if (entry.second->type == FOURCC('MLVL')) + { + MLVL mlvl; + { + PAKEntryReadStream rs = entry.second->beginReadStream(m_node); + mlvl.read(rs); + } + hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath(); + + if (mlvl.worldNameId) + pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml")); + + for (const MLVL::Area& area : mlvl.areas) + { + hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); + if (area.areaNameId) + pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _S("!name.yaml")); + } + + if (mlvl.worldMap) + { + const nod::Node* mapNode; + const DNAMP1::PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode); + if (mapEntry) + { + PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode); + u32 magic = rs.readUint32Big(); + if (magic == 0xDEADF00D) + { + rs.readUint32Big(); + u32 count = rs.readUint32Big(); + for (u32 i=0 ; i PAKBridge::LookupExtractor(const DNAMP1::PAK& pak, const DNAMP1::PAK::Entry& entry) { switch (entry.type) diff --git a/DataSpec/DNAMP2/DNAMP2.hpp b/DataSpec/DNAMP2/DNAMP2.hpp index b7ae189a9..b01639dc7 100644 --- a/DataSpec/DNAMP2/DNAMP2.hpp +++ b/DataSpec/DNAMP2/DNAMP2.hpp @@ -38,6 +38,10 @@ public: void addCMDLRigPairs(PAKRouter& pakRouter, std::unordered_map>& addTo, std::unordered_map>& cskrCinfToAncs) const; + + void addMAPATransforms(PAKRouter& pakRouter, + std::unordered_map& addTo, + std::unordered_map& pathOverrides) const; }; } diff --git a/DataSpec/DNAMP3/DNAMP3.cpp b/DataSpec/DNAMP3/DNAMP3.cpp index 406216a1f..f6b0548bf 100644 --- a/DataSpec/DNAMP3/DNAMP3.cpp +++ b/DataSpec/DNAMP3/DNAMP3.cpp @@ -15,6 +15,7 @@ #include "../DNACommon/FONT.hpp" #include "../DNACommon/FSM2.hpp" #include "../DNACommon/DGRP.hpp" +#include "Runtime/GCNTypes.hpp" namespace DataSpec { @@ -127,13 +128,7 @@ void PAKBridge::build() areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0); /* Trim possible trailing whitespace */ -#if HECL_UCS2 - while (areaDeps.name.size() && iswspace(areaDeps.name.back())) - areaDeps.name.pop_back(); -#else - while (areaDeps.name.size() && isspace(areaDeps.name.back())) - areaDeps.name.pop_back(); -#endif + areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name); } if (areaDeps.name.empty()) { @@ -218,6 +213,63 @@ void PAKBridge::addCMDLRigPairs(PAKRouter& pakRouter, } } +static const atVec4f BottomRow = {0.f, 0.f, 0.f, 1.f}; + +void PAKBridge::addMAPATransforms(PAKRouter& pakRouter, + std::unordered_map& addTo, + std::unordered_map& pathOverrides) const +{ + for (const std::pair& entry : m_pak.m_idMap) + { + if (entry.second->type == FOURCC('MLVL')) + { + MLVL mlvl; + { + PAKEntryReadStream rs = entry.second->beginReadStream(m_node); + mlvl.read(rs); + } + hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath(); + + if (mlvl.worldNameId) + pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml")); + + for (const MLVL::Area& area : mlvl.areas) + { + hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath(); + if (area.areaNameId) + pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _S("!name.yaml")); + } + + if (mlvl.worldMap) + { + const nod::Node* mapNode; + const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode); + if (mapEntry) + { + PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode); + u32 magic = rs.readUint32Big(); + if (magic == 0xDEADF00D) + { + rs.readUint32Big(); + u32 count = rs.readUint32Big(); + for (u32 i=0 ; i PAKBridge::LookupExtractor(const PAK& pak, const PAK::Entry& entry) { switch (entry.type) diff --git a/DataSpec/DNAMP3/DNAMP3.hpp b/DataSpec/DNAMP3/DNAMP3.hpp index 32c68259c..9b9ac59a0 100644 --- a/DataSpec/DNAMP3/DNAMP3.hpp +++ b/DataSpec/DNAMP3/DNAMP3.hpp @@ -38,6 +38,10 @@ public: void addCMDLRigPairs(PAKRouter& pakRouter, std::unordered_map>& addTo, std::unordered_map>& cskrCinfToChar) const; + + void addMAPATransforms(PAKRouter& pakRouter, + std::unordered_map& addTo, + std::unordered_map& pathOverrides) const; }; } diff --git a/DataSpec/SpecBase.cpp b/DataSpec/SpecBase.cpp index fd4d7209f..4848fe083 100644 --- a/DataSpec/SpecBase.cpp +++ b/DataSpec/SpecBase.cpp @@ -185,7 +185,7 @@ bool SpecBase::canCook(const hecl::ProjectPath& path, hecl::BlenderToken& btok) const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* oldEntry, - hecl::BlenderToken& btok) + hecl::BlenderToken& btok) const { if (!checkPathPrefix(path)) return nullptr; diff --git a/DataSpec/SpecBase.hpp b/DataSpec/SpecBase.hpp index 35ca28372..ea526010e 100644 --- a/DataSpec/SpecBase.hpp +++ b/DataSpec/SpecBase.hpp @@ -20,7 +20,7 @@ struct SpecBase : hecl::Database::IDataSpec bool canCook(const hecl::ProjectPath& path, hecl::BlenderToken& btok); const hecl::Database::DataSpecEntry* overrideDataSpec(const hecl::ProjectPath& path, const hecl::Database::DataSpecEntry* oldEntry, - hecl::BlenderToken& btok); + hecl::BlenderToken& btok) const; void doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath, bool fast, hecl::BlenderToken& btok, FCookProgress progress); @@ -46,7 +46,7 @@ struct SpecBase : hecl::Database::IDataSpec virtual const hecl::Database::DataSpecEntry* getOriginalSpec() const=0; /* Basic path check (game directory matching) */ - virtual bool checkPathPrefix(const hecl::ProjectPath& path)=0; + virtual bool checkPathPrefix(const hecl::ProjectPath& path) const=0; /* Pre-cook handlers */ virtual bool validateYAMLDNAType(athena::io::IStreamReader& fp) const=0; diff --git a/DataSpec/SpecMP1.cpp b/DataSpec/SpecMP1.cpp index a5efd4005..6f36ed04e 100644 --- a/DataSpec/SpecMP1.cpp +++ b/DataSpec/SpecMP1.cpp @@ -324,7 +324,7 @@ struct SpecMP1 : SpecBase return m_pakRouter.getWorking(id); } - bool checkPathPrefix(const hecl::ProjectPath& path) + bool checkPathPrefix(const hecl::ProjectPath& path) const { return path.getRelativePath().compare(0, 4, _S("MP1/")) == 0; } @@ -449,7 +449,7 @@ struct SpecMP1 : SpecBase FCookProgress progress) { BlendStream::World world = ds.compileWorld(); - + DNAMP1::MLVL::Cook(out, in, world); } void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, diff --git a/DataSpec/SpecMP2.cpp b/DataSpec/SpecMP2.cpp index 7cd48190a..42fdc9a42 100644 --- a/DataSpec/SpecMP2.cpp +++ b/DataSpec/SpecMP2.cpp @@ -282,7 +282,7 @@ struct SpecMP2 : SpecBase return m_pakRouter.getWorking(id); } - bool checkPathPrefix(const hecl::ProjectPath& path) + bool checkPathPrefix(const hecl::ProjectPath& path) const { return path.getRelativePath().compare(0, 4, _S("MP2/")) == 0; } diff --git a/DataSpec/SpecMP3.cpp b/DataSpec/SpecMP3.cpp index 06d560c17..2f2a96883 100644 --- a/DataSpec/SpecMP3.cpp +++ b/DataSpec/SpecMP3.cpp @@ -473,7 +473,7 @@ struct SpecMP3 : SpecBase return m_pakRouter.getWorking(id); } - bool checkPathPrefix(const hecl::ProjectPath& path) + bool checkPathPrefix(const hecl::ProjectPath& path) const { return path.getRelativePath().compare(0, 4, _S("MP3/")) == 0; } diff --git a/Editor/ProjectResourceFactoryBase.cpp b/Editor/ProjectResourceFactoryBase.cpp index fa448629e..dd4737e28 100644 --- a/Editor/ProjectResourceFactoryBase.cpp +++ b/Editor/ProjectResourceFactoryBase.cpp @@ -119,7 +119,7 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveCatalogs(const hecl::Pr continue; /* Read catalog.yaml for .pak directory if exists */ - if (level == 1 && !ent.m_name.compare(_S("catalog.yaml"))) + if (level == 1 && !ent.m_name.compare(_S("!catalog.yaml"))) { ReadCatalog(path, nameWriter); continue; @@ -228,6 +228,14 @@ bool ProjectResourceFactoryBase::AddFileToIndex(const hecl::ProjectPath& path, #if DUMP_CACHE_FILL DumpCacheAdd(pathTag, subPath); #endif + + subPath = asGlob.ensureAuxInfo(_S(".SAVW")); + pathTag = BuildTagFromPath(subPath, m_backgroundBlender); + m_tagToPath[pathTag] = subPath; + m_pathToTag[subPath.hash()] = pathTag; +#if DUMP_CACHE_FILL + DumpCacheAdd(pathTag, subPath); +#endif } /* Cache in-memory */ @@ -264,7 +272,7 @@ void ProjectResourceFactoryBase::BackgroundIndexRecursiveProc(const hecl::Projec continue; /* Read catalog.yaml for .pak directory if exists */ - if (level == 1 && !ent.m_name.compare(_S("catalog.yaml"))) + if (level == 1 && !ent.m_name.compare(_S("!catalog.yaml"))) { ReadCatalog(path, nameWriter); continue; diff --git a/Editor/ProjectResourceFactoryMP1.cpp b/Editor/ProjectResourceFactoryMP1.cpp index bfddbdac8..5862639eb 100644 --- a/Editor/ProjectResourceFactoryMP1.cpp +++ b/Editor/ProjectResourceFactoryMP1.cpp @@ -96,8 +96,12 @@ SObjectTag ProjectResourceFactoryMP1::BuildTagFromPath(const hecl::ProjectPath& case hecl::BlenderConnection::BlendType::World: { if (path.getAuxInfo().size()) + { if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _S(".MAPW"))) return {SBIG('MAPW'), path.hash().val32()}; + else if (hecl::StringUtils::EndsWith(path.getAuxInfo(), _S(".SAVW"))) + return {SBIG('SAVW'), path.hash().val32()}; + } return {SBIG('MLVL'), path.hash().val32()}; } case hecl::BlenderConnection::BlendType::MapArea: diff --git a/hecl b/hecl index b513ed1de..471385dd4 160000 --- a/hecl +++ b/hecl @@ -1 +1 @@ -Subproject commit b513ed1ded026067d9ba1ff6908783a0b678ba34 +Subproject commit 471385dd4a8cad60bd65211f7b17f118d961ef94 diff --git a/specter b/specter index f6318521f..b9877633b 160000 --- a/specter +++ b/specter @@ -1 +1 @@ -Subproject commit f6318521f9f28de34051f8e519f7ba8069501468 +Subproject commit b9877633b0774cd85557696228bfa8e7505ec153