mirror of https://github.com/AxioDL/metaforce.git
Initial cook tool integration
This commit is contained in:
parent
43ddaa0dc4
commit
0d2f2cfd34
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
2
NODLib
|
@ -1 +1 @@
|
||||||
Subproject commit dc9dcdcd7930328b87d4cc495e97e6475895a2f1
|
Subproject commit 322d1c48cdd2132fc9d5ffa0d1ca79469453b6df
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit e8544adf496c1aeb2b9be212fa34cfc295e807a8
|
Subproject commit dd557bb7c5a3a409988d1b24d81ddd1f66791701
|
Loading…
Reference in New Issue