mirror of https://github.com/AxioDL/metaforce.git
Add support for override paks
This commit is contained in:
parent
6631bd1ead
commit
655dc01a06
|
@ -3,13 +3,14 @@
|
|||
namespace urde {
|
||||
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())
|
||||
Log.report(logvisor::Fatal, fmt("{}: Unable to open"), GetPath());
|
||||
x28_24_buildDepList = buildDepList;
|
||||
//x28_24_buildDepList = true; // Always do this so URDE can rapidly pre-warm shaders
|
||||
x28_26_worldPak = worldPak;
|
||||
x28_27_stashedInARAM = false;
|
||||
m_override = override;
|
||||
}
|
||||
|
||||
CPakFile::~CPakFile() {
|
||||
|
|
|
@ -38,10 +38,11 @@ public:
|
|||
private:
|
||||
union {
|
||||
struct {
|
||||
bool x28_24_buildDepList;
|
||||
bool x28_25_aramFile;
|
||||
bool x28_26_worldPak;
|
||||
bool x28_27_stashedInARAM;
|
||||
bool x28_24_buildDepList : 1;
|
||||
bool x28_25_aramFile : 1;
|
||||
bool x28_26_worldPak : 1;
|
||||
bool x28_27_stashedInARAM : 1;
|
||||
bool m_override : 1;
|
||||
};
|
||||
u32 _dummy = 0;
|
||||
};
|
||||
|
@ -67,7 +68,7 @@ private:
|
|||
void Warmup();
|
||||
|
||||
public:
|
||||
CPakFile(std::string_view filename, bool buildDepList, bool worldPak);
|
||||
CPakFile(std::string_view filename, bool buildDepList, bool worldPak, bool override=false);
|
||||
~CPakFile();
|
||||
const std::vector<std::pair<std::string, SObjectTag>>& GetNameList() const { return x54_nameList; }
|
||||
const std::vector<CAssetId>& GetDepList() const { return x64_depList; }
|
||||
|
@ -76,6 +77,7 @@ public:
|
|||
const SResInfo* GetResInfoForLoadDirectionless(CAssetId id) const;
|
||||
const SResInfo* GetResInfo(CAssetId id) const;
|
||||
bool IsWorldPak() const { return x28_26_worldPak; }
|
||||
bool IsOverridePak() const { return m_override; }
|
||||
u32 GetFakeStaticSize() const { return 0; }
|
||||
void AsyncIdle();
|
||||
CAssetId GetMLVLId() const { return m_mlvlId; }
|
||||
|
|
|
@ -16,16 +16,16 @@ const std::vector<CAssetId>* CResLoader::GetTagListForFile(std::string_view name
|
|||
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");
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void CResLoader::AddPakFile(std::string_view name, bool samusPak, bool worldPak) {
|
||||
AddPakFileAsync(name, samusPak, worldPak);
|
||||
void CResLoader::AddPakFile(std::string_view name, bool samusPak, bool worldPak, bool override) {
|
||||
AddPakFileAsync(name, samusPak, worldPak, override);
|
||||
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 {
|
||||
std::string path = std::string(pakName) + ".upak";
|
||||
for (const std::unique_ptr<CPakFile>& file : x18_pakLoadedList) {
|
||||
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);
|
||||
}
|
||||
|
||||
for (const std::unique_ptr<CPakFile>& file : m_overridePakList) {
|
||||
if (_GetTagListForFile(out, path, file))
|
||||
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 {
|
||||
|
@ -150,6 +163,10 @@ FourCC CResLoader::GetResourceTypeById(CAssetId id) 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)
|
||||
if (const SObjectTag* id = file->GetResIdByName(name))
|
||||
return id;
|
||||
|
@ -175,6 +192,12 @@ bool CResLoader::FindResource(CAssetId id) const {
|
|||
if (x4c_cachedResId == id)
|
||||
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 (CacheFromPak(**x48_curPak, id))
|
||||
return true;
|
||||
|
@ -191,6 +214,12 @@ bool CResLoader::FindResource(CAssetId id) const {
|
|||
}
|
||||
|
||||
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 (CacheFromPakForLoad(**x48_curPak, id))
|
||||
return &**x48_curPak;
|
||||
|
@ -237,7 +266,10 @@ bool CResLoader::CacheFromPak(const CPakFile& file, CAssetId id) const {
|
|||
}
|
||||
|
||||
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 {
|
||||
|
@ -249,6 +281,13 @@ std::vector<std::pair<std::string, SObjectTag>> CResLoader::GetResourceIdToNameL
|
|||
}
|
||||
|
||||
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 (const CAssetId& id : (*it)->GetDepList()) {
|
||||
SObjectTag fcc(GetResourceTypeById(id), id);
|
||||
|
|
|
@ -19,17 +19,20 @@ class CResLoader {
|
|||
// std::list<std::unique_ptr<CPakFile>> x0_aramList;
|
||||
std::list<std::unique_ptr<CPakFile>> x18_pakLoadedList;
|
||||
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;
|
||||
std::list<std::unique_ptr<CPakFile>>::iterator x48_curPak;
|
||||
mutable CAssetId x4c_cachedResId;
|
||||
mutable const CPakFile::SResInfo* x50_cachedResInfo = nullptr;
|
||||
bool x54_forwardSeek = false;
|
||||
|
||||
bool _GetTagListForFile(std::vector<SObjectTag>& out, const std::string& path,
|
||||
const std::unique_ptr<CPakFile>& file) const;
|
||||
public:
|
||||
CResLoader();
|
||||
const std::vector<CAssetId>* GetTagListForFile(std::string_view name) const;
|
||||
void AddPakFileAsync(std::string_view name, bool buildDepList, bool worldPak);
|
||||
void AddPakFile(std::string_view name, bool samusPak, 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, bool override=false);
|
||||
void WaitForPakFileLoadingComplete();
|
||||
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);
|
||||
|
|
|
@ -337,6 +337,13 @@ void CMain::AddWorldPaks() {
|
|||
loader->WaitForPakFileLoadingComplete();
|
||||
}
|
||||
|
||||
void CMain::AddOverridePaks() {
|
||||
if (CResLoader* loader = g_ResFactory->GetResLoader()) {
|
||||
loader->AddPakFileAsync("URDE", false, false, true);
|
||||
loader->WaitForPakFileLoadingComplete();
|
||||
}
|
||||
}
|
||||
|
||||
void CMain::ResetGameState() {
|
||||
CPersistentOptions sysOpts = g_GameState->SystemOptions();
|
||||
CGameOptions gameOpts = g_GameState->GameOptions();
|
||||
|
@ -687,6 +694,7 @@ void CMain::Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarMana
|
|||
hecl::SConsoleCommand::ECommandFlags::Normal);
|
||||
|
||||
InitializeSubsystems();
|
||||
AddOverridePaks();
|
||||
x128_globalObjects.PostInitialize();
|
||||
x70_tweaks.RegisterTweaks(m_cvarMgr);
|
||||
x70_tweaks.RegisterResourceTweaks(m_cvarMgr);
|
||||
|
|
|
@ -102,6 +102,7 @@ public:
|
|||
CScriptMazeNode::LoadMazeSeeds();
|
||||
}
|
||||
|
||||
|
||||
void ResetGameState() {
|
||||
x134_gameState = std::make_unique<CGameState>();
|
||||
g_GameState = x134_gameState.get();
|
||||
|
@ -256,6 +257,7 @@ public:
|
|||
boo::IGraphicsCommandQueue* cmdQ, const boo::ObjToken<boo::ITextureR>& spareTex);
|
||||
void RegisterResourceTweaks();
|
||||
void AddWorldPaks();
|
||||
void AddOverridePaks();
|
||||
void ResetGameState();
|
||||
void StreamNewGameState(CBitStreamReader&, u32 idx);
|
||||
void RefreshGameState();
|
||||
|
|
Loading…
Reference in New Issue