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);
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);
if (cmdlE)
{

View File

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

View File

@ -151,7 +151,7 @@ void ReadMaterialSetToBlender_1_2(HECL::BlenderConnection::PyOutStream& os,
for (const UniqueID32& tex : matSet.head.textureIDs)
{
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);
HECL::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (txtrPath.getPathType() == HECL::ProjectPath::PT_NONE)

View File

@ -246,7 +246,7 @@ private:
HECL::ProjectPath m_sharedWorking;
HECL::ProjectPath m_sharedCooked;
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_sharedEntries;
std::unordered_map<IDType, RigPair> m_cmdlRigs;
@ -549,7 +549,7 @@ public:
}
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
{
if (!m_bridges)
@ -586,7 +586,7 @@ public:
template <typename DNA>
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);
if (!entry)
return false;

View File

@ -26,7 +26,7 @@ static bool GetNoShare(const std::string& name)
}
PAKBridge::PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node,
const NOD::Node& node,
bool 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
{
HECL::Database::Project& m_project;
const NOD::DiscBase::IPartition::Node& m_node;
const NOD::Node& m_node;
PAK m_pak;
public:
bool m_doExtract;
@ -24,7 +24,7 @@ public:
HECL::SystemString m_levelString;
PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node,
const NOD::Node& node,
bool doExtract=true);
void build();
static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry);
@ -32,7 +32,7 @@ public:
const HECL::SystemString& getLevelString() const {return m_levelString;}
using PAKType = 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;
};

View File

@ -73,7 +73,7 @@ void PAK::write(Athena::io::IStreamWriter& writer) const
}
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)
{

View File

@ -37,8 +37,8 @@ struct PAK : BigDNA
Value<atUint32> offset;
UniqueResult unique;
std::unique_ptr<atUint8[]> getBuffer(const NOD::DiscBase::IPartition::Node& pak, atUint64& szOut) const;
inline PAKEntryReadStream beginReadStream(const NOD::DiscBase::IPartition::Node& pak, atUint64 off=0) const
std::unique_ptr<atUint8[]> getBuffer(const NOD::Node& pak, atUint64& szOut) const;
inline PAKEntryReadStream beginReadStream(const NOD::Node& pak, atUint64 off=0) const
{
atUint64 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,
const NOD::DiscBase::IPartition::Node& node,
const NOD::Node& node,
bool 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
{
HECL::Database::Project& m_project;
const NOD::DiscBase::IPartition::Node& m_node;
const NOD::Node& m_node;
DNAMP1::PAK m_pak;
public:
bool m_doExtract;
@ -24,7 +24,7 @@ public:
HECL::SystemString m_levelString;
PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node,
const NOD::Node& node,
bool doExtract=true);
void build();
static ResExtractor<PAKBridge> LookupExtractor(const DNAMP1::PAK::Entry& entry);
@ -33,7 +33,7 @@ public:
using PAKType = DNAMP1::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;
};

View File

@ -116,7 +116,7 @@ void Material::SectionPASS::constructNode(HECL::BlenderConnection::PyOutStream&
if (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);
HECL::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
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,
const NOD::DiscBase::IPartition::Node& node,
const NOD::Node& node,
bool 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
{
HECL::Database::Project& m_project;
const NOD::DiscBase::IPartition::Node& m_node;
const NOD::Node& m_node;
PAK m_pak;
public:
bool m_doExtract;
@ -24,7 +24,7 @@ public:
HECL::SystemString m_levelString;
PAKBridge(HECL::Database::Project& project,
const NOD::DiscBase::IPartition::Node& node,
const NOD::Node& node,
bool doExtract=true);
void build();
static ResExtractor<PAKBridge> LookupExtractor(const PAK::Entry& entry);
@ -33,7 +33,7 @@ public:
using PAKType = 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;
};

View File

@ -98,7 +98,7 @@ void PAK::write(Athena::io::IStreamWriter& writer) const
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)
{

View File

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

View File

@ -7,7 +7,7 @@ namespace Retro
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);
if (!m_disc)
@ -54,7 +54,7 @@ void SpecBase::doExtract(const ExtractPassInfo& info, FProgress progress)
{
/* Extract update partition for repacking later */
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};
if (update)
@ -75,10 +75,10 @@ void SpecBase::doExtract(const ExtractPassInfo& info, FProgress progress)
if (!m_standalone)
{
progress(_S("Trilogy Files"), _S(""), 1, 0.0);
NOD::DiscBase::IPartition* data = m_disc->getDataPartition();
const NOD::DiscBase::IPartition::Node& root = data->getFSTRoot();
for (const NOD::DiscBase::IPartition::Node& child : root)
if (child.getKind() == NOD::DiscBase::IPartition::Node::NODE_FILE)
NOD::Partition* data = m_disc->getDataPartition();
const NOD::Node& root = data->getFSTRoot();
for (const NOD::Node& child : root)
if (child.getKind() == NOD::Node::NODE_FILE)
child.extractToDirectory(target, ctx);
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)
{
if (!checkPathPrefix(path))
return false;
if (HECL::IsPathBlend(path))
{
HECL::BlenderConnection& conn = HECL::BlenderConnection::SharedConnection();
@ -110,8 +112,22 @@ bool SpecBase::canCook(const HECL::ProjectPath& path)
return false;
}
using Mesh = HECL::BlenderConnection::DataStream::Mesh;
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)

View File

@ -5,13 +5,15 @@
#include <HECL/Database.hpp>
#include <NOD/NOD.hpp>
#include "BlenderConnection.hpp"
namespace Retro
{
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);
bool canCook(const HECL::ProjectPath& path);
@ -22,20 +24,33 @@ struct SpecBase : HECL::Database::IDataSpec
std::unordered_set<HECL::ProjectPath>& implicitsOut);
void doPackage(const PackagePassInfo& info);
/* Extract handlers */
virtual bool checkStandaloneID(const char* id) const=0;
virtual bool checkFromStandaloneDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args,
std::list<ExtractReport>& reps)=0;
const std::vector<HECL::SystemString>& args,
std::vector<ExtractReport>& reps)=0;
virtual bool checkFromTrilogyDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args,
std::list<ExtractReport>& reps)=0;
const std::vector<HECL::SystemString>& args,
std::vector<ExtractReport>& reps)=0;
virtual bool extractFromDisc(NOD::DiscBase& disc, bool force,
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;
/* 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;}
SpecBase(HECL::Database::Project& project)

View File

@ -23,7 +23,7 @@ struct SpecMP1 : SpecBase
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::map<std::string, DNAMP1::PAKBridge*, CaseInsensitiveCompare> m_orderedPaks;
@ -37,13 +37,13 @@ struct SpecMP1 : SpecBase
m_cookPath(project.getProjectCookedPath(SpecEntMP1), _S("MP1")),
m_pakRouter(*this, m_workPath, m_cookPath) {}
void buildPaks(NOD::DiscBase::IPartition::Node& root,
const std::list<HECL::SystemString>& args,
void buildPaks(NOD::Node& root,
const std::vector<HECL::SystemString>& args,
ExtractReport& rep)
{
m_nonPaks.clear();
m_paks.clear();
for (const NOD::DiscBase::IPartition::Node& child : root)
for (const NOD::Node& child : root)
{
bool isPak = false;
const std::string& name = child.getName();
@ -107,6 +107,7 @@ struct SpecMP1 : SpecBase
m_orderedPaks[dpak.getName()] = &dpak;
/* Assemble extract report */
rep.childOpts.reserve(m_orderedPaks.size());
for (const std::pair<std::string, DNAMP1::PAKBridge*>& item : m_orderedPaks)
{
if (!item.second->m_doExtract)
@ -121,10 +122,10 @@ struct SpecMP1 : SpecBase
bool checkFromStandaloneDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args,
std::list<ExtractReport>& reps)
const std::vector<HECL::SystemString>& args,
std::vector<ExtractReport>& reps)
{
NOD::DiscGCN::IPartition* partition = disc.getDataPartition();
NOD::Partition* partition = disc.getDataPartition();
std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf();
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 */
NOD::DiscBase::IPartition::Node& root = partition->getFSTRoot();
NOD::Node& root = partition->getFSTRoot();
buildPaks(root, args, rep);
return true;
@ -152,10 +153,10 @@ struct SpecMP1 : SpecBase
bool checkFromTrilogyDisc(NOD::DiscBase& disc,
const HECL::SystemString& regstr,
const std::list<HECL::SystemString>& args,
std::list<ExtractReport>& reps)
const std::vector<HECL::SystemString>& args,
std::vector<ExtractReport>& reps)
{
std::list<HECL::SystemString> mp1args;
std::vector<HECL::SystemString> mp1args;
bool doExtract = false;
if (args.size())
{
@ -167,6 +168,7 @@ struct SpecMP1 : SpecBase
if (!lowerArg.compare(0, 3, _S("mp1")))
{
doExtract = true;
mp1args.reserve(args.size());
size_t slashPos = arg.find(_S('/'));
if (slashPos == HECL::SystemString::npos)
slashPos = arg.find(_S('\\'));
@ -181,9 +183,9 @@ struct SpecMP1 : SpecBase
if (!doExtract)
return false;
NOD::DiscGCN::IPartition* partition = disc.getDataPartition();
NOD::DiscBase::IPartition::Node& root = partition->getFSTRoot();
NOD::DiscBase::IPartition::Node::DirectoryIterator dolIt = root.find("rs5mp1_p.dol");
NOD::Partition* partition = disc.getDataPartition();
NOD::Node& root = partition->getFSTRoot();
NOD::Node::DirectoryIterator dolIt = root.find("rs5mp1_p.dol");
if (dolIt == root.end())
return false;
@ -203,7 +205,7 @@ struct SpecMP1 : SpecBase
}
/* 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())
return false;
buildPaks(*mp1It, mp1args, rep);
@ -229,7 +231,7 @@ struct SpecMP1 : SpecBase
HECL::SystemStringView nameView(name);
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);
prog++;
@ -263,6 +265,11 @@ struct SpecMP1 : SpecBase
return true;
}
bool checkPathPrefix(const HECL::ProjectPath& path)
{
return path.getRelativePath().compare(0, 4, "MP1/") == 0;
}
bool validateYAMLDNAType(FILE* fp) const
{
if (BigYAML::ValidateFromYAMLFile<DNAMP1::MLVL>(fp))
@ -271,6 +278,22 @@ struct SpecMP1 : SpecBase
return true;
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 =

View File

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

View File

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

2
NODLib

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

2
hecl

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