mirror of
				https://github.com/AxioDL/metaforce.git
				synced 2025-10-27 15:30:23 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			241 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			241 lines
		
	
	
		
			7.8 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| #pragma once
 | |
| 
 | |
| #include <array>
 | |
| #include <memory>
 | |
| #include <string>
 | |
| #include <vector>
 | |
| 
 | |
| #include "Runtime/RetroTypes.hpp"
 | |
| #include "Runtime/rstl.hpp"
 | |
| #include "Runtime/Audio/CAudioGroupSet.hpp"
 | |
| #include "Runtime/Audio/CSfxManager.hpp"
 | |
| #include "Runtime/AutoMapper/CMapWorld.hpp"
 | |
| #include "Runtime/Graphics/CModel.hpp"
 | |
| #include "Runtime/World/CEnvFxManager.hpp"
 | |
| #include "Runtime/World/CGameArea.hpp"
 | |
| #include "Runtime/World/ScriptObjectSupport.hpp"
 | |
| 
 | |
| namespace metaforce {
 | |
| class CGameArea;
 | |
| class CResFactory;
 | |
| class IGameArea;
 | |
| class IObjectStore;
 | |
| 
 | |
| struct CWorldLayers;
 | |
| 
 | |
| class IWorld {
 | |
| public:
 | |
|   virtual ~IWorld() = default;
 | |
|   virtual CAssetId IGetWorldAssetId() const = 0;
 | |
|   virtual CAssetId IGetStringTableAssetId() const = 0;
 | |
|   virtual CAssetId IGetSaveWorldAssetId() const = 0;
 | |
|   virtual const CMapWorld* IGetMapWorld() const = 0;
 | |
|   virtual CMapWorld* IGetMapWorld() = 0;
 | |
|   virtual const IGameArea* IGetAreaAlways(TAreaId id) const = 0;
 | |
|   virtual TAreaId IGetCurrentAreaId() const = 0;
 | |
|   virtual TAreaId IGetAreaId(CAssetId id) const = 0;
 | |
|   virtual bool ICheckWorldComplete() = 0;
 | |
|   virtual std::string IGetDefaultAudioTrack() const = 0;
 | |
|   virtual int IGetAreaCount() const = 0;
 | |
|   // Metaforce addition
 | |
|   virtual const std::optional<CWorldLayers>& GetWorldLayers() const = 0;
 | |
| };
 | |
| 
 | |
| struct CWorldLayers {
 | |
|   struct Area {
 | |
|     u32 m_startNameIdx;
 | |
|     u32 m_layerCount;
 | |
|     u64 m_layerBits;
 | |
|   };
 | |
|   std::vector<Area> m_areas;
 | |
|   std::vector<std::string> m_names;
 | |
|   static std::optional<CWorldLayers> ReadWorldLayers(CInputStream& r, int version, CAssetId mlvlId);
 | |
| };
 | |
| 
 | |
| class CDummyWorld : public IWorld {
 | |
|   enum class Phase {
 | |
|     Loading,
 | |
|     LoadingMap,
 | |
|     LoadingMapAreas,
 | |
|     Done,
 | |
|   };
 | |
| 
 | |
|   bool x4_loadMap;
 | |
|   Phase x8_phase = Phase::Loading;
 | |
|   CAssetId xc_mlvlId;
 | |
|   CAssetId x10_strgId;
 | |
|   CAssetId x14_savwId;
 | |
|   std::vector<CDummyGameArea> x18_areas;
 | |
|   CAssetId x28_mapWorldId;
 | |
|   TLockedToken<CMapWorld> x2c_mapWorld;
 | |
|   std::shared_ptr<IDvdRequest> x30_loadToken;
 | |
|   std::unique_ptr<uint8_t[]> x34_loadBuf;
 | |
|   u32 x38_bufSz;
 | |
|   TAreaId x3c_curAreaId = kInvalidAreaId;
 | |
| 
 | |
|   // Metaforce addition
 | |
|   std::optional<CWorldLayers> m_worldLayers;
 | |
| 
 | |
| public:
 | |
|   CDummyWorld(CAssetId mlvlId, bool loadMap);
 | |
|   ~CDummyWorld() override;
 | |
|   CAssetId IGetWorldAssetId() const override;
 | |
|   CAssetId IGetStringTableAssetId() const override;
 | |
|   CAssetId IGetSaveWorldAssetId() const override;
 | |
|   const CMapWorld* IGetMapWorld() const override;
 | |
|   CMapWorld* IGetMapWorld() override;
 | |
|   const IGameArea* IGetAreaAlways(TAreaId id) const override;
 | |
|   TAreaId IGetCurrentAreaId() const override;
 | |
|   TAreaId IGetAreaId(CAssetId id) const override;
 | |
|   bool ICheckWorldComplete() override;
 | |
|   std::string IGetDefaultAudioTrack() const override;
 | |
|   int IGetAreaCount() const override;
 | |
|   const std::optional<CWorldLayers>& GetWorldLayers() const override;
 | |
| };
 | |
| 
 | |
| class CWorld : public IWorld {
 | |
|   friend class CStateManager;
 | |
| 
 | |
| public:
 | |
|   class CRelay {
 | |
|     TEditorId x0_relay = kInvalidEditorId;
 | |
|     TEditorId x4_target = kInvalidEditorId;
 | |
|     s16 x8_msg = -1;
 | |
|     bool xa_active = false;
 | |
| 
 | |
|   public:
 | |
|     CRelay() = default;
 | |
|     explicit CRelay(CInputStream& in);
 | |
| 
 | |
|     TEditorId GetRelayId() const { return x0_relay; }
 | |
|     TEditorId GetTargetId() const { return x4_target; }
 | |
|     s16 GetMessage() const { return x8_msg; }
 | |
|     bool GetActive() const { return xa_active; }
 | |
| 
 | |
|     static std::vector<CWorld::CRelay> ReadMemoryRelays(CInputStream& r);
 | |
|   };
 | |
| 
 | |
|   struct CSoundGroupData {
 | |
|     int x0_groupId;
 | |
|     CAssetId x4_agscId;
 | |
|     std::string xc_name;
 | |
|     TCachedToken<CAudioGroupSet> x1c_groupData;
 | |
| 
 | |
|   public:
 | |
|     CSoundGroupData(int grpId, CAssetId agsc);
 | |
|   };
 | |
| 
 | |
| private:
 | |
|   enum class Phase {
 | |
|     Loading,
 | |
|     LoadingMap,
 | |
|     LoadingMapAreas,
 | |
|     LoadingSkyBox,
 | |
|     LoadingSoundGroups,
 | |
|     Done,
 | |
|   };
 | |
| 
 | |
|   Phase x4_phase = Phase::Loading;
 | |
|   CAssetId x8_mlvlId;
 | |
|   CAssetId xc_strgId;
 | |
|   CAssetId x10_savwId;
 | |
|   std::vector<std::unique_ptr<CGameArea>> x18_areas;
 | |
|   CAssetId x24_mapwId;
 | |
|   TLockedToken<CMapWorld> x28_mapWorld;
 | |
|   std::vector<CRelay> x2c_relays;
 | |
|   std::shared_ptr<IDvdRequest> x3c_loadToken;
 | |
|   std::unique_ptr<uint8_t[]> x40_loadBuf;
 | |
|   u32 x44_bufSz;
 | |
|   u32 x48_chainCount = 0;
 | |
|   std::array<CGameArea*, 5> x4c_chainHeads{};
 | |
| 
 | |
|   IObjectStore& x60_objectStore;
 | |
|   IFactory& x64_resFactory;
 | |
|   TAreaId x68_curAreaId = kInvalidAreaId;
 | |
|   u32 x6c_loadedAudioGrpCount = 0;
 | |
|   bool x70_24_currentAreaNeedsAllocation : 1 = true;
 | |
|   bool x70_25_loadPaused : 1 = false;
 | |
|   bool x70_26_skyboxActive : 1 = false;
 | |
|   bool x70_27_skyboxVisible : 1 = false;
 | |
|   std::vector<CSoundGroupData> x74_soundGroupData;
 | |
|   std::string x84_defAudioTrack;
 | |
|   std::optional<TLockedToken<CModel>> x94_skyboxWorld;
 | |
|   std::optional<TLockedToken<CModel>> xa4_skyboxWorldLoaded;
 | |
|   std::optional<TLockedToken<CModel>> xb4_skyboxOverride;
 | |
|   EEnvFxType xc4_neededFx = EEnvFxType::None;
 | |
|   rstl::reserved_vector<CSfxHandle, 10> xc8_globalSfxHandles;
 | |
| 
 | |
|   // Metaforce addition
 | |
|   std::optional<CWorldLayers> m_worldLayers;
 | |
| 
 | |
|   void LoadSoundGroup(int groupId, CAssetId agscId, CSoundGroupData& data);
 | |
|   void LoadSoundGroups();
 | |
|   void UnloadSoundGroups();
 | |
|   void StopSounds();
 | |
| 
 | |
| public:
 | |
|   void MoveToChain(CGameArea* area, EChain chain);
 | |
|   void MoveAreaToAliveChain(TAreaId aid);
 | |
|   bool CheckWorldComplete(CStateManager* mgr, TAreaId id, CAssetId mreaId);
 | |
| 
 | |
|   [[nodiscard]] auto GetChainHead(EChain chain) { return CGameArea::CChainIterator{x4c_chainHeads[size_t(chain)]}; }
 | |
|   [[nodiscard]] auto GetChainHead(EChain chain) const {
 | |
|     return CGameArea::CConstChainIterator{x4c_chainHeads[size_t(chain)]};
 | |
|   }
 | |
|   [[nodiscard]] auto begin() { return GetChainHead(EChain::Alive); }
 | |
|   [[nodiscard]] auto end() { return AliveAreasEnd(); }
 | |
|   [[nodiscard]] auto begin() const { return GetChainHead(EChain::Alive); }
 | |
|   [[nodiscard]] auto end() const { return GetAliveAreasEnd(); }
 | |
| 
 | |
|   bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr);
 | |
|   void TravelToArea(TAreaId aid, CStateManager& mgr, bool skipLoadOther);
 | |
|   void SetLoadPauseState(bool paused);
 | |
|   void CycleLoadPauseState();
 | |
| 
 | |
|   CWorld(IObjectStore& objStore, IFactory& resFactory, CAssetId mlvlId);
 | |
|   ~CWorld() override;
 | |
|   bool DoesAreaExist(TAreaId area) const;
 | |
|   const std::vector<std::unique_ptr<CGameArea>>& GetGameAreas() const { return x18_areas; }
 | |
| 
 | |
|   CMapWorld* GetMapWorld() { return x28_mapWorld.GetObj(); }
 | |
|   const CMapWorld* GetMapWorld() const { return x28_mapWorld.GetObj(); }
 | |
| 
 | |
|   u32 GetRelayCount() const { return x2c_relays.size(); }
 | |
|   CRelay GetRelay(u32 idx) const { return x2c_relays[idx]; }
 | |
| 
 | |
|   CAssetId IGetWorldAssetId() const override;
 | |
|   CAssetId IGetStringTableAssetId() const override;
 | |
|   CAssetId IGetSaveWorldAssetId() const override;
 | |
|   const CMapWorld* IGetMapWorld() const override;
 | |
|   CMapWorld* IGetMapWorld() override;
 | |
|   const CGameArea* GetAreaAlways(TAreaId id) const;
 | |
|   CGameArea* GetArea(TAreaId);
 | |
|   s32 GetNumAreas() const { return x18_areas.size(); }
 | |
|   const IGameArea* IGetAreaAlways(TAreaId id) const override;
 | |
|   TAreaId IGetCurrentAreaId() const override;
 | |
|   TAreaId GetCurrentAreaId() const { return x68_curAreaId; }
 | |
|   TAreaId IGetAreaId(CAssetId id) const override;
 | |
|   bool ICheckWorldComplete() override;
 | |
|   std::string IGetDefaultAudioTrack() const override;
 | |
|   int IGetAreaCount() const override;
 | |
|   const std::optional<CWorldLayers>& GetWorldLayers() const override;
 | |
| 
 | |
|   static void PropogateAreaChain(CGameArea::EOcclusionState occlusionState, CGameArea* area, CWorld* world);
 | |
|   static constexpr CGameArea::CConstChainIterator GetAliveAreasEnd() { return CGameArea::CConstChainIterator{}; }
 | |
|   static constexpr CGameArea::CChainIterator AliveAreasEnd() { return CGameArea::CChainIterator{}; }
 | |
| 
 | |
|   void Update(float dt);
 | |
|   void PreRender();
 | |
|   void TouchSky();
 | |
|   void DrawSky(const zeus::CTransform& xf);
 | |
|   void StopGlobalSound(u16 id);
 | |
|   bool HasGlobalSound(u16 id) const;
 | |
|   void AddGlobalSound(const CSfxHandle& hnd);
 | |
|   EEnvFxType GetNeededEnvFx() const { return xc4_neededFx; }
 | |
|   CAssetId GetWorldAssetId() const { return x8_mlvlId; }
 | |
|   bool AreSkyNeedsMet();
 | |
|   TAreaId GetAreaIdForSaveId(s32 saveId) const;
 | |
| };
 | |
| 
 | |
| } // namespace metaforce
 |