mirror of https://github.com/AxioDL/metaforce.git
Pointer dereference bug fixes
This commit is contained in:
parent
2d093b6d80
commit
d2e9290363
|
@ -1,6 +0,0 @@
|
||||||
.directory
|
|
||||||
version.h
|
|
||||||
*.user
|
|
||||||
.DS_Store
|
|
||||||
*.autosave
|
|
||||||
docs/*
|
|
|
@ -1,18 +0,0 @@
|
||||||
[submodule "hecl"]
|
|
||||||
path = hecl
|
|
||||||
url = https://github.com/AxioDL/hecl.git
|
|
||||||
[submodule "specter"]
|
|
||||||
path = specter
|
|
||||||
url = https://github.com/AxioDL/specter.git
|
|
||||||
[submodule "nod"]
|
|
||||||
path = nod
|
|
||||||
url = https://github.com/AxioDL/nod.git
|
|
||||||
[submodule "amuse"]
|
|
||||||
path = amuse
|
|
||||||
url = https://github.com/AxioDL/amuse.git
|
|
||||||
[submodule "kabufuda"]
|
|
||||||
path = kabufuda
|
|
||||||
url = https://github.com/AxioDL/kabufuda.git
|
|
||||||
[submodule "jbus"]
|
|
||||||
path = jbus
|
|
||||||
url = https://github.com/AxioDL/jbus.git
|
|
|
@ -10,6 +10,8 @@ if(MSVC)
|
||||||
add_definitions(-DUNICODE=1 -D_UNICODE=1 -D__SSE__=1 -D_CRT_SECURE_NO_WARNINGS=1 -DD_SCL_SECURE_NO_WARNINGS=1
|
add_definitions(-DUNICODE=1 -D_UNICODE=1 -D__SSE__=1 -D_CRT_SECURE_NO_WARNINGS=1 -DD_SCL_SECURE_NO_WARNINGS=1
|
||||||
/IGNORE:4221 /wd4018 /wd4800 /wd4005 /wd4311 /wd4267 /wd4244 /wd4200 /wd4305 /wd4067 /wd4146 ${VS_DEFINES})
|
/IGNORE:4221 /wd4018 /wd4800 /wd4005 /wd4311 /wd4267 /wd4244 /wd4200 /wd4305 /wd4067 /wd4146 ${VS_DEFINES})
|
||||||
|
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
|
||||||
|
|
||||||
# Link-time Code Generation for Release builds
|
# Link-time Code Generation for Release builds
|
||||||
set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy /MD")
|
set(CMAKE_C_FLAGS_RELEASE "/DNDEBUG /O2 /Oy /GL /Gy /MD")
|
||||||
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE}")
|
||||||
|
|
|
@ -165,7 +165,7 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
|
||||||
|
|
||||||
/* Add to global entry lookup */
|
/* Add to global entry lookup */
|
||||||
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK();
|
const typename BRIDGETYPE::PAKType& pak = bridge.getPAK();
|
||||||
for (const auto& entry : pak.m_idMap)
|
for (const auto& entry : pak.m_entries)
|
||||||
{
|
{
|
||||||
if (!pak.m_noShare)
|
if (!pak.m_noShare)
|
||||||
{
|
{
|
||||||
|
@ -176,13 +176,13 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
|
||||||
if (uSearch != m_uniqueEntries.end())
|
if (uSearch != m_uniqueEntries.end())
|
||||||
{
|
{
|
||||||
m_uniqueEntries.erase(uSearch);
|
m_uniqueEntries.erase(uSearch);
|
||||||
m_sharedEntries[entry.first] = std::make_pair(bridgeIdx, entry.second);
|
m_sharedEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, entry.second);
|
m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, entry.second);
|
m_uniqueEntries[entry.first] = std::make_pair(bridgeIdx, &entry.second);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add RigPairs to global map */
|
/* Add RigPairs to global map */
|
||||||
|
@ -518,24 +518,25 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
|
||||||
{
|
{
|
||||||
enterPAKBridge(pakBridge);
|
enterPAKBridge(pakBridge);
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
size_t sz = m_pak->m_idMap.size();
|
size_t sz = m_pak->m_entries.size();
|
||||||
float fsz = sz;
|
float fsz = sz;
|
||||||
for (unsigned w=0 ; count<sz ; ++w)
|
for (unsigned w=0 ; count<sz ; ++w)
|
||||||
{
|
{
|
||||||
for (const auto& item : m_pak->m_firstEntries)
|
for (const auto& item : m_pak->m_firstEntries)
|
||||||
{
|
{
|
||||||
ResExtractor<BRIDGETYPE> extractor = BRIDGETYPE::LookupExtractor(*m_pak.get(), *item);
|
const auto* entryPtr = m_pak->lookupEntry(item);
|
||||||
|
ResExtractor<BRIDGETYPE> extractor = BRIDGETYPE::LookupExtractor(*m_pak.get(), *entryPtr);
|
||||||
if (extractor.weight != w)
|
if (extractor.weight != w)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::string bestName = getBestEntryName(*item, false);
|
std::string bestName = getBestEntryName(*entryPtr, false);
|
||||||
hecl::SystemStringView bestNameView(bestName);
|
hecl::SystemStringView bestNameView(bestName);
|
||||||
float thisFac = ++count / fsz;
|
float thisFac = ++count / fsz;
|
||||||
progress(bestNameView.c_str(), thisFac);
|
progress(bestNameView.c_str(), thisFac);
|
||||||
|
|
||||||
const nod::Node* node = m_node.get();
|
const nod::Node* node = m_node.get();
|
||||||
|
|
||||||
hecl::ProjectPath working = getWorking(item, extractor);
|
hecl::ProjectPath working = getWorking(entryPtr, extractor);
|
||||||
working.makeDirChain(false);
|
working.makeDirChain(false);
|
||||||
hecl::ResourceLock resLk(working);
|
hecl::ResourceLock resLk(working);
|
||||||
if (!resLk)
|
if (!resLk)
|
||||||
|
@ -546,7 +547,7 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
|
||||||
if (force || cooked.isNone())
|
if (force || cooked.isNone())
|
||||||
{
|
{
|
||||||
cooked.makeDirChain(false);
|
cooked.makeDirChain(false);
|
||||||
PAKEntryReadStream s = item->beginReadStream(*node);
|
PAKEntryReadStream s = entryPtr->beginReadStream(*node);
|
||||||
FILE* fout = hecl::Fopen(cooked.getAbsolutePath().c_str(), _S("wb"));
|
FILE* fout = hecl::Fopen(cooked.getAbsolutePath().c_str(), _S("wb"));
|
||||||
fwrite(s.data(), 1, s.length(), fout);
|
fwrite(s.data(), 1, s.length(), fout);
|
||||||
fclose(fout);
|
fclose(fout);
|
||||||
|
@ -556,7 +557,7 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
|
||||||
{
|
{
|
||||||
if (force || !extractor.IsFullyExtracted(working))
|
if (force || !extractor.IsFullyExtracted(working))
|
||||||
{
|
{
|
||||||
PAKEntryReadStream s = item->beginReadStream(*node);
|
PAKEntryReadStream s = entryPtr->beginReadStream(*node);
|
||||||
extractor.func_a(s, working);
|
extractor.func_a(s, working);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -564,8 +565,8 @@ bool PAKRouter<BRIDGETYPE>::extractResources(const BRIDGETYPE& pakBridge, bool f
|
||||||
{
|
{
|
||||||
if (force || !extractor.IsFullyExtracted(working))
|
if (force || !extractor.IsFullyExtracted(working))
|
||||||
{
|
{
|
||||||
PAKEntryReadStream s = item->beginReadStream(*node);
|
PAKEntryReadStream s = entryPtr->beginReadStream(*node);
|
||||||
extractor.func_b(m_dataSpec, s, working, *this, *item, force, btok,
|
extractor.func_b(m_dataSpec, s, working, *this, *entryPtr, force, btok,
|
||||||
[&progress, thisFac](const hecl::SystemChar* update)
|
[&progress, thisFac](const hecl::SystemChar* update)
|
||||||
{
|
{
|
||||||
progress(update, thisFac);
|
progress(update, thisFac);
|
||||||
|
|
|
@ -167,8 +167,8 @@ private:
|
||||||
hecl::ProjectPath m_sharedCooked;
|
hecl::ProjectPath m_sharedCooked;
|
||||||
ThreadLocalPtr<const PAKType> m_pak;
|
ThreadLocalPtr<const PAKType> m_pak;
|
||||||
ThreadLocalPtr<const nod::Node> m_node;
|
ThreadLocalPtr<const nod::Node> m_node;
|
||||||
std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_uniqueEntries;
|
std::unordered_map<IDType, std::pair<size_t, const EntryType*>> m_uniqueEntries;
|
||||||
std::unordered_map<IDType, std::pair<size_t, EntryType*>> m_sharedEntries;
|
std::unordered_map<IDType, std::pair<size_t, const EntryType*>> m_sharedEntries;
|
||||||
std::unordered_map<IDType, hecl::ProjectPath> m_overrideEntries;
|
std::unordered_map<IDType, hecl::ProjectPath> m_overrideEntries;
|
||||||
std::unordered_map<IDType, RigPair> m_cmdlRigs;
|
std::unordered_map<IDType, RigPair> m_cmdlRigs;
|
||||||
std::unordered_map<IDType, std::pair<IDType, std::string>> m_cskrCinfToCharacter;
|
std::unordered_map<IDType, std::pair<IDType, std::string>> m_cskrCinfToCharacter;
|
||||||
|
|
|
@ -66,8 +66,9 @@ PAKBridge::PAKBridge(hecl::Database::Project& project,
|
||||||
m_pak.read(rs);
|
m_pak.read(rs);
|
||||||
|
|
||||||
/* Append Level String */
|
/* 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'))
|
if (entry.type == FOURCC('MLVL'))
|
||||||
{
|
{
|
||||||
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
||||||
|
@ -100,8 +101,9 @@ static hecl::SystemString LayerName(const std::string& name)
|
||||||
void PAKBridge::build()
|
void PAKBridge::build()
|
||||||
{
|
{
|
||||||
/* First pass: build per-area/per-layer dependency map */
|
/* 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'))
|
if (entry.type == FOURCC('MLVL'))
|
||||||
{
|
{
|
||||||
Level& level = m_levelDeps[entry.id];
|
Level& level = m_levelDeps[entry.id];
|
||||||
|
@ -207,9 +209,9 @@ void PAKBridge::build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Second pass: cross-compare uniqueness */
|
/* 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, UniqueID32>>& addTo,
|
||||||
std::unordered_map<UniqueID32, std::pair<UniqueID32, std::string>>& cskrCinfToAncs) const
|
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 ancs;
|
||||||
ancs.read(rs);
|
ancs.read(rs);
|
||||||
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
|
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
|
||||||
{
|
{
|
||||||
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
|
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.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.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* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdl);
|
||||||
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr);
|
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskr);
|
||||||
PAK::Entry* cinfEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cinf);
|
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)
|
if (ci.cmdlOverlay && ci.cskrOverlay)
|
||||||
{
|
{
|
||||||
addTo[ci.cmdlOverlay] = std::make_pair(ci.cskrOverlay, ci.cinf);
|
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* cmdlEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cmdlOverlay);
|
||||||
PAK::Entry* cskrEnt = (PAK::Entry*)m_pak.lookupEntry(ci.cskrOverlay);
|
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());
|
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);
|
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());
|
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)
|
if (ae.second.evntId)
|
||||||
{
|
{
|
||||||
PAK::Entry* evntEnt = (PAK::Entry*)m_pak.lookupEntry(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());
|
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);
|
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, zeus::CMatrix4f>& addTo,
|
||||||
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const
|
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;
|
MLVL mlvl;
|
||||||
{
|
{
|
||||||
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
|
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||||
mlvl.read(rs);
|
mlvl.read(rs);
|
||||||
}
|
}
|
||||||
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath();
|
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
|
||||||
|
|
||||||
if (mlvl.worldNameId)
|
if (mlvl.worldNameId)
|
||||||
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));
|
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));
|
||||||
|
|
|
@ -29,37 +29,25 @@ void PAK::read(athena::io::IStreamReader& reader)
|
||||||
m_entries.reserve(count);
|
m_entries.reserve(count);
|
||||||
m_firstEntries.clear();
|
m_firstEntries.clear();
|
||||||
m_firstEntries.reserve(count);
|
m_firstEntries.reserve(count);
|
||||||
m_idMap.clear();
|
|
||||||
m_idMap.reserve(count);
|
|
||||||
for (atUint32 e=0 ; e<count ; ++e)
|
for (atUint32 e=0 ; e<count ; ++e)
|
||||||
{
|
{
|
||||||
m_entries.emplace_back();
|
Entry entry;
|
||||||
Entry& ent = m_entries.back();
|
entry.read(reader);
|
||||||
ent.read(reader);
|
if (entry.compressed && m_useLzo)
|
||||||
if (ent.compressed && m_useLzo)
|
entry.compressed = 2;
|
||||||
ent.compressed = 2;
|
|
||||||
}
|
auto search = m_entries.find(entry.id);
|
||||||
for (Entry& entry : m_entries)
|
if (search == m_entries.end())
|
||||||
{
|
|
||||||
auto search = m_idMap.find(entry.id);
|
|
||||||
if (search == m_idMap.end())
|
|
||||||
{
|
{
|
||||||
m_firstEntries.push_back(&entry);
|
m_firstEntries.push_back(entry.id);
|
||||||
m_idMap[entry.id] = &entry;
|
m_entries[entry.id] = std::move(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nameMap.clear();
|
m_nameMap.clear();
|
||||||
m_nameMap.reserve(nameCount);
|
m_nameMap.reserve(nameCount);
|
||||||
for (NameEntry& entry : m_nameEntries)
|
for (NameEntry& entry : m_nameEntries)
|
||||||
{
|
m_nameMap[entry.name] = entry.id;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void PAK::write(athena::io::IStreamWriter& writer) const
|
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());
|
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)
|
if (tmp.compressed)
|
||||||
tmp.compressed = 1;
|
tmp.compressed = 1;
|
||||||
tmp.write(writer);
|
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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,41 +48,13 @@ struct PAK : BigDNA
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<NameEntry> m_nameEntries;
|
std::vector<NameEntry> m_nameEntries;
|
||||||
std::vector<Entry> m_entries;
|
std::unordered_map<UniqueID32, Entry> m_entries;
|
||||||
std::vector<Entry*> m_firstEntries;
|
std::vector<UniqueID32> m_firstEntries;
|
||||||
std::unordered_map<UniqueID32, Entry*> m_idMap;
|
std::unordered_map<std::string, UniqueID32> m_nameMap;
|
||||||
std::unordered_map<std::string, Entry*> m_nameMap;
|
|
||||||
|
|
||||||
const Entry* lookupEntry(const UniqueID32& id) const
|
const Entry* lookupEntry(const UniqueID32& id) const;
|
||||||
{
|
const Entry* lookupEntry(const std::string& name) const;
|
||||||
std::unordered_map<UniqueID32, Entry*>::const_iterator result = m_idMap.find(id);
|
std::string bestEntryName(const Entry& entry, bool& named) const;
|
||||||
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();
|
|
||||||
}
|
|
||||||
|
|
||||||
using IDType = UniqueID32;
|
using IDType = UniqueID32;
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,11 +42,12 @@ PAKBridge::PAKBridge(hecl::Database::Project& project,
|
||||||
m_pak.read(rs);
|
m_pak.read(rs);
|
||||||
|
|
||||||
/* Append Level String */
|
/* Append Level String */
|
||||||
for (DNAMP1::PAK::Entry& entry : m_pak.m_entries)
|
for (const auto& entry : m_pak.m_entries)
|
||||||
{
|
{
|
||||||
if (entry.type == FOURCC('MLVL'))
|
const DNAMP1::PAK::Entry& e = entry.second;
|
||||||
|
if (e.type == FOURCC('MLVL'))
|
||||||
{
|
{
|
||||||
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
PAKEntryReadStream rs = e.beginReadStream(m_node);
|
||||||
MLVL mlvl;
|
MLVL mlvl;
|
||||||
mlvl.read(rs);
|
mlvl.read(rs);
|
||||||
const DNAMP1::PAK::Entry* nameEnt = m_pak.lookupEntry(mlvl.worldNameId);
|
const DNAMP1::PAK::Entry* nameEnt = m_pak.lookupEntry(mlvl.worldNameId);
|
||||||
|
@ -75,19 +76,20 @@ static hecl::SystemString LayerName(const std::string& name)
|
||||||
void PAKBridge::build()
|
void PAKBridge::build()
|
||||||
{
|
{
|
||||||
/* First pass: build per-area/per-layer dependency map */
|
/* First pass: build per-area/per-layer dependency map */
|
||||||
for (const DNAMP1::PAK::Entry& entry : m_pak.m_entries)
|
for (const auto& entry : m_pak.m_entries)
|
||||||
{
|
{
|
||||||
if (entry.type == FOURCC('MLVL'))
|
const DNAMP1::PAK::Entry& e = entry.second;
|
||||||
|
if (e.type == FOURCC('MLVL'))
|
||||||
{
|
{
|
||||||
Level& level = m_levelDeps[entry.id];
|
Level& level = m_levelDeps[e.id];
|
||||||
|
|
||||||
MLVL mlvl;
|
MLVL mlvl;
|
||||||
{
|
{
|
||||||
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
PAKEntryReadStream rs = e.beginReadStream(m_node);
|
||||||
mlvl.read(rs);
|
mlvl.read(rs);
|
||||||
}
|
}
|
||||||
bool named;
|
bool named;
|
||||||
std::string bestName = m_pak.bestEntryName(entry, named);
|
std::string bestName = m_pak.bestEntryName(e, named);
|
||||||
level.name = hecl::SystemStringView(bestName).sys_str();
|
level.name = hecl::SystemStringView(bestName).sys_str();
|
||||||
level.areas.reserve(mlvl.areaCount);
|
level.areas.reserve(mlvl.areaCount);
|
||||||
unsigned layerIdx = 0;
|
unsigned layerIdx = 0;
|
||||||
|
@ -163,9 +165,9 @@ void PAKBridge::build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Second pass: cross-compare uniqueness */
|
/* Second pass: cross-compare uniqueness */
|
||||||
for (DNAMP1::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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,22 +175,22 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
||||||
std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo,
|
std::unordered_map<UniqueID32, std::pair<UniqueID32, UniqueID32>>& addTo,
|
||||||
std::unordered_map<UniqueID32, std::pair<UniqueID32, std::string>>& cskrCinfToAncs) const
|
std::unordered_map<UniqueID32, std::pair<UniqueID32, std::string>>& cskrCinfToAncs) const
|
||||||
{
|
{
|
||||||
for (const std::pair<UniqueID32, DNAMP1::PAK::Entry*>& entry : m_pak.m_idMap)
|
for (const std::pair<UniqueID32, DNAMP1::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 ancs;
|
||||||
ancs.read(rs);
|
ancs.read(rs);
|
||||||
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
|
for (const ANCS::CharacterSet::CharacterInfo& ci : ancs.characterSet.characters)
|
||||||
{
|
{
|
||||||
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
|
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.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.cinf] = std::make_pair(entry.second.id, hecl::Format("CINF_%08X.CINF", ci.cinf.toUint32()));
|
||||||
if (ci.cmdlOverlay)
|
if (ci.cmdlOverlay)
|
||||||
{
|
{
|
||||||
addTo[ci.cmdlOverlay] = std::make_pair(ci.cskrOverlay, ci.cinf);
|
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()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -201,16 +203,16 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
||||||
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
|
std::unordered_map<UniqueID32, zeus::CMatrix4f>& addTo,
|
||||||
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const
|
std::unordered_map<UniqueID32, hecl::ProjectPath>& pathOverrides) const
|
||||||
{
|
{
|
||||||
for (const std::pair<UniqueID32, DNAMP1::PAK::Entry*>& entry : m_pak.m_idMap)
|
for (const std::pair<UniqueID32, DNAMP1::PAK::Entry>& entry : m_pak.m_entries)
|
||||||
{
|
{
|
||||||
if (entry.second->type == FOURCC('MLVL'))
|
if (entry.second.type == FOURCC('MLVL'))
|
||||||
{
|
{
|
||||||
MLVL mlvl;
|
MLVL mlvl;
|
||||||
{
|
{
|
||||||
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
|
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||||
mlvl.read(rs);
|
mlvl.read(rs);
|
||||||
}
|
}
|
||||||
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath();
|
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
|
||||||
|
|
||||||
if (mlvl.worldNameId)
|
if (mlvl.worldNameId)
|
||||||
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));
|
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));
|
||||||
|
|
|
@ -42,8 +42,9 @@ PAKBridge::PAKBridge(hecl::Database::Project& project,
|
||||||
|
|
||||||
/* Append Level String */
|
/* Append Level String */
|
||||||
std::set<hecl::SystemString, hecl::CaseInsensitiveCompare> uniq;
|
std::set<hecl::SystemString, hecl::CaseInsensitiveCompare> uniq;
|
||||||
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'))
|
if (entry.type == FOURCC('MLVL'))
|
||||||
{
|
{
|
||||||
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
PAKEntryReadStream rs = entry.beginReadStream(m_node);
|
||||||
|
@ -81,8 +82,9 @@ static hecl::SystemString LayerName(const std::string& name)
|
||||||
void PAKBridge::build()
|
void PAKBridge::build()
|
||||||
{
|
{
|
||||||
/* First pass: build per-area/per-layer dependency map */
|
/* 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'))
|
if (entry.type == FOURCC('MLVL'))
|
||||||
{
|
{
|
||||||
Level& level = m_levelDeps[entry.id];
|
Level& level = m_levelDeps[entry.id];
|
||||||
|
@ -173,9 +175,9 @@ void PAKBridge::build()
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Second pass: cross-compare uniqueness */
|
/* 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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,21 +185,21 @@ void PAKBridge::addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter,
|
||||||
std::unordered_map<UniqueID64, std::pair<UniqueID64, UniqueID64>>& addTo,
|
std::unordered_map<UniqueID64, std::pair<UniqueID64, UniqueID64>>& addTo,
|
||||||
std::unordered_map<UniqueID64, std::pair<UniqueID64, std::string>>& cskrCinfToChar) const
|
std::unordered_map<UniqueID64, std::pair<UniqueID64, std::string>>& cskrCinfToChar) const
|
||||||
{
|
{
|
||||||
for (const std::pair<UniqueID64, PAK::Entry*>& entry : m_pak.m_idMap)
|
for (const std::pair<UniqueID64, PAK::Entry>& entry : m_pak.m_entries)
|
||||||
{
|
{
|
||||||
if (entry.second->type == FOURCC('CHAR'))
|
if (entry.second.type == FOURCC('CHAR'))
|
||||||
{
|
{
|
||||||
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
|
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||||
CHAR aChar;
|
CHAR aChar;
|
||||||
aChar.read(rs);
|
aChar.read(rs);
|
||||||
const CHAR::CharacterInfo& ci = aChar.characterInfo;
|
const CHAR::CharacterInfo& ci = aChar.characterInfo;
|
||||||
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
|
addTo[ci.cmdl] = std::make_pair(ci.cskr, ci.cinf);
|
||||||
cskrCinfToChar[ci.cskr] = std::make_pair(entry.second->id, hecl::Format("%s.CSKR", ci.name.c_str()));
|
cskrCinfToChar[ci.cskr] = std::make_pair(entry.second.id, hecl::Format("%s.CSKR", ci.name.c_str()));
|
||||||
cskrCinfToChar[ci.cinf] = std::make_pair(entry.second->id, hecl::Format("CINF_%" PRIX64 ".CINF", ci.cinf.toUint64()));
|
cskrCinfToChar[ci.cinf] = std::make_pair(entry.second.id, hecl::Format("CINF_%" PRIX64 ".CINF", ci.cinf.toUint64()));
|
||||||
for (const CHAR::CharacterInfo::Overlay& overlay : ci.overlays)
|
for (const CHAR::CharacterInfo::Overlay& overlay : ci.overlays)
|
||||||
{
|
{
|
||||||
addTo[overlay.cmdl] = std::make_pair(overlay.cskr, ci.cinf);
|
addTo[overlay.cmdl] = std::make_pair(overlay.cskr, ci.cinf);
|
||||||
cskrCinfToChar[overlay.cskr] = std::make_pair(entry.second->id,
|
cskrCinfToChar[overlay.cskr] = std::make_pair(entry.second.id,
|
||||||
hecl::Format("%s.%s.CSKR", ci.name.c_str(), overlay.type.toString().c_str()));
|
hecl::Format("%s.%s.CSKR", ci.name.c_str(), overlay.type.toString().c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -210,16 +212,16 @@ void PAKBridge::addMAPATransforms(PAKRouter<PAKBridge>& pakRouter,
|
||||||
std::unordered_map<UniqueID64, zeus::CMatrix4f>& addTo,
|
std::unordered_map<UniqueID64, zeus::CMatrix4f>& addTo,
|
||||||
std::unordered_map<UniqueID64, hecl::ProjectPath>& pathOverrides) const
|
std::unordered_map<UniqueID64, hecl::ProjectPath>& pathOverrides) const
|
||||||
{
|
{
|
||||||
for (const std::pair<UniqueID64, PAK::Entry*>& entry : m_pak.m_idMap)
|
for (const std::pair<UniqueID64, PAK::Entry>& entry : m_pak.m_entries)
|
||||||
{
|
{
|
||||||
if (entry.second->type == FOURCC('MLVL'))
|
if (entry.second.type == FOURCC('MLVL'))
|
||||||
{
|
{
|
||||||
MLVL mlvl;
|
MLVL mlvl;
|
||||||
{
|
{
|
||||||
PAKEntryReadStream rs = entry.second->beginReadStream(m_node);
|
PAKEntryReadStream rs = entry.second.beginReadStream(m_node);
|
||||||
mlvl.read(rs);
|
mlvl.read(rs);
|
||||||
}
|
}
|
||||||
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(entry.second).getParentPath();
|
hecl::ProjectPath mlvlDirPath = pakRouter.getWorking(&entry.second).getParentPath();
|
||||||
|
|
||||||
if (mlvl.worldNameId)
|
if (mlvl.worldNameId)
|
||||||
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));
|
pathOverrides[mlvl.worldNameId] = hecl::ProjectPath(mlvlDirPath, _S("!name.yaml"));
|
||||||
|
|
|
@ -37,35 +37,24 @@ void PAK::read(athena::io::IStreamReader& reader)
|
||||||
m_entries.reserve(count);
|
m_entries.reserve(count);
|
||||||
m_firstEntries.clear();
|
m_firstEntries.clear();
|
||||||
m_firstEntries.reserve(count);
|
m_firstEntries.reserve(count);
|
||||||
m_idMap.clear();
|
|
||||||
m_idMap.reserve(count);
|
|
||||||
for (atUint32 e=0 ; e<count ; ++e)
|
for (atUint32 e=0 ; e<count ; ++e)
|
||||||
{
|
{
|
||||||
m_entries.emplace_back();
|
Entry entry;
|
||||||
m_entries.back().read(reader);
|
entry.read(reader);
|
||||||
m_entries.back().offset += dataOffset;
|
entry.offset += dataOffset;
|
||||||
}
|
|
||||||
for (Entry& entry : m_entries)
|
auto search = m_entries.find(entry.id);
|
||||||
{
|
if (search == m_entries.end())
|
||||||
auto search = m_idMap.find(entry.id);
|
|
||||||
if (search == m_idMap.end())
|
|
||||||
{
|
{
|
||||||
m_firstEntries.push_back(&entry);
|
m_firstEntries.push_back(entry.id);
|
||||||
m_idMap[entry.id] = &entry;
|
m_entries[entry.id] = std::move(entry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_nameMap.clear();
|
m_nameMap.clear();
|
||||||
m_nameMap.reserve(nameCount);
|
m_nameMap.reserve(nameCount);
|
||||||
for (NameEntry& entry : m_nameEntries)
|
for (NameEntry& entry : m_nameEntries)
|
||||||
{
|
m_nameMap[entry.name] = entry.id;
|
||||||
auto search = m_idMap.find(entry.id);
|
|
||||||
if (search != m_idMap.end())
|
|
||||||
{
|
|
||||||
m_nameMap[entry.name] = search->second;
|
|
||||||
search->second->name = entry.name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
void PAK::write(athena::io::IStreamWriter& writer) const
|
void PAK::write(athena::io::IStreamWriter& writer) const
|
||||||
{
|
{
|
||||||
|
@ -88,8 +77,8 @@ void PAK::write(athena::io::IStreamWriter& writer) const
|
||||||
|
|
||||||
DNAFourCC("DATA").write(writer);
|
DNAFourCC("DATA").write(writer);
|
||||||
atUint32 dataSz = 0;
|
atUint32 dataSz = 0;
|
||||||
for (const Entry& entry : m_entries)
|
for (const auto& entry : m_entries)
|
||||||
dataSz += (entry.size + 63) & ~63;
|
dataSz += (entry.second.size + 63) & ~63;
|
||||||
atUint32 dataPad = ((dataSz + 63) & ~63) - dataSz;
|
atUint32 dataPad = ((dataSz + 63) & ~63) - dataSz;
|
||||||
dataSz += dataPad;
|
dataSz += dataPad;
|
||||||
writer.writeUint32Big(dataSz);
|
writer.writeUint32Big(dataSz);
|
||||||
|
@ -101,9 +90,9 @@ void PAK::write(athena::io::IStreamWriter& writer) const
|
||||||
writer.seek(strgPad, athena::Current);
|
writer.seek(strgPad, athena::Current);
|
||||||
|
|
||||||
writer.writeUint32Big((atUint32)m_entries.size());
|
writer.writeUint32Big((atUint32)m_entries.size());
|
||||||
for (const Entry& entry : m_entries)
|
for (const auto& entry : m_entries)
|
||||||
{
|
{
|
||||||
Entry copy = entry;
|
Entry copy = entry.second;
|
||||||
copy.offset -= dataOffset;
|
copy.offset -= dataOffset;
|
||||||
copy.write(writer);
|
copy.write(writer);
|
||||||
}
|
}
|
||||||
|
@ -129,8 +118,8 @@ size_t PAK::binarySize(size_t __isz) const
|
||||||
__isz += strgPad;
|
__isz += strgPad;
|
||||||
|
|
||||||
__isz += 4;
|
__isz += 4;
|
||||||
for (const Entry& entry : m_entries)
|
for (const auto& entry : m_entries)
|
||||||
__isz = entry.binarySize(__isz);
|
__isz = entry.second.binarySize(__isz);
|
||||||
__isz += rshdPad;
|
__isz += rshdPad;
|
||||||
|
|
||||||
return __isz;
|
return __isz;
|
||||||
|
@ -215,5 +204,40 @@ std::unique_ptr<atUint8[]> PAK::Entry::getBuffer(const nod::Node& pak, atUint64&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const PAK::Entry* PAK::lookupEntry(const UniqueID64& 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();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,43 +57,15 @@ struct PAK : BigDNA
|
||||||
};
|
};
|
||||||
|
|
||||||
std::vector<NameEntry> m_nameEntries;
|
std::vector<NameEntry> m_nameEntries;
|
||||||
std::vector<Entry> m_entries;
|
std::unordered_map<UniqueID64, Entry> m_entries;
|
||||||
std::vector<Entry*> m_firstEntries;
|
std::vector<UniqueID64> m_firstEntries;
|
||||||
std::unordered_map<UniqueID64, Entry*> m_idMap;
|
std::unordered_map<std::string, UniqueID64> m_nameMap;
|
||||||
std::unordered_map<std::string, Entry*> m_nameMap;
|
|
||||||
|
|
||||||
DECL_EXPLICIT_DNA
|
DECL_EXPLICIT_DNA
|
||||||
|
|
||||||
inline const Entry* lookupEntry(const UniqueID64& id) const
|
const Entry* lookupEntry(const UniqueID64& id) const;
|
||||||
{
|
const Entry* lookupEntry(const std::string& name) const;
|
||||||
std::unordered_map<UniqueID64, Entry*>::const_iterator result = m_idMap.find(id);
|
std::string bestEntryName(const Entry& entry, bool& named) const;
|
||||||
if (result != m_idMap.end())
|
|
||||||
return result->second;
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline 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;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
typedef UniqueID64 IDType;
|
typedef UniqueID64 IDType;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "CMorphBall.hpp"
|
#include "CMorphBall.hpp"
|
||||||
#include "CPlayer.hpp"
|
#include "CPlayer.hpp"
|
||||||
#include "CMorphBallShadow.hpp"
|
#include "CMorphBallShadow.hpp"
|
||||||
|
#include "Particle/CGenDescription.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit 406cff486a82467877dd99fbe01beefd5f0f27a6
|
Subproject commit c193e52b49ffa43b5cf5fe5d12994f6e273b0166
|
|
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 3.0)
|
||||||
project(visigen)
|
project(visigen)
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /EHsc")
|
||||||
else()
|
else()
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}\
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}\
|
||||||
-std=c++14 -Wno-multichar -fno-exceptions -Wno-narrowing -Wno-nullability-completeness -Werror=return-type")
|
-std=c++14 -Wno-multichar -fno-exceptions -Wno-narrowing -Wno-nullability-completeness -Werror=return-type")
|
||||||
|
|
Loading…
Reference in New Issue