mirror of https://github.com/AxioDL/metaforce.git
Better null-tag handling; integrate CSaveWorld and CMapWorld loading
This commit is contained in:
parent
647643f579
commit
f7f5066038
|
@ -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);
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -105,6 +105,9 @@ public:
|
|||
void ClearTraversedFlags() const;
|
||||
};
|
||||
|
||||
CFactoryFnReturn FMapWorldFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param,
|
||||
CObjectReference* selfRef);
|
||||
|
||||
}
|
||||
|
||||
#endif // __URDE_CMAPWORLD_HPP__
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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; }
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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__
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue