2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-08 17:44:56 +00:00

Pointer dereference bug fixes

This commit is contained in:
Jack Andersen
2017-03-10 08:00:40 -10:00
parent 2d093b6d80
commit d2e9290363
15 changed files with 187 additions and 209 deletions

View File

@@ -66,8 +66,9 @@ PAKBridge::PAKBridge(hecl::Database::Project& project,
m_pak.read(rs);
/* Append Level String */
for (PAK::Entry& entry : m_pak.m_entries)
for (auto& ent : m_pak.m_entries)
{
PAK::Entry& entry = ent.second;
if (entry.type == FOURCC('MLVL'))
{
PAKEntryReadStream rs = entry.beginReadStream(m_node);
@@ -100,8 +101,9 @@ static hecl::SystemString LayerName(const std::string& name)
void PAKBridge::build()
{
/* First pass: build per-area/per-layer dependency map */
for (const PAK::Entry& entry : m_pak.m_entries)
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];
@@ -207,9 +209,9 @@ void PAKBridge::build()
}
/* Second pass: cross-compare uniqueness */
for (PAK::Entry& entry : m_pak.m_entries)
for (auto& entry : m_pak.m_entries)
{
entry.unique.checkEntry(*this, entry);
entry.second.unique.checkEntry(*this, entry.second);
}
}
@@ -217,18 +219,18 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo,
std::unordered_map<UniqueID32, std::pair<UniqueID32, std::string>>& cskrCinfToAncs) const
{
for (const std::pair<UniqueID32, PAK::Entry*>& entry : m_pak.m_idMap)
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries)
{
if (entry.second->type == FOURCC('ANCS'))
if (entry.second.type == FOURCC('ANCS'))
{
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
ANCS ancs;
ancs.read(rs);
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
{
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
cskrCinfToAncs[ci.cskr] = std::make_pair(entry.second->id, hecl::Format("%s.CSKR", ci.name.c_str()));
cskrCinfToAncs[ci.cinf] = std::make_pair(entry.second->id, hecl::Format("CINF_%08X.CINF", ci.cinf.toUint32()));
cskrCinfToAncs[ci.cskr] = std::make_pair(entry.second.id, hecl::Format("%s.CSKR", ci.name.c_str()));
cskrCinfToAncs[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);
@@ -238,7 +240,7 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
if (ci.cmdlOverlay && ci.cskrOverlay)
{
addTo[ci.cmdlOverlay] = std::make_pair(ci.cskrOverlay, ci.cinf);
cskrCinfToAncs[ci.cskrOverlay] = std::make_pair(entry.second->id, hecl::Format("%s.over.CSKR", ci.name.c_str()));
cskrCinfToAncs[ci.cskrOverlay] = std::make_pair(entry.second.id, hecl::Format("%s.over.CSKR", ci.name.c_str()));
PAK::Entry* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlOverlay);
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrOverlay);
cmdlEnt->name = hecl::Format("ANCS_%08X_%s_overmodel", entry.first.toUint32(), ci.name.c_str());
@@ -251,18 +253,18 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
{
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());
cskrCinfToAncs[ae.second.animId] = std::make_pair(entry.second->id, hecl::Format("%s.ANIM", ae.second.name.c_str()));
cskrCinfToAncs[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());
cskrCinfToAncs[ae.second.evntId] = std::make_pair(entry.second->id, hecl::Format("%s.evnt.yaml", ae.second.name.c_str()));
cskrCinfToAncs[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'))
else if (entry.second.type == FOURCC('MREA'))
{
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
MREA::AddCMDLRigPairs(rs, pakRouter, addTo);
}
}
@@ -274,16 +276,16 @@ 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_idMap)
for (const std::pair<UniqueID32, PAK::Entry>& entry : m_pak.m_entries)
{
if (entry.second->type == FOURCC('MLVL'))
if (entry.second.type == FOURCC('MLVL'))
{
MLVL mlvl;
{
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
mlvl.read(rs);
}
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath();
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
if (mlvl.worldNameId)
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));

View File

@@ -29,37 +29,25 @@ void PAK::read(athena::io::IStreamReader& reader)
m_entries.reserve(count);
m_firstEntries.clear();
m_firstEntries.reserve(count);
m_idMap.clear();
m_idMap.reserve(count);
for (atUint32 e=0 ; e<count ; ++e)
{
m_entries.emplace_back();
Entry& ent = m_entries.back();
ent.read(reader);
if (ent.compressed && m_useLzo)
ent.compressed = 2;
}
for (Entry& entry : m_entries)
{
auto search = m_idMap.find(entry.id);
if (search == m_idMap.end())
Entry entry;
entry.read(reader);
if (entry.compressed && m_useLzo)
entry.compressed = 2;
auto search = m_entries.find(entry.id);
if (search == m_entries.end())
{
m_firstEntries.push_back(&entry);
m_idMap[entry.id] = &entry;
m_firstEntries.push_back(entry.id);
m_entries[entry.id] = std::move(entry);
}
}
m_nameMap.clear();
m_nameMap.reserve(nameCount);
for (NameEntry& entry : m_nameEntries)
{
std::unordered_map<UniqueID32, Entry*>::iterator found = m_idMap.find(entry.id);
if (found != m_idMap.end())
{
m_nameMap[entry.name] = found->second;
found->second->name = entry.name;
}
}
m_nameMap[entry.name] = entry.id;
}
void PAK::write(athena::io::IStreamWriter& writer) const
@@ -76,9 +64,9 @@ void PAK::write(athena::io::IStreamWriter& writer) const
}
writer.writeUint32Big(m_entries.size());
for (const Entry& entry : m_entries)
for (const auto& entry : m_entries)
{
Entry tmp = entry;
Entry tmp = entry.second;
if (tmp.compressed)
tmp.compressed = 1;
tmp.write(writer);
@@ -156,5 +144,40 @@ PAK::Entry::getBuffer(const nod::Node& pak, atUint64& szOut) const
}
}
const PAK::Entry* PAK::lookupEntry(const UniqueID32& id) const
{
auto result = m_entries.find(id);
if (result != m_entries.end())
return &result->second;
return nullptr;
}
const PAK::Entry* PAK::lookupEntry(const std::string& name) const
{
auto result = m_nameMap.find(name);
if (result != m_nameMap.end())
{
auto result1 = m_entries.find(result->second);
if (result1 != m_entries.end())
return &result1->second;
}
return nullptr;
}
std::string PAK::bestEntryName(const Entry& entry, bool& named) const
{
/* Prefer named entries first */
for (const NameEntry& nentry : m_nameEntries)
if (nentry.id == entry.id)
{
named = true;
return nentry.name;
}
/* Otherwise return ID format string */
named = false;
return entry.type.toString() + '_' + entry.id.toString();
}
}
}

View File

@@ -48,41 +48,13 @@ struct PAK : BigDNA
};
std::vector<NameEntry> m_nameEntries;
std::vector<Entry> m_entries;
std::vector<Entry*> m_firstEntries;
std::unordered_map<UniqueID32, Entry*> m_idMap;
std::unordered_map<std::string, Entry*> m_nameMap;
std::unordered_map<UniqueID32, Entry> m_entries;
std::vector<UniqueID32> m_firstEntries;
std::unordered_map<std::string, UniqueID32> m_nameMap;
const Entry* lookupEntry(const UniqueID32& id) const
{
std::unordered_map<UniqueID32, Entry*>::const_iterator result = m_idMap.find(id);
if (result != m_idMap.end())
return result->second;
return nullptr;
}
const Entry* lookupEntry(const std::string& name) const
{
std::unordered_map<std::string, Entry*>::const_iterator result = m_nameMap.find(name);
if (result != m_nameMap.end())
return result->second;
return nullptr;
}
std::string bestEntryName(const Entry& entry, bool& named) const
{
/* Prefer named entries first */
for (const NameEntry& nentry : m_nameEntries)
if (nentry.id == entry.id)
{
named = true;
return nentry.name;
}
/* Otherwise return ID format string */
named = false;
return entry.type.toString() + '_' + entry.id.toString();
}
const Entry* lookupEntry(const UniqueID32& id) const;
const Entry* lookupEntry(const std::string& name) const;
std::string bestEntryName(const Entry& entry, bool& named) const;
using IDType = UniqueID32;
};