mirror of https://github.com/AxioDL/metaforce.git
PVS implementations
This commit is contained in:
parent
56328c3e4d
commit
50fe6d34ab
|
@ -21,7 +21,7 @@ struct HINT : BigYAML
|
||||||
Value<float> immediateTime;
|
Value<float> immediateTime;
|
||||||
Value<float> normalTime;
|
Value<float> normalTime;
|
||||||
UniqueID32 stringID;
|
UniqueID32 stringID;
|
||||||
Value<atUint32> continueDelayTime;
|
Value<atUint32> textPageCount;
|
||||||
struct Location : BigYAML
|
struct Location : BigYAML
|
||||||
{
|
{
|
||||||
DECL_YAML
|
DECL_YAML
|
||||||
|
|
|
@ -560,6 +560,16 @@ bool ProjectResourceFactoryBase::AsyncTask::AsyncPump()
|
||||||
return m_failed;
|
return m_failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ProjectResourceFactoryBase::AsyncTask::WaitForComplete()
|
||||||
|
{
|
||||||
|
using ItType = std::unordered_map<SObjectTag, std::shared_ptr<AsyncTask>>::iterator;
|
||||||
|
ItType search = m_parent.m_asyncLoadList.find(x0_tag);
|
||||||
|
if (search == m_parent.m_asyncLoadList.end())
|
||||||
|
return;
|
||||||
|
for (ItType tmp = search ; !m_parent.AsyncPumpTask(tmp) ; tmp = search)
|
||||||
|
{std::this_thread::sleep_for(std::chrono::milliseconds(2));}
|
||||||
|
}
|
||||||
|
|
||||||
bool ProjectResourceFactoryBase::WaitForTagReady(const urde::SObjectTag& tag,
|
bool ProjectResourceFactoryBase::WaitForTagReady(const urde::SObjectTag& tag,
|
||||||
const hecl::ProjectPath*& pathOut)
|
const hecl::ProjectPath*& pathOut)
|
||||||
{
|
{
|
||||||
|
@ -921,6 +931,70 @@ void ProjectResourceFactoryBase::EnumerateNamedResources(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ProjectResourceFactoryBase::AsyncPumpTask(
|
||||||
|
std::unordered_map<SObjectTag, std::shared_ptr<AsyncTask>>::iterator& it)
|
||||||
|
{
|
||||||
|
/* Ensure requested resource is in the index */
|
||||||
|
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
||||||
|
AsyncTask& task = *it->second;
|
||||||
|
auto search = m_tagToPath.find(task.x0_tag);
|
||||||
|
if (search == m_tagToPath.end())
|
||||||
|
{
|
||||||
|
if (!m_backgroundRunning)
|
||||||
|
{
|
||||||
|
Log.report(logvisor::Error, _S("unable to find async load resource (%s, %08X)"),
|
||||||
|
task.x0_tag.type.toString().c_str(), task.x0_tag.id);
|
||||||
|
it = m_asyncLoadList.erase(it);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
lk.unlock();
|
||||||
|
task.EnsurePath(task.x0_tag, search->second);
|
||||||
|
|
||||||
|
/* Pump load pipeline (cooking if needed) */
|
||||||
|
if (task.AsyncPump())
|
||||||
|
{
|
||||||
|
if (task.m_complete)
|
||||||
|
{
|
||||||
|
/* Load complete, build resource */
|
||||||
|
if (task.xc_targetObjPtr)
|
||||||
|
{
|
||||||
|
/* Factory build */
|
||||||
|
std::unique_ptr<IObj> newObj;
|
||||||
|
if (m_factoryMgr.CanMakeMemory(task.x0_tag))
|
||||||
|
{
|
||||||
|
newObj = m_factoryMgr.MakeObjectFromMemory(task.x0_tag, std::move(task.x10_loadBuffer),
|
||||||
|
task.x14_resSize, false, task.x18_cvXfer,
|
||||||
|
task.m_selfRef);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
|
||||||
|
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, task.m_selfRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
*task.xc_targetObjPtr = newObj.release();
|
||||||
|
Log.report(logvisor::Info, "async-built %.4s %08X",
|
||||||
|
task.x0_tag.type.toString().c_str(),
|
||||||
|
u32(task.x0_tag.id));
|
||||||
|
}
|
||||||
|
else if (task.xc_targetDataPtr)
|
||||||
|
{
|
||||||
|
/* Buffer only */
|
||||||
|
*task.xc_targetDataPtr = std::move(task.x10_loadBuffer);
|
||||||
|
Log.report(logvisor::Info, "async-loaded %.4s %08X",
|
||||||
|
task.x0_tag.type.toString().c_str(),
|
||||||
|
u32(task.x0_tag.id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
it = m_asyncLoadList.erase(it);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
++it;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void ProjectResourceFactoryBase::AsyncIdle()
|
void ProjectResourceFactoryBase::AsyncIdle()
|
||||||
{
|
{
|
||||||
/* Consume completed transactions, they will be processed this cycle at the latest */
|
/* Consume completed transactions, they will be processed this cycle at the latest */
|
||||||
|
@ -936,64 +1010,7 @@ void ProjectResourceFactoryBase::AsyncIdle()
|
||||||
if (std::chrono::duration_cast<std::chrono::milliseconds>(resStart - start).count() > 8)
|
if (std::chrono::duration_cast<std::chrono::milliseconds>(resStart - start).count() > 8)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Ensure requested resource is in the index */
|
AsyncPumpTask(it);
|
||||||
std::unique_lock<std::mutex> lk(m_backgroundIndexMutex);
|
|
||||||
AsyncTask& task = *it->second;
|
|
||||||
auto search = m_tagToPath.find(task.x0_tag);
|
|
||||||
if (search == m_tagToPath.end())
|
|
||||||
{
|
|
||||||
if (!m_backgroundRunning)
|
|
||||||
{
|
|
||||||
Log.report(logvisor::Error, _S("unable to find async load resource (%s, %08X)"),
|
|
||||||
task.x0_tag.type.toString().c_str(), task.x0_tag.id);
|
|
||||||
it = m_asyncLoadList.erase(it);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
lk.unlock();
|
|
||||||
task.EnsurePath(task.x0_tag, search->second);
|
|
||||||
|
|
||||||
/* Pump load pipeline (cooking if needed) */
|
|
||||||
if (task.AsyncPump())
|
|
||||||
{
|
|
||||||
if (task.m_complete)
|
|
||||||
{
|
|
||||||
/* Load complete, build resource */
|
|
||||||
if (task.xc_targetObjPtr)
|
|
||||||
{
|
|
||||||
/* Factory build */
|
|
||||||
std::unique_ptr<IObj> newObj;
|
|
||||||
if (m_factoryMgr.CanMakeMemory(task.x0_tag))
|
|
||||||
{
|
|
||||||
newObj = m_factoryMgr.MakeObjectFromMemory(task.x0_tag, std::move(task.x10_loadBuffer),
|
|
||||||
task.x14_resSize, false, task.x18_cvXfer,
|
|
||||||
task.m_selfRef);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
|
|
||||||
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, task.m_selfRef);
|
|
||||||
}
|
|
||||||
|
|
||||||
*task.xc_targetObjPtr = newObj.release();
|
|
||||||
Log.report(logvisor::Info, "async-built %.4s %08X",
|
|
||||||
task.x0_tag.type.toString().c_str(),
|
|
||||||
u32(task.x0_tag.id));
|
|
||||||
}
|
|
||||||
else if (task.xc_targetDataPtr)
|
|
||||||
{
|
|
||||||
/* Buffer only */
|
|
||||||
*task.xc_targetDataPtr = std::move(task.x10_loadBuffer);
|
|
||||||
Log.report(logvisor::Info, "async-loaded %.4s %08X",
|
|
||||||
task.x0_tag.type.toString().c_str(),
|
|
||||||
u32(task.x0_tag.id));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
it = m_asyncLoadList.erase(it);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
++it;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ public:
|
||||||
const hecl::ProjectPath& path);
|
const hecl::ProjectPath& path);
|
||||||
void CookComplete();
|
void CookComplete();
|
||||||
bool AsyncPump();
|
bool AsyncPump();
|
||||||
|
void WaitForComplete();
|
||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@ -133,6 +134,7 @@ public:
|
||||||
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
|
std::unique_ptr<u8[]> LoadResourceSync(const urde::SObjectTag& tag);
|
||||||
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);
|
std::unique_ptr<u8[]> LoadResourcePartSync(const urde::SObjectTag& tag, u32 size, u32 off);
|
||||||
|
|
||||||
|
bool AsyncPumpTask(std::unordered_map<SObjectTag, std::shared_ptr<AsyncTask>>::iterator& it);
|
||||||
void AsyncIdle();
|
void AsyncIdle();
|
||||||
void Shutdown() {CancelBackgroundIndex();}
|
void Shutdown() {CancelBackgroundIndex();}
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ CGameHintInfo::CGameHint::CGameHint(CInputStream& in, s32 version)
|
||||||
, x10_immediateTime(in.readFloatBig())
|
, x10_immediateTime(in.readFloatBig())
|
||||||
, x14_normalTime(in.readFloatBig())
|
, x14_normalTime(in.readFloatBig())
|
||||||
, x18_stringId(in.readUint32Big())
|
, x18_stringId(in.readUint32Big())
|
||||||
, x1c_continueDelayTime(3.f * float(version <= 0 ? 1 : in.readUint32Big()))
|
, x1c_textTime(3.f * float(version <= 0 ? 1 : in.readUint32Big()))
|
||||||
{
|
{
|
||||||
u32 locationCount = in.readUint32Big();
|
u32 locationCount = in.readUint32Big();
|
||||||
x20_locations.reserve(locationCount);
|
x20_locations.reserve(locationCount);
|
||||||
|
|
|
@ -24,14 +24,14 @@ public:
|
||||||
float x10_immediateTime;
|
float x10_immediateTime;
|
||||||
float x14_normalTime;
|
float x14_normalTime;
|
||||||
ResId x18_stringId;
|
ResId x18_stringId;
|
||||||
float x1c_continueDelayTime;
|
float x1c_textTime;
|
||||||
std::vector<SHintLocation> x20_locations;
|
std::vector<SHintLocation> x20_locations;
|
||||||
public:
|
public:
|
||||||
CGameHint(CInputStream&, s32);
|
CGameHint(CInputStream&, s32);
|
||||||
|
|
||||||
float GetNormalTime() const { return x14_normalTime; }
|
float GetNormalTime() const { return x14_normalTime; }
|
||||||
float GetImmediateTime() const { return x10_immediateTime; }
|
float GetImmediateTime() const { return x10_immediateTime; }
|
||||||
float GetContinueDelayTime() const { return x1c_continueDelayTime; }
|
float GetTextTime() const { return x1c_textTime; }
|
||||||
const std::string& GetName() const { return x0_name; }
|
const std::string& GetName() const { return x0_name; }
|
||||||
ResId GetStringID() const { return x18_stringId; }
|
ResId GetStringID() const { return x18_stringId; }
|
||||||
const std::vector<SHintLocation>& GetLocations() const { return x20_locations; }
|
const std::vector<SHintLocation>& GetLocations() const { return x20_locations; }
|
||||||
|
|
|
@ -564,7 +564,7 @@ void CHintOptions::SetNextHintTime()
|
||||||
if (x10_nextHintIdx == -1)
|
if (x10_nextHintIdx == -1)
|
||||||
return;
|
return;
|
||||||
x0_hintStates[x10_nextHintIdx].x4_time =
|
x0_hintStates[x10_nextHintIdx].x4_time =
|
||||||
g_MemoryCardSys->GetHints()[x10_nextHintIdx].GetContinueDelayTime() + 5.f;
|
g_MemoryCardSys->GetHints()[x10_nextHintIdx].GetTextTime() + 5.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CHintOptions::InitializeMemoryState()
|
void CHintOptions::InitializeMemoryState()
|
||||||
|
@ -583,7 +583,7 @@ const CHintOptions::SHintState* CHintOptions::GetCurrentDisplayedHint() const
|
||||||
|
|
||||||
const SHintState& hintState = x0_hintStates[x10_nextHintIdx];
|
const SHintState& hintState = x0_hintStates[x10_nextHintIdx];
|
||||||
const CGameHintInfo::CGameHint& hint = g_MemoryCardSys->GetHints()[x10_nextHintIdx];
|
const CGameHintInfo::CGameHint& hint = g_MemoryCardSys->GetHints()[x10_nextHintIdx];
|
||||||
if (hintState.x4_time >= hint.GetContinueDelayTime())
|
if (hintState.x4_time >= hint.GetTextTime())
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
||||||
if (hintState.x4_time < 3.f)
|
if (hintState.x4_time < 3.f)
|
||||||
|
@ -602,12 +602,9 @@ void CHintOptions::DelayHint(const char* name)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (x10_nextHintIdx == idx)
|
if (x10_nextHintIdx == idx)
|
||||||
{
|
|
||||||
for (SHintState& state : x0_hintStates)
|
for (SHintState& state : x0_hintStates)
|
||||||
state.x4_time += 60.f;
|
state.x4_time += 60.f;
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
x0_hintStates[idx].x0_state = EHintState::Delayed;
|
x0_hintStates[idx].x0_state = EHintState::Delayed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -639,7 +636,7 @@ void CHintOptions::ActivateContinueDelayHintTimer(const char* name)
|
||||||
if (hintState.x0_state != EHintState::Two)
|
if (hintState.x0_state != EHintState::Two)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
hintState.x4_time = hint.GetContinueDelayTime();
|
hintState.x4_time = hint.GetTextTime();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -366,7 +366,64 @@ void CStateManager::SetupFogForArea(const CGameArea& area) const {}
|
||||||
|
|
||||||
void CStateManager::PreRender() {}
|
void CStateManager::PreRender() {}
|
||||||
|
|
||||||
void CStateManager::GetVisSetForArea(TAreaId, TAreaId) const {}
|
bool CStateManager::GetVisSetForArea(TAreaId a, TAreaId b, CPVSVisSet& setOut) const
|
||||||
|
{
|
||||||
|
if (b == kInvalidAreaId)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
zeus::CVector3f viewPoint = CGraphics::g_ViewMatrix.origin;
|
||||||
|
zeus::CVector3f closestDockPoint = viewPoint;
|
||||||
|
bool hasClosestDock = false;
|
||||||
|
if (a != b)
|
||||||
|
{
|
||||||
|
CGameArea& area = *x850_world->GetGameAreas()[b];
|
||||||
|
if (area.IsPostConstructed())
|
||||||
|
{
|
||||||
|
for (const CGameArea::Dock& dock : area.GetDocks())
|
||||||
|
{
|
||||||
|
for (int i=0 ; i<dock.GetDockRefs().size() ; ++i)
|
||||||
|
{
|
||||||
|
TAreaId connArea = dock.GetConnectedAreaId(i);
|
||||||
|
if (connArea == a)
|
||||||
|
{
|
||||||
|
const auto& verts = dock.GetPlaneVertices();
|
||||||
|
zeus::CVector3f dockCenter = (verts[0] + verts[1] + verts[2] + verts[4]) * 0.25f;
|
||||||
|
if (hasClosestDock)
|
||||||
|
if ((dockCenter - viewPoint).magSquared() >=
|
||||||
|
(closestDockPoint - viewPoint).magSquared())
|
||||||
|
continue;
|
||||||
|
closestDockPoint = dockCenter;
|
||||||
|
hasClosestDock = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
hasClosestDock = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasClosestDock)
|
||||||
|
{
|
||||||
|
if (CPVSAreaSet* pvs = x850_world->GetGameAreas()[a]->GetPostConstructed()->xa0_pvs.get())
|
||||||
|
{
|
||||||
|
const CPVSVisOctree& octree = pvs->GetVisOctree();
|
||||||
|
zeus::CVector3f closestDockLocal =
|
||||||
|
x850_world->GetGameAreas()[a]->GetInverseTransform() * closestDockPoint;
|
||||||
|
CPVSVisSet set;
|
||||||
|
set.SetTestPoint(octree, closestDockLocal);
|
||||||
|
|
||||||
|
if (set.GetState() == EPVSVisSetState::NodeFound)
|
||||||
|
{
|
||||||
|
setOut = set;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void CStateManager::RecursiveDrawTree(TUniqueId) const {}
|
void CStateManager::RecursiveDrawTree(TUniqueId) const {}
|
||||||
|
|
||||||
|
@ -557,14 +614,14 @@ std::pair<TEditorId, TUniqueId> CStateManager::GenerateObject(TEditorId)
|
||||||
return {kInvalidEditorId, kInvalidUniqueId};
|
return {kInvalidEditorId, kInvalidUniqueId};
|
||||||
}
|
}
|
||||||
|
|
||||||
void CStateManager::InitScriptObjects(std::vector<TEditorId>& ids)
|
void CStateManager::InitScriptObjects(const std::vector<TEditorId>& ids)
|
||||||
{
|
{
|
||||||
for (TEditorId id : ids)
|
for (TEditorId id : ids)
|
||||||
{
|
{
|
||||||
if (id == kInvalidEditorId)
|
if (id == kInvalidEditorId)
|
||||||
continue;
|
continue;
|
||||||
TUniqueId uid = GetIdForScript(id);
|
TUniqueId uid = GetIdForScript(id);
|
||||||
SendScriptMsg(uid, kInvalidUniqueId, EScriptObjectMessage::InternalMessage13);
|
SendScriptMsg(uid, kInvalidUniqueId, EScriptObjectMessage::Constructed);
|
||||||
}
|
}
|
||||||
MurderScriptInstanceNames();
|
MurderScriptInstanceNames();
|
||||||
}
|
}
|
||||||
|
|
|
@ -269,7 +269,7 @@ public:
|
||||||
void DrawWorld() const;
|
void DrawWorld() const;
|
||||||
void SetupFogForArea(const CGameArea& area) const;
|
void SetupFogForArea(const CGameArea& area) const;
|
||||||
void PreRender();
|
void PreRender();
|
||||||
void GetVisSetForArea(TAreaId, TAreaId) const;
|
bool GetVisSetForArea(TAreaId, TAreaId, CPVSVisSet& setOut) const;
|
||||||
void RecursiveDrawTree(TUniqueId) const;
|
void RecursiveDrawTree(TUniqueId) const;
|
||||||
void SendScriptMsg(CEntity* dest, TUniqueId src, EScriptObjectMessage msg);
|
void SendScriptMsg(CEntity* dest, TUniqueId src, EScriptObjectMessage msg);
|
||||||
void SendScriptMsg(TUniqueId dest, TUniqueId src, EScriptObjectMessage msg);
|
void SendScriptMsg(TUniqueId dest, TUniqueId src, EScriptObjectMessage msg);
|
||||||
|
@ -285,9 +285,10 @@ public:
|
||||||
std::multimap<TEditorId, TUniqueId>::const_iterator>
|
std::multimap<TEditorId, TUniqueId>::const_iterator>
|
||||||
GetIdListForScript(TEditorId) const;
|
GetIdListForScript(TEditorId) const;
|
||||||
void LoadScriptObjects(TAreaId, CInputStream& in, std::vector<TEditorId>& idsOut);
|
void LoadScriptObjects(TAreaId, CInputStream& in, std::vector<TEditorId>& idsOut);
|
||||||
|
void InitializeScriptObjects(const std::vector<TEditorId>& objIds);
|
||||||
std::pair<TEditorId, TUniqueId> LoadScriptObject(TAreaId, EScriptObjectType, u32, CInputStream& in);
|
std::pair<TEditorId, TUniqueId> LoadScriptObject(TAreaId, EScriptObjectType, u32, CInputStream& in);
|
||||||
std::pair<TEditorId, TUniqueId> GenerateObject(TEditorId);
|
std::pair<TEditorId, TUniqueId> GenerateObject(TEditorId);
|
||||||
void InitScriptObjects(std::vector<TEditorId>& ids);
|
void InitScriptObjects(const std::vector<TEditorId>& ids);
|
||||||
void InformListeners(const zeus::CVector3f&, EListenNoiseType);
|
void InformListeners(const zeus::CVector3f&, EListenNoiseType);
|
||||||
bool ApplyKnockBack(CActor& actor, const CDamageInfo& info,
|
bool ApplyKnockBack(CActor& actor, const CDamageInfo& info,
|
||||||
const CDamageVulnerability&, const zeus::CVector3f&, float);
|
const CDamageVulnerability&, const zeus::CVector3f&, float);
|
||||||
|
|
|
@ -386,13 +386,13 @@ void CBooRenderer::DrawUnsortedGeometry(int areaIdx, int mask, int targetMask)
|
||||||
if (xe0_pvsModelCount != item.x10_models.size())
|
if (xe0_pvsModelCount != item.x10_models.size())
|
||||||
pvs = nullptr;
|
pvs = nullptr;
|
||||||
|
|
||||||
int idx = 0;
|
u32 idx = 0;
|
||||||
for (auto it = item.x10_models.begin() ; it != item.x10_models.end() ; ++it, ++idx)
|
for (auto it = item.x10_models.begin() ; it != item.x10_models.end() ; ++it, ++idx)
|
||||||
{
|
{
|
||||||
CBooModel* model = *it;
|
CBooModel* model = *it;
|
||||||
if (pvs)
|
if (pvs)
|
||||||
{
|
{
|
||||||
bool vis = pvs->GetVisible(idx);
|
bool vis = pvs->GetVisible(idx) != EPVSVisSetState::EndOfTree;
|
||||||
switch (xc4_pvsMode)
|
switch (xc4_pvsMode)
|
||||||
{
|
{
|
||||||
case EPVSMode::PVS:
|
case EPVSMode::PVS:
|
||||||
|
|
|
@ -41,7 +41,6 @@ set(GRAPHICS_SOURCES
|
||||||
CGraphicsPalette.hpp CGraphicsPalette.cpp
|
CGraphicsPalette.hpp CGraphicsPalette.cpp
|
||||||
CPVSVisSet.hpp CPVSVisSet.cpp
|
CPVSVisSet.hpp CPVSVisSet.cpp
|
||||||
CPVSVisOctree.hpp CPVSVisOctree.cpp
|
CPVSVisOctree.hpp CPVSVisOctree.cpp
|
||||||
CPVSBounds.hpp CPVSBounds.cpp
|
|
||||||
CPVSAreaSet.hpp CPVSAreaSet.cpp
|
CPVSAreaSet.hpp CPVSAreaSet.cpp
|
||||||
CGraphics.hpp CGraphics.cpp
|
CGraphics.hpp CGraphics.cpp
|
||||||
CSimpleShadow.hpp CSimpleShadow.cpp
|
CSimpleShadow.hpp CSimpleShadow.cpp
|
||||||
|
|
|
@ -3,12 +3,19 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
CPVSAreaSet::CPVSAreaHolder::CPVSAreaHolder(CInputStream& in)
|
CPVSAreaSet::CPVSAreaSet(const u8* data, u32 len)
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
CPVSAreaSet::CPVSAreaSet(CInputStream& in)
|
|
||||||
{
|
{
|
||||||
|
CMemoryInStream r(data, len);
|
||||||
|
x0_numFeatures = r.readUint32Big();
|
||||||
|
x4_numLights = r.readUint32Big();
|
||||||
|
x8_c = r.readUint32Big();
|
||||||
|
xc_numActors = r.readUint32Big();
|
||||||
|
x10_leafSize = r.readUint32Big();
|
||||||
|
x14_lightIndexCount = r.readUint32Big();
|
||||||
|
x18_entityIndex = data + r.position();
|
||||||
|
x1c_lightLeaves = x18_entityIndex + xc_numActors * 4;
|
||||||
|
const u8* octreeData = x1c_lightLeaves + x14_lightIndexCount * x10_leafSize;
|
||||||
|
x20_octree = CPVSVisOctree::MakePVSVisOctree(octreeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,29 @@
|
||||||
#define __URDE_CPVSAREASET_HPP__
|
#define __URDE_CPVSAREASET_HPP__
|
||||||
|
|
||||||
#include "RetroTypes.hpp"
|
#include "RetroTypes.hpp"
|
||||||
|
#include "CPVSVisOctree.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
class CPVSAreaSet
|
class CPVSAreaSet
|
||||||
{
|
{
|
||||||
|
u32 x0_numFeatures;
|
||||||
|
u32 x4_numLights;
|
||||||
|
u32 x8_c;
|
||||||
|
u32 xc_numActors;
|
||||||
|
u32 x10_leafSize;
|
||||||
|
u32 x14_lightIndexCount;
|
||||||
|
const u8* x18_entityIndex;
|
||||||
|
const u8* x1c_lightLeaves;
|
||||||
|
CPVSVisOctree x20_octree;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
struct CPVSAreaHolder
|
CPVSAreaSet(const u8* data, u32 len);
|
||||||
{
|
u32 GetNumFeatures() const { return x0_numFeatures; }
|
||||||
CPVSAreaHolder(CInputStream& in);
|
u32 GetNumActors() const { return xc_numActors; }
|
||||||
};
|
u32 GetEntityIdByIndex(int idx) const { return x18_entityIndex[idx]; }
|
||||||
private:
|
const CPVSVisOctree& GetVisOctree() { return x20_octree; }
|
||||||
std::vector<CPVSAreaHolder> xunk;
|
|
||||||
public:
|
|
||||||
CPVSAreaSet(CInputStream& in);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +0,0 @@
|
||||||
#include "CPVSBounds.hpp"
|
|
||||||
|
|
||||||
namespace urde
|
|
||||||
{
|
|
||||||
|
|
||||||
CPVSBounds::CPVSBounds(CInputStream& in)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
u32 CPVSBounds::GetBoundsFileSize()
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool CPVSBounds::PointInBounds(const zeus::CVector3f&) const
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
#ifndef __URDE_CPVSBOUNDS_HPP__
|
|
||||||
#define __URDE_CPVSBOUNDS_HPP__
|
|
||||||
|
|
||||||
#include "RetroTypes.hpp"
|
|
||||||
#include "zeus/CVector3f.hpp"
|
|
||||||
|
|
||||||
namespace urde
|
|
||||||
{
|
|
||||||
|
|
||||||
class CPVSBounds
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
CPVSBounds(CInputStream& in);
|
|
||||||
u32 GetBoundsFileSize();
|
|
||||||
bool PointInBounds(const zeus::CVector3f&) const;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __URDE_CPVSBOUNDS_HPP__
|
|
|
@ -3,23 +3,111 @@
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
CPVSVisOctree::CPVSVisOctree(CInputStream& in)
|
CPVSVisOctree CPVSVisOctree::MakePVSVisOctree(const u8* data)
|
||||||
{
|
{
|
||||||
|
CMemoryInStream r(data, 68);
|
||||||
|
zeus::CAABox aabb = aabb.ReadBoundingBoxBig(r);
|
||||||
|
u32 a = r.readUint32Big();
|
||||||
|
u32 b = r.readUint32Big();
|
||||||
|
r.readUint32Big();
|
||||||
|
return CPVSVisOctree(aabb, a, b, data + r.position());
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CPVSVisOctree::GetNumChildren(const unsigned char*) const
|
CPVSVisOctree::CPVSVisOctree(const zeus::CAABox& aabb, u32 a, u32 b, const u8* c)
|
||||||
|
: x0_aabb(aabb), x18_totalBits(a), x1c_lightBits(b), x20_bufferFlag(c != nullptr), x24_octreeData(c)
|
||||||
|
{
|
||||||
|
x2c_searchAabb = x0_aabb;
|
||||||
|
x20_bufferFlag = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const u32 NumChildTable[] =
|
||||||
|
{
|
||||||
|
0, 2, 2, 4, 2, 4, 4, 8
|
||||||
|
};
|
||||||
|
|
||||||
|
u32 CPVSVisOctree::GetNumChildren(u8 byte) const
|
||||||
|
{
|
||||||
|
return NumChildTable[byte & 0x7];
|
||||||
|
}
|
||||||
|
|
||||||
|
u32 CPVSVisOctree::GetChildIndex(const u8*, const zeus::CVector3f&) const
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CPVSVisOctree::GetChildIndex(const unsigned char*, const zeus::CVector3f&) const
|
s32 CPVSVisOctree::IterateSearch(u8 nodeData, const zeus::CVector3f& tp) const
|
||||||
{
|
{
|
||||||
return 0;
|
if (!(nodeData & 0x7))
|
||||||
}
|
return -1; // Leaf node
|
||||||
|
|
||||||
u32 CPVSVisOctree::SetTestPoint(const zeus::CVector3f&) const
|
zeus::CVector3f newMin = x2c_searchAabb.center();
|
||||||
{
|
zeus::CVector3f newMax;
|
||||||
return 0;
|
bool highFlags[3];
|
||||||
|
|
||||||
|
if (tp.x > newMin.x)
|
||||||
|
{
|
||||||
|
newMax.x = x2c_searchAabb.max.x;
|
||||||
|
highFlags[0] = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newMax.x = newMin.x;
|
||||||
|
newMin.x = x2c_searchAabb.min.x;
|
||||||
|
highFlags[0] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp.y > newMin.y)
|
||||||
|
{
|
||||||
|
newMax.y = x2c_searchAabb.max.y;
|
||||||
|
highFlags[1] = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newMax.y = newMin.y;
|
||||||
|
newMin.y = x2c_searchAabb.min.y;
|
||||||
|
highFlags[1] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (tp.z > newMin.z)
|
||||||
|
{
|
||||||
|
newMax.z = x2c_searchAabb.max.z;
|
||||||
|
highFlags[2] = true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
newMax.z = newMin.z;
|
||||||
|
newMin.z = x2c_searchAabb.min.z;
|
||||||
|
highFlags[2] = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
u8 axisCounts[2] = {1, 1};
|
||||||
|
if (nodeData & 0x1)
|
||||||
|
axisCounts[0] = 2;
|
||||||
|
if (nodeData & 0x2)
|
||||||
|
axisCounts[1] = 2;
|
||||||
|
|
||||||
|
zeus::CAABox& newSearch = const_cast<zeus::CAABox&>(x2c_searchAabb);
|
||||||
|
if (nodeData & 0x1)
|
||||||
|
{
|
||||||
|
newSearch.min.x = newMin.x;
|
||||||
|
newSearch.max.x = newMax.x;
|
||||||
|
}
|
||||||
|
if (nodeData & 0x2)
|
||||||
|
{
|
||||||
|
newSearch.min.y = newMin.y;
|
||||||
|
newSearch.max.y = newMax.y;
|
||||||
|
}
|
||||||
|
if (nodeData & 0x4)
|
||||||
|
{
|
||||||
|
newSearch.min.z = newMin.z;
|
||||||
|
newSearch.max.z = newMax.z;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Branch node - calculate next relative pointer
|
||||||
|
return
|
||||||
|
highFlags[0] * bool(nodeData & 0x1) +
|
||||||
|
highFlags[1] * axisCounts[0] * bool(nodeData & 0x2) +
|
||||||
|
highFlags[2] * axisCounts[0] * axisCounts[1] * bool(nodeData & 0x4);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,17 +3,32 @@
|
||||||
|
|
||||||
#include "RetroTypes.hpp"
|
#include "RetroTypes.hpp"
|
||||||
#include "zeus/CVector3f.hpp"
|
#include "zeus/CVector3f.hpp"
|
||||||
|
#include "CPVSVisSet.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
class CPVSVisOctree
|
class CPVSVisOctree
|
||||||
{
|
{
|
||||||
|
zeus::CAABox x0_aabb;
|
||||||
|
u32 x18_totalBits;
|
||||||
|
u32 x1c_lightBits;
|
||||||
|
bool x20_bufferFlag;
|
||||||
|
const u8* x24_octreeData;
|
||||||
|
zeus::CAABox x2c_searchAabb;
|
||||||
public:
|
public:
|
||||||
CPVSVisOctree(CInputStream& in);
|
static CPVSVisOctree MakePVSVisOctree(const u8* data);
|
||||||
u32 GetNumChildren(const unsigned char*) const;
|
CPVSVisOctree() = default;
|
||||||
u32 GetChildIndex(const unsigned char*, const zeus::CVector3f&) const;
|
CPVSVisOctree(const zeus::CAABox& aabb, u32 a, u32 b, const u8* c);
|
||||||
u32 SetTestPoint(const zeus::CVector3f&) const;
|
u32 GetNumChildren(u8 byte) const;
|
||||||
|
u32 GetChildIndex(const u8*, const zeus::CVector3f&) const;
|
||||||
|
const zeus::CAABox& GetBounds() const { return x0_aabb; }
|
||||||
|
const u8* GetOctreeData() const { return x24_octreeData; }
|
||||||
|
|
||||||
|
u32 GetTotalBits() const { return x18_totalBits; }
|
||||||
|
u32 GetLightBits() const { return x1c_lightBits; }
|
||||||
|
void ResetSearch() const { const_cast<CPVSVisOctree&>(*this).x2c_searchAabb = x0_aabb; }
|
||||||
|
s32 IterateSearch(u8 nodeData, const zeus::CVector3f& tp) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,23 +1,110 @@
|
||||||
#include "CPVSVisSet.hpp"
|
#include "CPVSVisSet.hpp"
|
||||||
|
#include "CPVSVisOctree.hpp"
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
|
||||||
void CPVSVisSet::Reset(bool)
|
void CPVSVisSet::Reset(EPVSVisSetState state)
|
||||||
{
|
{
|
||||||
|
x0_state = state;
|
||||||
|
x4_numBits = 0;
|
||||||
|
x8_numLights = 0;
|
||||||
|
//xc_ = false;
|
||||||
|
x10_ptr = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CPVSVisSet::GetVisible(int)
|
EPVSVisSetState CPVSVisSet::GetVisible(u32 idx) const
|
||||||
{
|
{
|
||||||
return false;
|
if (x0_state != EPVSVisSetState::NodeFound)
|
||||||
|
return x0_state;
|
||||||
|
|
||||||
|
u32 numFeatures = x4_numBits - x8_numLights;
|
||||||
|
if (idx < numFeatures)
|
||||||
|
{
|
||||||
|
/* This is a feature lookup */
|
||||||
|
if (!x10_ptr[idx / 8] & (1 << (idx & 0x7)))
|
||||||
|
return EPVSVisSetState::EndOfTree;
|
||||||
|
return EPVSVisSetState::OutOfBounds;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* This is a light lookup */
|
||||||
|
u32 lightTest = idx - numFeatures + x4_numBits;
|
||||||
|
const u8* ptr = &x10_ptr[lightTest / 8];
|
||||||
|
lightTest &= 0x7;
|
||||||
|
if (lightTest != 0x7)
|
||||||
|
return EPVSVisSetState((ptr[0] & (0x3 << lightTest)) >> lightTest);
|
||||||
|
return EPVSVisSetState((ptr[0] >> 7) | ((ptr[1] & 0x1) << 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPVSVisSet::SetVisible(int,bool)
|
void CPVSVisSet::SetFromMemory(u32 numBits, u32 numLights, const u8* leafPtr)
|
||||||
{
|
{
|
||||||
|
x0_state = EPVSVisSetState::NodeFound;
|
||||||
|
x4_numBits = numBits;
|
||||||
|
x8_numLights = numLights;
|
||||||
|
x10_ptr = leafPtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPVSVisSet::SetFromMemory(const unsigned char*)
|
void CPVSVisSet::SetTestPoint(const CPVSVisOctree& octree, const zeus::CVector3f& point)
|
||||||
{
|
{
|
||||||
|
if (!octree.GetBounds().pointInside(point))
|
||||||
|
{
|
||||||
|
Reset(EPVSVisSetState::OutOfBounds);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const u8* octCur = octree.GetOctreeData();
|
||||||
|
octree.ResetSearch();
|
||||||
|
s32 nextNodeRel;
|
||||||
|
u8 curNode;
|
||||||
|
while ((nextNodeRel = octree.IterateSearch((curNode = *octCur++), point)) != -1)
|
||||||
|
{
|
||||||
|
if (nextNodeRel)
|
||||||
|
{
|
||||||
|
/* Skip node data */
|
||||||
|
if (!(curNode & 0x60))
|
||||||
|
{
|
||||||
|
octCur += hecl::SBig(reinterpret_cast<const u16*>(octCur)[nextNodeRel - 1]);
|
||||||
|
}
|
||||||
|
else if (curNode & 0x20)
|
||||||
|
{
|
||||||
|
octCur += *(octCur + nextNodeRel - 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const u8* tmp = octCur + (nextNodeRel - 1) * 3;
|
||||||
|
octCur += (tmp[0] << 16) + (tmp[1] << 8) + tmp[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Skip children data */
|
||||||
|
if (!(curNode & 0x60))
|
||||||
|
{
|
||||||
|
octCur += (octree.GetNumChildren(curNode) - 1) * 2;
|
||||||
|
}
|
||||||
|
else if (curNode & 0x20)
|
||||||
|
{
|
||||||
|
octCur += octree.GetNumChildren(curNode) - 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
octCur += (octree.GetNumChildren(curNode) - 1) * 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Handle leaf type */
|
||||||
|
switch (curNode & 0x18)
|
||||||
|
{
|
||||||
|
case 0x18:
|
||||||
|
SetFromMemory(octree.GetTotalBits(), octree.GetLightBits(), octCur);
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
Reset(EPVSVisSetState::EndOfTree);
|
||||||
|
break;
|
||||||
|
case 0x08:
|
||||||
|
default:
|
||||||
|
Reset(EPVSVisSetState::OutOfBounds);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,24 +2,33 @@
|
||||||
#define __URDE_CPVSVISSET_HPP__
|
#define __URDE_CPVSVISSET_HPP__
|
||||||
|
|
||||||
#include "RetroTypes.hpp"
|
#include "RetroTypes.hpp"
|
||||||
|
#include "zeus/CAABox.hpp"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace urde
|
namespace urde
|
||||||
{
|
{
|
||||||
|
class CPVSVisOctree;
|
||||||
|
|
||||||
|
enum class EPVSVisSetState
|
||||||
|
{
|
||||||
|
EndOfTree,
|
||||||
|
NodeFound,
|
||||||
|
OutOfBounds
|
||||||
|
};
|
||||||
|
|
||||||
class CPVSVisSet
|
class CPVSVisSet
|
||||||
{
|
{
|
||||||
int x0_bitCount;
|
EPVSVisSetState x0_state;
|
||||||
int x4_setCount = 0;
|
u32 x4_numBits;
|
||||||
std::vector<unsigned char> x8_bitset;
|
u32 x8_numLights;
|
||||||
|
//bool xc_; Used to be part of auto_ptr
|
||||||
|
const u8* x10_ptr;
|
||||||
public:
|
public:
|
||||||
CPVSVisSet(int count) : x0_bitCount(count) {}
|
void Reset(EPVSVisSetState state);
|
||||||
CPVSVisSet(int a, std::vector<unsigned char>&& bitset)
|
EPVSVisSetState GetState() const { return x0_state; }
|
||||||
: x0_bitCount(1), x4_setCount(a), x8_bitset(std::move(bitset)) {}
|
EPVSVisSetState GetVisible(u32 idx) const;
|
||||||
void Reset(bool);
|
void SetFromMemory(u32 numBits, u32 numLights, const u8* leafPtr);
|
||||||
bool GetVisible(int);
|
void SetTestPoint(const CPVSVisOctree& octree, const zeus::CVector3f&);
|
||||||
void SetVisible(int,bool);
|
|
||||||
void SetFromMemory(const unsigned char*);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -2008,7 +2008,7 @@ CFrontEndUI::CFrontEndUI()
|
||||||
m_touchBar = NewFrontEndUITouchBar();
|
m_touchBar = NewFrontEndUITouchBar();
|
||||||
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
|
m_touchBar->SetPhase(CFrontEndUITouchBar::EPhase::None);
|
||||||
|
|
||||||
//x14_phase = EPhase::ExitFrontEnd;
|
x14_phase = EPhase::ExitFrontEnd;
|
||||||
}
|
}
|
||||||
|
|
||||||
void CFrontEndUI::StartSlideShow(CArchitectureQueue& queue)
|
void CFrontEndUI::StartSlideShow(CArchitectureQueue& queue)
|
||||||
|
|
|
@ -65,7 +65,7 @@ void CActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateMana
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case EScriptObjectMessage::InternalMessage13: // 35
|
case EScriptObjectMessage::Constructed: // 35
|
||||||
{
|
{
|
||||||
for (const SConnection& conn : x20_conns)
|
for (const SConnection& conn : x20_conns)
|
||||||
{
|
{
|
||||||
|
|
|
@ -709,9 +709,76 @@ void CGameArea::StartStreamIn(CStateManager& mgr)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CGameArea::Validate(CStateManager& mgr)
|
void CGameArea::Validate(CStateManager& mgr)
|
||||||
{
|
{
|
||||||
return false;
|
if (xf0_24_postConstructed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
while (StartStreamingMainArea()) {}
|
||||||
|
|
||||||
|
for (auto& req : xf8_loadTransactions)
|
||||||
|
req->WaitForComplete();
|
||||||
|
|
||||||
|
if (xdc_tokens.empty())
|
||||||
|
{
|
||||||
|
VerifyTokenList(mgr);
|
||||||
|
for (CToken& tok : xdc_tokens)
|
||||||
|
tok.Lock();
|
||||||
|
for (CToken& tok : xdc_tokens)
|
||||||
|
tok.GetObj();
|
||||||
|
xf0_26_tokensReady = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
xf8_loadTransactions.clear();
|
||||||
|
|
||||||
|
PostConstructArea();
|
||||||
|
if (x4_selfIdx != kInvalidAreaId)
|
||||||
|
mgr.WorldNC()->MoveAreaToChain3(x4_selfIdx);
|
||||||
|
|
||||||
|
LoadScriptObjects(mgr);
|
||||||
|
|
||||||
|
CPVSAreaSet* pvs = x12c_postConstructed->xa0_pvs.get();
|
||||||
|
if (pvs && x12c_postConstructed->x1108_29_)
|
||||||
|
{
|
||||||
|
for (int i=0 ; i<pvs->GetNumActors() ; ++i)
|
||||||
|
{
|
||||||
|
TEditorId entId = pvs->GetEntityIdByIndex(i) | (x4_selfIdx << 16);
|
||||||
|
TUniqueId id = mgr.GetIdForScript(entId);
|
||||||
|
if (id != kInvalidUniqueId)
|
||||||
|
{
|
||||||
|
CPostConstructed::MapEntry& ent = x12c_postConstructed->xa8_pvsEntityMap[id & 0x3ff];
|
||||||
|
ent.x0_id = i + (pvs->GetNumFeatures() - pvs->GetNumActors());
|
||||||
|
ent.x4_uid = id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xf0_28_validated = true;
|
||||||
|
mgr.AreaLoaded(x4_selfIdx);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGameArea::LoadScriptObjects(CStateManager& mgr)
|
||||||
|
{
|
||||||
|
CWorldLayerState& layerState = *mgr.LayerState();
|
||||||
|
u32 layerCount = layerState.GetAreaLayerCount(x4_selfIdx);
|
||||||
|
std::vector<TEditorId> objIds;
|
||||||
|
for (u32 i=0 ; i<layerCount ; ++i)
|
||||||
|
{
|
||||||
|
if (layerState.IsLayerActive(x4_selfIdx, i))
|
||||||
|
{
|
||||||
|
auto layerBuf = GetLayerScriptBuffer(i);
|
||||||
|
CMemoryInStream r(layerBuf.first, layerBuf.second);
|
||||||
|
mgr.LoadScriptObjects(x4_selfIdx, r, objIds);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mgr.InitScriptObjects(objIds);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<u8*, u32> CGameArea::GetLayerScriptBuffer(int layer)
|
||||||
|
{
|
||||||
|
if (!xf0_24_postConstructed)
|
||||||
|
return {};
|
||||||
|
return x12c_postConstructed->x110c_layerPtrs[layer];
|
||||||
}
|
}
|
||||||
|
|
||||||
void CGameArea::PostConstructArea()
|
void CGameArea::PostConstructArea()
|
||||||
|
@ -797,7 +864,8 @@ void CGameArea::PostConstructArea()
|
||||||
{
|
{
|
||||||
x12c_postConstructed->x1108_29_ = r.readBool();
|
x12c_postConstructed->x1108_29_ = r.readBool();
|
||||||
x12c_postConstructed->x1108_30_ = r.readBool();
|
x12c_postConstructed->x1108_30_ = r.readBool();
|
||||||
x12c_postConstructed->xa0_pvs.reset(new CPVSAreaSet::CPVSAreaHolder(r));
|
x12c_postConstructed->xa0_pvs = std::make_unique<CPVSAreaSet>(secIt->first.get() + r.position(),
|
||||||
|
secIt->second - r.position());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -848,7 +916,7 @@ void CGameArea::FillInStaticGeometry()
|
||||||
|
|
||||||
void CGameArea::VerifyTokenList(CStateManager& stateMgr)
|
void CGameArea::VerifyTokenList(CStateManager& stateMgr)
|
||||||
{
|
{
|
||||||
if (xdc_tokens.empty())
|
if (xdc_tokens.size())
|
||||||
return;
|
return;
|
||||||
ClearTokenList();
|
ClearTokenList();
|
||||||
|
|
||||||
|
@ -881,7 +949,7 @@ void CGameArea::ClearTokenList()
|
||||||
else
|
else
|
||||||
xdc_tokens.clear();
|
xdc_tokens.clear();
|
||||||
|
|
||||||
xf0_26_tokensReady = 0;
|
xf0_26_tokensReady = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 CGameArea::GetPreConstructedSize() const
|
u32 CGameArea::GetPreConstructedSize() const
|
||||||
|
|
|
@ -105,7 +105,7 @@ class CGameArea : public IGameArea
|
||||||
bool xf0_25_active : 1;
|
bool xf0_25_active : 1;
|
||||||
bool xf0_26_tokensReady : 1;
|
bool xf0_26_tokensReady : 1;
|
||||||
bool xf0_27_paused : 1;
|
bool xf0_27_paused : 1;
|
||||||
bool xf0_28_ : 1;
|
bool xf0_28_validated : 1;
|
||||||
};
|
};
|
||||||
u8 _dummy = 0;
|
u8 _dummy = 0;
|
||||||
};
|
};
|
||||||
|
@ -174,13 +174,13 @@ public:
|
||||||
std::vector<CLight> x70_gfxLightsA;
|
std::vector<CLight> x70_gfxLightsA;
|
||||||
std::vector<CWorldLight> x80_lightsB;
|
std::vector<CWorldLight> x80_lightsB;
|
||||||
std::vector<CLight> x90_gfxLightsB;
|
std::vector<CLight> x90_gfxLightsB;
|
||||||
std::unique_ptr<CPVSAreaSet::CPVSAreaHolder> xa0_pvs;
|
std::unique_ptr<CPVSAreaSet> xa0_pvs;
|
||||||
u32 xa4_elemCount = 1024;
|
u32 xa4_elemCount = 1024;
|
||||||
struct MapEntry
|
struct MapEntry
|
||||||
{
|
{
|
||||||
s16 x0_id = -1;
|
s16 x0_id = -1;
|
||||||
TUniqueId x4_uid = kInvalidUniqueId;
|
TUniqueId x4_uid = kInvalidUniqueId;
|
||||||
} xa8_map[1024];
|
} xa8_pvsEntityMap[1024];
|
||||||
u32 x10a8_pvsVersion = 0;
|
u32 x10a8_pvsVersion = 0;
|
||||||
TLockedToken<CPFArea> x10ac_path;
|
TLockedToken<CPFArea> x10ac_path;
|
||||||
// bool x10b8_ = 0; optional flag for CToken
|
// bool x10b8_ = 0; optional flag for CToken
|
||||||
|
@ -301,7 +301,9 @@ public:
|
||||||
bool Invalidate(CStateManager& mgr);
|
bool Invalidate(CStateManager& mgr);
|
||||||
void CullDeadAreaRequests();
|
void CullDeadAreaRequests();
|
||||||
void StartStreamIn(CStateManager& mgr);
|
void StartStreamIn(CStateManager& mgr);
|
||||||
bool Validate(CStateManager& mgr);
|
void Validate(CStateManager& mgr);
|
||||||
|
void LoadScriptObjects(CStateManager& mgr);
|
||||||
|
std::pair<u8*, u32> GetLayerScriptBuffer(int layer);
|
||||||
void PostConstructArea();
|
void PostConstructArea();
|
||||||
void FillInStaticGeometry();
|
void FillInStaticGeometry();
|
||||||
void VerifyTokenList(CStateManager& stateMgr);
|
void VerifyTokenList(CStateManager& stateMgr);
|
||||||
|
@ -313,7 +315,7 @@ public:
|
||||||
const zeus::CTransform& GetInverseTransform() const {return x3c_invTransform;}
|
const zeus::CTransform& GetInverseTransform() const {return x3c_invTransform;}
|
||||||
const zeus::CAABox& GetAABB() const {return x6c_aabb;}
|
const zeus::CAABox& GetAABB() const {return x6c_aabb;}
|
||||||
|
|
||||||
const std::vector<Dock> GetDocks() const {return xcc_docks;}
|
const std::vector<Dock>& GetDocks() const {return xcc_docks;}
|
||||||
const Dock* GetDock(s32 dock) const { return &xcc_docks[dock]; }
|
const Dock* GetDock(s32 dock) const { return &xcc_docks[dock]; }
|
||||||
s32 GetDockCount() const { return xcc_docks.size(); }
|
s32 GetDockCount() const { return xcc_docks.size(); }
|
||||||
Dock* DockNC(s32 dock) { return &xcc_docks[dock]; }
|
Dock* DockNC(s32 dock) { return &xcc_docks[dock]; }
|
||||||
|
|
|
@ -57,7 +57,7 @@ void CScriptActor::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CSta
|
||||||
{
|
{
|
||||||
CScriptColorModulate::FadeOutHelper(mgr, x8_uid, x2d4_alphaMin);
|
CScriptColorModulate::FadeOutHelper(mgr, x8_uid, x2d4_alphaMin);
|
||||||
}
|
}
|
||||||
else if (msg == EScriptObjectMessage::InternalMessage13)
|
else if (msg == EScriptObjectMessage::Constructed)
|
||||||
{
|
{
|
||||||
for (const SConnection& conn : x20_conns)
|
for (const SConnection& conn : x20_conns)
|
||||||
{
|
{
|
||||||
|
|
|
@ -32,7 +32,7 @@ void CScriptAiJumpPoint::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId oth
|
||||||
{
|
{
|
||||||
AcceptScriptMsg(msg, other, mgr);
|
AcceptScriptMsg(msg, other, mgr);
|
||||||
|
|
||||||
if (msg != EScriptObjectMessage::InternalMessage13)
|
if (msg != EScriptObjectMessage::Constructed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (SConnection& conn : x20_conns)
|
for (SConnection& conn : x20_conns)
|
||||||
|
|
|
@ -33,7 +33,7 @@ void CScriptAreaAttributes::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
|
||||||
if (x4_areaId == kInvalidAreaId)
|
if (x4_areaId == kInvalidAreaId)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (msg == EScriptObjectMessage::InternalMessage13)
|
if (msg == EScriptObjectMessage::Constructed)
|
||||||
{
|
{
|
||||||
CGameArea* area = stateMgr.WorldNC()->GetArea(x4_areaId);
|
CGameArea* area = stateMgr.WorldNC()->GetArea(x4_areaId);
|
||||||
area->SetAreaAttributes(this);
|
area->SetAreaAttributes(this);
|
||||||
|
|
|
@ -41,7 +41,7 @@ void CScriptDistanceFog::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId obj
|
||||||
if (x4_areaId == kInvalidAreaId || !GetActive())
|
if (x4_areaId == kInvalidAreaId || !GetActive())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (msg == EScriptObjectMessage::InternalMessage13)
|
if (msg == EScriptObjectMessage::Constructed)
|
||||||
{
|
{
|
||||||
if (!x60_explicit)
|
if (!x60_explicit)
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -103,7 +103,7 @@ void CScriptDock::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStat
|
||||||
case EScriptObjectMessage::Deleted:
|
case EScriptObjectMessage::Deleted:
|
||||||
CleanUp();
|
CleanUp();
|
||||||
break;
|
break;
|
||||||
case EScriptObjectMessage::InternalMessage13:
|
case EScriptObjectMessage::Constructed:
|
||||||
AreaLoaded(mgr);
|
AreaLoaded(mgr);
|
||||||
break;
|
break;
|
||||||
case EScriptObjectMessage::InternalMessage14:
|
case EScriptObjectMessage::InternalMessage14:
|
||||||
|
|
|
@ -64,7 +64,7 @@ void CScriptShadowProjector::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId
|
||||||
|
|
||||||
x110_25_shadowInvalidated = true;
|
x110_25_shadowInvalidated = true;
|
||||||
}
|
}
|
||||||
else if (msg == EScriptObjectMessage::InternalMessage13)
|
else if (msg == EScriptObjectMessage::Constructed)
|
||||||
{
|
{
|
||||||
for (const SConnection& conn : x20_conns)
|
for (const SConnection& conn : x20_conns)
|
||||||
{
|
{
|
||||||
|
|
|
@ -235,6 +235,11 @@ void CWorld::MoveToChain(CGameArea* area, EChain chain)
|
||||||
x4c_chainHeads[int(chain)] = area;
|
x4c_chainHeads[int(chain)] = area;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CWorld::MoveAreaToChain3(TAreaId aid)
|
||||||
|
{
|
||||||
|
MoveToChain(x18_areas[aid].get(), EChain::Three);
|
||||||
|
}
|
||||||
|
|
||||||
void CWorld::LoadSoundGroup(int groupId, ResId agscId, CSoundGroupData& data) {}
|
void CWorld::LoadSoundGroup(int groupId, ResId agscId, CSoundGroupData& data) {}
|
||||||
|
|
||||||
void CWorld::LoadSoundGroups() {}
|
void CWorld::LoadSoundGroups() {}
|
||||||
|
|
|
@ -152,6 +152,7 @@ private:
|
||||||
public:
|
public:
|
||||||
|
|
||||||
void MoveToChain(CGameArea* area, EChain chain);
|
void MoveToChain(CGameArea* area, EChain chain);
|
||||||
|
void MoveAreaToChain3(TAreaId aid);
|
||||||
bool CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId);
|
bool CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId);
|
||||||
bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr);
|
bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr);
|
||||||
void TravelToArea(TAreaId aid, CStateManager& mgr, bool);
|
void TravelToArea(TAreaId aid, CStateManager& mgr, bool);
|
||||||
|
|
|
@ -212,7 +212,7 @@ enum class EScriptObjectMessage
|
||||||
InternalMessage10 = 32,
|
InternalMessage10 = 32,
|
||||||
InternalMessage11 = 33,
|
InternalMessage11 = 33,
|
||||||
Deleted = 34,
|
Deleted = 34,
|
||||||
InternalMessage13 = 35,
|
Constructed = 35,
|
||||||
InternalMessage14 = 36,
|
InternalMessage14 = 36,
|
||||||
InternalMessage15 = 37,
|
InternalMessage15 = 37,
|
||||||
InternalMessage16 = 38,
|
InternalMessage16 = 38,
|
||||||
|
|
Loading…
Reference in New Issue