metaforce/Runtime/CResLoader.cpp

205 lines
5.7 KiB
C++
Raw Normal View History

2015-08-23 23:58:07 +00:00
#include "CResLoader.hpp"
#include "CPakFile.hpp"
#include "CMemory.hpp"
#include "CCallStack.hpp"
2016-03-04 23:04:53 +00:00
namespace urde
2015-08-23 23:58:07 +00:00
{
const std::vector<u32>* CResLoader::GetTagListForFile(const std::string& name) const
{
std::string namePak = name + ".pak";
for (const std::unique_ptr<CPakFile>& pak : x1c_pakLoadedList)
2016-03-07 03:12:32 +00:00
if (!CStringExtras::CompareCaseInsensitive(namePak, pak->x18_path))
2015-08-23 23:58:07 +00:00
return &pak->GetDepList();
return nullptr;
}
void CResLoader::AddPakFileAsync(const std::string& name, bool flag)
{
std::string namePak = name + ".pak";
if (CDvdFile::FileExists(namePak.c_str()))
{
x34_pakLoadingList.emplace_back(new CPakFile(namePak, flag));
2015-08-23 23:58:07 +00:00
++x44_pakLoadingCount;
}
}
void CResLoader::AddPakFile(const std::string& name, bool flag)
{
AddPakFileAsync(name, flag);
while (x44_pakLoadingCount)
AsyncIdlePakLoading();
}
CInputStream* CResLoader::LoadNewResourcePartSync(const SObjectTag& tag, int offset, int length, void* extBuf)
{
void* buf = extBuf;
CPakFile* file = FindResourceForLoad(tag);
if (!buf)
2016-04-15 20:42:40 +00:00
buf = new u8[length];
2015-11-21 01:16:07 +00:00
file->SyncSeekRead(buf, length, ESeekOrigin::Begin, x50_cachedResInfo->x4_offset + offset);
return new CMemoryInStream((atUint8*)buf, length, !extBuf);
2015-08-23 23:58:07 +00:00
}
void CResLoader::LoadMemResourceSync(const SObjectTag& tag, void** bufOut, int* sizeOut)
{
CPakFile* file = FindResourceForLoad(tag);
2016-04-15 20:42:40 +00:00
void* buf = new u8[x50_cachedResInfo->x8_size];
2015-11-21 01:16:07 +00:00
file->SyncSeekRead(buf, x50_cachedResInfo->x8_size, ESeekOrigin::Begin,
2015-08-23 23:58:07 +00:00
x50_cachedResInfo->x4_offset);
*bufOut = buf;
*sizeOut = x50_cachedResInfo->x8_size;
}
CInputStream* CResLoader::LoadResourceFromMemorySync(const SObjectTag& tag, const void* buf)
{
FindResourceForLoad(tag);
CInputStream* newStrm = new CMemoryInStream((atUint8*)buf, x50_cachedResInfo->x8_size);
2015-08-23 23:58:07 +00:00
if (x50_cachedResInfo->xb_compressed)
{
newStrm->readUint32Big();
newStrm = new CZipInputStream(std::move(std::unique_ptr<CInputStream>(newStrm)));
2015-08-23 23:58:07 +00:00
}
return newStrm;
}
CInputStream* CResLoader::LoadNewResourceSync(const SObjectTag& tag, void* extBuf)
{
void* buf = extBuf;
CPakFile* file = FindResourceForLoad(tag);
size_t resSz = ROUND_UP_32(x50_cachedResInfo->x8_size);
if (!buf)
2016-04-15 20:42:40 +00:00
buf = new u8[resSz];
2015-11-21 01:16:07 +00:00
file->SyncSeekRead(buf, resSz, ESeekOrigin::Begin, x50_cachedResInfo->x4_offset);
CInputStream* newStrm = new CMemoryInStream((atUint8*)buf, resSz, !extBuf);
2015-08-23 23:58:07 +00:00
if (x50_cachedResInfo->xb_compressed)
{
newStrm->readUint32Big();
newStrm = new CZipInputStream(std::move(std::unique_ptr<CInputStream>(newStrm)));
2015-08-23 23:58:07 +00:00
}
return newStrm;
}
2016-03-07 03:12:32 +00:00
std::shared_ptr<IDvdRequest> CResLoader::LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf)
2015-08-23 23:58:07 +00:00
{
return FindResourceForLoad(tag.id)->AsyncSeekRead(buf, length,
2015-11-21 01:16:07 +00:00
ESeekOrigin::Begin, x50_cachedResInfo->x4_offset + offset);
2015-08-23 23:58:07 +00:00
}
2016-03-07 03:12:32 +00:00
std::shared_ptr<IDvdRequest> CResLoader::LoadResourceAsync(const SObjectTag& tag, void* buf)
2015-08-23 23:58:07 +00:00
{
return FindResourceForLoad(tag.id)->AsyncSeekRead(buf, ROUND_UP_32(x50_cachedResInfo->x8_size),
2015-11-21 01:16:07 +00:00
ESeekOrigin::Begin, x50_cachedResInfo->x4_offset);
2015-08-23 23:58:07 +00:00
}
bool CResLoader::GetResourceCompression(const SObjectTag& tag)
{
if (FindResource(tag.id))
return x50_cachedResInfo->xb_compressed;
return false;
}
u32 CResLoader::ResourceSize(const SObjectTag& tag)
{
if (FindResource(tag.id))
return x50_cachedResInfo->x8_size;
return false;
}
bool CResLoader::ResourceExists(const SObjectTag& tag)
{
return FindResource(tag.id);
}
2016-04-14 21:42:47 +00:00
FourCC CResLoader::GetResourceTypeById(u32 id) const
2015-08-23 23:58:07 +00:00
{
if (FindResource(id))
return x50_cachedResInfo->x0_type;
2015-08-31 03:44:42 +00:00
return FourCC();
2015-08-23 23:58:07 +00:00
}
2015-08-28 00:11:31 +00:00
const SObjectTag* CResLoader::GetResourceIdByName(const char* name) const
2015-08-23 23:58:07 +00:00
{
for (const std::unique_ptr<CPakFile>& file : x1c_pakLoadedList)
{
2015-08-28 00:11:31 +00:00
const SObjectTag* id = file->GetResIdByName(name);
2015-08-23 23:58:07 +00:00
if (id)
return id;
}
2015-08-28 00:11:31 +00:00
return nullptr;
2015-08-23 23:58:07 +00:00
}
bool CResLoader::AreAllPaksLoaded() const
{
return x44_pakLoadingCount == 0;
}
void CResLoader::AsyncIdlePakLoading()
{
for (auto it=x34_pakLoadingList.begin();
it != x34_pakLoadingList.end();
++it)
{
(*it)->AsyncIdle();
2015-11-21 01:16:07 +00:00
if ((*it)->x2c_asyncLoadPhase == CPakFile::EAsyncPhase::Loaded)
2015-08-23 23:58:07 +00:00
{
MoveToCorrectLoadedList(std::move(*it));
it = x34_pakLoadingList.erase(it);
--x44_pakLoadingCount;
}
}
}
2016-04-14 21:42:47 +00:00
bool CResLoader::FindResource(u32 id) const
2015-08-23 23:58:07 +00:00
{
for (const std::unique_ptr<CPakFile>& file : x1c_pakLoadedList)
2016-04-14 21:42:47 +00:00
if (((CResLoader*)this)->CacheFromPak(*file, id))
2015-08-23 23:58:07 +00:00
return true;
return false;
}
CPakFile* CResLoader::FindResourceForLoad(u32 id)
{
for (std::unique_ptr<CPakFile>& file : x1c_pakLoadedList)
if (CacheFromPakForLoad(*file, id))
return file.get();
return nullptr;
}
CPakFile* CResLoader::FindResourceForLoad(const SObjectTag& tag)
{
return FindResourceForLoad(tag.id);
}
bool CResLoader::CacheFromPakForLoad(CPakFile& file, u32 id)
{
const CPakFile::SResInfo* info = file.GetResInfoForLoad(id);
if (info)
{
x4c_cachedResId = id;
x50_cachedResInfo = info;
return true;
}
return false;
}
bool CResLoader::CacheFromPak(const CPakFile& file, u32 id)
{
const CPakFile::SResInfo* info = file.GetResInfo(id);
if (info)
{
x4c_cachedResId = id;
x50_cachedResInfo = info;
return true;
}
return false;
}
void CResLoader::MoveToCorrectLoadedList(std::unique_ptr<CPakFile>&& file)
{
x1c_pakLoadedList.push_back(std::move(file));
}
}