Initial cook tool integration

This commit is contained in:
Jack Andersen 2015-10-03 19:08:56 -10:00
parent 43ddaa0dc4
commit 0d2f2cfd34
22 changed files with 195 additions and 96 deletions

View File

@ -44,7 +44,7 @@ bool ReadANCSToBlender(HECL::BlenderConnection& conn,
ancs.getCharacterResInfo(chResInfo); ancs.getCharacterResInfo(chResInfo);
for (const auto& info : chResInfo) for (const auto& info : chResInfo)
{ {
const NOD::DiscBase::IPartition::Node* node; const NOD::Node* node;
const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node, true); const typename PAKRouter::EntryType* cmdlE = pakRouter.lookupEntry(info.cmdl, &node, true);
if (cmdlE) if (cmdlE)
{ {

View File

@ -440,8 +440,8 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
QuantizedRot qrCur = QuantizeRotation(*it, rotDivOut); QuantizedRot qrCur = QuantizeRotation(*it, rotDivOut);
quantizeBit(newData, qrCur.w); quantizeBit(newData, qrCur.w);
quantize(newData, chan.q[0], qrCur.v[0] - qrLast.v[0]); quantize(newData, chan.q[0], qrCur.v[0] - qrLast.v[0]);
quantize(newData, chan.q[1], qrCur.v[1] - qrLast.v[0]); quantize(newData, chan.q[1], qrCur.v[1] - qrLast.v[1]);
quantize(newData, chan.q[2], qrCur.v[2] - qrLast.v[0]); quantize(newData, chan.q[2], qrCur.v[2] - qrLast.v[2]);
qrLast = qrCur; qrLast = qrCur;
} }
break; break;
@ -459,8 +459,8 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
atInt16(it->v3.vec[1] / transMultOut), atInt16(it->v3.vec[1] / transMultOut),
atInt16(it->v3.vec[2] / transMultOut)}; atInt16(it->v3.vec[2] / transMultOut)};
quantize(newData, chan.q[0], cur[0] - last[0]); quantize(newData, chan.q[0], cur[0] - last[0]);
quantize(newData, chan.q[1], cur[1] - last[0]); quantize(newData, chan.q[1], cur[1] - last[1]);
quantize(newData, chan.q[2], cur[2] - last[0]); quantize(newData, chan.q[2], cur[2] - last[2]);
last = cur; last = cur;
} }
break; break;
@ -478,8 +478,8 @@ BitstreamWriter::write(const std::vector<std::vector<Value>>& chanKeys,
atInt16(it->v3.vec[1] * rotDivOut), atInt16(it->v3.vec[1] * rotDivOut),
atInt16(it->v3.vec[2] * rotDivOut)}; atInt16(it->v3.vec[2] * rotDivOut)};
quantize(newData, chan.q[0], cur[0] - last[0]); quantize(newData, chan.q[0], cur[0] - last[0]);
quantize(newData, chan.q[1], cur[1] - last[0]); quantize(newData, chan.q[1], cur[1] - last[1]);
quantize(newData, chan.q[2], cur[2] - last[0]); quantize(newData, chan.q[2], cur[2] - last[2]);
last = cur; last = cur;
} }
break; break;

View File

@ -151,7 +151,7 @@ void ReadMaterialSetToBlender_1_2(HECL::BlenderConnection::PyOutStream& os,
for (const UniqueID32& tex : matSet.head.textureIDs) for (const UniqueID32& tex : matSet.head.textureIDs)
{ {
std::string texName = pakRouter.getBestEntryName(tex); std::string texName = pakRouter.getBestEntryName(tex);
const NOD::DiscBase::IPartition::Node* node; const NOD::Node* node;
const typename PAKRouter::EntryType* texEntry = pakRouter.lookupEntry(tex, &node); const typename PAKRouter::EntryType* texEntry = pakRouter.lookupEntry(tex, &node);
HECL::ProjectPath txtrPath = pakRouter.getWorking(texEntry); HECL::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (txtrPath.getPathType() == HECL::ProjectPath::PT_NONE) if (txtrPath.getPathType() == HECL::ProjectPath::PT_NONE)

View File

@ -246,7 +246,7 @@ private:
HECL::ProjectPath m_sharedWorking; HECL::ProjectPath m_sharedWorking;
HECL::ProjectPath m_sharedCooked; HECL::ProjectPath m_sharedCooked;
const PAKType* m_pak = nullptr; const PAKType* m_pak = nullptr;
const NOD::DiscBase::IPartition::Node* m_node = nullptr; const NOD::Node* m_node = nullptr;
std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_uniqueEntries; std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_uniqueEntries;
std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_sharedEntries; std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_sharedEntries;
std::unordered_map<IDType, RigPair> m_cmdlRigs; std::unordered_map<IDType, RigPair> m_cmdlRigs;
@ -549,7 +549,7 @@ public:
} }
const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry, const typename BRIDGETYPE::PAKType::Entry* lookupEntry(const IDType& entry,
const NOD::DiscBase::IPartition::Node** nodeOut=nullptr, const NOD::Node** nodeOut=nullptr,
bool silenceWarnings=false) const bool silenceWarnings=false) const
{ {
if (!m_bridges) if (!m_bridges)
@ -586,7 +586,7 @@ public:
template <typename DNA> template <typename DNA>
bool lookupAndReadDNA(const IDType& id, DNA& out, bool silenceWarnings=false) bool lookupAndReadDNA(const IDType& id, DNA& out, bool silenceWarnings=false)
{ {
const NOD::DiscBase::IPartition::Node* node; const NOD::Node* node;
const EntryType* entry = lookupEntry(id, &node, silenceWarnings); const EntryType* entry = lookupEntry(id, &node, silenceWarnings);
if (!entry) if (!entry)
return false; return false;

View File

@ -26,7 +26,7 @@ static bool GetNoShare(const std::string& name)
} }
PAKBridge::PAKBridge(HECL::Database::Project& project, PAKBridge::PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node, const NOD::Node& node,
bool doExtract) bool doExtract)
: m_project(project), m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract) : m_project(project), m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract)
{ {

View File

@ -15,7 +15,7 @@ extern LogVisor::LogModule Log;
class PAKBridge class PAKBridge
{ {
HECL::Database::Project& m_project; HECL::Database::Project& m_project;
const NOD::DiscBase::IPartition::Node& m_node; const NOD::Node& m_node;
PAK m_pak; PAK m_pak;
public: public:
bool m_doExtract; bool m_doExtract;
@ -24,7 +24,7 @@ public:
HECL::SystemString m_levelString; HECL::SystemString m_levelString;
PAKBridge(HECL::Database::Project& project, PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node, const NOD::Node& node,
bool doExtract=true); bool doExtract=true);
void build(); void build();
static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry); static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry);
@ -32,7 +32,7 @@ public:
const HECL::SystemString& getLevelString() const {return m_levelString;} const HECL::SystemString& getLevelString() const {return m_levelString;}
using PAKType = PAK; using PAKType = PAK;
const PAKType& getPAK() const {return m_pak;} const PAKType& getPAK() const {return m_pak;}
const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;} const NOD::Node& getNode() const {return m_node;}
void addCMDLRigPairs(std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo) const; void addCMDLRigPairs(std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo) const;
}; };

View File

@ -73,7 +73,7 @@ void PAK::write(Athena::io::IStreamWriter& writer) const
} }
std::unique_ptr<atUint8[]> std::unique_ptr<atUint8[]>
PAK::Entry::getBuffer(const NOD::DiscBase::IPartition::Node& pak, atUint64& szOut) const PAK::Entry::getBuffer(const NOD::Node& pak, atUint64& szOut) const
{ {
if (compressed) if (compressed)
{ {

View File

@ -37,8 +37,8 @@ struct PAK : BigDNA
Value<atUint32> offset; Value<atUint32> offset;
UniqueResult unique; UniqueResult unique;
std::unique_ptr<atUint8[]> getBuffer(const NOD::DiscBase::IPartition::Node& pak, atUint64& szOut) const; std::unique_ptr<atUint8[]> getBuffer(const NOD::Node& pak, atUint64& szOut) const;
inline PAKEntryReadStream beginReadStream(const NOD::DiscBase::IPartition::Node& pak, atUint64 off=0) const inline PAKEntryReadStream beginReadStream(const NOD::Node& pak, atUint64 off=0) const
{ {
atUint64 sz; atUint64 sz;
std::unique_ptr<atUint8[]> buf = getBuffer(pak, sz); std::unique_ptr<atUint8[]> buf = getBuffer(pak, sz);

View File

@ -23,7 +23,7 @@ static bool GetNoShare(const std::string& name)
} }
PAKBridge::PAKBridge(HECL::Database::Project& project, PAKBridge::PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node, const NOD::Node& node,
bool doExtract) bool doExtract)
: m_project(project), m_node(node), m_pak(true, GetNoShare(node.getName())), m_doExtract(doExtract) : m_project(project), m_node(node), m_pak(true, GetNoShare(node.getName())), m_doExtract(doExtract)
{ {

View File

@ -15,7 +15,7 @@ extern LogVisor::LogModule Log;
class PAKBridge class PAKBridge
{ {
HECL::Database::Project& m_project; HECL::Database::Project& m_project;
const NOD::DiscBase::IPartition::Node& m_node; const NOD::Node& m_node;
DNAMP1::PAK m_pak; DNAMP1::PAK m_pak;
public: public:
bool m_doExtract; bool m_doExtract;
@ -24,7 +24,7 @@ public:
HECL::SystemString m_levelString; HECL::SystemString m_levelString;
PAKBridge(HECL::Database::Project& project, PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node, const NOD::Node& node,
bool doExtract=true); bool doExtract=true);
void build(); void build();
static ResExtractor<PAKBridge> LookupExtractor(const DNAMP1::PAK::Entry& entry); static ResExtractor<PAKBridge> LookupExtractor(const DNAMP1::PAK::Entry& entry);
@ -33,7 +33,7 @@ public:
using PAKType = DNAMP1::PAK; using PAKType = DNAMP1::PAK;
const PAKType& getPAK() const {return m_pak;} const PAKType& getPAK() const {return m_pak;}
const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;} const NOD::Node& getNode() const {return m_node;}
void addCMDLRigPairs(std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo) const; void addCMDLRigPairs(std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo) const;
}; };

View File

@ -116,7 +116,7 @@ void Material::SectionPASS::constructNode(HECL::BlenderConnection::PyOutStream&
if (txtrId) if (txtrId)
{ {
std::string texName = pakRouter.getBestEntryName(txtrId); std::string texName = pakRouter.getBestEntryName(txtrId);
const NOD::DiscBase::IPartition::Node* node; const NOD::Node* node;
const PAK::Entry* texEntry = pakRouter.lookupEntry(txtrId, &node); const PAK::Entry* texEntry = pakRouter.lookupEntry(txtrId, &node);
HECL::ProjectPath txtrPath = pakRouter.getWorking(texEntry); HECL::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (txtrPath.getPathType() == HECL::ProjectPath::PT_NONE) if (txtrPath.getPathType() == HECL::ProjectPath::PT_NONE)

View File

@ -25,7 +25,7 @@ static bool GetNoShare(const std::string& name)
} }
PAKBridge::PAKBridge(HECL::Database::Project& project, PAKBridge::PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node, const NOD::Node& node,
bool doExtract) bool doExtract)
: m_project(project), m_node(node), m_pak(GetNoShare(node.getName())), m_doExtract(doExtract) : m_project(project), m_node(node), m_pak(GetNoShare(node.getName())), m_doExtract(doExtract)
{ {

View File

@ -15,7 +15,7 @@ extern LogVisor::LogModule Log;
class PAKBridge class PAKBridge
{ {
HECL::Database::Project& m_project; HECL::Database::Project& m_project;
const NOD::DiscBase::IPartition::Node& m_node; const NOD::Node& m_node;
PAK m_pak; PAK m_pak;
public: public:
bool m_doExtract; bool m_doExtract;
@ -24,7 +24,7 @@ public:
HECL::SystemString m_levelString; HECL::SystemString m_levelString;
PAKBridge(HECL::Database::Project& project, PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node, const NOD::Node& node,
bool doExtract=true); bool doExtract=true);
void build(); void build();
static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry); static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry);
@ -33,7 +33,7 @@ public:
using PAKType = PAK; using PAKType = PAK;
inline const PAKType& getPAK() const {return m_pak;} inline const PAKType& getPAK() const {return m_pak;}
inline const NOD::DiscBase::IPartition::Node& getNode() const {return m_node;} inline const NOD::Node& getNode() const {return m_node;}
void addCMDLRigPairs(std::unordered_map<UniqueID64, std::pair<UniqueID64, UniqueID64>>& addTo) const; void addCMDLRigPairs(std::unordered_map<UniqueID64, std::pair<UniqueID64, UniqueID64>>& addTo) const;
}; };

View File

@ -98,7 +98,7 @@ void PAK::write(Athena::io::IStreamWriter& writer) const
writer.seek(rshdPad, Athena::Current); writer.seek(rshdPad, Athena::Current);
} }
std::unique_ptr<atUint8[]> PAK::Entry::getBuffer(const NOD::DiscBase::IPartition::Node& pak, atUint64& szOut) const std::unique_ptr<atUint8[]> PAK::Entry::getBuffer(const NOD::Node& pak, atUint64& szOut) const
{ {
if (compressed) if (compressed)
{ {

View File

@ -46,8 +46,8 @@ struct PAK : BigDNA
Value<atUint32> offset; Value<atUint32> offset;
UniqueResult unique; UniqueResult unique;
std::unique_ptr<atUint8[]> getBuffer(const NOD::DiscBase::IPartition::Node& pak, atUint64& szOut) const; std::unique_ptr<atUint8[]> getBuffer(const NOD::Node& pak, atUint64& szOut) const;
inline PAKEntryReadStream beginReadStream(const NOD::DiscBase::IPartition::Node& pak, atUint64 off=0) const inline PAKEntryReadStream beginReadStream(const NOD::Node& pak, atUint64 off=0) const
{ {
atUint64 sz; atUint64 sz;
std::unique_ptr<atUint8[]> buf = getBuffer(pak, sz); std::unique_ptr<atUint8[]> buf = getBuffer(pak, sz);

View File

@ -7,7 +7,7 @@ namespace Retro
static LogVisor::LogModule Log("Retro::SpecBase"); static LogVisor::LogModule Log("Retro::SpecBase");
bool SpecBase::canExtract(const ExtractPassInfo& info, std::list<ExtractReport>& reps) bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps)
{ {
m_disc = NOD::OpenDiscFromImage(info.srcpath.c_str(), m_isWii); m_disc = NOD::OpenDiscFromImage(info.srcpath.c_str(), m_isWii);
if (!m_disc) if (!m_disc)
@ -54,7 +54,7 @@ void SpecBase::doExtract(const ExtractPassInfo& info, FProgress progress)
{ {
/* Extract update partition for repacking later */ /* Extract update partition for repacking later */
const HECL::SystemString& target = m_project.getProjectWorkingPath().getAbsolutePath(); const HECL::SystemString& target = m_project.getProjectWorkingPath().getAbsolutePath();
NOD::DiscBase::IPartition* update = m_disc->getUpdatePartition(); NOD::Partition* update = m_disc->getUpdatePartition();
NOD::ExtractionContext ctx = {true, info.force, nullptr}; NOD::ExtractionContext ctx = {true, info.force, nullptr};
if (update) if (update)
@ -75,10 +75,10 @@ void SpecBase::doExtract(const ExtractPassInfo& info, FProgress progress)
if (!m_standalone) if (!m_standalone)
{ {
progress(_S("Trilogy Files"), _S(""), 1, 0.0); progress(_S("Trilogy Files"), _S(""), 1, 0.0);
NOD::DiscBase::IPartition* data = m_disc->getDataPartition(); NOD::Partition* data = m_disc->getDataPartition();
const NOD::DiscBase::IPartition::Node& root = data->getFSTRoot(); const NOD::Node& root = data->getFSTRoot();
for (const NOD::DiscBase::IPartition::Node& child : root) for (const NOD::Node& child : root)
if (child.getKind() == NOD::DiscBase::IPartition::Node::NODE_FILE) if (child.getKind() == NOD::Node::NODE_FILE)
child.extractToDirectory(target, ctx); child.extractToDirectory(target, ctx);
progress(_S("Trilogy Files"), _S(""), 1, 1.0); progress(_S("Trilogy Files"), _S(""), 1, 1.0);
} }
@ -88,6 +88,8 @@ void SpecBase::doExtract(const ExtractPassInfo& info, FProgress progress)
bool SpecBase::canCook(const HECL::ProjectPath& path) bool SpecBase::canCook(const HECL::ProjectPath& path)
{ {
if (!checkPathPrefix(path))
return false;
if (HECL::IsPathBlend(path)) if (HECL::IsPathBlend(path))
{ {
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection(); HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
@ -110,8 +112,22 @@ bool SpecBase::canCook(const HECL::ProjectPath& path)
return false; return false;
} }
using Mesh = HECL::BlenderConnection::DataStream::Mesh;
void SpecBase::doCook(const HECL::ProjectPath& path, const HECL::ProjectPath& cookedPath) void SpecBase::doCook(const HECL::ProjectPath& path, const HECL::ProjectPath& cookedPath)
{ {
if (HECL::IsPathBlend(path))
{
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
if (!conn.openBlend(path.getAbsolutePath()))
return;
if (conn.getBlendType() == HECL::BlenderConnection::TypeMesh)
{
HECL::BlenderConnection::DataStream ds = conn.beginData();
Mesh mesh = ds.compileMesh();
ds.close();
}
}
} }
bool SpecBase::canPackage(const PackagePassInfo& info) bool SpecBase::canPackage(const PackagePassInfo& info)

View File

@ -5,13 +5,15 @@
#include <HECL/Database.hpp> #include <HECL/Database.hpp>
#include <NOD/NOD.hpp> #include <NOD/NOD.hpp>
#include "BlenderConnection.hpp"
namespace Retro namespace Retro
{ {
struct SpecBase : HECL::Database::IDataSpec struct SpecBase : HECL::Database::IDataSpec
{ {
bool canExtract(const ExtractPassInfo& info, std::list<ExtractReport>& reps); /* HECL Adaptors */
bool canExtract(const ExtractPassInfo& info, std::vector<ExtractReport>& reps);
void doExtract(const ExtractPassInfo& info, FProgress progress); void doExtract(const ExtractPassInfo& info, FProgress progress);
bool canCook(const HECL::ProjectPath& path); bool canCook(const HECL::ProjectPath& path);
@ -22,20 +24,33 @@ struct SpecBase : HECL::Database::IDataSpec
std::unordered_set<HECL::ProjectPath>& implicitsOut); std::unordered_set<HECL::ProjectPath>& implicitsOut);
void doPackage(const PackagePassInfo& info); void doPackage(const PackagePassInfo& info);
/* Extract handlers */
virtual bool checkStandaloneID(const char* id) const=0; virtual bool checkStandaloneID(const char* id) const=0;
virtual bool checkFromStandaloneDisc(NOD::DiscBase& disc, virtual bool checkFromStandaloneDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr, const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
std::list<ExtractReport>& reps)=0; std::vector<ExtractReport>& reps)=0;
virtual bool checkFromTrilogyDisc(NOD::DiscBase& disc, virtual bool checkFromTrilogyDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr, const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
std::list<ExtractReport>& reps)=0; std::vector<ExtractReport>& reps)=0;
virtual bool extractFromDisc(NOD::DiscBase& disc, bool force, virtual bool extractFromDisc(NOD::DiscBase& disc, bool force,
FProgress progress)=0; FProgress progress)=0;
/* Basic path check (game directory matching) */
virtual bool checkPathPrefix(const HECL::ProjectPath& path)=0;
/* Pre-cook handlers */
virtual bool validateYAMLDNAType(FILE* fp) const=0; virtual bool validateYAMLDNAType(FILE* fp) const=0;
/* Cook handlers */
using BlendStream = HECL::BlenderConnection::DataStream;
virtual void cookMesh(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const=0;
virtual void cookActor(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const=0;
virtual void cookArea(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const=0;
virtual void cookYAML(FILE* in, const HECL::ProjectPath& out) const=0;
const HECL::ProjectPath& getMasterShaderPath() const {return m_masterShader;} const HECL::ProjectPath& getMasterShaderPath() const {return m_masterShader;}
SpecBase(HECL::Database::Project& project) SpecBase(HECL::Database::Project& project)

View File

@ -23,7 +23,7 @@ struct SpecMP1 : SpecBase
return false; return false;
} }
std::vector<const NOD::DiscBase::IPartition::Node*> m_nonPaks; std::vector<const NOD::Node*> m_nonPaks;
std::vector<DNAMP1::PAKBridge> m_paks; std::vector<DNAMP1::PAKBridge> m_paks;
std::map<std::string, DNAMP1::PAKBridge*, CaseInsensitiveCompare> m_orderedPaks; std::map<std::string, DNAMP1::PAKBridge*, CaseInsensitiveCompare> m_orderedPaks;
@ -37,13 +37,13 @@ struct SpecMP1 : SpecBase
m_cookPath(project.getProjectCookedPath(SpecEntMP1), _S("MP1")), m_cookPath(project.getProjectCookedPath(SpecEntMP1), _S("MP1")),
m_pakRouter(*this, m_workPath, m_cookPath) {} m_pakRouter(*this, m_workPath, m_cookPath) {}
void buildPaks(NOD::DiscBase::IPartition::Node& root, void buildPaks(NOD::Node& root,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
ExtractReport& rep) ExtractReport& rep)
{ {
m_nonPaks.clear(); m_nonPaks.clear();
m_paks.clear(); m_paks.clear();
for (const NOD::DiscBase::IPartition::Node& child : root) for (const NOD::Node& child : root)
{ {
bool isPak = false; bool isPak = false;
const std::string& name = child.getName(); const std::string& name = child.getName();
@ -107,6 +107,7 @@ struct SpecMP1 : SpecBase
m_orderedPaks[dpak.getName()] = &dpak; m_orderedPaks[dpak.getName()] = &dpak;
/* Assemble extract report */ /* Assemble extract report */
rep.childOpts.reserve(m_orderedPaks.size());
for (const std::pair<std::string, DNAMP1::PAKBridge*>& item : m_orderedPaks) for (const std::pair<std::string, DNAMP1::PAKBridge*>& item : m_orderedPaks)
{ {
if (!item.second->m_doExtract) if (!item.second->m_doExtract)
@ -121,10 +122,10 @@ struct SpecMP1 : SpecBase
bool checkFromStandaloneDisc(NOD::DiscBase& disc, bool checkFromStandaloneDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr, const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
std::list<ExtractReport>& reps) std::vector<ExtractReport>& reps)
{ {
NOD::DiscGCN::IPartition* partition = disc.getDataPartition(); NOD::Partition* partition = disc.getDataPartition();
std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf(); std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf();
const char* buildInfo = (char*)memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16) + 19; const char* buildInfo = (char*)memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16) + 19;
@ -144,7 +145,7 @@ struct SpecMP1 : SpecBase
} }
/* Iterate PAKs and build level options */ /* Iterate PAKs and build level options */
NOD::DiscBase::IPartition::Node& root = partition->getFSTRoot(); NOD::Node& root = partition->getFSTRoot();
buildPaks(root, args, rep); buildPaks(root, args, rep);
return true; return true;
@ -152,10 +153,10 @@ struct SpecMP1 : SpecBase
bool checkFromTrilogyDisc(NOD::DiscBase& disc, bool checkFromTrilogyDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr, const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
std::list<ExtractReport>& reps) std::vector<ExtractReport>& reps)
{ {
std::list<HECL::SystemString> mp1args; std::vector<HECL::SystemString> mp1args;
bool doExtract = false; bool doExtract = false;
if (args.size()) if (args.size())
{ {
@ -167,6 +168,7 @@ struct SpecMP1 : SpecBase
if (!lowerArg.compare(0, 3, _S("mp1"))) if (!lowerArg.compare(0, 3, _S("mp1")))
{ {
doExtract = true; doExtract = true;
mp1args.reserve(args.size());
size_t slashPos = arg.find(_S('/')); size_t slashPos = arg.find(_S('/'));
if (slashPos == HECL::SystemString::npos) if (slashPos == HECL::SystemString::npos)
slashPos = arg.find(_S('\\')); slashPos = arg.find(_S('\\'));
@ -181,9 +183,9 @@ struct SpecMP1 : SpecBase
if (!doExtract) if (!doExtract)
return false; return false;
NOD::DiscGCN::IPartition* partition = disc.getDataPartition(); NOD::Partition* partition = disc.getDataPartition();
NOD::DiscBase::IPartition::Node& root = partition->getFSTRoot(); NOD::Node& root = partition->getFSTRoot();
NOD::DiscBase::IPartition::Node::DirectoryIterator dolIt = root.find("rs5mp1_p.dol"); NOD::Node::DirectoryIterator dolIt = root.find("rs5mp1_p.dol");
if (dolIt == root.end()) if (dolIt == root.end())
return false; return false;
@ -203,7 +205,7 @@ struct SpecMP1 : SpecBase
} }
/* Iterate PAKs and build level options */ /* Iterate PAKs and build level options */
NOD::DiscBase::IPartition::Node::DirectoryIterator mp1It = root.find("MP1"); NOD::Node::DirectoryIterator mp1It = root.find("MP1");
if (mp1It == root.end()) if (mp1It == root.end())
return false; return false;
buildPaks(*mp1It, mp1args, rep); buildPaks(*mp1It, mp1args, rep);
@ -229,7 +231,7 @@ struct SpecMP1 : SpecBase
HECL::SystemStringView nameView(name); HECL::SystemStringView nameView(name);
progress(_S("MP1 Root"), nameView.sys_str().c_str(), 3, prog / (float)m_nonPaks.size()); progress(_S("MP1 Root"), nameView.sys_str().c_str(), 3, prog / (float)m_nonPaks.size());
}; };
for (const NOD::DiscBase::IPartition::Node* node : m_nonPaks) for (const NOD::Node* node : m_nonPaks)
{ {
node->extractToDirectory(m_workPath.getAbsolutePath(), ctx); node->extractToDirectory(m_workPath.getAbsolutePath(), ctx);
prog++; prog++;
@ -263,6 +265,11 @@ struct SpecMP1 : SpecBase
return true; return true;
} }
bool checkPathPrefix(const HECL::ProjectPath& path)
{
return path.getRelativePath().compare(0, 4, "MP1/") == 0;
}
bool validateYAMLDNAType(FILE* fp) const bool validateYAMLDNAType(FILE* fp) const
{ {
if (BigYAML::ValidateFromYAMLFile<DNAMP1::MLVL>(fp)) if (BigYAML::ValidateFromYAMLFile<DNAMP1::MLVL>(fp))
@ -271,6 +278,22 @@ struct SpecMP1 : SpecBase
return true; return true;
return false; return false;
} }
void cookMesh(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const
{
}
void cookActor(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const
{
}
void cookArea(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const
{
}
void cookYAML(FILE* in, const HECL::ProjectPath& out) const
{
}
}; };
HECL::Database::DataSpecEntry SpecEntMP1 = HECL::Database::DataSpecEntry SpecEntMP1 =

View File

@ -21,7 +21,7 @@ struct SpecMP2 : SpecBase
return false; return false;
} }
std::vector<const NOD::DiscBase::IPartition::Node*> m_nonPaks; std::vector<const NOD::Node*> m_nonPaks;
std::vector<DNAMP2::PAKBridge> m_paks; std::vector<DNAMP2::PAKBridge> m_paks;
std::map<std::string, DNAMP2::PAKBridge*, CaseInsensitiveCompare> m_orderedPaks; std::map<std::string, DNAMP2::PAKBridge*, CaseInsensitiveCompare> m_orderedPaks;
@ -35,13 +35,13 @@ struct SpecMP2 : SpecBase
m_cookPath(project.getProjectCookedPath(SpecEntMP2), _S("MP2")), m_cookPath(project.getProjectCookedPath(SpecEntMP2), _S("MP2")),
m_pakRouter(*this, m_workPath, m_cookPath) {} m_pakRouter(*this, m_workPath, m_cookPath) {}
void buildPaks(NOD::DiscBase::IPartition::Node& root, void buildPaks(NOD::Node& root,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
ExtractReport& rep) ExtractReport& rep)
{ {
m_nonPaks.clear(); m_nonPaks.clear();
m_paks.clear(); m_paks.clear();
for (const NOD::DiscBase::IPartition::Node& child : root) for (const NOD::Node& child : root)
{ {
bool isPak = false; bool isPak = false;
const std::string& name = child.getName(); const std::string& name = child.getName();
@ -118,10 +118,10 @@ struct SpecMP2 : SpecBase
bool checkFromStandaloneDisc(NOD::DiscBase& disc, bool checkFromStandaloneDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr, const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
std::list<ExtractReport>& reps) std::vector<ExtractReport>& reps)
{ {
NOD::DiscGCN::IPartition* partition = disc.getDataPartition(); NOD::Partition* partition = disc.getDataPartition();
std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf(); std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf();
const char* buildInfo = (char*)memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16) + 19; const char* buildInfo = (char*)memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16) + 19;
if (!buildInfo) if (!buildInfo)
@ -137,7 +137,7 @@ struct SpecMP2 : SpecBase
rep.desc += _S(" (") + buildView + _S(")"); rep.desc += _S(" (") + buildView + _S(")");
/* Iterate PAKs and build level options */ /* Iterate PAKs and build level options */
NOD::DiscBase::IPartition::Node& root = partition->getFSTRoot(); NOD::Node& root = partition->getFSTRoot();
buildPaks(root, args, rep); buildPaks(root, args, rep);
return true; return true;
@ -145,10 +145,10 @@ struct SpecMP2 : SpecBase
bool checkFromTrilogyDisc(NOD::DiscBase& disc, bool checkFromTrilogyDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr, const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
std::list<ExtractReport>& reps) std::vector<ExtractReport>& reps)
{ {
std::list<HECL::SystemString> mp2args; std::vector<HECL::SystemString> mp2args;
bool doExtract = false; bool doExtract = false;
if (args.size()) if (args.size())
{ {
@ -160,6 +160,7 @@ struct SpecMP2 : SpecBase
if (!lowerArg.compare(0, 3, _S("mp2"))) if (!lowerArg.compare(0, 3, _S("mp2")))
{ {
doExtract = true; doExtract = true;
mp2args.reserve(args.size());
size_t slashPos = arg.find(_S('/')); size_t slashPos = arg.find(_S('/'));
if (slashPos == HECL::SystemString::npos) if (slashPos == HECL::SystemString::npos)
slashPos = arg.find(_S('\\')); slashPos = arg.find(_S('\\'));
@ -174,9 +175,9 @@ struct SpecMP2 : SpecBase
if (!doExtract) if (!doExtract)
return false; return false;
NOD::DiscGCN::IPartition* partition = disc.getDataPartition(); NOD::Partition* partition = disc.getDataPartition();
NOD::DiscBase::IPartition::Node& root = partition->getFSTRoot(); NOD::Node& root = partition->getFSTRoot();
NOD::DiscBase::IPartition::Node::DirectoryIterator dolIt = root.find("rs5mp2_p.dol"); NOD::Node::DirectoryIterator dolIt = root.find("rs5mp2_p.dol");
if (dolIt == root.end()) if (dolIt == root.end())
return false; return false;
@ -196,7 +197,7 @@ struct SpecMP2 : SpecBase
} }
/* Iterate PAKs and build level options */ /* Iterate PAKs and build level options */
NOD::DiscBase::IPartition::Node::DirectoryIterator mp2It = root.find("MP2"); NOD::Node::DirectoryIterator mp2It = root.find("MP2");
if (mp2It == root.end()) if (mp2It == root.end())
return false; return false;
buildPaks(*mp2It, mp2args, rep); buildPaks(*mp2It, mp2args, rep);
@ -221,7 +222,7 @@ struct SpecMP2 : SpecBase
HECL::SystemStringView nameView(name); HECL::SystemStringView nameView(name);
progress(_S("MP2 Root"), nameView.sys_str().c_str(), 3, prog / (float)m_nonPaks.size()); progress(_S("MP2 Root"), nameView.sys_str().c_str(), 3, prog / (float)m_nonPaks.size());
}; };
for (const NOD::DiscBase::IPartition::Node* node : m_nonPaks) for (const NOD::Node* node : m_nonPaks)
{ {
node->extractToDirectory(m_workPath.getAbsolutePath(), ctx); node->extractToDirectory(m_workPath.getAbsolutePath(), ctx);
prog++; prog++;
@ -255,6 +256,11 @@ struct SpecMP2 : SpecBase
return true; return true;
} }
bool checkPathPrefix(const HECL::ProjectPath& path)
{
return path.getRelativePath().compare(0, 4, "MP2/") == 0;
}
bool validateYAMLDNAType(FILE* fp) const bool validateYAMLDNAType(FILE* fp) const
{ {
if (BigYAML::ValidateFromYAMLFile<DNAMP2::MLVL>(fp)) if (BigYAML::ValidateFromYAMLFile<DNAMP2::MLVL>(fp))
@ -263,6 +269,22 @@ struct SpecMP2 : SpecBase
return true; return true;
return false; return false;
} }
void cookMesh(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const
{
}
void cookActor(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const
{
}
void cookArea(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const
{
}
void cookYAML(FILE* in, const HECL::ProjectPath& out) const
{
}
}; };
HECL::Database::DataSpecEntry SpecEntMP2 HECL::Database::DataSpecEntry SpecEntMP2

View File

@ -24,7 +24,7 @@ struct SpecMP3 : SpecBase
} }
bool doMP3 = false; bool doMP3 = false;
std::vector<const NOD::DiscBase::IPartition::Node*> m_nonPaks; std::vector<const NOD::Node*> m_nonPaks;
std::vector<DNAMP3::PAKBridge> m_paks; std::vector<DNAMP3::PAKBridge> m_paks;
std::map<std::string, DNAMP3::PAKBridge*, CaseInsensitiveCompare> m_orderedPaks; std::map<std::string, DNAMP3::PAKBridge*, CaseInsensitiveCompare> m_orderedPaks;
@ -34,7 +34,7 @@ struct SpecMP3 : SpecBase
/* These are populated when extracting MPT's frontend (uses MP3's DataSpec) */ /* These are populated when extracting MPT's frontend (uses MP3's DataSpec) */
bool doMPTFE = false; bool doMPTFE = false;
std::vector<const NOD::DiscBase::IPartition::Node*> m_feNonPaks; std::vector<const NOD::Node*> m_feNonPaks;
std::vector<DNAMP3::PAKBridge> m_fePaks; std::vector<DNAMP3::PAKBridge> m_fePaks;
std::map<std::string, DNAMP3::PAKBridge*, CaseInsensitiveCompare> m_feOrderedPaks; std::map<std::string, DNAMP3::PAKBridge*, CaseInsensitiveCompare> m_feOrderedPaks;
@ -51,8 +51,8 @@ struct SpecMP3 : SpecBase
m_feCookPath(project.getProjectCookedPath(SpecEntMP3), _S("fe")), m_feCookPath(project.getProjectCookedPath(SpecEntMP3), _S("fe")),
m_fePakRouter(*this, m_feWorkPath, m_feCookPath) {} m_fePakRouter(*this, m_feWorkPath, m_feCookPath) {}
void buildPaks(NOD::DiscBase::IPartition::Node& root, void buildPaks(NOD::Node& root,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
ExtractReport& rep, ExtractReport& rep,
bool fe) bool fe)
{ {
@ -66,7 +66,7 @@ struct SpecMP3 : SpecBase
m_nonPaks.clear(); m_nonPaks.clear();
m_paks.clear(); m_paks.clear();
} }
for (const NOD::DiscBase::IPartition::Node& child : root) for (const NOD::Node& child : root)
{ {
bool isPak = false; bool isPak = false;
const std::string& name = child.getName(); const std::string& name = child.getName();
@ -174,11 +174,11 @@ struct SpecMP3 : SpecBase
bool checkFromStandaloneDisc(NOD::DiscBase& disc, bool checkFromStandaloneDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr, const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
std::list<ExtractReport>& reps) std::vector<ExtractReport>& reps)
{ {
doMP3 = true; doMP3 = true;
NOD::DiscGCN::IPartition* partition = disc.getDataPartition(); NOD::Partition* partition = disc.getDataPartition();
std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf(); std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf();
const char* buildInfo = (char*)memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16) + 19; const char* buildInfo = (char*)memmem(dolBuf.get(), partition->getDOLSize(), "MetroidBuildInfo", 16) + 19;
if (!buildInfo) if (!buildInfo)
@ -198,7 +198,7 @@ struct SpecMP3 : SpecBase
rep.desc += _S(" (") + buildView + _S(")"); rep.desc += _S(" (") + buildView + _S(")");
/* Iterate PAKs and build level options */ /* Iterate PAKs and build level options */
NOD::DiscBase::IPartition::Node& root = partition->getFSTRoot(); NOD::Node& root = partition->getFSTRoot();
buildPaks(root, args, rep, false); buildPaks(root, args, rep, false);
return true; return true;
@ -206,11 +206,11 @@ struct SpecMP3 : SpecBase
bool checkFromTrilogyDisc(NOD::DiscBase& disc, bool checkFromTrilogyDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr, const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args, const std::vector<HECL::SystemString>& args,
std::list<ExtractReport>& reps) std::vector<ExtractReport>& reps)
{ {
std::list<HECL::SystemString> mp3args; std::vector<HECL::SystemString> mp3args;
std::list<HECL::SystemString> feargs; std::vector<HECL::SystemString> feargs;
if (args.size()) if (args.size())
{ {
/* Needs filter */ /* Needs filter */
@ -221,6 +221,7 @@ struct SpecMP3 : SpecBase
if (!lowerArg.compare(0, 3, _S("mp3"))) if (!lowerArg.compare(0, 3, _S("mp3")))
{ {
doMP3 = true; doMP3 = true;
mp3args.reserve(args.size());
size_t slashPos = arg.find(_S('/')); size_t slashPos = arg.find(_S('/'));
if (slashPos == HECL::SystemString::npos) if (slashPos == HECL::SystemString::npos)
slashPos = arg.find(_S('\\')); slashPos = arg.find(_S('\\'));
@ -236,6 +237,7 @@ struct SpecMP3 : SpecBase
if (!lowerArg.compare(0, 2, _S("fe"))) if (!lowerArg.compare(0, 2, _S("fe")))
{ {
doMPTFE = true; doMPTFE = true;
feargs.reserve(args.size());
size_t slashPos = arg.find(_S('/')); size_t slashPos = arg.find(_S('/'));
if (slashPos == HECL::SystemString::npos) if (slashPos == HECL::SystemString::npos)
slashPos = arg.find(_S('\\')); slashPos = arg.find(_S('\\'));
@ -253,13 +255,13 @@ struct SpecMP3 : SpecBase
if (!doMP3 && !doMPTFE) if (!doMP3 && !doMPTFE)
return false; return false;
NOD::DiscGCN::IPartition* partition = disc.getDataPartition(); NOD::Partition* partition = disc.getDataPartition();
NOD::DiscBase::IPartition::Node& root = partition->getFSTRoot(); NOD::Node& root = partition->getFSTRoot();
/* MP3 extract */ /* MP3 extract */
if (doMP3) if (doMP3)
{ {
NOD::DiscBase::IPartition::Node::DirectoryIterator dolIt = root.find("rs5mp3_p.dol"); NOD::Node::DirectoryIterator dolIt = root.find("rs5mp3_p.dol");
if (dolIt == root.end()) if (dolIt == root.end())
return false; return false;
@ -285,7 +287,7 @@ struct SpecMP3 : SpecBase
/* Iterate PAKs and build level options */ /* Iterate PAKs and build level options */
NOD::DiscBase::IPartition::Node::DirectoryIterator mp3It = root.find("MP3"); NOD::Node::DirectoryIterator mp3It = root.find("MP3");
if (mp3It == root.end()) if (mp3It == root.end())
return false; return false;
buildPaks(*mp3It, mp3args, rep, false); buildPaks(*mp3It, mp3args, rep, false);
@ -294,7 +296,7 @@ struct SpecMP3 : SpecBase
/* MPT Frontend extract */ /* MPT Frontend extract */
if (doMPTFE) if (doMPTFE)
{ {
NOD::DiscBase::IPartition::Node::DirectoryIterator dolIt = root.find("rs5fe_p.dol"); NOD::Node::DirectoryIterator dolIt = root.find("rs5fe_p.dol");
if (dolIt == root.end()) if (dolIt == root.end())
return false; return false;
@ -314,7 +316,7 @@ struct SpecMP3 : SpecBase
} }
/* Iterate PAKs and build level options */ /* Iterate PAKs and build level options */
NOD::DiscBase::IPartition::Node::DirectoryIterator feIt = root.find("fe"); NOD::Node::DirectoryIterator feIt = root.find("fe");
if (feIt == root.end()) if (feIt == root.end())
return false; return false;
buildPaks(*feIt, feargs, rep, true); buildPaks(*feIt, feargs, rep, true);
@ -352,7 +354,7 @@ struct SpecMP3 : SpecBase
nodeCount = m_nonPaks.size(); nodeCount = m_nonPaks.size();
// TODO: Make this more granular // TODO: Make this more granular
for (const NOD::DiscBase::IPartition::Node* node : m_nonPaks) for (const NOD::Node* node : m_nonPaks)
{ {
node->extractToDirectory(mp3WorkPath.getAbsolutePath(), ctx); node->extractToDirectory(mp3WorkPath.getAbsolutePath(), ctx);
prog++; prog++;
@ -402,7 +404,7 @@ struct SpecMP3 : SpecBase
nodeCount = m_feNonPaks.size(); nodeCount = m_feNonPaks.size();
// TODO: Make this more granular // TODO: Make this more granular
for (const NOD::DiscBase::IPartition::Node* node : m_feNonPaks) for (const NOD::Node* node : m_feNonPaks)
{ {
node->extractToDirectory(m_feWorkPath.getAbsolutePath(), ctx); node->extractToDirectory(m_feWorkPath.getAbsolutePath(), ctx);
prog++; prog++;
@ -435,6 +437,11 @@ struct SpecMP3 : SpecBase
return true; return true;
} }
bool checkPathPrefix(const HECL::ProjectPath& path)
{
return path.getRelativePath().compare(0, 4, "MP3/") == 0;
}
bool validateYAMLDNAType(FILE* fp) const bool validateYAMLDNAType(FILE* fp) const
{ {
if (BigYAML::ValidateFromYAMLFile<DNAMP3::MLVL>(fp)) if (BigYAML::ValidateFromYAMLFile<DNAMP3::MLVL>(fp))
@ -445,6 +452,22 @@ struct SpecMP3 : SpecBase
return true; return true;
return false; return false;
} }
void cookMesh(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const
{
}
void cookActor(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const
{
}
void cookArea(const HECL::ProjectPath& in, BlendStream& ds, const HECL::ProjectPath& out) const
{
}
void cookYAML(FILE* in, const HECL::ProjectPath& out) const
{
}
}; };
HECL::Database::DataSpecEntry SpecEntMP3 HECL::Database::DataSpecEntry SpecEntMP3

2
NODLib

@ -1 +1 @@
Subproject commit dc9dcdcd7930328b87d4cc495e97e6475895a2f1 Subproject commit 322d1c48cdd2132fc9d5ffa0d1ca79469453b6df

2
hecl

@ -1 +1 @@
Subproject commit e8544adf496c1aeb2b9be212fa34cfc295e807a8 Subproject commit dd557bb7c5a3a409988d1b24d81ddd1f66791701