metaforce/Runtime/World/CGameArea.hpp

382 lines
12 KiB
C++
Raw Normal View History

2016-04-16 23:48:29 +00:00
#ifndef __URDE_CGAMEAREA_HPP__
#define __URDE_CGAMEAREA_HPP__
2016-04-17 02:50:45 +00:00
#include "zeus/CVector2f.hpp"
#include "zeus/CColor.hpp"
2016-04-19 00:17:49 +00:00
#include "zeus/CAABox.hpp"
#include "CToken.hpp"
2016-04-17 02:50:45 +00:00
#include "RetroTypes.hpp"
2016-04-19 00:17:49 +00:00
#include "IGameArea.hpp"
2016-08-05 20:26:23 +00:00
#include "Collision/CAreaOctTree.hpp"
2016-04-19 00:17:49 +00:00
#include "hecl/ClientProcess.hpp"
2016-07-23 00:26:17 +00:00
#include "Graphics/CMetroidModelInstance.hpp"
2016-08-07 00:20:02 +00:00
#include "CObjectList.hpp"
#include "CWorldLight.hpp"
#include "Graphics/CPVSAreaSet.hpp"
2016-08-08 04:48:18 +00:00
#include "Graphics/CGraphics.hpp"
#include "Graphics/CModel.hpp"
2016-08-08 04:48:18 +00:00
#include "CPathFindArea.hpp"
#include "Editor/ProjectResourceFactoryBase.hpp"
#include "World/CEnvFxManager.hpp"
2016-04-17 02:50:45 +00:00
2016-04-16 23:48:29 +00:00
namespace urde
{
2016-07-23 00:26:17 +00:00
class CStateManager;
class CScriptAreaAttributes;
2016-07-23 00:26:17 +00:00
class CDummyGameArea : public IGameArea
{
2016-07-24 04:46:32 +00:00
friend class CDummyWorld;
int x4_mlvlVersion;
2017-08-13 05:26:14 +00:00
CAssetId x8_nameSTRG;
CAssetId xc_mrea;
TAreaId x10_areaId;
zeus::CTransform x14_transform;
std::vector<u16> x44_attachedAreaIndices;
std::vector<Dock> x54_docks;
2016-07-23 00:26:17 +00:00
public:
CDummyGameArea(CInputStream& in, int idx, int mlvlVersion);
2016-07-23 00:26:17 +00:00
bool IGetScriptingMemoryAlways() const;
TAreaId IGetAreaId() const;
2017-08-13 05:26:14 +00:00
CAssetId IGetAreaAssetId() const;
2016-07-23 00:26:17 +00:00
bool IIsActive() const;
TAreaId IGetAttachedAreaId(int) const;
u32 IGetNumAttachedAreas() const;
2017-08-13 05:26:14 +00:00
CAssetId IGetStringTableAssetId() const;
2016-07-23 00:26:17 +00:00
const zeus::CTransform& IGetTM() const;
};
2016-08-07 00:20:02 +00:00
struct CAreaRenderOctTree
{
struct Node
{
u16 x0_bitmapIdx;
u16 x2_flags;
u16 x4_children[];
u32 GetChildCount() const;
zeus::CAABox GetNodeBounds(const zeus::CAABox& curAABB, int idx) const;
void RecursiveBuildOverlaps(u32* out, const CAreaRenderOctTree& parent, const zeus::CAABox& curAABB,
const zeus::CAABox& testAABB) const;
};
const u8* x0_buf;
2016-08-07 00:20:02 +00:00
u32 x8_bitmapCount;
u32 xc_meshCount;
u32 x10_nodeCount;
u32 x14_bitmapWordCount;
zeus::CAABox x18_aabb;
const u32* x30_bitmaps;
const u32* x34_indirectionTable;
const u8* x38_entries;
2016-08-07 00:20:02 +00:00
CAreaRenderOctTree(const u8* buf);
2016-08-07 00:20:02 +00:00
void FindOverlappingModels(std::vector<u32>& out, const zeus::CAABox& testAABB) const;
void FindOverlappingModels(u32* out, const zeus::CAABox& testAABB) const;
2016-08-07 00:20:02 +00:00
};
2016-04-19 00:17:49 +00:00
class CGameArea : public IGameArea
2016-04-16 23:48:29 +00:00
{
2016-07-24 04:46:32 +00:00
friend class CWorld;
friend class CStateManager;
2016-07-24 04:46:32 +00:00
int x4_selfIdx;
2017-08-13 05:26:14 +00:00
CAssetId x8_nameSTRG;
2016-04-19 00:17:49 +00:00
zeus::CTransform xc_transform;
zeus::CTransform x3c_invTransform;
zeus::CAABox x6c_aabb;
2017-08-13 05:26:14 +00:00
CAssetId x84_mrea;
2016-04-19 00:17:49 +00:00
u32 x88_areaId;
std::vector<u16> x8c_attachedAreaIndices;
std::vector<SObjectTag> x9c_deps1;
std::vector<SObjectTag> xac_deps2;
2016-08-07 00:20:02 +00:00
std::vector<u32> xbc_layerDepOffsets;
2016-04-19 00:17:49 +00:00
std::vector<Dock> xcc_docks;
std::vector<CToken> xdc_tokens;
u32 xec_totalResourcesSize = 0;
union
{
struct
{
2016-07-23 03:07:07 +00:00
bool xf0_24_postConstructed : 1;
2016-04-23 18:04:49 +00:00
bool xf0_25_active : 1;
2016-08-07 00:20:02 +00:00
bool xf0_26_tokensReady : 1;
2017-02-18 02:19:50 +00:00
bool xf0_27_paused : 1;
2017-02-19 09:27:01 +00:00
bool xf0_28_validated : 1;
2016-04-19 00:17:49 +00:00
};
u8 _dummy = 0;
};
enum class EPhase
2016-08-08 04:48:18 +00:00
{
LoadHeader,
LoadSecSizes,
ReserveSections,
LoadDataSections,
WaitForFinish
} xf4_phase = EPhase::LoadHeader;
2016-08-08 04:48:18 +00:00
std::list<std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>> xf8_loadTransactions;
2016-04-19 00:17:49 +00:00
2016-04-17 02:50:45 +00:00
public:
2017-01-15 03:59:37 +00:00
class CChainIterator
{
CGameArea* m_area;
public:
CChainIterator(CGameArea* area) : m_area(area) {}
CGameArea& operator*() const { return *m_area; }
CGameArea* operator->() const { return m_area; }
CChainIterator& operator++() { m_area = m_area->GetNext(); return *this; }
bool operator!=(const CChainIterator& other) const { return m_area != other.m_area; }
bool operator==(const CChainIterator& other) const { return m_area == other.m_area; }
};
class CConstChainIterator
{
const CGameArea* m_area;
public:
CConstChainIterator(const CGameArea* area) : m_area(area) {}
const CGameArea& operator*() const { return *m_area; }
const CGameArea* operator->() const { return m_area; }
CConstChainIterator& operator++() { m_area = m_area->GetNext(); return *this; }
bool operator!=(const CConstChainIterator& other) const { return m_area != other.m_area; }
bool operator==(const CConstChainIterator& other) const { return m_area == other.m_area; }
};
2017-01-15 03:59:37 +00:00
class CAreaObjectList : public CObjectList
{
private:
TAreaId x200c_areaIdx = 0;
public:
CAreaObjectList(TAreaId areaIdx)
: CObjectList(EGameObjectList::Invalid)
, x200c_areaIdx(areaIdx)
{
}
bool IsQualified(const CEntity& ent);
};
2016-08-10 00:46:53 +00:00
enum class EOcclusionState
{
Occluded,
Visible
2016-08-10 00:46:53 +00:00
};
2016-08-07 00:20:02 +00:00
class CAreaFog
{
2016-08-08 04:48:18 +00:00
ERglFogMode x0_fogMode = ERglFogMode::None;
zeus::CVector2f x4_rangeCur = {0.f, 1024.f};
zeus::CVector2f xc_rangeTarget = {0.f, 1024.f};
zeus::CVector2f x14_rangeDelta;
zeus::CColor x1c_colorCur = {0.5f, 0.5f, 0.5f, 1.f};
zeus::CColor x28_colorTarget = {0.5f, 0.5f, 0.5f, 1.f};
float x34_colorDelta = 0.f;
2016-08-07 00:20:02 +00:00
public:
void SetCurrent() const;
void Update(float dt);
2016-08-08 04:48:18 +00:00
void RollFogOut(float rangeDelta, float colorDelta, const zeus::CColor& color);
2016-08-07 00:20:02 +00:00
void FadeFog(ERglFogMode, const zeus::CColor& color, const zeus::CVector2f& vec1,
float, const zeus::CVector2f& vec2);
2016-08-08 04:48:18 +00:00
void SetFogExplicit(ERglFogMode mode, const zeus::CColor& color, const zeus::CVector2f& range);
2016-08-07 00:20:02 +00:00
bool IsFogDisabled() const;
void DisableFog();
};
2016-07-23 00:26:17 +00:00
struct CPostConstructed
{
2016-08-07 00:20:02 +00:00
std::unique_ptr<CAreaOctTree> x0_collision;
u32 x8_collisionSize = 0;
std::experimental::optional<CAreaRenderOctTree> xc_octTree;
2016-07-28 04:55:06 +00:00
std::vector<CMetroidModelInstance> x4c_insts;
CBooModel::SShader m_materialSet = {0};
boo::GraphicsDataToken m_gfxToken;
2016-08-07 00:20:02 +00:00
//std::unique_ptr<from unknown, pointless MREA section> x5c_;
std::vector<CWorldLight> x60_lightsA;
std::vector<CLight> x70_gfxLightsA;
std::vector<CWorldLight> x80_lightsB;
std::vector<CLight> x90_gfxLightsB;
2017-02-19 09:27:01 +00:00
std::unique_ptr<CPVSAreaSet> xa0_pvs;
2016-07-23 00:26:17 +00:00
u32 xa4_elemCount = 1024;
struct MapEntry
{
s16 x0_id = -1;
TUniqueId x4_uid = kInvalidUniqueId;
2017-02-19 09:27:01 +00:00
} xa8_pvsEntityMap[1024];
2016-08-07 00:20:02 +00:00
u32 x10a8_pvsVersion = 0;
2016-08-10 16:05:14 +00:00
TLockedToken<CPFArea> x10ac_path;
2016-07-23 00:26:17 +00:00
// bool x10b8_ = 0; optional flag for CToken
u32 x10bc_ = 0;
2017-01-15 03:59:37 +00:00
std::unique_ptr<CAreaObjectList> x10c0_areaObjs;
2016-08-07 00:20:02 +00:00
std::unique_ptr<CAreaFog> x10c4_areaFog;
const u8* x10c8_sclyBuf = nullptr;
2016-08-07 00:20:02 +00:00
u32 x10d0_sclySize = 0;
2016-07-23 00:26:17 +00:00
u32 x10d4_ = 0;
const CScriptAreaAttributes* x10d8_areaAttributes = nullptr;
EOcclusionState x10dc_occlusionState = EOcclusionState::Occluded;
2016-07-23 00:26:17 +00:00
u32 x10e0_ = 0;
float x10e4_ = 5.f;
u32 x10e8_ = -1;
u32 x10ec_ = 0;
// std::vector<CAramToken> x10f0_tokens;
u32 x1100_ = 0;
u32 x1104_ = 0;
union
{
struct
{
bool x1108_24_ : 1;
bool x1108_25_modelsConstructed : 1;
2016-07-23 00:26:17 +00:00
bool x1108_26_ : 1;
2016-08-10 00:46:53 +00:00
bool x1108_27_ : 1;
2016-07-23 00:26:17 +00:00
bool x1108_28_ : 1;
bool x1108_29_ : 1;
bool x1108_30_ : 1;
};
u32 _dummy = 0;
2016-07-23 00:26:17 +00:00
};
std::vector<std::pair<const u8*, u32>> x110c_layerPtrs;
2016-07-23 03:07:07 +00:00
float x111c_thermalCurrent = 0.f;
float x1120_thermalSpeed = 0.f;
float x1124_thermalTarget = 0.f;
float x1128_worldLightingLevel = 1.f;
2016-08-09 03:58:19 +00:00
float x112c_xraySpeed = 0.f;
float x1130_xrayTarget = 1.f;
2017-09-07 03:55:31 +00:00
float x1134_weaponWorldLightingSpeed = 0.f;
float x1138_weaponWorldLightingTarget = 1.f;
2016-07-23 00:26:17 +00:00
u32 x113c_ = 0;
};
2016-07-23 03:07:07 +00:00
private:
2016-08-07 00:20:02 +00:00
std::vector<std::pair<std::unique_ptr<u8[]>, int>> x110_mreaSecBufs;
std::vector<std::pair<const u8*, int>> m_resolvedBufs;
2016-08-08 04:48:18 +00:00
u32 x124_secCount = 0;
u32 x128_mreaDataOffset = 0;
2016-07-23 03:07:07 +00:00
std::unique_ptr<CPostConstructed> x12c_postConstructed;
CGameArea* x130_next = nullptr;
CGameArea* x134_prev = nullptr;
2017-04-13 19:28:31 +00:00
EChain x138_curChain = EChain::ToDeallocate;
2016-07-23 03:07:07 +00:00
void UpdateFog(float dt);
void UpdateThermalVisor(float dt);
2017-09-07 03:55:31 +00:00
void UpdateWeaponWorldLighting(float dt);
2016-07-23 03:07:07 +00:00
2016-08-07 00:20:02 +00:00
struct MREAHeader
{
u32 version = 0;
zeus::CTransform xf;
u32 modelCount;
u32 secCount;
u32 geomSecIdx;
u32 sclySecIdx;
u32 collisionSecIdx;
u32 unkSecIdx;
u32 lightSecIdx;
u32 visiSecIdx;
u32 pathSecIdx;
u32 arotSecIdx;
};
2016-07-23 03:07:07 +00:00
public:
2016-07-23 00:26:17 +00:00
2016-07-24 04:46:32 +00:00
CGameArea(CInputStream& in, int idx, int mlvlVersion);
2017-10-17 05:51:53 +00:00
CGameArea(CAssetId mreaId); // Warmup constructor
2016-04-19 00:17:49 +00:00
2016-07-23 00:26:17 +00:00
bool IsFinishedOccluding() const;
void ReadDependencyList();
2017-02-18 02:19:50 +00:00
void SetPauseState(bool paused);
2016-07-23 00:26:17 +00:00
bool IGetScriptingMemoryAlways() const;
2017-03-05 07:57:12 +00:00
TAreaId GetAreaId() const { return x4_selfIdx; }
TAreaId IGetAreaId() const { return x4_selfIdx; }
2017-08-13 05:26:14 +00:00
CAssetId IGetAreaAssetId() const { return x84_mrea; }
2016-07-23 00:26:17 +00:00
bool IIsActive() const;
TAreaId IGetAttachedAreaId(int) const;
u32 IGetNumAttachedAreas() const;
2017-08-13 05:26:14 +00:00
CAssetId IGetStringTableAssetId() const;
2016-07-23 00:26:17 +00:00
const zeus::CTransform& IGetTM() const;
2016-08-09 03:58:19 +00:00
void SetXRaySpeedAndTarget(float f1, float f2);
void SetThermalSpeedAndTarget(float f1, float f2);
2017-09-07 03:55:31 +00:00
void SetWeaponWorldLighting(float speed, float target);
2016-08-09 03:58:19 +00:00
2017-08-13 05:26:14 +00:00
CAssetId GetAreaAssetId() const { return x84_mrea; }
2016-08-09 03:58:19 +00:00
const CAreaFog* GetAreaFog() const { return GetPostConstructed()->x10c4_areaFog.get(); }
CAreaFog* AreaFog() { return const_cast<CAreaFog*>(GetAreaFog()); }
float GetXRayFogDistance() const;
EEnvFxType DoesAreaNeedEnvFx() const;
2016-07-23 00:26:17 +00:00
bool DoesAreaNeedSkyNow() const;
bool OtherAreaOcclusionChanged();
void PingOcclusionState();
void PreRender();
void AliveUpdate(float dt);
void SetOcclusionState(EOcclusionState state);
2017-01-07 01:58:05 +00:00
EOcclusionState GetOcclusionState() const { return GetPostConstructed()->x10dc_occlusionState; }
2016-07-23 00:26:17 +00:00
void RemoveStaticGeometry();
void AddStaticGeometry();
//void TransferTokensToARAM();
//void TransferARAMTokensOver();
EChain SetChain(CGameArea* prev, EChain chain);
2016-08-08 04:48:18 +00:00
bool StartStreamingMainArea();
2016-07-23 00:26:17 +00:00
//void UnloadAllLoadedTextures();
//void ReloadAllLoadedTextures();
2016-08-10 00:46:53 +00:00
void ReloadAllUnloadedTextures();
2017-01-07 01:58:05 +00:00
void PrepTokens();
2016-07-23 00:26:17 +00:00
u32 GetNumPartSizes() const;
void AllocNewAreaData(int, int);
bool Invalidate(CStateManager& mgr);
2016-07-23 00:26:17 +00:00
void CullDeadAreaRequests();
void StartStreamIn(CStateManager& mgr);
2017-02-19 09:27:01 +00:00
void Validate(CStateManager& mgr);
void LoadScriptObjects(CStateManager& mgr);
std::pair<const u8*, u32> GetLayerScriptBuffer(int layer);
2016-07-23 00:26:17 +00:00
void PostConstructArea();
void FillInStaticGeometry(bool textures = true);
2016-08-07 00:20:02 +00:00
void VerifyTokenList(CStateManager& stateMgr);
2016-07-23 00:26:17 +00:00
void ClearTokenList();
u32 GetPreConstructedSize() const;
2016-08-07 00:20:02 +00:00
MREAHeader VerifyHeader() const;
TUniqueId LookupPVSUniqueID(TUniqueId id) const;
s16 LookupPVSID(TUniqueId id) const;
const CPVSAreaSet* GetAreaVisSet() const { return GetPostConstructed()->xa0_pvs.get(); }
u32 Get1stPVSLightFeature(u32 lightIdx) const
{ return GetAreaVisSet() ? GetAreaVisSet()->Get1stLightIndex(lightIdx) : -1; }
u32 Get2ndPVSLightFeature(u32 lightIdx) const
{ return GetAreaVisSet() ? GetAreaVisSet()->Get2ndLightIndex(lightIdx) : -1; }
2016-07-23 00:26:17 +00:00
2016-04-19 00:17:49 +00:00
const zeus::CTransform& GetTransform() const {return xc_transform;}
const zeus::CTransform& GetInverseTransform() const {return x3c_invTransform;}
const zeus::CAABox& GetAABB() const {return x6c_aabb;}
2017-02-19 09:27:01 +00:00
const std::vector<Dock>& GetDocks() const {return xcc_docks;}
const Dock* GetDock(s32 dock) const { return &xcc_docks[dock]; }
s32 GetDockCount() const { return xcc_docks.size(); }
2016-12-22 02:48:22 +00:00
Dock* DockNC(s32 dock) { return &xcc_docks[dock]; }
2016-07-23 03:07:07 +00:00
bool IsPostConstructed() const {return xf0_24_postConstructed;}
const CPostConstructed* GetPostConstructed() const {return x12c_postConstructed.get();}
2017-03-24 05:30:16 +00:00
bool IsValidated() const { return xf0_28_validated; }
void SetAreaAttributes(const CScriptAreaAttributes* areaAttributes);
bool GetActive() const { return xf0_25_active; }
void SetActive(bool active) { xf0_25_active = active; }
CObjectList& GetAreaObjects() const { return *GetPostConstructed()->x10c0_areaObjs.get(); }
CGameArea* GetNext() const { return x130_next; }
2017-10-17 05:51:53 +00:00
static void WarmupShaders(const SObjectTag& mreaTag);
2016-04-16 23:48:29 +00:00
};
}
#endif // __URDE_CGAMEAREA_HPP__