Externally track MemoryRelays

This commit is contained in:
Phillip Stephens 2017-01-31 03:21:45 -08:00
parent 0ed44f1cdc
commit 5b5f3318b0
10 changed files with 471 additions and 379 deletions

View File

@ -20,7 +20,7 @@ struct ISTRG : BigYAML
virtual hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const=0; virtual hecl::SystemString getSystemString(const FourCC& lang, size_t idx) const=0;
virtual int32_t lookupIdx(const std::string& name) const=0; virtual int32_t lookupIdx(const std::string& name) const=0;
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const; virtual void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const;
}; };
std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader); std::unique_ptr<ISTRG> LoadSTRG(athena::io::IStreamReader& reader);

View File

@ -13,36 +13,59 @@ namespace DataSpec
namespace DNAMP1 namespace DNAMP1
{ {
bool MLVL::Extract(const SpecBase& dataSpec, bool MLVL::Extract(const SpecBase& dataSpec, PAKEntryReadStream& rs, const hecl::ProjectPath& outPath,
PAKEntryReadStream& rs, PAKRouter<PAKBridge>& pakRouter, const PAK::Entry& entry, bool force, hecl::BlenderToken& btok,
const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry,
bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged) std::function<void(const hecl::SystemChar*)> fileChanged)
{ {
MLVL mlvl; MLVL mlvl;
mlvl.read(rs); mlvl.read(rs);
const nod::Node* node;
const typename PAKRouter<PAKBridge>::EntryType* texEntry = pakRouter.lookupEntry(mlvl.saveWorldId, &node);
hecl::ProjectPath savwPath = pakRouter.getWorking(texEntry);
SAVW savw;
if (!savwPath.isNone())
{
savwPath.makeDirChain(false);
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
savw.read(rs);
}
atUint32 areaIdx = 0;
for (const MLVL::Area& area : mlvl.areas) for (const MLVL::Area& area : mlvl.areas)
{ {
hecl::ProjectPath areaDir = pakRouter.getWorking(area.areaMREAId).getParentPath(); hecl::ProjectPath areaDir = pakRouter.getWorking(area.areaMREAId).getParentPath();
{
athena::io::FileWriter fw(hecl::ProjectPath(areaDir, _S("!memoryid.yaml")).getAbsolutePath()); athena::io::FileWriter fw(hecl::ProjectPath(areaDir, _S("!memoryid.yaml")).getAbsolutePath());
athena::io::YAMLDocWriter w(nullptr); athena::io::YAMLDocWriter w(nullptr);
w.writeUint32("memoryid", area.areaId); w.writeUint32("memoryid", area.areaId);
w.finish(&fw); w.finish(&fw);
} }
{
athena::io::FileWriter fw(hecl::ProjectPath(areaDir, _S("!memoryrelays.yaml")).getAbsolutePath());
athena::io::YAMLDocWriter w(nullptr);
std::vector<atUint32> relayIds;
for (const atUint32& relay : savw.relays)
{
atUint16 aIdx = ((relay >> 16) & 0x3ff);
if (aIdx == areaIdx && std::find(relayIds.begin(), relayIds.end(), relay) == relayIds.end())
relayIds.push_back(relay);
}
w.enumerate<atUint32>("memrelays", relayIds);
w.finish(&fw);
}
areaIdx++;
}
athena::io::FileWriter writer(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath()); athena::io::FileWriter writer(outPath.getWithExtension(_S(".yaml"), true).getAbsolutePath());
mlvl.toYAMLStream(writer, static_cast<YAMLWriteMemberFn>(&MLVL::writeMeta)); mlvl.toYAMLStream(writer, static_cast<YAMLWriteMemberFn>(&MLVL::writeMeta));
hecl::BlenderConnection& conn = btok.getBlenderConnection(); hecl::BlenderConnection& conn = btok.getBlenderConnection();
return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, return DNAMLVL::ReadMLVLToBlender(conn, mlvl, outPath, pakRouter, entry, force, fileChanged);
entry, force, fileChanged);
} }
bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const World& wld,
const World& wld, hecl::BlenderToken& btok) hecl::BlenderToken& btok)
{ {
MLVL mlvl = {}; MLVL mlvl = {};
athena::io::FileReader reader(inPath.getWithExtension(_S(".yaml"), true).getAbsolutePath()); athena::io::FileReader reader(inPath.getWithExtension(_S(".yaml"), true).getAbsolutePath());
@ -77,8 +100,24 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
if (!areaPath.isFile()) if (!areaPath.isFile())
continue; continue;
hecl::DirectoryEnumerator dEnum(area.path.getAbsolutePath(), hecl::ProjectPath memRelayPath(area.path, _S("/!memoryrelays.yaml"));
hecl::DirectoryEnumerator::Mode::DirsSorted);
std::vector<atUint32> memRelays;
if (memRelayPath.isFile())
{
athena::io::FileReader fr(memRelayPath.getAbsolutePath());
athena::io::YAMLDocReader r;
if (r.parse(&fr))
r.enumerate<atUint32>("memrelays", memRelays);
}
savw.relays.insert(savw.relays.end(), memRelays.begin(), memRelays.end());
/* Bare minimum we'll need exactly the same number of links as relays */
std::vector<MemRelayLink> memRelayLinks(memRelays.size());
hecl::DirectoryEnumerator dEnum(area.path.getAbsolutePath(), hecl::DirectoryEnumerator::Mode::DirsSorted);
bool areaInit = false; bool areaInit = false;
size_t layerIdx = 0; size_t layerIdx = 0;
@ -201,6 +240,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
MLVL::Area& areaOut = mlvl.areas.back(); MLVL::Area& areaOut = mlvl.areas.back();
areaOut.depLayers.push_back(areaOut.deps.size()); areaOut.depLayers.push_back(areaOut.deps.size());
/* Gather memory relays, scans, and dependencies */ /* Gather memory relays, scans, and dependencies */
{ {
g_ThreadBlenderToken.reset(&btok); g_ThreadBlenderToken.reset(&btok);
@ -213,14 +253,28 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
MemoryRelay& memRelay = static_cast<MemoryRelay&>(*obj); MemoryRelay& memRelay = static_cast<MemoryRelay&>(*obj);
for (IScriptObject::Connection& conn : memRelay.connections) for (IScriptObject::Connection& conn : memRelay.connections)
{ {
mlvl.memRelayLinks.emplace_back(); MemRelayLink linkOut;
MemRelayLink& linkOut = mlvl.memRelayLinks.back();
linkOut.memRelayId = memRelay.id; linkOut.memRelayId = memRelay.id;
linkOut.targetId = conn.target; linkOut.targetId = conn.target;
linkOut.msg = conn.msg; linkOut.msg = conn.msg;
linkOut.active = memRelay.active; linkOut.active = memRelay.active;
} auto iter = std::find(memRelays.begin(), memRelays.end(), linkOut.memRelayId);
if (iter == memRelays.end())
{
/* We must have a new relay, let's track it */
memRelayLinks.push_back(linkOut);
savw.relays.push_back(memRelay.id); savw.relays.push_back(memRelay.id);
memRelays.push_back(memRelay.id);
}
else /* Lets insert this in it's appropriate location, target order doesn't matter */
{
atUint32 idx = iter - memRelays.begin();
if (idx >= memRelayLinks.size())
memRelayLinks.push_back(linkOut);
else
memRelayLinks.insert(memRelayLinks.begin() + idx, linkOut);
}
}
} }
else if (obj->type == int(urde::EScriptObjectType::SpecialFunction)) else if (obj->type == int(urde::EScriptObjectType::SpecialFunction))
{ {
@ -286,6 +340,9 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
++layerIdx; ++layerIdx;
} }
/* Append Memory Relays */
mlvl.memRelayLinks.insert(mlvl.memRelayLinks.end(), memRelayLinks.begin(), memRelayLinks.end());
/* Cull duplicate area paths and add typed hash to list */ /* Cull duplicate area paths and add typed hash to list */
auto& conn = btok.getBlenderConnection(); auto& conn = btok.getBlenderConnection();
if (conn.openBlend(areaPath)) if (conn.openBlend(areaPath))
@ -332,8 +389,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
/* Write out MAPW */ /* Write out MAPW */
{ {
hecl::ProjectPath mapwCooked = hecl::ProjectPath mapwCooked = mapwPath.getCookedPath(*g_curSpec->overrideDataSpec(mapwPath, nullptr, btok));
mapwPath.getCookedPath(*g_curSpec->overrideDataSpec(mapwPath, nullptr, btok));
mapwCooked.makeDirChain(false); mapwCooked.makeDirChain(false);
athena::io::FileWriter fo(mapwCooked.getAbsolutePath()); athena::io::FileWriter fo(mapwCooked.getAbsolutePath());
fo.writeUint32Big(0xDEADF00D); fo.writeUint32Big(0xDEADF00D);
@ -352,8 +408,7 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
savw.doorCount = savw.doors.size(); savw.doorCount = savw.doors.size();
savw.scanCount = savw.scans.size(); savw.scanCount = savw.scans.size();
hecl::ProjectPath savwCooked = hecl::ProjectPath savwCooked = savwPath.getCookedPath(*g_curSpec->overrideDataSpec(savwPath, nullptr, btok));
savwPath.getCookedPath(*g_curSpec->overrideDataSpec(savwPath, nullptr, btok));
savwCooked.makeDirChain(false); savwCooked.makeDirChain(false);
athena::io::FileWriter fo(savwCooked.getAbsolutePath()); athena::io::FileWriter fo(savwCooked.getAbsolutePath());
savw.write(fo); savw.write(fo);
@ -361,6 +416,5 @@ bool MLVL::Cook(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPat
return true; return true;
} }
} }
} }

View File

@ -161,11 +161,8 @@ struct SCAN : BigYAML
return true; return true;
} }
static bool Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPath) static bool Cook(const SCAN& scan, const hecl::ProjectPath& outPath)
{ {
SCAN scan;
athena::io::FileReader reader(inPath.getAbsolutePath());
scan.fromYAMLStream(reader);
athena::io::FileWriter ws(outPath.getAbsolutePath()); athena::io::FileWriter ws(outPath.getAbsolutePath());
scan.write(ws); scan.write(ws);
return true; return true;
@ -204,6 +201,12 @@ struct SCAN : BigYAML
} }
} }
} }
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut)
{
for (int i = 0; i < 4; ++i)
g_curSpec->flattenDependencies(textures[i].texture, pathsOut);
}
}; };
} }
} }

View File

@ -6,22 +6,14 @@ namespace DataSpec
namespace DNAMP1 namespace DNAMP1
{ {
const std::vector<FourCC> skLanguages = const std::vector<FourCC> skLanguages = {FOURCC('ENGL'), FOURCC('FREN'), FOURCC('GERM'), FOURCC('SPAN'),
{ FOURCC('ITAL'), FOURCC('DUTC'), FOURCC('JAPN')};
FOURCC('ENGL'),
FOURCC('FREN'),
FOURCC('GERM'),
FOURCC('SPAN'),
FOURCC('ITAL'),
FOURCC('DUTC'),
FOURCC('JAPN')
};
static float u16stof(char16_t* str) static float u16stof(char16_t* str)
{ {
char cstr[16]; char cstr[16];
int i; int i;
for (i=0 ; i<15 && str[i] != u'\0' ; ++i) for (i = 0; i < 15 && str[i] != u'\0'; ++i)
cstr[i] = str[i]; cstr[i] = str[i];
cstr[i] = '\0'; cstr[i] = '\0';
return strtof(cstr, nullptr); return strtof(cstr, nullptr);
@ -31,18 +23,16 @@ static uint32_t ParseTag(const char16_t* str)
{ {
char parseStr[9]; char parseStr[9];
int i; int i;
for (i=0 ; i<8 && str[i] ; ++i) for (i = 0; i < 8 && str[i]; ++i)
parseStr[i] = str[i]; parseStr[i] = str[i];
parseStr[i] = '\0'; parseStr[i] = '\0';
return strtoul(parseStr, nullptr, 16); return strtoul(parseStr, nullptr, 16);
} }
static std::u16string::const_iterator SkipCommas(std::u16string& ret, static std::u16string::const_iterator SkipCommas(std::u16string& ret, const std::u16string& str,
const std::u16string& str, std::u16string::const_iterator it, size_t count)
std::u16string::const_iterator it,
size_t count)
{ {
for (size_t i=0 ; i<count ; ++i) for (size_t i = 0; i < count; ++i)
{ {
auto cpos = str.find(u',', it - str.begin()); auto cpos = str.find(u',', it - str.begin());
if (cpos == std::u16string::npos) if (cpos == std::u16string::npos)
@ -54,8 +44,7 @@ static std::u16string::const_iterator SkipCommas(std::u16string& ret,
return it; return it;
} }
static std::u16string::const_iterator UncookTextureList(std::u16string& ret, static std::u16string::const_iterator UncookTextureList(std::u16string& ret, const std::u16string& str,
const std::u16string& str,
std::u16string::const_iterator it) std::u16string::const_iterator it)
{ {
while (true) while (true)
@ -87,20 +76,17 @@ static std::u16string::const_iterator UncookTextureList(std::u16string& ret,
return str.begin() + scpos + 1; return str.begin() + scpos + 1;
} }
static std::u16string::const_iterator CookTextureList(std::u16string& ret, static std::u16string::const_iterator CookTextureList(std::u16string& ret, const std::u16string& str,
const std::u16string& str,
std::u16string::const_iterator it) std::u16string::const_iterator it)
{ {
while (true) while (true)
{ {
auto end = str.find_first_of(u",;", it - str.begin()); auto end = str.find_first_of(u",;", it - str.begin());
if (end == std::u16string::npos) if (end == std::u16string::npos)
Log.report(logvisor::Fatal, Log.report(logvisor::Fatal, "Missing comma/semicolon token while pasing font tag");
"Missing comma/semicolon token while pasing font tag");
auto endIt = str.begin() + end; auto endIt = str.begin() + end;
hecl::ProjectPath path = hecl::ProjectPath path =
UniqueIDBridge::MakePathFromString<UniqueID32>( UniqueIDBridge::MakePathFromString<UniqueID32>(hecl::Char16ToUTF8(std::u16string(it, endIt)));
hecl::Char16ToUTF8(std::u16string(it, endIt)));
ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString())); ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString()));
it = endIt; it = endIt;
if (*it == u';') if (*it == u';')
@ -126,11 +112,47 @@ static std::u16string::const_iterator CookTextureList(std::u16string& ret,
return str.begin() + scpos + 1; return str.begin() + scpos + 1;
} }
static std::u16string::const_iterator GatherTextureList(std::vector<hecl::ProjectPath>& pathsOut,
const std::u16string& str, std::u16string::const_iterator it)
{
while (true)
{
auto end = str.find_first_of(u",;", it - str.begin());
if (end == std::u16string::npos)
Log.report(logvisor::Fatal, "Missing comma/semicolon token while pasing font tag");
auto endIt = str.begin() + end;
hecl::ProjectPath path =
UniqueIDBridge::MakePathFromString<UniqueID32>(hecl::Char16ToUTF8(std::u16string(it, endIt)));
if (path)
pathsOut.push_back(path);
it = endIt;
if (*it == u';')
{
return it + 1;
}
else if (*it == u',')
{
++it;
}
else
{
break;
}
}
/* Failsafe */
auto scpos = str.find(u';', it - str.begin());
if (scpos == std::u16string::npos)
return str.end();
return str.begin() + scpos + 1;
}
static std::u16string UncookString(const std::u16string& str) static std::u16string UncookString(const std::u16string& str)
{ {
std::u16string ret; std::u16string ret;
ret.reserve(str.size()); ret.reserve(str.size());
for (auto it = str.begin() ; it != str.end() ;) for (auto it = str.begin(); it != str.end();)
{ {
if (*it == u'&') if (*it == u'&')
{ {
@ -202,7 +224,7 @@ static std::u16string CookString(const std::u16string& str)
{ {
std::u16string ret; std::u16string ret;
ret.reserve(str.size()); ret.reserve(str.size());
for (auto it = str.begin() ; it != str.end() ;) for (auto it = str.begin(); it != str.end();)
{ {
if (*it == u'&') if (*it == u'&')
{ {
@ -238,8 +260,7 @@ static std::u16string CookString(const std::u16string& str)
auto scpos = str.find(u';', it - str.begin()); auto scpos = str.find(u';', it - str.begin());
if (scpos == std::u16string::npos) if (scpos == std::u16string::npos)
Log.report(logvisor::Fatal, "Missing semicolon token while pasing font tag"); Log.report(logvisor::Fatal, "Missing semicolon token while pasing font tag");
hecl::ProjectPath path = hecl::ProjectPath path = UniqueIDBridge::MakePathFromString<UniqueID32>(
UniqueIDBridge::MakePathFromString<UniqueID32>(
hecl::Char16ToUTF8(std::u16string(it, str.begin() + scpos))); hecl::Char16ToUTF8(std::u16string(it, str.begin() + scpos)));
ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString())); ret.append(hecl::UTF8ToChar16(UniqueID32(path).toString()));
ret.push_back(u';'); ret.push_back(u';');
@ -269,6 +290,68 @@ static std::u16string CookString(const std::u16string& str)
return ret; return ret;
} }
void STRG::gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
{
std::u16string skip;
for (const auto& lang : langs)
{
for (const std::u16string& str : lang.second)
{
for (auto it = str.begin(); it != str.end();)
{
if (*it == u'&')
{
++it;
if (!str.compare(it - str.begin(), 5, u"image"))
{
it += 6;
if (!str.compare(it - str.begin(), 1, u"A"))
{
it = SkipCommas(skip, str, it, 2);
it = GatherTextureList(pathsOut, str, it);
continue;
}
else if (!str.compare(it - str.begin(), 2, u"SA"))
{
it = SkipCommas(skip, str, it, 4);
it = GatherTextureList(pathsOut, str, it);
continue;
}
else if (!str.compare(it - str.begin(), 2, u"SI"))
{
it = SkipCommas(skip, str, it, 3);
it = GatherTextureList(pathsOut, str, it);
continue;
}
}
else if (!str.compare(it - str.begin(), 4, u"font"))
{
it += 5;
auto scpos = str.find(u';', it - str.begin());
if (scpos == std::u16string::npos)
Log.report(logvisor::Fatal, "Missing semicolon token while pasing font tag");
hecl::ProjectPath path = UniqueIDBridge::MakePathFromString<UniqueID32>(
hecl::Char16ToUTF8(std::u16string(it, str.begin() + scpos)));
if (path)
pathsOut.push_back(path);
it = str.begin() + scpos + 1;
}
else
{
auto scpos = str.find(u';', it - str.begin());
if (scpos == std::u16string::npos)
it = str.end();
else
it = str.begin() + scpos + 1;
}
}
else
++it;
}
}
}
}
void STRG::_read(athena::io::IStreamReader& reader) void STRG::_read(athena::io::IStreamReader& reader)
{ {
atUint32 langCount = reader.readUint32Big(); atUint32 langCount = reader.readUint32Big();
@ -277,7 +360,7 @@ void STRG::_read(athena::io::IStreamReader& reader)
std::vector<std::pair<FourCC, atUint32>> readLangs; std::vector<std::pair<FourCC, atUint32>> readLangs;
readLangs.reserve(langCount); readLangs.reserve(langCount);
for (atUint32 l=0 ; l<langCount ; ++l) for (atUint32 l = 0; l < langCount; ++l)
{ {
DNAFourCC lang; DNAFourCC lang;
lang.read(reader); lang.read(reader);
@ -294,7 +377,7 @@ void STRG::_read(athena::io::IStreamReader& reader)
reader.seek(tablesStart + lang.second, athena::SeekOrigin::Begin); reader.seek(tablesStart + lang.second, athena::SeekOrigin::Begin);
reader.readUint32Big(); // table size reader.readUint32Big(); // table size
atUint32 langStart = reader.position(); atUint32 langStart = reader.position();
for (atUint32 s=0 ; s<strCount ; ++s) for (atUint32 s = 0; s < strCount; ++s)
{ {
atUint32 strOffset = reader.readUint32Big(); atUint32 strOffset = reader.readUint32Big();
atUint32 tmpOffset = reader.position(); atUint32 tmpOffset = reader.position();
@ -342,7 +425,7 @@ void STRG::write(athena::io::IStreamWriter& writer) const
writer.writeUint32Big(offset); writer.writeUint32Big(offset);
offset += strCount * 4 + 4; offset += strCount * 4 + 4;
atUint32 langStrCount = lang.second.size(); atUint32 langStrCount = lang.second.size();
for (atUint32 s=0 ; s<strCount ; ++s) for (atUint32 s = 0; s < strCount; ++s)
{ {
std::u16string str = CookString(lang.second[s]); std::u16string str = CookString(lang.second[s]);
atUint32 chCount = str.size(); atUint32 chCount = str.size();
@ -360,7 +443,7 @@ void STRG::write(athena::io::IStreamWriter& writer) const
atUint32 langStrCount = lang.second.size(); atUint32 langStrCount = lang.second.size();
atUint32 tableSz = strCount * 4; atUint32 tableSz = strCount * 4;
auto strIt = langIt; auto strIt = langIt;
for (atUint32 s=0 ; s<strCount ; ++s) for (atUint32 s = 0; s < strCount; ++s)
{ {
if (s < langStrCount) if (s < langStrCount)
tableSz += ((strIt++)->size() + 1) * 2; tableSz += ((strIt++)->size() + 1) * 2;
@ -371,7 +454,7 @@ void STRG::write(athena::io::IStreamWriter& writer) const
offset = strCount * 4; offset = strCount * 4;
strIt = langIt; strIt = langIt;
for (atUint32 s=0 ; s<strCount ; ++s) for (atUint32 s = 0; s < strCount; ++s)
{ {
writer.writeUint32Big(offset); writer.writeUint32Big(offset);
if (s < langStrCount) if (s < langStrCount)
@ -381,7 +464,7 @@ void STRG::write(athena::io::IStreamWriter& writer) const
} }
strIt = langIt; strIt = langIt;
for (atUint32 s=0 ; s<strCount ; ++s) for (atUint32 s = 0; s < strCount; ++s)
{ {
if (s < langStrCount) if (s < langStrCount)
writer.writeU16StringBig(*strIt++); writer.writeU16StringBig(*strIt++);
@ -403,7 +486,7 @@ size_t STRG::binarySize(size_t __isz) const
for (const std::pair<FourCC, std::vector<std::u16string>>& lang : langs) for (const std::pair<FourCC, std::vector<std::u16string>>& lang : langs)
{ {
atUint32 langStrCount = lang.second.size(); atUint32 langStrCount = lang.second.size();
for (atUint32 s=0 ; s<strCount ; ++s) for (atUint32 s = 0; s < strCount; ++s)
{ {
if (s < langStrCount) if (s < langStrCount)
__isz += (CookString(lang.second[s]).size() + 1) * 2; __isz += (CookString(lang.second[s]).size() + 1) * 2;
@ -429,19 +512,22 @@ void STRG::read(athena::io::YAMLDocReader& reader)
if (lang.first.size() != 4) if (lang.first.size() != 4)
{ {
Log.report(logvisor::Warning, "STRG language string '%s' must be exactly 4 characters; skipping", lang.first.c_str()); Log.report(logvisor::Warning, "STRG language string '%s' must be exactly 4 characters; skipping",
lang.first.c_str());
return; return;
} }
if (lang.second->m_type != YAML_SEQUENCE_NODE) if (lang.second->m_type != YAML_SEQUENCE_NODE)
{ {
Log.report(logvisor::Warning, "STRG language string '%s' must contain a sequence; skipping", lang.first.c_str()); Log.report(logvisor::Warning, "STRG language string '%s' must contain a sequence; skipping",
lang.first.c_str());
return; return;
} }
for (const auto& str : lang.second->m_seqChildren) for (const auto& str : lang.second->m_seqChildren)
{ {
if (str->m_type != YAML_SCALAR_NODE) if (str->m_type != YAML_SCALAR_NODE)
{ {
Log.report(logvisor::Warning, "STRG language '%s' must contain all scalars; skipping", lang.first.c_str()); Log.report(logvisor::Warning, "STRG language '%s' must contain all scalars; skipping",
lang.first.c_str());
return; return;
} }
} }
@ -483,10 +569,6 @@ void STRG::write(athena::io::YAMLDocWriter& writer) const
} }
} }
const char* STRG::DNAType() const char* STRG::DNAType() { return "urde::DNAMP1::STRG"; }
{
return "urde::DNAMP1::STRG";
}
} }
} }

View File

@ -84,6 +84,7 @@ struct STRG : ISTRG
return true; return true;
} }
void gatherDependencies(std::vector<hecl::ProjectPath> &pathsOut) const;
}; };
} }

View File

@ -8,6 +8,7 @@
#include "DNAMP1/HINT.hpp" #include "DNAMP1/HINT.hpp"
#include "DNAMP1/MLVL.hpp" #include "DNAMP1/MLVL.hpp"
#include "DNAMP1/STRG.hpp" #include "DNAMP1/STRG.hpp"
#include "DNAMP1/SCAN.hpp"
#include "DNAMP1/CMDL.hpp" #include "DNAMP1/CMDL.hpp"
#include "DNAMP1/MREA.hpp" #include "DNAMP1/MREA.hpp"
#include "DNAMP1/ANCS.hpp" #include "DNAMP1/ANCS.hpp"
@ -50,12 +51,10 @@ extern hecl::Database::DataSpecEntry SpecEntMP1ORIG;
struct OriginalIDs struct OriginalIDs
{ {
static void Generate(PAKRouter<DNAMP1::PAKBridge>& pakRouter, static void Generate(PAKRouter<DNAMP1::PAKBridge>& pakRouter, hecl::Database::Project& project)
hecl::Database::Project& project)
{ {
std::vector<UniqueID32> originalIDs; std::vector<UniqueID32> originalIDs;
pakRouter.enumerateResources([&](const DNAMP1::PAK::Entry* ent) -> bool pakRouter.enumerateResources([&](const DNAMP1::PAK::Entry* ent) -> bool {
{
if (ent->type == FOURCC('MLVL') || ent->type == FOURCC('SCAN')) if (ent->type == FOURCC('MLVL') || ent->type == FOURCC('SCAN'))
originalIDs.push_back(ent->id); originalIDs.push_back(ent->id);
return true; return true;
@ -91,14 +90,11 @@ struct OriginalIDs
if (end != node.first.c_str() + 8) if (end != node.first.c_str() + 8)
continue; continue;
hecl::ProjectPath path(project.getProjectWorkingPath(), hecl::ProjectPath path(project.getProjectWorkingPath(), node.second->m_scalarString.c_str());
node.second->m_scalarString.c_str());
originalIDs.push_back(std::make_pair(id, path.hash().val32())); originalIDs.push_back(std::make_pair(id, path.hash().val32()));
} }
std::sort(originalIDs.begin(), originalIDs.end(), std::sort(originalIDs.begin(), originalIDs.end(),
[](const std::pair<UniqueID32, UniqueID32>& a, [](const std::pair<UniqueID32, UniqueID32>& a, const std::pair<UniqueID32, UniqueID32>& b) -> bool {
const std::pair<UniqueID32, UniqueID32>& b) -> bool
{
return a.first < b.first; return a.first < b.first;
}); });
@ -111,9 +107,7 @@ struct OriginalIDs
} }
std::sort(originalIDs.begin(), originalIDs.end(), std::sort(originalIDs.begin(), originalIDs.end(),
[](const std::pair<UniqueID32, UniqueID32>& a, [](const std::pair<UniqueID32, UniqueID32>& a, const std::pair<UniqueID32, UniqueID32>& b) -> bool {
const std::pair<UniqueID32, UniqueID32>& b) -> bool
{
return a.second < b.second; return a.second < b.second;
}); });
for (const auto& idPair : originalIDs) for (const auto& idPair : originalIDs)
@ -142,14 +136,14 @@ struct SpecMP1 : SpecBase
PAKRouter<DNAMP1::PAKBridge> m_pakRouter; PAKRouter<DNAMP1::PAKBridge> m_pakRouter;
SpecMP1(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc) SpecMP1(const hecl::Database::DataSpecEntry* specEntry, hecl::Database::Project& project, bool pc)
: SpecBase(specEntry, project, pc), : SpecBase(specEntry, project, pc)
m_workPath(project.getProjectWorkingPath(), _S("MP1")), , m_workPath(project.getProjectWorkingPath(), _S("MP1"))
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::Node& root, void buildPaks(nod::Node& root, const std::vector<hecl::SystemString>& args, ExtractReport& rep)
const std::vector<hecl::SystemString>& args,
ExtractReport& rep)
{ {
m_nonPaks.clear(); m_nonPaks.clear();
m_paks.clear(); m_paks.clear();
@ -199,7 +193,6 @@ struct SpecMP1 : SpecBase
} }
m_paks.emplace_back(m_project, child, good); m_paks.emplace_back(m_project, child, good);
} }
} }
@ -226,10 +219,8 @@ struct SpecMP1 : SpecBase
} }
} }
bool checkFromStandaloneDisc(nod::DiscBase& disc, bool checkFromStandaloneDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const hecl::SystemString& regstr, const std::vector<hecl::SystemString>& args, std::vector<ExtractReport>& reps)
const std::vector<hecl::SystemString>& args,
std::vector<ExtractReport>& reps)
{ {
nod::Partition* partition = disc.getDataPartition(); nod::Partition* partition = disc.getDataPartition();
std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf(); std::unique_ptr<uint8_t[]> dolBuf = partition->getDOLBuf();
@ -257,10 +248,8 @@ struct SpecMP1 : SpecBase
return true; return true;
} }
bool checkFromTrilogyDisc(nod::DiscBase& disc, bool checkFromTrilogyDisc(nod::DiscBase& disc, const hecl::SystemString& regstr,
const hecl::SystemString& regstr, const std::vector<hecl::SystemString>& args, std::vector<ExtractReport>& reps)
const std::vector<hecl::SystemString>& args,
std::vector<ExtractReport>& reps)
{ {
std::vector<hecl::SystemString> mp1args; std::vector<hecl::SystemString> mp1args;
bool doExtract = false; bool doExtract = false;
@ -328,10 +317,7 @@ struct SpecMP1 : SpecBase
m_workPath.makeDir(); m_workPath.makeDir();
progress(_S("Indexing PAKs"), _S(""), 2, 0.0); progress(_S("Indexing PAKs"), _S(""), 2, 0.0);
m_pakRouter.build(m_paks, [&progress](float factor) m_pakRouter.build(m_paks, [&progress](float factor) { progress(_S("Indexing PAKs"), _S(""), 2, factor); });
{
progress(_S("Indexing PAKs"), _S(""), 2, factor);
});
progress(_S("Indexing PAKs"), _S(""), 2, 1.0); progress(_S("Indexing PAKs"), _S(""), 2, 1.0);
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), _S("out")); hecl::ProjectPath outPath(m_project.getProjectWorkingPath(), _S("out"));
@ -388,11 +374,8 @@ struct SpecMP1 : SpecBase
progress(sysName.c_str(), _S(""), compIdx, 0.0); progress(sysName.c_str(), _S(""), compIdx, 0.0);
} }
hecl::SystemString pakName = sysName.sys_str(); hecl::SystemString pakName = sysName.sys_str();
process.addLambdaTransaction([&, pakName](hecl::BlenderToken& btok) process.addLambdaTransaction([&, pakName](hecl::BlenderToken& btok) {
{ m_pakRouter.extractResources(pak, force, btok, [&](const hecl::SystemChar* substr, float factor) {
m_pakRouter.extractResources(pak, force, btok,
[&](const hecl::SystemChar* substr, float factor)
{
std::unique_lock<std::mutex> lk(msgLock); std::unique_lock<std::mutex> lk(msgLock);
progress(pakName.c_str(), substr, compIdx, factor); progress(pakName.c_str(), substr, compIdx, factor);
}); });
@ -404,20 +387,11 @@ struct SpecMP1 : SpecBase
return true; return true;
} }
const hecl::Database::DataSpecEntry& getOriginalSpec() const const hecl::Database::DataSpecEntry& getOriginalSpec() const { return SpecEntMP1; }
{
return SpecEntMP1;
}
const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const const hecl::Database::DataSpecEntry& getUnmodifiedSpec() const { return SpecEntMP1ORIG; }
{
return SpecEntMP1ORIG;
}
hecl::ProjectPath getWorking(class UniqueID32& id) hecl::ProjectPath getWorking(class UniqueID32& id) { return m_pakRouter.getWorking(id); }
{
return m_pakRouter.getWorking(id);
}
bool checkPathPrefix(const hecl::ProjectPath& path) const bool checkPathPrefix(const hecl::ProjectPath& path) const
{ {
@ -428,12 +402,13 @@ struct SpecMP1 : SpecBase
{ {
athena::io::YAMLDocReader reader; athena::io::YAMLDocReader reader;
yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp); yaml_parser_set_input(reader.getParser(), (yaml_read_handler_t*)athena::io::YAMLAthenaReader, &fp);
return reader.ClassTypeOperation([](const char* classType) return reader.ClassTypeOperation([](const char* classType) {
{
if (!strcmp(classType, DNAMP1::MLVL::DNAType())) if (!strcmp(classType, DNAMP1::MLVL::DNAType()))
return true; return true;
else if (!strcmp(classType, DNAMP1::STRG::DNAType())) else if (!strcmp(classType, DNAMP1::STRG::DNAType()))
return true; return true;
else if (!strcmp(classType, DNAMP1::SCAN::DNAType()))
return true;
else if (!strcmp(classType, DNAParticle::GPSM<UniqueID32>::DNAType())) else if (!strcmp(classType, DNAParticle::GPSM<UniqueID32>::DNAType()))
return true; return true;
else if (!strcmp(classType, DNAParticle::SWSH<UniqueID32>::DNAType())) else if (!strcmp(classType, DNAParticle::SWSH<UniqueID32>::DNAType()))
@ -575,8 +550,7 @@ struct SpecMP1 : SpecBase
yaml_parser_set_input_file(reader.getParser(), fp); yaml_parser_set_input_file(reader.getParser(), fp);
urde::SObjectTag resTag; urde::SObjectTag resTag;
if (reader.ClassTypeOperation([&](const char* className) -> bool if (reader.ClassTypeOperation([&](const char* className) -> bool {
{
if (!strcmp(className, "GPSM")) if (!strcmp(className, "GPSM"))
{ {
resTag.type = SBIG('PART'); resTag.type = SBIG('PART');
@ -627,6 +601,11 @@ struct SpecMP1 : SpecBase
resTag.type = SBIG('STRG'); resTag.type = SBIG('STRG');
return true; return true;
} }
else if (!strcmp(className, "urde::DNAMP1::SCAN"))
{
resTag.type = SBIG('SCAN');
return true;
}
else if (!strcmp(className, "DataSpec::DNAMP1::CTweakPlayerRes") || else if (!strcmp(className, "DataSpec::DNAMP1::CTweakPlayerRes") ||
!strcmp(className, "DataSpec::DNAMP1::CTweakGunRes") || !strcmp(className, "DataSpec::DNAMP1::CTweakGunRes") ||
!strcmp(className, "DataSpec::DNAMP1::CTweakSlideShow") || !strcmp(className, "DataSpec::DNAMP1::CTweakSlideShow") ||
@ -673,15 +652,12 @@ struct SpecMP1 : SpecBase
return {}; return {};
} }
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
BlendStream& ds, bool fast, hecl::BlenderToken& btok, hecl::BlenderToken& btok, FCookProgress progress)
FCookProgress progress)
{ {
Mesh mesh = ds.compileMesh(fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, m_pc ? 16 : -1, Mesh mesh =
[&progress](int surfCount) ds.compileMesh(fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, m_pc ? 16 : -1,
{ [&progress](int surfCount) { progress(hecl::SysFormat(_S("%d"), surfCount).c_str()); });
progress(hecl::SysFormat(_S("%d"), surfCount).c_str());
});
if (m_pc) if (m_pc)
DNAMP1::CMDL::HMDLCook(out, in, mesh); DNAMP1::CMDL::HMDLCook(out, in, mesh);
@ -689,14 +665,11 @@ struct SpecMP1 : SpecBase
DNAMP1::CMDL::Cook(out, in, mesh); DNAMP1::CMDL::Cook(out, in, mesh);
} }
void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
BlendStream& ds, bool fast, hecl::BlenderToken& btok, hecl::BlenderToken& btok, FCookProgress progress)
FCookProgress progress)
{ {
Actor actor = ds.compileActor(); Actor actor = ds.compileActor();
DNAMP1::ANCS::Cook(out, in, actor, ds, m_pc, DNAMP1::ANCS::Cook(out, in, actor, ds, m_pc, [&](const hecl::ProjectPath& modelPath) -> bool {
[&](const hecl::ProjectPath& modelPath) -> bool
{
hecl::ProjectPath cooked; hecl::ProjectPath cooked;
if (m_pc) if (m_pc)
cooked = modelPath.getCookedPath(SpecEntMP1PC); cooked = modelPath.getCookedPath(SpecEntMP1PC);
@ -707,9 +680,8 @@ struct SpecMP1 : SpecBase
}); });
} }
void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
BlendStream& ds, bool fast, hecl::BlenderToken& btok, hecl::BlenderToken& btok, FCookProgress progress)
FCookProgress progress)
{ {
std::vector<std::string> meshes = ds.getMeshList(); std::vector<std::string> meshes = ds.getMeshList();
std::vector<Mesh> meshCompiles; std::vector<Mesh> meshCompiles;
@ -726,11 +698,9 @@ struct SpecMP1 : SpecBase
progress(_S("Collision Mesh")); progress(_S("Collision Mesh"));
continue; continue;
} }
meshCompiles.push_back(ds.compileMesh(mesh, fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1, meshCompiles.push_back(ds.compileMesh(
[&](int surfCount) mesh, fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1,
{ [&](int surfCount) { progress(hecl::SysFormat(_S("%s %d"), meshSys.c_str(), surfCount).c_str()); }));
progress(hecl::SysFormat(_S("%s %d"), meshSys.c_str(), surfCount).c_str());
}));
} }
if (!colMesh) if (!colMesh)
@ -744,24 +714,22 @@ struct SpecMP1 : SpecBase
DNAMP1::MREA::Cook(out, in, meshCompiles, *colMesh, lights); DNAMP1::MREA::Cook(out, in, meshCompiles, *colMesh, lights);
} }
void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookWorld(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds, bool fast,
BlendStream& ds, bool fast, hecl::BlenderToken& btok, hecl::BlenderToken& btok, FCookProgress progress)
FCookProgress progress)
{ {
BlendStream::World world = ds.compileWorld(); BlendStream::World world = ds.compileWorld();
ds.close(); ds.close();
DNAMP1::MLVL::Cook(out, in, world, btok); DNAMP1::MLVL::Cook(out, in, world, btok);
} }
void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookGuiFrame(const hecl::ProjectPath& out, const hecl::ProjectPath& in, BlendStream& ds,
BlendStream& ds, hecl::BlenderToken& btok, hecl::BlenderToken& btok, FCookProgress progress)
FCookProgress progress)
{ {
ds.compileGuiFrame(out.getAbsolutePathUTF8(), 0); ds.compileGuiFrame(out.getAbsolutePathUTF8(), 0);
} }
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in, athena::io::IStreamReader& fin,
athena::io::IStreamReader& fin, FCookProgress progress) FCookProgress progress)
{ {
athena::io::YAMLDocReader reader; athena::io::YAMLDocReader reader;
if (reader.parse(&fin)) if (reader.parse(&fin))
@ -776,6 +744,12 @@ struct SpecMP1 : SpecBase
strg.read(reader); strg.read(reader);
DNAMP1::STRG::Cook(strg, out); DNAMP1::STRG::Cook(strg, out);
} }
else if (!classStr.compare(DNAMP1::SCAN::DNAType()))
{
DNAMP1::SCAN scan;
scan.read(reader);
DNAMP1::SCAN::Cook(scan, out);
}
else if (!classStr.compare(DNAParticle::GPSM<UniqueID32>::DNAType())) else if (!classStr.compare(DNAParticle::GPSM<UniqueID32>::DNAType()))
{ {
DNAParticle::GPSM<UniqueID32> gpsm; DNAParticle::GPSM<UniqueID32> gpsm;
@ -945,6 +919,12 @@ struct SpecMP1 : SpecBase
strg.read(reader); strg.read(reader);
strg.gatherDependencies(pathsOut); strg.gatherDependencies(pathsOut);
} }
if (!classStr.compare(DNAMP1::SCAN::DNAType()))
{
DNAMP1::SCAN scan;
scan.read(reader);
scan.gatherDependencies(pathsOut);
}
else if (!classStr.compare(DNAParticle::GPSM<UniqueID32>::DNAType())) else if (!classStr.compare(DNAParticle::GPSM<UniqueID32>::DNAType()))
{ {
DNAParticle::GPSM<UniqueID32> gpsm; DNAParticle::GPSM<UniqueID32> gpsm;
@ -990,49 +970,33 @@ struct SpecMP1 : SpecBase
} }
} }
void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookAudioGroup(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress)
FCookProgress progress)
{ {
DNAMP1::AGSC::Cook(in, out); DNAMP1::AGSC::Cook(in, out);
progress(_S("Done")); progress(_S("Done"));
} }
void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, void cookSong(const hecl::ProjectPath& out, const hecl::ProjectPath& in, FCookProgress progress)
FCookProgress progress)
{ {
DNAMP1::CSNG::Cook(in, out); DNAMP1::CSNG::Cook(in, out);
progress(_S("Done")); progress(_S("Done"));
} }
}; };
hecl::Database::DataSpecEntry SpecEntMP1 = hecl::Database::DataSpecEntry SpecEntMP1 = {
{ _S("MP1"), _S("Data specification for original Metroid Prime engine"),
_S("MP1"), [](hecl::Database::Project& project, hecl::Database::DataSpecTool) -> hecl::Database::IDataSpec* {
_S("Data specification for original Metroid Prime engine"), return new struct SpecMP1(&SpecEntMP1, project, false);
[](hecl::Database::Project& project, hecl::Database::DataSpecTool) }};
-> hecl::Database::IDataSpec* {return new struct SpecMP1(&SpecEntMP1, project, false);}
};
hecl::Database::DataSpecEntry SpecEntMP1PC = hecl::Database::DataSpecEntry SpecEntMP1PC = {
{ _S("MP1-PC"), _S("Data specification for PC-optimized Metroid Prime engine"),
_S("MP1-PC"), [](hecl::Database::Project& project, hecl::Database::DataSpecTool tool) -> hecl::Database::IDataSpec* {
_S("Data specification for PC-optimized Metroid Prime engine"),
[](hecl::Database::Project& project, hecl::Database::DataSpecTool tool)
-> hecl::Database::IDataSpec*
{
if (tool != hecl::Database::DataSpecTool::Extract) if (tool != hecl::Database::DataSpecTool::Extract)
return new struct SpecMP1(&SpecEntMP1PC, project, true); return new struct SpecMP1(&SpecEntMP1PC, project, true);
return nullptr; return nullptr;
} }};
};
hecl::Database::DataSpecEntry SpecEntMP1ORIG =
{
_S("MP1-ORIG"),
_S("Data specification for unmodified Metroid Prime resources"),
{}
};
hecl::Database::DataSpecEntry SpecEntMP1ORIG = {
_S("MP1-ORIG"), _S("Data specification for unmodified Metroid Prime resources"), {}};
} }

View File

@ -19,6 +19,7 @@
#include "Runtime/Collision/CCollidableOBBTreeGroup.hpp" #include "Runtime/Collision/CCollidableOBBTreeGroup.hpp"
#include "Runtime/CSaveWorld.hpp" #include "Runtime/CSaveWorld.hpp"
#include "Runtime/AutoMapper/CMapWorld.hpp" #include "Runtime/AutoMapper/CMapWorld.hpp"
#include "Runtime/CScannableObjectInfo.hpp"
#include "Audio/CAudioGroupSet.hpp" #include "Audio/CAudioGroupSet.hpp"
#include "Audio/CSfxManager.hpp" #include "Audio/CSfxManager.hpp"
#include "Runtime/CDependencyGroup.hpp" #include "Runtime/CDependencyGroup.hpp"
@ -108,6 +109,7 @@ ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& client
m_factoryMgr.AddFactory(FOURCC('SAVW'), FFactoryFunc(FSaveWorldFactory)); m_factoryMgr.AddFactory(FOURCC('SAVW'), FFactoryFunc(FSaveWorldFactory));
m_factoryMgr.AddFactory(FOURCC('MAPW'), FFactoryFunc(FMapWorldFactory)); m_factoryMgr.AddFactory(FOURCC('MAPW'), FFactoryFunc(FMapWorldFactory));
m_factoryMgr.AddFactory(FOURCC('OIDS'), FFactoryFunc(FMP1OriginalIDsFactory)); m_factoryMgr.AddFactory(FOURCC('OIDS'), FFactoryFunc(FMP1OriginalIDsFactory));
m_factoryMgr.AddFactory(FOURCC('SCAN'), FFactoryFunc(FScannableObjectInfoFactory));
} }
void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj, CSimplePool& sp) void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj, CSimplePool& sp)

View File

@ -3,32 +3,19 @@
namespace urde namespace urde
{ {
CScannableObjectInfo::CScannableObjectInfo(CInputStream& in, ResId resId) CScannableObjectInfo::CScannableObjectInfo(CInputStream& in, ResId resId) : x0_scannableObjectId(resId)
: x0_scannableObjectId(resId)
{ {
u32 version = in.readUint32Big(); u32 version = in.readUint32Big();
Load(in, version); Load(in, version);
} }
ResId CScannableObjectInfo::GetScannableObjectId() const ResId CScannableObjectInfo::GetScannableObjectId() const { return x0_scannableObjectId; }
{
return x0_scannableObjectId;
}
ResId CScannableObjectInfo::GetStringTableId() const ResId CScannableObjectInfo::GetStringTableId() const { return x4_stringId; }
{
return x4_stringId;
}
float CScannableObjectInfo::GetTotalDownloadTime() const float CScannableObjectInfo::GetTotalDownloadTime() const { return x8_totalDownloadTime; }
{
return x8_totalDownloadTime;
}
const CScannableObjectInfo::SBucket& CScannableObjectInfo::GetBucket(s32 idx) const const CScannableObjectInfo::SBucket& CScannableObjectInfo::GetBucket(s32 idx) const { return x14_buckets[idx]; }
{
return x14_buckets[idx];
}
void CScannableObjectInfo::Load(CInputStream& in, u32 version) void CScannableObjectInfo::Load(CInputStream& in, u32 version)
{ {
@ -46,7 +33,7 @@ void CScannableObjectInfo::Load(CInputStream& in, u32 version)
if (version > 4) if (version > 4)
x10_important = in.readBool(); x10_important = in.readBool();
for (u32 i = 0 ; i<4 ; i++) for (u32 i = 0; i < 4; i++)
x14_buckets.emplace_back(in, version); x14_buckets.emplace_back(in, version);
} }
@ -65,9 +52,9 @@ CScannableObjectInfo::SBucket::SBucket(CInputStream& in, u32 version)
} }
} }
CFactoryFnReturn FScannableObjectInfoFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer &) CFactoryFnReturn FScannableObjectInfoFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer&,
CObjectReference* selfRef)
{ {
return TToken<CScannableObjectInfo>::GetIObjObjectFor(std::make_unique<CScannableObjectInfo>(in, tag.id)); return TToken<CScannableObjectInfo>::GetIObjObjectFor(std::make_unique<CScannableObjectInfo>(in, tag.id));
} }
} }

View File

@ -34,6 +34,7 @@ private:
u32 xc_category = 0; u32 xc_category = 0;
bool x10_important = false; bool x10_important = false;
rstl::reserved_vector<SBucket, 4> x14_buckets; rstl::reserved_vector<SBucket, 4> x14_buckets;
public: public:
CScannableObjectInfo(CInputStream&, ResId); CScannableObjectInfo(CInputStream&, ResId);
ResId GetStringTableId() const; ResId GetStringTableId() const;
@ -43,6 +44,7 @@ public:
bool IsImportant() const; bool IsImportant() const;
}; };
CFactoryFnReturn FScannableObjectInfoFactory(const SObjectTag&, CInputStream&, const CVParamTransfer&); CFactoryFnReturn FScannableObjectInfoFactory(const SObjectTag&, CInputStream&, const CVParamTransfer&,
CObjectReference* selfRef);
} }
#endif // __URDE_CSCANNABLEOBJECTINFO_HPP__ #endif // __URDE_CSCANNABLEOBJECTINFO_HPP__

View File

@ -23,9 +23,7 @@ void CScriptGenerator::Accept(IVisitor& visitor) { visitor.Visit(this); }
void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr) void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, CStateManager& stateMgr)
{ {
if (msg == EScriptObjectMessage::SetToZero && GetActive()) if (msg == EScriptObjectMessage::SetToZero && GetActive() && !x20_conns.empty())
{
if (!x20_conns.empty())
{ {
std::vector<TUniqueId> follows; std::vector<TUniqueId> follows;
follows.reserve(x20_conns.size()); follows.reserve(x20_conns.size());
@ -132,7 +130,6 @@ void CScriptGenerator::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId
} }
} }
} }
}
CEntity::AcceptScriptMsg(msg, objId, stateMgr); CEntity::AcceptScriptMsg(msg, objId, stateMgr);
} }