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 {
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() {

View File

@ -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; }

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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();