2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-14 02:31:21 +00:00

Add support for override paks

This commit is contained in:
Phillip Stephens 2019-11-21 07:37:08 -08:00
parent 6631bd1ead
commit 655dc01a06
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
6 changed files with 77 additions and 22 deletions

View File

@ -3,13 +3,14 @@
namespace urde { namespace urde {
static logvisor::Module Log("urde::CPakFile"); static logvisor::Module Log("urde::CPakFile");
CPakFile::CPakFile(std::string_view filename, bool buildDepList, bool worldPak) : CDvdFile(filename) { CPakFile::CPakFile(std::string_view filename, bool buildDepList, bool worldPak, bool override) : CDvdFile(filename) {
if (!CDvdFile::operator bool()) if (!CDvdFile::operator bool())
Log.report(logvisor::Fatal, fmt("{}: Unable to open"), GetPath()); Log.report(logvisor::Fatal, fmt("{}: Unable to open"), GetPath());
x28_24_buildDepList = buildDepList; x28_24_buildDepList = buildDepList;
//x28_24_buildDepList = true; // Always do this so URDE can rapidly pre-warm shaders //x28_24_buildDepList = true; // Always do this so URDE can rapidly pre-warm shaders
x28_26_worldPak = worldPak; x28_26_worldPak = worldPak;
x28_27_stashedInARAM = false; x28_27_stashedInARAM = false;
m_override = override;
} }
CPakFile::~CPakFile() { CPakFile::~CPakFile() {

View File

@ -38,10 +38,11 @@ public:
private: private:
union { union {
struct { struct {
bool x28_24_buildDepList; bool x28_24_buildDepList : 1;
bool x28_25_aramFile; bool x28_25_aramFile : 1;
bool x28_26_worldPak; bool x28_26_worldPak : 1;
bool x28_27_stashedInARAM; bool x28_27_stashedInARAM : 1;
bool m_override : 1;
}; };
u32 _dummy = 0; u32 _dummy = 0;
}; };
@ -67,7 +68,7 @@ private:
void Warmup(); void Warmup();
public: public:
CPakFile(std::string_view filename, bool buildDepList, bool worldPak); CPakFile(std::string_view filename, bool buildDepList, bool worldPak, bool override=false);
~CPakFile(); ~CPakFile();
const std::vector<std::pair<std::string, SObjectTag>>& GetNameList() const { return x54_nameList; } const std::vector<std::pair<std::string, SObjectTag>>& GetNameList() const { return x54_nameList; }
const std::vector<CAssetId>& GetDepList() const { return x64_depList; } const std::vector<CAssetId>& GetDepList() const { return x64_depList; }
@ -76,6 +77,7 @@ public:
const SResInfo* GetResInfoForLoadDirectionless(CAssetId id) const; const SResInfo* GetResInfoForLoadDirectionless(CAssetId id) const;
const SResInfo* GetResInfo(CAssetId id) const; const SResInfo* GetResInfo(CAssetId id) const;
bool IsWorldPak() const { return x28_26_worldPak; } bool IsWorldPak() const { return x28_26_worldPak; }
bool IsOverridePak() const { return m_override; }
u32 GetFakeStaticSize() const { return 0; } u32 GetFakeStaticSize() const { return 0; }
void AsyncIdle(); void AsyncIdle();
CAssetId GetMLVLId() const { return m_mlvlId; } CAssetId GetMLVLId() const { return m_mlvlId; }

View File

@ -16,16 +16,16 @@ const std::vector<CAssetId>* CResLoader::GetTagListForFile(std::string_view name
return nullptr; return nullptr;
} }
void CResLoader::AddPakFileAsync(std::string_view name, bool buildDepList, bool worldPak) { void CResLoader::AddPakFileAsync(std::string_view name, bool buildDepList, bool worldPak, bool override) {
const std::string namePak = std::string(name).append(".upak"); const std::string namePak = std::string(name).append(".upak");
if (CDvdFile::FileExists(namePak)) { if (CDvdFile::FileExists(namePak)) {
x30_pakLoadingList.emplace_back(std::make_unique<CPakFile>(namePak, buildDepList, worldPak)); x30_pakLoadingList.emplace_back(std::make_unique<CPakFile>(namePak, buildDepList, worldPak, override));
++x44_pakLoadingCount; ++x44_pakLoadingCount;
} }
} }
void CResLoader::AddPakFile(std::string_view name, bool samusPak, bool worldPak) { void CResLoader::AddPakFile(std::string_view name, bool samusPak, bool worldPak, bool override) {
AddPakFileAsync(name, samusPak, worldPak); AddPakFileAsync(name, samusPak, worldPak, override);
WaitForPakFileLoadingComplete(); WaitForPakFileLoadingComplete();
} }
@ -116,17 +116,30 @@ std::unique_ptr<u8[]> CResLoader::LoadNewResourcePartSync(const urde::SObjectTag
void CResLoader::GetTagListForFile(const char* pakName, std::vector<SObjectTag>& out) const { void CResLoader::GetTagListForFile(const char* pakName, std::vector<SObjectTag>& out) const {
std::string path = std::string(pakName) + ".upak"; std::string path = std::string(pakName) + ".upak";
for (const std::unique_ptr<CPakFile>& file : x18_pakLoadedList) {
if (CStringExtras::CompareCaseInsensitive(file->GetPath(), path)) { for (const std::unique_ptr<CPakFile>& file : m_overridePakList) {
auto& depList = file->GetDepList(); if (_GetTagListForFile(out, path, file))
out.reserve(depList.size());
for (const auto& dep : depList) {
auto resInfo = file->GetResInfo(dep);
out.emplace_back(resInfo->GetType(), dep);
}
return; return;
}
} }
for (const std::unique_ptr<CPakFile>& file : x18_pakLoadedList) {
if (_GetTagListForFile(out, path, file))
return;
}
}
bool CResLoader::_GetTagListForFile(std::vector<SObjectTag>& out, const std::string& path,
const std::unique_ptr<CPakFile>& file) const {
if (CStringExtras::CompareCaseInsensitive(file->GetPath(), path)) {
auto& depList = file->GetDepList();
out.reserve(depList.size());
for (const auto& dep : depList) {
auto resInfo = file->GetResInfo(dep);
out.emplace_back(resInfo->GetType(), dep);
}
return true;
}
return false;
} }
bool CResLoader::GetResourceCompression(const SObjectTag& tag) const { bool CResLoader::GetResourceCompression(const SObjectTag& tag) const {
@ -150,6 +163,10 @@ FourCC CResLoader::GetResourceTypeById(CAssetId id) const {
} }
const SObjectTag* CResLoader::GetResourceIdByName(std::string_view name) const { const SObjectTag* CResLoader::GetResourceIdByName(std::string_view name) const {
for (const std::unique_ptr<CPakFile>& file : m_overridePakList)
if (const SObjectTag* id = file->GetResIdByName(name))
return id;
for (const std::unique_ptr<CPakFile>& file : x18_pakLoadedList) for (const std::unique_ptr<CPakFile>& file : x18_pakLoadedList)
if (const SObjectTag* id = file->GetResIdByName(name)) if (const SObjectTag* id = file->GetResIdByName(name))
return id; return id;
@ -175,6 +192,12 @@ bool CResLoader::FindResource(CAssetId id) const {
if (x4c_cachedResId == id) if (x4c_cachedResId == id)
return true; return true;
for (auto it = m_overridePakList.begin(); it != m_overridePakList.end(); ++it) {
if (CacheFromPak(**it, id)) {
return true;
}
}
if (x48_curPak != x18_pakLoadedList.end()) if (x48_curPak != x18_pakLoadedList.end())
if (CacheFromPak(**x48_curPak, id)) if (CacheFromPak(**x48_curPak, id))
return true; return true;
@ -191,6 +214,12 @@ bool CResLoader::FindResource(CAssetId id) const {
} }
CPakFile* CResLoader::FindResourceForLoad(CAssetId id) { CPakFile* CResLoader::FindResourceForLoad(CAssetId id) {
for (auto it = m_overridePakList.begin(); it != m_overridePakList.end(); ++it) {
if (CacheFromPakForLoad(**it, id)) {
return &**it;
}
}
if (x48_curPak != x18_pakLoadedList.end()) if (x48_curPak != x18_pakLoadedList.end())
if (CacheFromPakForLoad(**x48_curPak, id)) if (CacheFromPakForLoad(**x48_curPak, id))
return &**x48_curPak; return &**x48_curPak;
@ -237,7 +266,10 @@ bool CResLoader::CacheFromPak(const CPakFile& file, CAssetId id) const {
} }
void CResLoader::MoveToCorrectLoadedList(std::unique_ptr<CPakFile>&& file) { void CResLoader::MoveToCorrectLoadedList(std::unique_ptr<CPakFile>&& file) {
x18_pakLoadedList.push_back(std::move(file)); if (file->IsOverridePak())
m_overridePakList.push_back(std::move(file));
else
x18_pakLoadedList.push_back(std::move(file));
} }
std::vector<std::pair<std::string, SObjectTag>> CResLoader::GetResourceIdToNameList() const { std::vector<std::pair<std::string, SObjectTag>> CResLoader::GetResourceIdToNameList() const {
@ -249,6 +281,13 @@ std::vector<std::pair<std::string, SObjectTag>> CResLoader::GetResourceIdToNameL
} }
void CResLoader::EnumerateResources(const std::function<bool(const SObjectTag&)>& lambda) const { void CResLoader::EnumerateResources(const std::function<bool(const SObjectTag&)>& lambda) const {
for (auto it = m_overridePakList.begin(); it != m_overridePakList.end(); ++it) {
for (const CAssetId& id : (*it)->GetDepList()) {
SObjectTag fcc(GetResourceTypeById(id), id);
if (!lambda(fcc))
return;
}
}
for (auto it = x18_pakLoadedList.begin(); it != x18_pakLoadedList.end(); ++it) { for (auto it = x18_pakLoadedList.begin(); it != x18_pakLoadedList.end(); ++it) {
for (const CAssetId& id : (*it)->GetDepList()) { for (const CAssetId& id : (*it)->GetDepList()) {
SObjectTag fcc(GetResourceTypeById(id), id); SObjectTag fcc(GetResourceTypeById(id), id);

View File

@ -19,17 +19,20 @@ class CResLoader {
// std::list<std::unique_ptr<CPakFile>> x0_aramList; // std::list<std::unique_ptr<CPakFile>> x0_aramList;
std::list<std::unique_ptr<CPakFile>> x18_pakLoadedList; std::list<std::unique_ptr<CPakFile>> x18_pakLoadedList;
std::list<std::unique_ptr<CPakFile>> x30_pakLoadingList; std::list<std::unique_ptr<CPakFile>> x30_pakLoadingList;
std::list<std::unique_ptr<CPakFile>> m_overridePakList; // URDE Addition, Trilogy has a similar mechanism, need to verify behavior against it
u32 x44_pakLoadingCount = 0; u32 x44_pakLoadingCount = 0;
std::list<std::unique_ptr<CPakFile>>::iterator x48_curPak; std::list<std::unique_ptr<CPakFile>>::iterator x48_curPak;
mutable CAssetId x4c_cachedResId; mutable CAssetId x4c_cachedResId;
mutable const CPakFile::SResInfo* x50_cachedResInfo = nullptr; mutable const CPakFile::SResInfo* x50_cachedResInfo = nullptr;
bool x54_forwardSeek = false; bool x54_forwardSeek = false;
bool _GetTagListForFile(std::vector<SObjectTag>& out, const std::string& path,
const std::unique_ptr<CPakFile>& file) const;
public: public:
CResLoader(); CResLoader();
const std::vector<CAssetId>* GetTagListForFile(std::string_view name) const; const std::vector<CAssetId>* GetTagListForFile(std::string_view name) const;
void AddPakFileAsync(std::string_view name, bool buildDepList, bool worldPak); void AddPakFileAsync(std::string_view name, bool buildDepList, bool worldPak, bool override=false);
void AddPakFile(std::string_view name, bool samusPak, bool worldPak); void AddPakFile(std::string_view name, bool samusPak, bool worldPak, bool override=false);
void WaitForPakFileLoadingComplete(); void WaitForPakFileLoadingComplete();
std::unique_ptr<CInputStream> LoadNewResourcePartSync(const SObjectTag& tag, u32 length, u32 offset, void* extBuf); std::unique_ptr<CInputStream> LoadNewResourcePartSync(const SObjectTag& tag, u32 length, u32 offset, void* extBuf);
void LoadMemResourceSync(const SObjectTag& tag, std::unique_ptr<u8[]>& bufOut, int* sizeOut); void LoadMemResourceSync(const SObjectTag& tag, std::unique_ptr<u8[]>& bufOut, int* sizeOut);

View File

@ -337,6 +337,13 @@ void CMain::AddWorldPaks() {
loader->WaitForPakFileLoadingComplete(); loader->WaitForPakFileLoadingComplete();
} }
void CMain::AddOverridePaks() {
if (CResLoader* loader = g_ResFactory->GetResLoader()) {
loader->AddPakFileAsync("URDE", false, false, true);
loader->WaitForPakFileLoadingComplete();
}
}
void CMain::ResetGameState() { void CMain::ResetGameState() {
CPersistentOptions sysOpts = g_GameState->SystemOptions(); CPersistentOptions sysOpts = g_GameState->SystemOptions();
CGameOptions gameOpts = g_GameState->GameOptions(); CGameOptions gameOpts = g_GameState->GameOptions();
@ -687,6 +694,7 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarMana
hecl::SConsoleCommand::ECommandFlags::Normal); hecl::SConsoleCommand::ECommandFlags::Normal);
InitializeSubsystems(); InitializeSubsystems();
AddOverridePaks();
x128_globalObjects.PostInitialize(); x128_globalObjects.PostInitialize();
x70_tweaks.RegisterTweaks(m_cvarMgr); x70_tweaks.RegisterTweaks(m_cvarMgr);
x70_tweaks.RegisterResourceTweaks(m_cvarMgr); x70_tweaks.RegisterResourceTweaks(m_cvarMgr);

View File

@ -102,6 +102,7 @@ public:
CScriptMazeNode::LoadMazeSeeds(); CScriptMazeNode::LoadMazeSeeds();
} }
void ResetGameState() { void ResetGameState() {
x134_gameState = std::make_unique<CGameState>(); x134_gameState = std::make_unique<CGameState>();
g_GameState = x134_gameState.get(); g_GameState = x134_gameState.get();
@ -256,6 +257,7 @@ public:
boo::IGraphicsCommandQueue* cmdQ, const boo::ObjToken<boo::ITextureR>& spareTex); boo::IGraphicsCommandQueue* cmdQ, const boo::ObjToken<boo::ITextureR>& spareTex);
void RegisterResourceTweaks(); void RegisterResourceTweaks();
void AddWorldPaks(); void AddWorldPaks();
void AddOverridePaks();
void ResetGameState(); void ResetGameState();
void StreamNewGameState(CBitStreamReader&, u32 idx); void StreamNewGameState(CBitStreamReader&, u32 idx);
void RefreshGameState(); void RefreshGameState();