mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-09 19:07:44 +00:00
New code style refactor
This commit is contained in:
@@ -47,419 +47,373 @@
|
||||
#include "MazeSeeds.hpp"
|
||||
#include "SnowForces.hpp"
|
||||
|
||||
namespace DataSpec::DNAMP1
|
||||
{
|
||||
namespace DataSpec::DNAMP1 {
|
||||
logvisor::Module Log("urde::DNAMP1");
|
||||
|
||||
static bool GetNoShare(std::string_view name)
|
||||
{
|
||||
std::string lowerName(name);
|
||||
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
|
||||
if (!lowerName.compare(0, 7, "metroid"))
|
||||
return false;
|
||||
return true;
|
||||
static bool GetNoShare(std::string_view name) {
|
||||
std::string lowerName(name);
|
||||
std::transform(lowerName.begin(), lowerName.end(), lowerName.begin(), tolower);
|
||||
if (!lowerName.compare(0, 7, "metroid"))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
PAKBridge::PAKBridge(const nod::Node& node, bool doExtract)
|
||||
: m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract)
|
||||
{
|
||||
nod::AthenaPartReadStream rs(node.beginReadStream());
|
||||
m_pak.read(rs);
|
||||
: m_node(node), m_pak(false, GetNoShare(node.getName())), m_doExtract(doExtract) {
|
||||
nod::AthenaPartReadStream rs(node.beginReadStream());
|
||||
m_pak.read(rs);
|
||||
|
||||
/* Append Level String */
|
||||
for (auto& ent : m_pak.m_entries)
|
||||
{
|
||||
PAK::Entry& entry = ent.second;
|
||||
if (entry.type == FOURCC('MLVL'))
|
||||
{
|
||||
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
||||
MLVL mlvl;
|
||||
mlvl.read(rs);
|
||||
PAK::Entry* nameEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldNameId);
|
||||
if (nameEnt)
|
||||
{
|
||||
nameEnt->name = entry.name + "_name";
|
||||
PAKEntryReadStream rs = nameEnt->beginReadStream(m_node);
|
||||
STRG mlvlName;
|
||||
mlvlName.read(rs);
|
||||
if (m_levelString.size())
|
||||
m_levelString += _SYS_STR(", ");
|
||||
m_levelString += mlvlName.getSystemString(FOURCC('ENGL'), 0);
|
||||
}
|
||||
}
|
||||
/* Append Level String */
|
||||
for (auto& ent : m_pak.m_entries) {
|
||||
PAK::Entry& entry = ent.second;
|
||||
if (entry.type == FOURCC('MLVL')) {
|
||||
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
||||
MLVL mlvl;
|
||||
mlvl.read(rs);
|
||||
PAK::Entry* nameEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldNameId);
|
||||
if (nameEnt) {
|
||||
nameEnt->name = entry.name + "_name";
|
||||
PAKEntryReadStream rs = nameEnt->beginReadStream(m_node);
|
||||
STRG mlvlName;
|
||||
mlvlName.read(rs);
|
||||
if (m_levelString.size())
|
||||
m_levelString += _SYS_STR(", ");
|
||||
m_levelString += mlvlName.getSystemString(FOURCC('ENGL'), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static hecl::SystemString LayerName(std::string_view name)
|
||||
{
|
||||
hecl::SystemString ret(hecl::SystemStringConv(name).sys_str());
|
||||
for (auto& ch : ret)
|
||||
if (ch == _SYS_STR('/') || ch == _SYS_STR('\\'))
|
||||
ch = _SYS_STR('-');
|
||||
return ret;
|
||||
static hecl::SystemString LayerName(std::string_view name) {
|
||||
hecl::SystemString ret(hecl::SystemStringConv(name).sys_str());
|
||||
for (auto& ch : ret)
|
||||
if (ch == _SYS_STR('/') || ch == _SYS_STR('\\'))
|
||||
ch = _SYS_STR('-');
|
||||
return ret;
|
||||
}
|
||||
|
||||
void PAKBridge::build()
|
||||
{
|
||||
/* First pass: build per-area/per-layer dependency map */
|
||||
for (const auto& ent : m_pak.m_entries)
|
||||
{
|
||||
const PAK::Entry& entry = ent.second;
|
||||
if (entry.type == FOURCC('MLVL'))
|
||||
{
|
||||
Level& level = m_levelDeps[entry.id];
|
||||
void PAKBridge::build() {
|
||||
/* First pass: build per-area/per-layer dependency map */
|
||||
for (const auto& ent : m_pak.m_entries) {
|
||||
const PAK::Entry& entry = ent.second;
|
||||
if (entry.type == FOURCC('MLVL')) {
|
||||
Level& level = m_levelDeps[entry.id];
|
||||
|
||||
MLVL mlvl;
|
||||
{
|
||||
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
||||
mlvl.read(rs);
|
||||
}
|
||||
bool named;
|
||||
std::string bestName = m_pak.bestEntryName(m_node, entry, named);
|
||||
level.name = hecl::SystemStringConv(bestName).sys_str();
|
||||
level.areas.reserve(mlvl.areaCount);
|
||||
unsigned layerIdx = 0;
|
||||
MLVL mlvl;
|
||||
{
|
||||
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
||||
mlvl.read(rs);
|
||||
}
|
||||
bool named;
|
||||
std::string bestName = m_pak.bestEntryName(m_node, entry, named);
|
||||
level.name = hecl::SystemStringConv(bestName).sys_str();
|
||||
level.areas.reserve(mlvl.areaCount);
|
||||
unsigned layerIdx = 0;
|
||||
|
||||
/* Make MAPW available to lookup MAPAs */
|
||||
PAK::Entry* worldMapEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldMap);
|
||||
std::vector<UniqueID32> mapw;
|
||||
if (worldMapEnt)
|
||||
{
|
||||
worldMapEnt->name = entry.name + "_mapw";
|
||||
PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node);
|
||||
rs.seek(8, athena::Current);
|
||||
atUint32 areaCount = rs.readUint32Big();
|
||||
mapw.reserve(areaCount);
|
||||
for (atUint32 i=0 ; i<areaCount ; ++i)
|
||||
mapw.emplace_back(rs);
|
||||
}
|
||||
/* Make MAPW available to lookup MAPAs */
|
||||
PAK::Entry* worldMapEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldMap);
|
||||
std::vector<UniqueID32> mapw;
|
||||
if (worldMapEnt) {
|
||||
worldMapEnt->name = entry.name + "_mapw";
|
||||
PAKEntryReadStream rs = worldMapEnt->beginReadStream(m_node);
|
||||
rs.seek(8, athena::Current);
|
||||
atUint32 areaCount = rs.readUint32Big();
|
||||
mapw.reserve(areaCount);
|
||||
for (atUint32 i = 0; i < areaCount; ++i)
|
||||
mapw.emplace_back(rs);
|
||||
}
|
||||
|
||||
PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId);
|
||||
if (savwEnt)
|
||||
savwEnt->name = entry.name + "_savw";
|
||||
PAK::Entry* savwEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.saveWorldId);
|
||||
if (savwEnt)
|
||||
savwEnt->name = entry.name + "_savw";
|
||||
|
||||
PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId);
|
||||
if (skyEnt)
|
||||
skyEnt->name = entry.name + "_skybox";
|
||||
PAK::Entry* skyEnt = (PAK::Entry*)m_pak.lookupEntry(mlvl.worldSkyboxId);
|
||||
if (skyEnt)
|
||||
skyEnt->name = entry.name + "_skybox";
|
||||
|
||||
/* Index areas */
|
||||
unsigned ai = 0;
|
||||
for (const MLVL::Area& area : mlvl.areas)
|
||||
{
|
||||
Level::Area& areaDeps = level.areas[area.areaMREAId];
|
||||
MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai];
|
||||
PAK::Entry* areaNameEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaNameId);
|
||||
if (areaNameEnt)
|
||||
{
|
||||
STRG areaName;
|
||||
{
|
||||
PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node);
|
||||
areaName.read(rs);
|
||||
}
|
||||
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
|
||||
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
|
||||
}
|
||||
if (areaDeps.name.empty())
|
||||
{
|
||||
std::string idStr = area.areaMREAId.toString();
|
||||
areaDeps.name = hecl::SystemString(_SYS_STR("MREA_")) + hecl::SystemStringConv(idStr).c_str();
|
||||
}
|
||||
hecl::SystemChar num[16];
|
||||
hecl::SNPrintf(num, 16, _SYS_STR("%02u "), ai);
|
||||
areaDeps.name = num + areaDeps.name;
|
||||
|
||||
std::string lowerName(hecl::SystemUTF8Conv(areaDeps.name).str());
|
||||
for (char& ch : lowerName)
|
||||
{
|
||||
ch = tolower(ch);
|
||||
if (ch == ' ')
|
||||
ch = '_';
|
||||
}
|
||||
if (areaNameEnt)
|
||||
areaNameEnt->name = lowerName + "_name";
|
||||
PAK::Entry* areaEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaMREAId);
|
||||
if (areaEnt)
|
||||
areaEnt->name = lowerName;
|
||||
|
||||
areaDeps.layers.reserve(area.depLayerCount-1);
|
||||
unsigned r=0;
|
||||
for (unsigned l=1 ; l<area.depLayerCount ; ++l)
|
||||
{
|
||||
areaDeps.layers.emplace_back();
|
||||
Level::Area::Layer& layer = areaDeps.layers.back();
|
||||
layer.name = LayerName(mlvl.layerNames[layerIdx++]);
|
||||
layer.active = layerFlags.flags >> (l-1) & 0x1;
|
||||
layer.name = hecl::StringUtils::TrimWhitespace(layer.name);
|
||||
|
||||
hecl::SNPrintf(num, 16, _SYS_STR("%02u "), l-1);
|
||||
layer.name = num + layer.name;
|
||||
|
||||
layer.resources.reserve(area.depLayers[l] - r);
|
||||
for (; r<area.depLayers[l] ; ++r)
|
||||
layer.resources.emplace(area.deps[r].id);
|
||||
}
|
||||
areaDeps.resources.reserve(area.depCount - r + 2);
|
||||
for (; r<area.depCount ; ++r)
|
||||
areaDeps.resources.emplace(area.deps[r].id);
|
||||
areaDeps.resources.emplace(area.areaMREAId);
|
||||
if (mapw.size() > ai)
|
||||
areaDeps.resources.emplace(mapw[ai]);
|
||||
++ai;
|
||||
}
|
||||
/* Index areas */
|
||||
unsigned ai = 0;
|
||||
for (const MLVL::Area& area : mlvl.areas) {
|
||||
Level::Area& areaDeps = level.areas[area.areaMREAId];
|
||||
MLVL::LayerFlags& layerFlags = mlvl.layerFlags[ai];
|
||||
PAK::Entry* areaNameEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaNameId);
|
||||
if (areaNameEnt) {
|
||||
STRG areaName;
|
||||
{
|
||||
PAKEntryReadStream rs = areaNameEnt->beginReadStream(m_node);
|
||||
areaName.read(rs);
|
||||
}
|
||||
areaDeps.name = areaName.getSystemString(FOURCC('ENGL'), 0);
|
||||
areaDeps.name = hecl::StringUtils::TrimWhitespace(areaDeps.name);
|
||||
}
|
||||
}
|
||||
if (areaDeps.name.empty()) {
|
||||
std::string idStr = area.areaMREAId.toString();
|
||||
areaDeps.name = hecl::SystemString(_SYS_STR("MREA_")) + hecl::SystemStringConv(idStr).c_str();
|
||||
}
|
||||
hecl::SystemChar num[16];
|
||||
hecl::SNPrintf(num, 16, _SYS_STR("%02u "), ai);
|
||||
areaDeps.name = num + areaDeps.name;
|
||||
|
||||
/* Second pass: cross-compare uniqueness */
|
||||
for (auto& entry : m_pak.m_entries)
|
||||
{
|
||||
entry.second.unique.checkEntry(*this, entry.second);
|
||||
std::string lowerName(hecl::SystemUTF8Conv(areaDeps.name).str());
|
||||
for (char& ch : lowerName) {
|
||||
ch = tolower(ch);
|
||||
if (ch == ' ')
|
||||
ch = '_';
|
||||
}
|
||||
if (areaNameEnt)
|
||||
areaNameEnt->name = lowerName + "_name";
|
||||
PAK::Entry* areaEnt = (PAK::Entry*)m_pak.lookupEntry(area.areaMREAId);
|
||||
if (areaEnt)
|
||||
areaEnt->name = lowerName;
|
||||
|
||||
areaDeps.layers.reserve(area.depLayerCount - 1);
|
||||
unsigned r = 0;
|
||||
for (unsigned l = 1; l < area.depLayerCount; ++l) {
|
||||
areaDeps.layers.emplace_back();
|
||||
Level::Area::Layer& layer = areaDeps.layers.back();
|
||||
layer.name = LayerName(mlvl.layerNames[layerIdx++]);
|
||||
layer.active = layerFlags.flags >> (l - 1) & 0x1;
|
||||
layer.name = hecl::StringUtils::TrimWhitespace(layer.name);
|
||||
|
||||
hecl::SNPrintf(num, 16, _SYS_STR("%02u "), l - 1);
|
||||
layer.name = num + layer.name;
|
||||
|
||||
layer.resources.reserve(area.depLayers[l] - r);
|
||||
for (; r < area.depLayers[l]; ++r)
|
||||
layer.resources.emplace(area.deps[r].id);
|
||||
}
|
||||
areaDeps.resources.reserve(area.depCount - r + 2);
|
||||
for (; r < area.depCount; ++r)
|
||||
areaDeps.resources.emplace(area.deps[r].id);
|
||||
areaDeps.resources.emplace(area.areaMREAId);
|
||||
if (mapw.size() > ai)
|
||||
areaDeps.resources.emplace(mapw[ai]);
|
||||
++ai;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Second pass: cross-compare uniqueness */
|
||||
for (auto& entry : m_pak.m_entries) {
|
||||
entry.second.unique.checkEntry(*this, entry.second);
|
||||
}
|
||||
}
|
||||
|
||||
void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const
|
||||
{
|
||||
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries)
|
||||
{
|
||||
if (entry.second.type == FOURCC('ANCS'))
|
||||
{
|
||||
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||
ANCS ancs;
|
||||
ancs.read(rs);
|
||||
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
|
||||
{
|
||||
charAssoc.m_cmdlRigs[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
|
||||
charAssoc.m_cskrCinfToCharacter[ci.cskr] =
|
||||
std::make_pair(entry.second.id, hecl::Format("%s.CSKR", ci.name.c_str()));
|
||||
charAssoc.m_cskrCinfToCharacter[ci.cinf] =
|
||||
std::make_pair(entry.second.id, hecl::Format("CINF_%08X.CINF", ci.cinf.toUint32()));
|
||||
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl);
|
||||
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr);
|
||||
PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf);
|
||||
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_model", entry.first.toUint32(), ci.name.c_str());
|
||||
cskrEnt->name = hecl::Format("ANCS_%08X_%s_skin", entry.first.toUint32(), ci.name.c_str());
|
||||
cinfEnt->name = hecl::Format("ANCS_%08X_%s_skel", entry.first.toUint32(), ci.name.c_str());
|
||||
if (ci.cmdlIce && ci.cskrIce)
|
||||
{
|
||||
charAssoc.m_cmdlRigs[ci.cmdlIce] = std::make_pair(ci.cskrIce, ci.cinf);
|
||||
charAssoc.m_cskrCinfToCharacter[ci.cskrIce] =
|
||||
std::make_pair(entry.second.id, hecl::Format("%s.ICE.CSKR", ci.name.c_str()));
|
||||
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlIce);
|
||||
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrIce);
|
||||
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_icemodel", entry.first.toUint32(), ci.name.c_str());
|
||||
cskrEnt->name = hecl::Format("ANCS_%08X_%s_iceskin", entry.first.toUint32(), ci.name.c_str());
|
||||
}
|
||||
}
|
||||
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animInfo;
|
||||
ancs.getAnimationResInfo(&pakRouter, animInfo);
|
||||
for (auto& ae : animInfo)
|
||||
{
|
||||
PAK::Entry* animEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.animId);
|
||||
animEnt->name = hecl::Format("ANCS_%08X_%s", entry.first.toUint32(), ae.second.name.c_str());
|
||||
charAssoc.m_cskrCinfToCharacter[ae.second.animId] =
|
||||
std::make_pair(entry.second.id, hecl::Format("%s.ANIM", ae.second.name.c_str()));
|
||||
if (ae.second.evntId)
|
||||
{
|
||||
PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.evntId);
|
||||
evntEnt->name = hecl::Format("ANCS_%08X_%s_evnt", entry.first.toUint32(), ae.second.name.c_str());
|
||||
charAssoc.m_cskrCinfToCharacter[ae.second.evntId] =
|
||||
std::make_pair(entry.second.id, hecl::Format("%s.evnt.yaml", ae.second.name.c_str()));
|
||||
}
|
||||
}
|
||||
void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
|
||||
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) {
|
||||
if (entry.second.type == FOURCC('ANCS')) {
|
||||
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||
ANCS ancs;
|
||||
ancs.read(rs);
|
||||
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters) {
|
||||
charAssoc.m_cmdlRigs[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
|
||||
charAssoc.m_cskrCinfToCharacter[ci.cskr] =
|
||||
std::make_pair(entry.second.id, hecl::Format("%s.CSKR", ci.name.c_str()));
|
||||
charAssoc.m_cskrCinfToCharacter[ci.cinf] =
|
||||
std::make_pair(entry.second.id, hecl::Format("CINF_%08X.CINF", ci.cinf.toUint32()));
|
||||
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl);
|
||||
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr);
|
||||
PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf);
|
||||
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_model", entry.first.toUint32(), ci.name.c_str());
|
||||
cskrEnt->name = hecl::Format("ANCS_%08X_%s_skin", entry.first.toUint32(), ci.name.c_str());
|
||||
cinfEnt->name = hecl::Format("ANCS_%08X_%s_skel", entry.first.toUint32(), ci.name.c_str());
|
||||
if (ci.cmdlIce && ci.cskrIce) {
|
||||
charAssoc.m_cmdlRigs[ci.cmdlIce] = std::make_pair(ci.cskrIce, ci.cinf);
|
||||
charAssoc.m_cskrCinfToCharacter[ci.cskrIce] =
|
||||
std::make_pair(entry.second.id, hecl::Format("%s.ICE.CSKR", ci.name.c_str()));
|
||||
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlIce);
|
||||
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrIce);
|
||||
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_icemodel", entry.first.toUint32(), ci.name.c_str());
|
||||
cskrEnt->name = hecl::Format("ANCS_%08X_%s_iceskin", entry.first.toUint32(), ci.name.c_str());
|
||||
}
|
||||
else if (entry.second.type == FOURCC('MREA'))
|
||||
{
|
||||
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||
MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc);
|
||||
}
|
||||
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animInfo;
|
||||
ancs.getAnimationResInfo(&pakRouter, animInfo);
|
||||
for (auto& ae : animInfo) {
|
||||
PAK::Entry* animEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.animId);
|
||||
animEnt->name = hecl::Format("ANCS_%08X_%s", entry.first.toUint32(), ae.second.name.c_str());
|
||||
charAssoc.m_cskrCinfToCharacter[ae.second.animId] =
|
||||
std::make_pair(entry.second.id, hecl::Format("%s.ANIM", ae.second.name.c_str()));
|
||||
if (ae.second.evntId) {
|
||||
PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(ae.second.evntId);
|
||||
evntEnt->name = hecl::Format("ANCS_%08X_%s_evnt", entry.first.toUint32(), ae.second.name.c_str());
|
||||
charAssoc.m_cskrCinfToCharacter[ae.second.evntId] =
|
||||
std::make_pair(entry.second.id, hecl::Format("%s.evnt.yaml", ae.second.name.c_str()));
|
||||
}
|
||||
}
|
||||
} else if (entry.second.type == FOURCC('MREA')) {
|
||||
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||
MREA::AddCMDLRigPairs(rs, pakRouter, charAssoc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PAKBridge::addPATHToMREA(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const
|
||||
{
|
||||
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries)
|
||||
{
|
||||
if (entry.second.type == FOURCC('MREA'))
|
||||
{
|
||||
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||
UniqueID32 pathID = MREA::GetPATHId(rs);
|
||||
if (pathID)
|
||||
pathToMrea[pathID] = entry.first;
|
||||
}
|
||||
std::unordered_map<UniqueID32, UniqueID32>& pathToMrea) const {
|
||||
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) {
|
||||
if (entry.second.type == FOURCC('MREA')) {
|
||||
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||
UniqueID32 pathID = MREA::GetPATHId(rs);
|
||||
if (pathID)
|
||||
pathToMrea[pathID] = entry.first;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const atVec4f BottomRow = {{0.f, 0.f, 0.f, 1.f}};
|
||||
|
||||
void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
||||
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
|
||||
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const
|
||||
{
|
||||
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries)
|
||||
{
|
||||
if (entry.second.type == FOURCC('MLVL'))
|
||||
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
|
||||
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const {
|
||||
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries) {
|
||||
if (entry.second.type == FOURCC('MLVL')) {
|
||||
MLVL mlvl;
|
||||
{
|
||||
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||
mlvl.read(rs);
|
||||
}
|
||||
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
|
||||
|
||||
if (mlvl.worldNameId)
|
||||
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _SYS_STR("!name.yaml"));
|
||||
|
||||
for (const MLVL::Area& area : mlvl.areas) {
|
||||
{
|
||||
MLVL mlvl;
|
||||
{
|
||||
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||
mlvl.read(rs);
|
||||
}
|
||||
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
|
||||
|
||||
if (mlvl.worldNameId)
|
||||
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _SYS_STR("!name.yaml"));
|
||||
|
||||
for (const MLVL::Area& area : mlvl.areas)
|
||||
{
|
||||
{
|
||||
/* Get PATH transform */
|
||||
const nod::Node* areaNode;
|
||||
const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode);
|
||||
PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode);
|
||||
UniqueID32 pathId = MREA::GetPATHId(rs);
|
||||
if (pathId)
|
||||
addTo[pathId] = zeus::CMatrix4f(
|
||||
area.transformMtx[0],
|
||||
area.transformMtx[1],
|
||||
area.transformMtx[2],
|
||||
BottomRow).transposed();
|
||||
}
|
||||
|
||||
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
|
||||
if (area.areaNameId)
|
||||
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _SYS_STR("!name.yaml"));
|
||||
}
|
||||
|
||||
if (mlvl.worldMap)
|
||||
{
|
||||
const nod::Node* mapNode;
|
||||
const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode);
|
||||
if (mapEntry)
|
||||
{
|
||||
PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode);
|
||||
u32 magic = rs.readUint32Big();
|
||||
if (magic == 0xDEADF00D)
|
||||
{
|
||||
rs.readUint32Big();
|
||||
u32 count = rs.readUint32Big();
|
||||
for (u32 i=0 ; i<count && i<mlvl.areas.size() ; ++i)
|
||||
{
|
||||
MLVL::Area& areaData = mlvl.areas[i];
|
||||
UniqueID32 mapaId;
|
||||
mapaId.read(rs);
|
||||
addTo[mapaId] = zeus::CMatrix4f(
|
||||
areaData.transformMtx[0],
|
||||
areaData.transformMtx[1],
|
||||
areaData.transformMtx[2],
|
||||
BottomRow).transposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/* Get PATH transform */
|
||||
const nod::Node* areaNode;
|
||||
const PAK::Entry* areaEntry = pakRouter.lookupEntry(area.areaMREAId, &areaNode);
|
||||
PAKEntryReadStream rs = areaEntry->beginReadStream(*areaNode);
|
||||
UniqueID32 pathId = MREA::GetPATHId(rs);
|
||||
if (pathId)
|
||||
addTo[pathId] = zeus::CMatrix4f(area.transformMtx[0], area.transformMtx[1], area.transformMtx[2], BottomRow)
|
||||
.transposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry)
|
||||
{
|
||||
switch (entry.type)
|
||||
{
|
||||
case SBIG('STRG'):
|
||||
return {STRG::Extract, {_SYS_STR(".yaml")}};
|
||||
case SBIG('SCAN'):
|
||||
return {SCAN::Extract, {_SYS_STR(".yaml")}, 0, SCAN::Name};
|
||||
case SBIG('HINT'):
|
||||
return {HINT::Extract, {_SYS_STR(".yaml")}};
|
||||
case SBIG('SAVW'):
|
||||
return {SAVWCommon::ExtractSAVW<SAVW>, {_SYS_STR(".yaml")}};
|
||||
case SBIG('TXTR'):
|
||||
return {TXTR::Extract, {_SYS_STR(".png")}};
|
||||
case SBIG('AFSM'):
|
||||
return {AFSM::Extract, {_SYS_STR(".yaml")}};
|
||||
case SBIG('FRME'):
|
||||
return {FRME::Extract, {_SYS_STR(".blend")}, 2};
|
||||
case SBIG('CMDL'):
|
||||
return {CMDL::Extract, {_SYS_STR(".blend")}, 1, CMDL::Name};
|
||||
case SBIG('DCLN'):
|
||||
return {DCLN::Extract, {_SYS_STR(".blend")}};
|
||||
case SBIG('ANCS'):
|
||||
return {ANCS::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 2};
|
||||
case SBIG('MLVL'):
|
||||
return {MLVL::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 3};
|
||||
case SBIG('MREA'):
|
||||
return {MREA::Extract, {_SYS_STR(".blend")}, 4, MREA::Name};
|
||||
case SBIG('MAPA'):
|
||||
return {MAPA::Extract, {_SYS_STR(".blend")}, 4};
|
||||
case SBIG('MAPU'):
|
||||
return {MAPU::Extract, {_SYS_STR(".blend")}, 5};
|
||||
case SBIG('PATH'):
|
||||
return {PATH::Extract, {_SYS_STR(".blend")}, 5};
|
||||
case SBIG('PART'):
|
||||
return {DNAParticle::ExtractGPSM<UniqueID32>, {_SYS_STR(".gpsm.yaml")}};
|
||||
case SBIG('ELSC'):
|
||||
return {DNAParticle::ExtractELSM<UniqueID32>, {_SYS_STR(".elsm.yaml")}};
|
||||
case SBIG('SWHC'):
|
||||
return {DNAParticle::ExtractSWSH<UniqueID32>, {_SYS_STR(".swsh.yaml")}};
|
||||
case SBIG('CRSC'):
|
||||
return {DNAParticle::ExtractCRSM<UniqueID32>, {_SYS_STR(".crsm.yaml")}};
|
||||
case SBIG('WPSC'):
|
||||
return {DNAParticle::ExtractWPSM<UniqueID32>, {_SYS_STR(".wpsm.yaml")}};
|
||||
case SBIG('DPSC'):
|
||||
return {DNAParticle::ExtractDPSM<UniqueID32>, {_SYS_STR(".dpsm.yaml")}};
|
||||
case SBIG('FONT'):
|
||||
return {DNAFont::ExtractFONT<UniqueID32>, {_SYS_STR(".yaml")}};
|
||||
case SBIG('DGRP'):
|
||||
return {DNADGRP::ExtractDGRP<UniqueID32>, {_SYS_STR(".yaml")}};
|
||||
case SBIG('AGSC'):
|
||||
return {AGSC::Extract, {}};
|
||||
case SBIG('CSNG'):
|
||||
return {CSNG::Extract, {_SYS_STR(".mid"), _SYS_STR(".yaml")}};
|
||||
case SBIG('ATBL'):
|
||||
return {DNAAudio::ATBL::Extract, {_SYS_STR(".yaml")}};
|
||||
case SBIG('CTWK'):
|
||||
case SBIG('DUMB'):
|
||||
{
|
||||
bool named;
|
||||
std::string name = pak.bestEntryName(pakNode, entry, named);
|
||||
if (named)
|
||||
{
|
||||
if (!name.compare("PlayerRes"))
|
||||
return {ExtractTweak<CTweakPlayerRes>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("GunRes"))
|
||||
return {ExtractTweak<CTweakGunRes>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Player"))
|
||||
return {ExtractTweak<CTweakPlayer>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("CameraBob"))
|
||||
return {ExtractTweak<CTweakCameraBob>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("SlideShow"))
|
||||
return {ExtractTweak<CTweakSlideShow>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Game"))
|
||||
return {ExtractTweak<CTweakGame>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Targeting"))
|
||||
return {ExtractTweak<CTweakTargeting>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Gui"))
|
||||
return {ExtractTweak<CTweakGui>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("AutoMapper"))
|
||||
return {ExtractTweak<CTweakAutoMapper>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("PlayerControls") || !name.compare("PlayerControls2"))
|
||||
return {ExtractTweak<CTweakPlayerControl>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Ball"))
|
||||
return {ExtractTweak<CTweakBall>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Particle"))
|
||||
return {ExtractTweak<CTweakParticle>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("GuiColors"))
|
||||
return {ExtractTweak<CTweakGuiColors>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("PlayerGun"))
|
||||
return {ExtractTweak<CTweakPlayerGun>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("DUMB_MazeSeeds"))
|
||||
return {ExtractTweak<MazeSeeds>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("DUMB_SnowForces"))
|
||||
return {ExtractTweak<SnowForces>, {_SYS_STR(".yaml")}};
|
||||
hecl::ProjectPath areaDirPath = pakRouter.getWorking(area.areaMREAId).getParentPath();
|
||||
if (area.areaNameId)
|
||||
pathOverrides[area.areaNameId] = hecl::ProjectPath(areaDirPath, _SYS_STR("!name.yaml"));
|
||||
}
|
||||
|
||||
if (mlvl.worldMap) {
|
||||
const nod::Node* mapNode;
|
||||
const PAK::Entry* mapEntry = pakRouter.lookupEntry(mlvl.worldMap, &mapNode);
|
||||
if (mapEntry) {
|
||||
PAKEntryReadStream rs = mapEntry->beginReadStream(*mapNode);
|
||||
u32 magic = rs.readUint32Big();
|
||||
if (magic == 0xDEADF00D) {
|
||||
rs.readUint32Big();
|
||||
u32 count = rs.readUint32Big();
|
||||
for (u32 i = 0; i < count && i < mlvl.areas.size(); ++i) {
|
||||
MLVL::Area& areaData = mlvl.areas[i];
|
||||
UniqueID32 mapaId;
|
||||
mapaId.read(rs);
|
||||
addTo[mapaId] = zeus::CMatrix4f(areaData.transformMtx[0], areaData.transformMtx[1],
|
||||
areaData.transformMtx[2], BottomRow)
|
||||
.transposed();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
ResExtractor<PAKBridge> PAKBridge::LookupExtractor(const nod::Node& pakNode, const PAK& pak, const PAK::Entry& entry) {
|
||||
switch (entry.type) {
|
||||
case SBIG('STRG'):
|
||||
return {STRG::Extract, {_SYS_STR(".yaml")}};
|
||||
case SBIG('SCAN'):
|
||||
return {SCAN::Extract, {_SYS_STR(".yaml")}, 0, SCAN::Name};
|
||||
case SBIG('HINT'):
|
||||
return {HINT::Extract, {_SYS_STR(".yaml")}};
|
||||
case SBIG('SAVW'):
|
||||
return {SAVWCommon::ExtractSAVW<SAVW>, {_SYS_STR(".yaml")}};
|
||||
case SBIG('TXTR'):
|
||||
return {TXTR::Extract, {_SYS_STR(".png")}};
|
||||
case SBIG('AFSM'):
|
||||
return {AFSM::Extract, {_SYS_STR(".yaml")}};
|
||||
case SBIG('FRME'):
|
||||
return {FRME::Extract, {_SYS_STR(".blend")}, 2};
|
||||
case SBIG('CMDL'):
|
||||
return {CMDL::Extract, {_SYS_STR(".blend")}, 1, CMDL::Name};
|
||||
case SBIG('DCLN'):
|
||||
return {DCLN::Extract, {_SYS_STR(".blend")}};
|
||||
case SBIG('ANCS'):
|
||||
return {ANCS::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 2};
|
||||
case SBIG('MLVL'):
|
||||
return {MLVL::Extract, {_SYS_STR(".yaml"), _SYS_STR(".blend")}, 3};
|
||||
case SBIG('MREA'):
|
||||
return {MREA::Extract, {_SYS_STR(".blend")}, 4, MREA::Name};
|
||||
case SBIG('MAPA'):
|
||||
return {MAPA::Extract, {_SYS_STR(".blend")}, 4};
|
||||
case SBIG('MAPU'):
|
||||
return {MAPU::Extract, {_SYS_STR(".blend")}, 5};
|
||||
case SBIG('PATH'):
|
||||
return {PATH::Extract, {_SYS_STR(".blend")}, 5};
|
||||
case SBIG('PART'):
|
||||
return {DNAParticle::ExtractGPSM<UniqueID32>, {_SYS_STR(".gpsm.yaml")}};
|
||||
case SBIG('ELSC'):
|
||||
return {DNAParticle::ExtractELSM<UniqueID32>, {_SYS_STR(".elsm.yaml")}};
|
||||
case SBIG('SWHC'):
|
||||
return {DNAParticle::ExtractSWSH<UniqueID32>, {_SYS_STR(".swsh.yaml")}};
|
||||
case SBIG('CRSC'):
|
||||
return {DNAParticle::ExtractCRSM<UniqueID32>, {_SYS_STR(".crsm.yaml")}};
|
||||
case SBIG('WPSC'):
|
||||
return {DNAParticle::ExtractWPSM<UniqueID32>, {_SYS_STR(".wpsm.yaml")}};
|
||||
case SBIG('DPSC'):
|
||||
return {DNAParticle::ExtractDPSM<UniqueID32>, {_SYS_STR(".dpsm.yaml")}};
|
||||
case SBIG('FONT'):
|
||||
return {DNAFont::ExtractFONT<UniqueID32>, {_SYS_STR(".yaml")}};
|
||||
case SBIG('DGRP'):
|
||||
return {DNADGRP::ExtractDGRP<UniqueID32>, {_SYS_STR(".yaml")}};
|
||||
case SBIG('AGSC'):
|
||||
return {AGSC::Extract, {}};
|
||||
case SBIG('CSNG'):
|
||||
return {CSNG::Extract, {_SYS_STR(".mid"), _SYS_STR(".yaml")}};
|
||||
case SBIG('ATBL'):
|
||||
return {DNAAudio::ATBL::Extract, {_SYS_STR(".yaml")}};
|
||||
case SBIG('CTWK'):
|
||||
case SBIG('DUMB'): {
|
||||
bool named;
|
||||
std::string name = pak.bestEntryName(pakNode, entry, named);
|
||||
if (named) {
|
||||
if (!name.compare("PlayerRes"))
|
||||
return {ExtractTweak<CTweakPlayerRes>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("GunRes"))
|
||||
return {ExtractTweak<CTweakGunRes>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Player"))
|
||||
return {ExtractTweak<CTweakPlayer>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("CameraBob"))
|
||||
return {ExtractTweak<CTweakCameraBob>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("SlideShow"))
|
||||
return {ExtractTweak<CTweakSlideShow>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Game"))
|
||||
return {ExtractTweak<CTweakGame>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Targeting"))
|
||||
return {ExtractTweak<CTweakTargeting>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Gui"))
|
||||
return {ExtractTweak<CTweakGui>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("AutoMapper"))
|
||||
return {ExtractTweak<CTweakAutoMapper>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("PlayerControls") || !name.compare("PlayerControls2"))
|
||||
return {ExtractTweak<CTweakPlayerControl>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Ball"))
|
||||
return {ExtractTweak<CTweakBall>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("Particle"))
|
||||
return {ExtractTweak<CTweakParticle>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("GuiColors"))
|
||||
return {ExtractTweak<CTweakGuiColors>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("PlayerGun"))
|
||||
return {ExtractTweak<CTweakPlayerGun>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("DUMB_MazeSeeds"))
|
||||
return {ExtractTweak<MazeSeeds>, {_SYS_STR(".yaml")}};
|
||||
if (!name.compare("DUMB_SnowForces"))
|
||||
return {ExtractTweak<SnowForces>, {_SYS_STR(".yaml")}};
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
} // namespace DataSpec::DNAMP1
|
||||
|
||||
Reference in New Issue
Block a user