Lots of CResFactory fixes

This commit is contained in:
Jack Andersen 2017-10-27 00:10:32 -10:00
parent 8346f56595
commit 2f4cddd3d2
29 changed files with 210 additions and 139 deletions

View File

@ -512,7 +512,6 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
if (!visiGood)
{
hecl::ProjectPath visiIntOut = outPath.getWithExtension(_S(".visiint"));
hecl::ProjectPath visiIn = inPath.getWithExtension(_S(".visi"));
athena::io::FileWriter w(visiIntOut.getAbsolutePath());
w.writeUint32Big(meshes.size());
for (const DNACMDL::Mesh& mesh : meshes)
@ -568,16 +567,20 @@ bool MREA::PCCook(const hecl::ProjectPath& outPath,
#endif
const hecl::SystemChar* args[] = {VisiGenPath.c_str(),
visiIntOut.getAbsolutePath().c_str(),
visiIn.getAbsolutePath().c_str(),
preVisiPath.getAbsolutePath().c_str(),
thrIdx, parPid, nullptr};
if (0 == hecl::RunProcess(VisiGenPath.c_str(), args))
{
athena::io::FileReader r(visiIn.getAbsolutePath());
athena::io::FileReader r(preVisiPath.getAbsolutePath());
size_t length = r.length();
secs.emplace_back(length, 0);
r.readBytesToBuf(secs.back().data(), length);
visiGood = true;
}
else
{
Log.report(logvisor::Fatal, _S("Unable to launch %s"), VisiGenPath.c_str());
}
}
}
}

View File

@ -441,14 +441,7 @@ bool SpecBase::canPackage(const hecl::ProjectPath& path)
auto components = path.getPathComponents();
if (components.size() <= 1)
return false;
hecl::ProjectPath outDir(m_project.getProjectWorkingPath(), _S("out"));
if (path.getPathType() == hecl::ProjectPath::Type::File &&
!hecl::StrCmp(path.getLastComponent(), _S("!world.blend")))
return true;
else if (path.getPathType() == hecl::ProjectPath::Type::Directory)
return true;
return false;
return path.isFile() || path.isDirectory();
}
void SpecBase::recursiveBuildResourceList(std::vector<urde::SObjectTag>& listOut,
@ -537,7 +530,7 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
waitForIndexComplete();
/* Name pak based on root-relative components */
auto components = path.getPathComponents();
auto components = path.getWithExtension(_S(""), true).getPathComponents();
if (components.size() <= 1)
return;
hecl::ProjectPath outPath(m_project.getProjectWorkingPath(),
@ -582,6 +575,38 @@ void SpecBase::doPackage(const hecl::ProjectPath& path, const hecl::Database::Da
for (int64_t i=0 ; i<32-rem ; ++i)
pakOut.writeUByte(0xff);
}
else if (path.getPathType() == hecl::ProjectPath::Type::File) /* One-file General PAK */
{
/* Build resource list */
std::vector<hecl::ProjectPath> subPaths;
flattenDependencies(path, subPaths, btok);
std::unordered_set<urde::SObjectTag> addedTags;
std::vector<std::pair<urde::SObjectTag, std::string>> nameList;
for (const auto& subPath : subPaths)
{
if (urde::SObjectTag tag = tagFromPath(subPath, btok))
{
if (addedTags.find(tag) != addedTags.end())
continue;
addedTags.insert(tag);
buildList.push_back(tag);
}
}
/* Build name list */
for (const auto& item : buildList)
{
auto search = m_catalogTagToName.find(item);
if (search != m_catalogTagToName.end())
nameList.emplace_back(item, search->second);
}
/* Write resource list structure */
buildPakList(btok, pakOut, buildList, nameList, resTableOffset);
if (int64_t rem = pakOut.position() % 32)
for (int64_t i=0 ; i<32-rem ; ++i)
pakOut.writeUByte(0xff);
}
/* Async cook resource list if using ClientProcess */
if (cp)

View File

@ -1165,8 +1165,6 @@ struct SpecMP1 : SpecBase
nameEnt.name = parentDir.getLastComponent();
nameEnt.write(w);
w.writeUint32Big(atUint32(count));
resTableOffset = w.position();
for (const auto& area : mlvl.areas)
for (const auto& dep : area.deps)
listOut.push_back({dep.type, dep.id.toUint32()});
@ -1231,6 +1229,8 @@ struct SpecMP1 : SpecBase
listOut.push_back(worldTag);
w.writeUint32Big(atUint32(listOut.size()));
resTableOffset = w.position();
for (const auto& item : listOut)
{
DNAMP1::PAK::Entry ent;

View File

@ -55,5 +55,7 @@ add_dependencies(urde visigen hecl)
add_custom_command(TARGET urde POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:visigen> $<TARGET_FILE_DIR:urde>)
add_custom_command(TARGET urde POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:visigen> $<TARGET_FILE_DIR:hecl>)
add_custom_command(TARGET urde POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:hecl> $<TARGET_FILE_DIR:urde>)

View File

@ -160,7 +160,7 @@ bool ProjectResourceFactoryBase::AsyncTask::AsyncPump()
return m_failed;
}
void ProjectResourceFactoryBase::AsyncTask::WaitForComplete()
void ProjectResourceFactoryBase::AsyncTask::WaitUntilComplete()
{
using ItType = std::unordered_map<SObjectTag,
std::list<std::shared_ptr<AsyncTask>>::iterator>::iterator;
@ -365,37 +365,25 @@ u32 ProjectResourceFactoryBase::ResourceSize(const SObjectTag& tag)
return fr->length();
}
std::shared_ptr<AsyncTask>
ProjectResourceFactoryBase::LoadResourceAsync(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>& target)
std::shared_ptr<urde::IDvdRequest>
ProjectResourceFactoryBase::LoadResourceAsync(const urde::SObjectTag& tag, void* target)
{
if (!tag.id.IsValid())
Log.report(logvisor::Fatal, "attempted to access null id");
if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end())
return {};
return _AddTask(std::make_shared<AsyncTask>(*this, tag, target));
return std::static_pointer_cast<urde::IDvdRequest>(_AddTask(std::make_shared<AsyncTask>(*this, tag, reinterpret_cast<u8*>(target))));
}
std::shared_ptr<AsyncTask>
std::shared_ptr<urde::IDvdRequest>
ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag,
u32 size, u32 off,
std::unique_ptr<u8[]>& target)
u32 size, u32 off, void* target)
{
if (!tag.id.IsValid())
Log.report(logvisor::Fatal, "attempted to access null id");
if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end())
return {};
return _AddTask(std::make_shared<AsyncTask>(*this, tag, target, size, off));
}
std::shared_ptr<AsyncTask>
ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, u8* target)
{
if (!tag.id.IsValid())
Log.report(logvisor::Fatal, "attempted to access null id");
if (m_asyncLoadMap.find(tag) != m_asyncLoadMap.end())
return {};
return _AddTask(std::make_shared<AsyncTask>(*this, tag, target, size, off));
return std::static_pointer_cast<urde::IDvdRequest>(_AddTask(std::make_shared<AsyncTask>(*this, tag, reinterpret_cast<u8*>(target), size, off)));
}
std::unique_ptr<u8[]> ProjectResourceFactoryBase::LoadResourceSync(const urde::SObjectTag& tag)

View File

@ -21,7 +21,7 @@ class ProjectResourceFactoryBase : public IFactory
hecl::ClientProcess& m_clientProc;
public:
struct AsyncTask
struct AsyncTask : urde::IDvdRequest
{
ProjectResourceFactoryBase& m_parent;
@ -52,6 +52,10 @@ public:
: m_parent(parent), x0_tag(tag), xc_targetDataPtr(&ptr), x14_resSize(size),
x14_resOffset(off) {}
AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag,
u8* ptr)
: m_parent(parent), x0_tag(tag), xc_targetDataRawPtr(ptr) {}
AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag,
u8* ptr, u32 size, u32 off)
: m_parent(parent), x0_tag(tag), xc_targetDataRawPtr(ptr), x14_resSize(size),
@ -69,7 +73,10 @@ public:
const hecl::ProjectPath& path);
void CookComplete();
bool AsyncPump();
void WaitForComplete();
void WaitUntilComplete();
bool IsComplete() { return m_complete; }
void PostCancelRequest() {}
EMediaType GetMediaType() const { return EMediaType::Real; }
};
protected:
@ -154,9 +161,8 @@ public:
void EnumerateNamedResources(const std::function<bool(const std::string&, const SObjectTag&)>& lambda) const;
u32 ResourceSize(const SObjectTag& tag);
std::shared_ptr<AsyncTask> LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr<u8[]>& target);
std::shared_ptr<AsyncTask> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr<u8[]>& target);
std::shared_ptr<AsyncTask> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, u8* target);
std::shared_ptr<urde::IDvdRequest> LoadResourceAsync(const urde::SObjectTag& tag, void* target);
std::shared_ptr<urde::IDvdRequest> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, void* target);
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);

View File

@ -73,7 +73,7 @@ static const FourCC TypeTable[] =
FOURCC('WPSC'), FOURCC('SWHC'), FOURCC('DPSC'), FOURCC('ELSC'), FOURCC('CRSC'), FOURCC('AFSM'),
FOURCC('DCLN'), FOURCC('AGSC'), FOURCC('ATBL'), FOURCC('CSNG'), FOURCC('STRG'), FOURCC('SCAN'),
FOURCC('PATH'), FOURCC('DGRP'), FOURCC('HMAP'), FOURCC('CTWK'), FOURCC('FRME'), FOURCC('HINT'),
FOURCC('MAPU'), FOURCC('DUMB')
FOURCC('MAPU'), FOURCC('DUMB'), FOURCC('OIDS')
};
CFactoryMgr::ETypeTable CFactoryMgr::FourCCToTypeIdx(FourCC fcc)

View File

@ -30,14 +30,14 @@ public:
enum class ETypeTable : s8
{
Invalid = -1,
CLSN, CMDL, CSKR, ANIM, CINF, TXTR,
PLTT, FONT, ANCS, EVNT, MADF, MLVL,
MREA, MAPW, MAPA, SAVW, SAVA, PART,
WPSC, SWHC, DPSC, ELSC, CRSC, AFSM,
DCLN, AGSC, ATBL, CSNG, STRG, SCAN,
PATH, DGRP, HMAP, CTWK, FRME, HINT,
MAPU, DUMB
MAPU, DUMB, OIDS,
Invalid = 127
};
static ETypeTable FourCCToTypeIdx(FourCC fcc);

View File

@ -7,8 +7,12 @@ static logvisor::Module Log("urde::CPakFile");
CPakFile::CPakFile(const std::string& filename, bool buildDepList, bool worldPak)
: CDvdFile(filename.c_str())
{
if (!CDvdFile::operator bool())
Log.report(logvisor::Fatal, "%s: Unable to open", GetPath().c_str());
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;
}
const SObjectTag* CPakFile::GetResIdByName(const char* name) const
@ -79,7 +83,7 @@ void CPakFile::InitialHeaderLoad()
x4c_resTableCount = r.readUint32Big();
x48_resTableOffset = u32(r.position());
x2c_asyncLoadPhase = EAsyncPhase::DataLoad;
u32 newSize = ROUND_UP_32(x4c_resTableCount * 16 + x48_resTableOffset);
u32 newSize = ROUND_UP_32(x4c_resTableCount * 20 + x48_resTableOffset);
u32 origSize = u32(x38_headerData.size());
if (newSize > origSize)
{
@ -103,10 +107,10 @@ void CPakFile::Warmup()
const CPakFile::SResInfo* CPakFile::GetResInfoForLoadPreferForward(CAssetId id) const
{
if (!x28_27_worldPakInitialized)
if (x28_27_stashedInARAM)
return nullptr;
auto search = std::lower_bound(x74_resList.begin(), x74_resList.end(), id,
[](const SResInfo& left, const CAssetId& right) { return left.x0_id < right; });
auto search = rstl::binary_find(x74_resList.begin(), x74_resList.end(), id,
[](const SResInfo& test) { return test.x0_id; });
if (search == x74_resList.end())
return nullptr;
const SResInfo* bestInfo = &*search;
@ -130,10 +134,10 @@ const CPakFile::SResInfo* CPakFile::GetResInfoForLoadPreferForward(CAssetId id)
const CPakFile::SResInfo* CPakFile::GetResInfoForLoadDirectionless(CAssetId id) const
{
if (!x28_27_worldPakInitialized)
if (x28_27_stashedInARAM)
return nullptr;
auto search = std::lower_bound(x74_resList.begin(), x74_resList.end(), id,
[](const SResInfo& left, const CAssetId& right) { return left.x0_id < right; });
auto search = rstl::binary_find(x74_resList.begin(), x74_resList.end(), id,
[](const SResInfo& test) { return test.x0_id; });
if (search == x74_resList.end())
return nullptr;
const SResInfo* bestInfo = &*search;
@ -158,7 +162,7 @@ const CPakFile::SResInfo* CPakFile::GetResInfo(CAssetId id) const
{
if (x2c_asyncLoadPhase != EAsyncPhase::Loaded)
return nullptr;
if (!x28_27_worldPakInitialized)
if (x28_27_stashedInARAM)
return nullptr;
auto search = rstl::binary_find(x74_resList.begin(), x74_resList.end(), id,
[](const SResInfo& i) { return i.x0_id; });
@ -171,7 +175,7 @@ void CPakFile::AsyncIdle()
{
if (x2c_asyncLoadPhase == EAsyncPhase::Loaded)
return;
if (x30_dvdReq && x30_dvdReq->IsComplete())
if (x30_dvdReq && !x30_dvdReq->IsComplete())
return;
switch (x2c_asyncLoadPhase)
{

View File

@ -44,7 +44,7 @@ private:
bool x28_24_buildDepList;
bool x28_25_aramFile;
bool x28_26_worldPak;
bool x28_27_worldPakInitialized;
bool x28_27_stashedInARAM;
};
u32 _dummy = 0;
};

View File

@ -3,6 +3,7 @@
namespace urde
{
static logvisor::Module Log("CResFactory");
void CResFactory::AddToLoadList(SLoadingData&& data)
{
@ -11,19 +12,22 @@ void CResFactory::AddToLoadList(SLoadingData&& data)
CFactoryFnReturn CResFactory::BuildSync(const SObjectTag& tag, const CVParamTransfer& xfer, CObjectReference* selfRef)
{
CFactoryFnReturn ret;
if (x5c_factoryMgr.CanMakeMemory(tag))
{
std::unique_ptr<uint8_t[]> data;
int size;
x4_loader.LoadMemResourceSync(tag, data, &size);
return x5c_factoryMgr.MakeObjectFromMemory(tag, std::move(data), size,
ret = x5c_factoryMgr.MakeObjectFromMemory(tag, std::move(data), size,
x4_loader.GetResourceCompression(tag), xfer, selfRef);
}
else
{
auto rp = x4_loader.LoadNewResourceSync(tag, nullptr);
return x5c_factoryMgr.MakeObject(tag, *rp, xfer, selfRef);
ret = x5c_factoryMgr.MakeObject(tag, *rp, xfer, selfRef);
}
Log.report(logvisor::Warning, "sync-built %.4s %08X", tag.type.getChars(), tag.id.Value());
return ret;
}
bool CResFactory::PumpResource(SLoadingData& data)
@ -34,6 +38,7 @@ bool CResFactory::PumpResource(SLoadingData& data)
x5c_factoryMgr.MakeObjectFromMemory(data.x0_tag, std::move(data.x10_loadBuffer),
data.x14_resSize, data.m_compressed, data.x18_cvXfer,
data.m_selfRef);
Log.report(logvisor::Info, "async-built %.4s %08X", data.x0_tag.type.getChars(), data.x0_tag.id.Value());
return true;
}
return false;
@ -60,13 +65,15 @@ void CResFactory::BuildAsync(const SObjectTag& tag, const CVParamTransfer& xfer,
{
SLoadingData data(tag, target, xfer, x4_loader.GetResourceCompression(tag), selfRef);
data.x10_loadBuffer = std::unique_ptr<u8[]>(new u8[x4_loader.ResourceSize(tag)]);
x4_loader.LoadResourceAsync(tag, data.x10_loadBuffer.get());
data.x8_dvdReq = x4_loader.LoadResourceAsync(tag, data.x10_loadBuffer.get());
AddToLoadList(std::move(data));
}
}
void CResFactory::AsyncIdle()
{
if (m_loadList.empty())
return;
auto startTime = std::chrono::steady_clock::now();
while (std::chrono::duration_cast<std::chrono::milliseconds>(
std::chrono::steady_clock::now() - startTime).count() < 2)

View File

@ -69,6 +69,16 @@ public:
return x4_loader.LoadResourcePartSync(tag, size, off);
}
std::shared_ptr<IDvdRequest> LoadResourceAsync(const urde::SObjectTag& tag, void* target)
{
return x4_loader.LoadResourceAsync(tag, target);
}
std::shared_ptr<IDvdRequest> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, void* target)
{
return x4_loader.LoadResourcePartAsync(tag, size, off, target);
}
const SObjectTag* GetResourceIdByName(const char* name) const
{
return x4_loader.GetResourceIdByName(name);
@ -97,6 +107,9 @@ public:
void LoadOriginalIDs(CSimplePool& sp);
CAssetId TranslateOriginalToNew(CAssetId id) const;
CAssetId TranslateNewToOriginal(CAssetId id) const;
CResLoader* GetResLoader() { return &x4_loader; }
CFactoryMgr* GetFactoryMgr() { return &x5c_factoryMgr; }
};
}

View File

@ -3,6 +3,7 @@
namespace urde
{
static logvisor::Module Log("CResLoader");
CResLoader::CResLoader()
{
@ -18,12 +19,12 @@ const std::vector<CAssetId>* CResLoader::GetTagListForFile(const std::string& na
return nullptr;
}
void CResLoader::AddPakFileAsync(const std::string& name, bool samusPak, bool worldPak)
void CResLoader::AddPakFileAsync(const std::string& name, bool buildDepList, bool worldPak)
{
std::string namePak = name + ".upak";
if (CDvdFile::FileExists(namePak.c_str()))
{
x30_pakLoadingList.emplace_back(new CPakFile(namePak, samusPak, worldPak));
x30_pakLoadingList.emplace_back(new CPakFile(namePak, buildDepList, worldPak));
++x44_pakLoadingCount;
}
}
@ -31,11 +32,16 @@ void CResLoader::AddPakFileAsync(const std::string& name, bool samusPak, bool wo
void CResLoader::AddPakFile(const std::string& name, bool samusPak, bool worldPak)
{
AddPakFileAsync(name, samusPak, worldPak);
WaitForPakFileLoadingComplete();
}
void CResLoader::WaitForPakFileLoadingComplete()
{
while (x44_pakLoadingCount)
AsyncIdlePakLoading();
}
std::unique_ptr<CInputStream> CResLoader::LoadNewResourcePartSync(const SObjectTag& tag, int offset, int length, void* extBuf)
std::unique_ptr<CInputStream> CResLoader::LoadNewResourcePartSync(const SObjectTag& tag, u32 length, u32 offset, void* extBuf)
{
void* buf = extBuf;
CPakFile* file = FindResourceForLoad(tag);
@ -83,7 +89,7 @@ std::unique_ptr<CInputStream> CResLoader::LoadNewResourceSync(const SObjectTag&
return std::unique_ptr<CInputStream>(newStrm);
}
std::shared_ptr<IDvdRequest> CResLoader::LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf)
std::shared_ptr<IDvdRequest> CResLoader::LoadResourcePartAsync(const SObjectTag& tag, u32 length, u32 offset, void* buf)
{
return FindResourceForLoad(tag.id)->AsyncSeekRead(buf, length,
ESeekOrigin::Begin, x50_cachedResInfo->GetOffset() + offset);
@ -187,6 +193,7 @@ bool CResLoader::FindResource(CAssetId id) const
return true;
}
Log.report(logvisor::Fatal, "Unable to find asset %08X", id);
return false;
}
@ -207,6 +214,7 @@ CPakFile* CResLoader::FindResourceForLoad(CAssetId id)
}
}
Log.report(logvisor::Fatal, "Unable to find asset %08X", id);
return nullptr;
}

View File

@ -26,13 +26,14 @@ class CResLoader
public:
CResLoader();
const std::vector<CAssetId>* GetTagListForFile(const std::string& name) const;
void AddPakFileAsync(const std::string& name, bool samusPak, bool worldPak);
void AddPakFileAsync(const std::string& name, bool buildDepList, bool worldPak);
void AddPakFile(const std::string& name, bool samusPak, bool worldPak);
std::unique_ptr<CInputStream> LoadNewResourcePartSync(const SObjectTag& tag, int offset, int length, void* extBuf);
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);
std::unique_ptr<CInputStream> LoadResourceFromMemorySync(const SObjectTag& tag, const void* buf);
std::unique_ptr<CInputStream> LoadNewResourceSync(const SObjectTag& tag, void* extBuf=nullptr);
std::shared_ptr<IDvdRequest> LoadResourcePartAsync(const SObjectTag& tag, int offset, int length, void* buf);
std::shared_ptr<IDvdRequest> LoadResourcePartAsync(const SObjectTag& tag, u32 length, u32 offset, void* buf);
std::shared_ptr<IDvdRequest> LoadResourceAsync(const SObjectTag& tag, void* buf);
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);

View File

@ -60,17 +60,17 @@ u32 CCharacterFactoryBuilder::CDummyFactory::ResourceSize(const urde::SObjectTag
return 0;
}
bool CCharacterFactoryBuilder::CDummyFactory::LoadResourceAsync(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>& target)
std::shared_ptr<IDvdRequest> CCharacterFactoryBuilder::CDummyFactory::LoadResourceAsync(const urde::SObjectTag& tag,
void* target)
{
return false;
return {};
}
bool CCharacterFactoryBuilder::CDummyFactory::LoadResourcePartAsync(const urde::SObjectTag& tag,
std::shared_ptr<IDvdRequest> CCharacterFactoryBuilder::CDummyFactory::LoadResourcePartAsync(const urde::SObjectTag& tag,
u32 size, u32 off,
std::unique_ptr<u8[]>& target)
void* target)
{
return false;
return {};
}
std::unique_ptr<u8[]> CCharacterFactoryBuilder::CDummyFactory::LoadResourceSync(const urde::SObjectTag& tag)

View File

@ -28,8 +28,8 @@ public:
void EnumerateNamedResources(const std::function<bool(const std::string&, const SObjectTag&)>& lambda) const;
u32 ResourceSize(const urde::SObjectTag& tag);
bool LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr<u8[]>& target);
bool LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr<u8[]>& target);
std::shared_ptr<IDvdRequest> LoadResourceAsync(const urde::SObjectTag& tag, void* target);
std::shared_ptr<IDvdRequest> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, void* target);
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);
};

View File

@ -88,17 +88,17 @@ u32 CCharacterFactory::CDummyFactory::ResourceSize(const urde::SObjectTag& tag)
return 0;
}
bool CCharacterFactory::CDummyFactory::LoadResourceAsync(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>& target)
std::shared_ptr<IDvdRequest> CCharacterFactory::CDummyFactory::LoadResourceAsync(const urde::SObjectTag& tag,
void* target)
{
return false;
return {};
}
bool CCharacterFactory::CDummyFactory::LoadResourcePartAsync(const urde::SObjectTag& tag,
std::shared_ptr<IDvdRequest> CCharacterFactory::CDummyFactory::LoadResourcePartAsync(const urde::SObjectTag& tag,
u32 size, u32 off,
std::unique_ptr<u8[]>& target)
void* target)
{
return false;
return {};
}
std::unique_ptr<u8[]> CCharacterFactory::CDummyFactory::LoadResourceSync(const urde::SObjectTag& tag)

View File

@ -37,8 +37,8 @@ public:
void EnumerateNamedResources(const std::function<bool(const std::string&, const SObjectTag&)>& lambda) const;
u32 ResourceSize(const urde::SObjectTag& tag);
bool LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr<u8[]>& target);
bool LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr<u8[]>& target);
std::shared_ptr<IDvdRequest> LoadResourceAsync(const urde::SObjectTag& tag, void* target);
std::shared_ptr<IDvdRequest> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, void* target);
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);
};

View File

@ -13,6 +13,7 @@ class CObjectReference;
class CResLoader;
class CFactoryMgr;
class CSimplePool;
class IDvdRequest;
using CFactoryFnReturn = std::unique_ptr<IObj>;
using FFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag,
@ -36,15 +37,15 @@ public:
virtual FourCC GetResourceTypeById(CAssetId id) const=0;
virtual void EnumerateResources(const std::function<bool(const SObjectTag&)>& lambda) const=0;
virtual void EnumerateNamedResources(const std::function<bool(const std::string&, const SObjectTag&)>& lambda) const=0;
virtual CResLoader* GetResLoader() const { return nullptr; }
virtual CFactoryMgr* GetFactoryMgr() const { return nullptr; }
virtual CResLoader* GetResLoader() { return nullptr; }
virtual CFactoryMgr* GetFactoryMgr() { return nullptr; }
virtual void LoadOriginalIDs(CSimplePool& sp) {}
virtual void AsyncIdle() {}
/* Non-factory versions, replaces CResLoader */
virtual u32 ResourceSize(const urde::SObjectTag& tag)=0;
//virtual bool LoadResourceAsync(const urde::SObjectTag& tag, std::unique_ptr<u8[]>& target)=0;
//virtual bool LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, std::unique_ptr<u8[]>& target)=0;
virtual std::shared_ptr<IDvdRequest> LoadResourceAsync(const urde::SObjectTag& tag, void* target)=0;
virtual std::shared_ptr<IDvdRequest> LoadResourcePartAsync(const urde::SObjectTag& tag, u32 size, u32 off, void* target)=0;
virtual std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag)=0;
virtual std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off)=0;

View File

@ -149,13 +149,14 @@ atUint64 CZipInputStream::readUBytesToBuf(void *buf, atUint64 len)
{
x30_zstrm.next_out = (Bytef*)buf;
x30_zstrm.avail_out = len;
if (!x30_zstrm.avail_in)
while (x30_zstrm.avail_out != 0)
{
atUint64 readSz = x28_strm->readUBytesToBuf(x24_compBuf.get(), 4096);
x30_zstrm.avail_in = readSz;
x30_zstrm.next_in = x24_compBuf.get();
if (inflate(&x30_zstrm, Z_NO_FLUSH) != Z_OK)
break;
}
inflate(&x30_zstrm, Z_NO_FLUSH);
return x30_zstrm.total_out;
}

View File

@ -25,8 +25,8 @@ CPauseScreen::CPauseScreen(ESubScreen subscreen,
{
SObjectTag frmeTag(FOURCC('FRME'), x54_frmePauseScreenId);
x58_frmePauseScreenBufSz = g_ResFactory->ResourceSize(frmeTag);
ProjectResourceFactoryBase& resFac = static_cast<ProjectResourceFactoryBase&>(*g_ResFactory);
x60_loadTok = resFac.LoadResourceAsync(frmeTag, x5c_frmePauseScreenBuf);
x5c_frmePauseScreenBuf.reset(new u8[x58_frmePauseScreenBufSz]);
x60_loadTok = g_ResFactory->LoadResourceAsync(frmeTag, x5c_frmePauseScreenBuf.get());
CSfxManager::SfxStart(1435, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId);
}
@ -89,7 +89,7 @@ bool CPauseScreen::CheckLoadComplete(const CStateManager& mgr)
}
if (x60_loadTok)
{
if (!x60_loadTok->m_complete)
if (!x60_loadTok->IsComplete())
return false;
for (int i=0 ; i<2 ; ++i)
{

View File

@ -45,7 +45,7 @@ private:
CAssetId x54_frmePauseScreenId;
u32 x58_frmePauseScreenBufSz;
std::unique_ptr<u8[]> x5c_frmePauseScreenBuf;
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask> x60_loadTok;
std::shared_ptr<IDvdRequest> x60_loadTok;
rstl::reserved_vector<std::unique_ptr<CGuiFrame>, 2> x64_frameInsts;
u32 x78_activeIdx = 0;
rstl::reserved_vector<std::unique_ptr<CPauseScreenBase>, 2> x7c_screens;

View File

@ -21,7 +21,7 @@ CIOWin::EMessageReturn CPreFrontEnd::OnMessage(const CArchitectureMessage& msg,
CMain* m = static_cast<CMain*>(g_Main);
if (CResLoader* loader = g_ResFactory->GetResLoader())
if (loader->AreAllPaksLoaded())
if (!loader->AreAllPaksLoaded())
return EMessageReturn::Exit;
if (!x14_resourceTweaksRegistered)
{

View File

@ -38,93 +38,91 @@ static const SObjectTag& IDFromFactory(CResFactory& factory, const char* name)
void CTweaks::RegisterTweaks()
{
ProjectResourceFactoryMP1& factory = ProjectManager::g_SharedManager->resourceFactoryMP1();
std::experimental::optional<CMemoryInStream> strm;
const SObjectTag* tag;
/* Particle */
tag = factory.GetResourceIdByName("Particle");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("Particle");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakParticle = new DataSpec::DNAMP1::CTweakParticle(*strm);
/* Player */
tag = factory.GetResourceIdByName("Player");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("Player");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakPlayer = new DataSpec::DNAMP1::CTweakPlayer(*strm);
/* CameraBob */
tag = factory.GetResourceIdByName("CameraBob");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("CameraBob");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
CPlayerCameraBob::ReadTweaks(*strm);
/* Ball */
tag = factory.GetResourceIdByName("Ball");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("Ball");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakBall = new DataSpec::DNAMP1::CTweakBall(*strm);
/* PlayerGun */
tag = factory.GetResourceIdByName("PlayerGun");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("PlayerGun");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakPlayerGun = new DataSpec::DNAMP1::CTweakPlayerGun(*strm);
/* Targeting */
tag = factory.GetResourceIdByName("Targeting");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("Targeting");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakTargeting = new DataSpec::DNAMP1::CTweakTargeting(*strm);
/* Game */
tag = factory.GetResourceIdByName("Game");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("Game");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakGame = new DataSpec::DNAMP1::CTweakGame(*strm);
/* GuiColors */
tag = factory.GetResourceIdByName("GuiColors");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("GuiColors");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakGuiColors = new DataSpec::DNAMP1::CTweakGuiColors(*strm);
/* AutoMapper */
tag = factory.GetResourceIdByName("AutoMapper");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("AutoMapper");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakAutoMapper = new DataSpec::DNAMP1::CTweakAutoMapper(*strm);
CMappableObject::ReadAutoMapperTweaks(*g_tweakAutoMapper);
/* Gui */
tag = factory.GetResourceIdByName("Gui");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("Gui");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakGui = new DataSpec::DNAMP1::CTweakGui(*strm);
/* PlayerControls */
tag = factory.GetResourceIdByName("PlayerControls");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("PlayerControls");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakPlayerControl = new DataSpec::DNAMP1::CTweakPlayerControl(*strm);
/* PlayerControls2 */
tag = factory.GetResourceIdByName("PlayerControls2");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("PlayerControls2");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakPlayerControlAlt = new DataSpec::DNAMP1::CTweakPlayerControl(*strm);
g_currentPlayerControl = g_tweakPlayerControl;
/* SlideShow */
tag = factory.GetResourceIdByName("SlideShow");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("SlideShow");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakSlideShow = new DataSpec::DNAMP1::CTweakSlideShow(*strm);
}
void CTweaks::RegisterResourceTweaks()
{
ProjectResourceFactoryMP1& factory = ProjectManager::g_SharedManager->resourceFactoryMP1();
std::experimental::optional<CMemoryInStream> strm;
const SObjectTag* tag = factory.GetResourceIdByName("GunRes");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
const SObjectTag* tag = g_ResFactory->GetResourceIdByName("GunRes");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakGunRes = new DataSpec::DNAMP1::CTweakGunRes(*strm);
g_tweakGunRes->ResolveResources(factory);
g_tweakGunRes->ResolveResources(*g_ResFactory);
tag = factory.GetResourceIdByName("PlayerRes");
strm.emplace(factory.LoadResourceSync(*tag).release(), factory.ResourceSize(*tag));
tag = g_ResFactory->GetResourceIdByName("PlayerRes");
strm.emplace(g_ResFactory->LoadResourceSync(*tag).release(), g_ResFactory->ResourceSize(*tag), true);
g_tweakPlayerRes = new DataSpec::DNAMP1::CTweakPlayerRes(*strm);
g_tweakPlayerRes->ResolveResources(factory);
g_tweakPlayerRes->ResolveResources(*g_ResFactory);
}
}

View File

@ -296,6 +296,8 @@ void CGameGlobalObjects::AddPaksAndFactories()
loader->AddPakFileAsync("SamGunFx", true, false);
loader->AddPakFileAsync("MidiData", false, false);
loader->AddPakFileAsync("GGuiSys", false, false);
loader->AddPakFileAsync("!original_ids", false, false);
loader->WaitForPakFileLoadingComplete();
}
if (CFactoryMgr* fmgr = g_ResFactory->GetFactoryMgr())
@ -333,16 +335,19 @@ void CGameGlobalObjects::AddPaksAndFactories()
void CMain::AddWorldPaks()
{
CResLoader* loader = g_ResFactory->GetResLoader();
if (!loader)
return;
auto& pakPrefix = g_tweakGame->GetWorldPrefix();
for (int i=0 ; i<9 ; ++i)
{
std::string path = pakPrefix;
if (i != 0)
path += '0' + i;
if (CDvdFile::FileExists(path.c_str()))
if (CResLoader* loader = g_ResFactory->GetResLoader())
if (CDvdFile::FileExists((path + ".upak").c_str()))
loader->AddPakFileAsync(path, false, true);
}
loader->WaitForPakFileLoadingComplete();
}
void CMain::ResetGameState()
@ -449,16 +454,24 @@ void CMain::WarmupShaders()
});
m_warmupTags.reserve(modelCount);
std::unordered_set<SObjectTag> addedTags;
addedTags.reserve(modelCount);
g_ResFactory->EnumerateResources([&](const SObjectTag& tag)
{
if (tag.type == FOURCC('CMDL') || tag.type == FOURCC('MREA'))
{
if (addedTags.find(tag) != addedTags.end())
return true;
addedTags.insert(tag);
m_warmupTags.push_back(tag);
}
return true;
});
m_warmupIt = m_warmupTags.begin();
WarmupLog.report(logvisor::Info, "Began warmup of %" PRISize " objects", modelCount);
WarmupLog.report(logvisor::Info, "Began warmup of %" PRISize " objects", m_warmupTags.size());
}
bool CMain::Proc()

View File

@ -416,7 +416,7 @@ CGameArea::CGameArea(CAssetId mreaId)
{
while (StartStreamingMainArea())
for (auto& req : xf8_loadTransactions)
req->WaitForComplete();
req->WaitUntilComplete();
MREAHeader header = VerifyHeader();
x12c_postConstructed->x4c_insts.resize(header.modelCount);
@ -794,8 +794,7 @@ u32 CGameArea::GetNumPartSizes() const
void CGameArea::AllocNewAreaData(int offset, int size)
{
x110_mreaSecBufs.emplace_back(std::unique_ptr<u8[]>(new u8[size]), size);
xf8_loadTransactions.push_back(
static_cast<ProjectResourceFactoryBase*>(g_ResFactory)->
xf8_loadTransactions.push_back(g_ResFactory->
LoadResourcePartAsync(SObjectTag{FOURCC('MREA'), x84_mrea}, size, offset,
x110_mreaSecBufs.back().first.get()));
}
@ -809,7 +808,7 @@ void CGameArea::CullDeadAreaRequests()
{
for (auto it = xf8_loadTransactions.begin() ; it != xf8_loadTransactions.end() ;)
{
if ((*it)->m_complete)
if ((*it)->IsComplete())
{
it = xf8_loadTransactions.erase(it);
continue;
@ -856,7 +855,7 @@ void CGameArea::Validate(CStateManager& mgr)
while (StartStreamingMainArea()) {}
for (auto& req : xf8_loadTransactions)
req->WaitForComplete();
req->WaitUntilComplete();
if (xdc_tokens.empty())
{

View File

@ -123,7 +123,7 @@ class CGameArea : public IGameArea
WaitForFinish
} xf4_phase = EPhase::LoadHeader;
std::list<std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>> xf8_loadTransactions;
std::list<std::shared_ptr<IDvdRequest>> xf8_loadTransactions;
public:

View File

@ -18,7 +18,8 @@ CWorld::CSoundGroupData::CSoundGroupData(int grpId, CAssetId agsc) : x0_groupId(
CDummyWorld::CDummyWorld(CAssetId mlvlId, bool loadMap) : x4_loadMap(loadMap), xc_mlvlId(mlvlId)
{
SObjectTag tag{FOURCC('MLVL'), mlvlId};
static_cast<ProjectResourceFactoryBase*>(g_ResFactory)->LoadResourceAsync(tag, x34_loadBuf);
x34_loadBuf.reset(new u8[g_ResFactory->ResourceSize(tag)]);
g_ResFactory->LoadResourceAsync(tag, x34_loadBuf.get());
}
CAssetId CDummyWorld::IGetWorldAssetId() const { return xc_mlvlId; }
@ -186,7 +187,8 @@ CWorld::CWorld(IObjectStore& objStore, IFactory& resFactory, CAssetId mlvlId)
{
x70_24_currentAreaNeedsAllocation = true;
SObjectTag tag{FOURCC('MLVL'), mlvlId};
static_cast<ProjectResourceFactoryBase&>(resFactory).LoadResourceAsync(tag, x40_loadBuf);
x40_loadBuf.reset(new u8[resFactory.ResourceSize(tag)]);
resFactory.LoadResourceAsync(tag, x40_loadBuf.get());
}
CAssetId CWorld::IGetWorldAssetId() const { return x8_mlvlId; }

2
hecl

@ -1 +1 @@
Subproject commit 038917dc59aaf50efed8925ff5fd53d62fd8cfe8
Subproject commit e6f5ea29c23008f5eb4aa353b4adc8a82b4a0332