Better null-tag handling; integrate CSaveWorld and CMapWorld loading

This commit is contained in:
Jack Andersen 2016-10-08 10:32:36 -10:00
parent 647643f579
commit f7f5066038
14 changed files with 85 additions and 9 deletions

View File

@ -225,6 +225,7 @@ bool ProjectResourceFactoryBase::AddFileToIndex(const hecl::ProjectPath& path,
SObjectTag pathTag = BuildTagFromPath(subPath, m_backgroundBlender);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
@ -233,6 +234,7 @@ bool ProjectResourceFactoryBase::AddFileToIndex(const hecl::ProjectPath& path,
pathTag = BuildTagFromPath(subPath, m_backgroundBlender);
m_tagToPath[pathTag] = subPath;
m_pathToTag[subPath.hash()] = pathTag;
WriteTag(cacheWriter, pathTag, subPath);
#if DUMP_CACHE_FILL
DumpCacheAdd(pathTag, subPath);
#endif
@ -610,6 +612,9 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
const urde::CVParamTransfer& paramXfer,
CObjectReference* selfRef)
{
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
Log.report(logvisor::Fatal, "attempted to access null id");
const hecl::ProjectPath* resPath = nullptr;
if (!WaitForTagReady(tag, resPath))
return {};
@ -673,11 +678,17 @@ void ProjectResourceFactoryBase::BuildAsync(const urde::SObjectTag& tag,
urde::IObj** objOut,
CObjectReference* selfRef)
{
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
Log.report(logvisor::Fatal, "attempted to access null id");
BuildAsyncInternal(tag, paramXfer, objOut, selfRef);
}
u32 ProjectResourceFactoryBase::ResourceSize(const SObjectTag& tag)
{
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
Log.report(logvisor::Fatal, "attempted to access null id");
/* Ensure resource at requested path is indexed and not cooking */
const hecl::ProjectPath* resPath = nullptr;
if (!WaitForTagReady(tag, resPath))
@ -695,6 +706,8 @@ std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
ProjectResourceFactoryBase::LoadResourceAsync(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>& target)
{
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
Log.report(logvisor::Fatal, "attempted to access null id");
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
return {};
return m_asyncLoadList.emplace(std::make_pair(tag, std::make_shared<AsyncTask>(*this, tag, target))).first->second;
@ -705,6 +718,8 @@ ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag,
u32 size, u32 off,
std::unique_ptr<u8[]>& target)
{
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
Log.report(logvisor::Fatal, "attempted to access null id");
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
return {};
return m_asyncLoadList.emplace(std::make_pair(tag, std::make_shared<AsyncTask>(*this, tag, target, size, off))).first->second;
@ -712,6 +727,9 @@ ProjectResourceFactoryBase::LoadResourcePartAsync(const urde::SObjectTag& tag,
std::unique_ptr<u8[]> ProjectResourceFactoryBase::LoadResourceSync(const urde::SObjectTag& tag)
{
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
Log.report(logvisor::Fatal, "attempted to access null id");
/* Ensure resource at requested path is indexed and not cooking */
const hecl::ProjectPath* resPath = nullptr;
if (!WaitForTagReady(tag, resPath))
@ -728,6 +746,9 @@ std::unique_ptr<u8[]> ProjectResourceFactoryBase::LoadResourceSync(const urde::S
std::unique_ptr<u8[]> ProjectResourceFactoryBase::LoadResourcePartSync(const urde::SObjectTag& tag,
u32 size, u32 off)
{
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
Log.report(logvisor::Fatal, "attempted to access null id");
/* Ensure resource at requested path is indexed and not cooking */
const hecl::ProjectPath* resPath = nullptr;
if (!WaitForTagReady(tag, resPath))
@ -750,6 +771,9 @@ void ProjectResourceFactoryBase::CancelBuild(const urde::SObjectTag& tag)
bool ProjectResourceFactoryBase::CanBuild(const urde::SObjectTag& tag)
{
if ((tag.id & 0xffffffff) == 0xffffffff || !tag.id)
Log.report(logvisor::Fatal, "attempted to access null id");
const hecl::ProjectPath* resPath = nullptr;
if (!WaitForTagReady(tag, resPath))
return false;
@ -791,6 +815,9 @@ const urde::SObjectTag* ProjectResourceFactoryBase::GetResourceIdByName(const ch
FourCC ProjectResourceFactoryBase::GetResourceTypeById(ResId id) const
{
if ((id & 0xffffffff) == 0xffffffff || !id)
Log.report(logvisor::Fatal, "attempted to access null id");
std::unique_lock<std::mutex> lk(const_cast<ProjectResourceFactoryBase*>(this)->m_backgroundIndexMutex);
SObjectTag searchTag = {FourCC(), id};
auto search = m_tagToPath.find(searchTag);

View File

@ -17,6 +17,8 @@
#include "Runtime/Character/CAllFormatsAnimSource.hpp"
#include "Runtime/Character/CAnimPOIData.hpp"
#include "Runtime/Collision/CCollidableOBBTreeGroup.hpp"
#include "Runtime/CSaveWorld.hpp"
#include "Runtime/AutoMapper/CMapWorld.hpp"
#include "Audio/CAudioGroupSet.hpp"
#include "Runtime/CDependencyGroup.hpp"
#include "DataSpec/DNACommon/TXTR.hpp"
@ -48,6 +50,8 @@ ProjectResourceFactoryMP1::ProjectResourceFactoryMP1(hecl::ClientProcess& client
m_factoryMgr.AddFactory(FOURCC('AGSC'), FMemFactoryFunc(FAudioGroupSetDataFactory));
m_factoryMgr.AddFactory(FOURCC('STRG'), FFactoryFunc(FStringTableFactory));
m_factoryMgr.AddFactory(FOURCC('HINT'), FFactoryFunc(FHintFactory));
m_factoryMgr.AddFactory(FOURCC('SAVW'), FFactoryFunc(FSaveWorldFactory));
m_factoryMgr.AddFactory(FOURCC('MAPW'), FFactoryFunc(FMapWorldFactory));
}
void ProjectResourceFactoryMP1::IndexMP1Resources(hecl::Database::Project& proj)

View File

@ -2,6 +2,11 @@
namespace urde
{
CMapWorld::CMapWorld(CInputStream& in)
{
}
u32 CMapWorld::GetNumAreas() const
{
return x0_areas.size();
@ -81,4 +86,10 @@ void CMapWorld::ClearTraversedFlags() const
}
CFactoryFnReturn FMapWorldFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param,
CObjectReference* selfRef)
{
return TToken<CMapWorld>::GetIObjObjectFor(std::make_unique<CMapWorld>(in));
}
}

View File

@ -105,6 +105,9 @@ public:
void ClearTraversedFlags() const;
};
CFactoryFnReturn FMapWorldFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param,
CObjectReference* selfRef);
}
#endif // __URDE_CMAPWORLD_HPP__

View File

@ -9,6 +9,15 @@
namespace urde
{
CWorldState::CWorldState(ResId id)
: x0_mlvlId(id), x4_areaId(0)
{
x8_relayTracker = std::make_shared<CRelayTracker>();
xc_mapWorldInfo = std::make_shared<CMapWorldInfo>();
x10_ = -1;
x14_ = std::make_shared<CWorldSomethingState>();
}
CWorldState::CWorldState(CBitStreamReader& reader, ResId mlvlId, const CSaveWorld& saveWorld)
: x0_mlvlId(mlvlId)
{

View File

@ -20,6 +20,7 @@ class CWorldSomethingState
u32 x10_bitCount = 0;
std::vector<u32> x14_;
public:
CWorldSomethingState() = default;
CWorldSomethingState(CBitStreamReader& reader, const CSaveWorld& saveWorld)
{
u32 bitCount = reader.ReadEncoded(10);
@ -47,7 +48,7 @@ class CWorldState
u32 x10_;
std::shared_ptr<CWorldSomethingState> x14_;
public:
CWorldState(ResId id) : x0_mlvlId(id) {}
CWorldState(ResId id);
CWorldState(CBitStreamReader& reader, ResId mlvlId, const CSaveWorld& saveWorld);
ResId GetWorldAssetId() const {return x0_mlvlId;}
void SetAreaId(TAreaId aid) { x4_areaId = aid; }

View File

@ -54,6 +54,7 @@ bool CSaveWorldIntermediate::InitializePump()
CMemoryCardSys::CMemoryCardSys()
{
x0_hints = g_SimplePool->GetObj("HINT_Hints");
xc_memoryWorlds.reserve(16);
x1c_worldInter.emplace();
x1c_worldInter->reserve(16);
@ -81,6 +82,8 @@ bool CMemoryCardSys::InitializePump()
for (const auto& world : xc_memoryWorlds)
{
const CSaveWorldMemory& wld = world.second;
if (!wld.GetWorldName())
continue;
if (!wld.GetWorldName().IsLoaded() ||
!wld.GetWorldName().GetObj())
return false;

View File

@ -18,7 +18,7 @@ class CSaveWorldMemory
ResId x0_strgId = -1;
ResId x4_savwId = -1;
u32 x8_areaCount;
std::vector<TAreaId> xc_areaIds; /* 4 byte element */
std::vector<ResId> xc_areaIds; /* 4 byte element */
std::vector<u32> x1c_; /* 16 byte element */
TLockedToken<CStringTable> x2c_worldName; /* used to be optional */
TLockedToken<CSaveWorld> x3c_saveWorld; /* used to be optional */
@ -34,10 +34,10 @@ public:
class CSaveWorldIntermediate
{
friend class CMemoryCardSys;
u32 x0_mlvlId;
u32 x4_strgId;
u32 x8_savwId;
std::vector<TAreaId> xc_areaIds;
ResId x0_mlvlId;
ResId x4_strgId;
ResId x8_savwId;
std::vector<ResId> xc_areaIds;
std::vector<u32> x1c_;
std::unique_ptr<CDummyWorld> x2c_dummyWorld;
TLockedToken<CSaveWorld> x34_saveWorld; /* Used to be auto_ptr */

View File

@ -1,4 +1,5 @@
#include "CSaveWorld.hpp"
#include "CToken.hpp"
namespace urde
{
@ -98,4 +99,10 @@ s32 CSaveWorld::GetDoorIndex(const TEditorId &id) const
return x34_doors.begin() - it;
}
CFactoryFnReturn FSaveWorldFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param,
CObjectReference* selfRef)
{
return TToken<CSaveWorld>::GetIObjObjectFor(std::make_unique<CSaveWorld>(in));
}
}

View File

@ -3,6 +3,7 @@
#include "RetroTypes.hpp"
#include "DNACommon/SAVWCommon.hpp"
#include "CFactoryMgr.hpp"
namespace urde
{
@ -43,6 +44,10 @@ public:
u32 GetDoorCount() const;
s32 GetDoorIndex(const TEditorId &id) const;
};
CFactoryFnReturn FSaveWorldFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param,
CObjectReference* selfRef);
}
#endif // __URDE_CSAVEWORLD_HPP__

View File

@ -11,6 +11,9 @@ CSimplePool::CSimplePool(IFactory& factory)
CToken CSimplePool::GetObj(const SObjectTag& tag, const CVParamTransfer& paramXfer)
{
if (!tag)
return {};
auto iter = x4_resources.find(tag);
if (iter != x4_resources.end())
return CToken(iter->second);

View File

@ -19,7 +19,7 @@ struct SObjectTag
{
FourCC type;
ResId id = -1;
operator bool() const { return id != -1; }
operator bool() const { return (id & 0xffffffff) != 0xffffffff; }
bool operator!=(const SObjectTag& other) const { return id != other.id; }
bool operator==(const SObjectTag& other) const { return id == other.id; }
SObjectTag() = default;

View File

@ -17,7 +17,7 @@ CWorld::CSoundGroupData::CSoundGroupData(int grpId, ResId agsc)
}
CDummyWorld::CDummyWorld(ResId mlvlId, bool loadMap)
: x4_loadMap(loadMap)
: x4_loadMap(loadMap), xc_mlvlId(mlvlId)
{
SObjectTag tag{FOURCC('MLVL'), mlvlId};
static_cast<ProjectResourceFactoryBase*>(g_ResFactory)->LoadResourceAsync(tag, x34_loadBuf);
@ -146,6 +146,9 @@ bool CDummyWorld::ICheckWorldComplete()
if (x4_loadMap)
x2c_mapWorld = g_SimplePool->GetObj(SObjectTag{FOURCC('MAPW'), x28_mapWorldId});
r.readByte();
r.readUint32Big();
if (version > 10)
{
u32 audioGroupCount = r.readUint32Big();