metaforce/Runtime/MP1/MP1.hpp

339 lines
11 KiB
C++
Raw Normal View History

2018-10-07 03:42:33 +00:00
#pragma once
2015-08-27 00:23:46 +00:00
#ifndef MP1_USE_BOO
2016-04-15 20:42:40 +00:00
#define MP1_USE_BOO 0
#endif
#ifndef MP1_VARIABLE_DELTA_TIME
#define MP1_VARIABLE_DELTA_TIME 0
#endif
2016-04-15 20:42:40 +00:00
2016-09-17 06:40:45 +00:00
#include "IMain.hpp"
2015-08-27 00:23:46 +00:00
#include "CTweaks.hpp"
#include "CPlayMovie.hpp"
#include "IOStreams.hpp"
2016-04-15 20:42:40 +00:00
#include "CBasics.hpp"
#include "CMemoryCardSys.hpp"
#include "CResFactory.hpp"
#include "CSimplePool.hpp"
#include "Character/CAssetFactory.hpp"
2016-04-16 23:48:29 +00:00
#include "World/CAi.hpp"
2016-04-15 20:42:40 +00:00
#include "CGameState.hpp"
#include "CInGameTweakManager.hpp"
#include "Particle/CElementGen.hpp"
#include "Character/CAnimData.hpp"
#include "Particle/CDecalManager.hpp"
#include "Particle/CGenDescription.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "Audio/CAudioSys.hpp"
#include "Input/CInputGenerator.hpp"
#include "GuiSys/CGuiSys.hpp"
#include "CIOWinManager.hpp"
#include "GuiSys/CSplashScreen.hpp"
#include "CMainFlow.hpp"
#include "GuiSys/CConsoleOutputWindow.hpp"
2016-09-14 05:54:09 +00:00
#include "GuiSys/CErrorOutputWindow.hpp"
2016-04-15 20:42:40 +00:00
#include "GuiSys/CTextParser.hpp"
#include "CAudioStateWin.hpp"
2016-04-15 20:42:40 +00:00
#include "GameGlobalObjects.hpp"
#include "CArchitectureQueue.hpp"
#include "CTimeProvider.hpp"
#include "GuiSys/CTextExecuteBuffer.hpp"
#include "DataSpec/DNAMP1/Tweaks/CTweakPlayer.hpp"
#include "DataSpec/DNAMP1/Tweaks/CTweakGame.hpp"
#include "World/CScriptMazeNode.hpp"
2018-01-15 16:00:20 +00:00
#include "hecl/Console.hpp"
2015-08-27 00:23:46 +00:00
struct DiscordUser;
2018-12-08 05:30:43 +00:00
namespace urde {
2016-04-15 20:42:40 +00:00
class IFactory;
class IObjectStore;
2015-08-27 00:23:46 +00:00
2018-12-08 05:30:43 +00:00
namespace MP1 {
class CMain;
2018-12-08 05:30:43 +00:00
class CGameGlobalObjects {
friend class CMain;
std::unique_ptr<CSimplePool> m_gameSimplePool;
std::unique_ptr<CResFactory> m_gameResFactory;
std::unique_ptr<CMemoryCardSys> x0_memoryCardSys;
IFactory* x4_resFactory;
CSimplePool* xcc_simplePool;
CCharacterFactoryBuilder xec_charFactoryBuilder;
CAiFuncMap x110_aiFuncMap;
std::unique_ptr<CGameState> x134_gameState;
TLockedToken<CStringTable> x13c_mainStringTable;
CInGameTweakManager x150_tweakManager;
std::unique_ptr<IRenderer> m_renderer;
TLockedToken<CTextureCache> m_textureCache;
2018-12-08 05:30:43 +00:00
void LoadStringTable() {
x13c_mainStringTable = g_SimplePool->GetObj("STRG_Main");
g_MainStringTable = x13c_mainStringTable.GetObj();
}
void LoadTextureCache() {
m_textureCache = g_SimplePool->GetObj("TextureCache"sv);
g_TextureCache = m_textureCache.GetObj();
}
2018-12-08 05:30:43 +00:00
void AddPaksAndFactories();
static IRenderer* AllocateRenderer(IObjectStore& store, IFactory& resFactory) {
g_Renderer = new CBooRenderer(store, resFactory);
return g_Renderer;
}
2016-04-15 20:42:40 +00:00
public:
2018-12-08 05:30:43 +00:00
CGameGlobalObjects(IFactory* resFactory, CSimplePool* objStore)
: x4_resFactory(resFactory), xcc_simplePool(objStore) {
if (!x4_resFactory) {
m_gameResFactory = std::make_unique<CResFactory>();
2018-12-08 05:30:43 +00:00
x4_resFactory = m_gameResFactory.get();
2016-12-29 21:38:59 +00:00
}
2018-12-08 05:30:43 +00:00
if (!xcc_simplePool) {
m_gameSimplePool = std::make_unique<CSimplePool>(*x4_resFactory);
2018-12-08 05:30:43 +00:00
xcc_simplePool = m_gameSimplePool.get();
}
2018-12-08 05:30:43 +00:00
g_ResFactory = x4_resFactory;
g_SimplePool = xcc_simplePool;
g_CharFactoryBuilder = &xec_charFactoryBuilder;
g_AiFuncMap = &x110_aiFuncMap;
x134_gameState = std::make_unique<CGameState>();
2018-12-08 05:30:43 +00:00
g_GameState = x134_gameState.get();
g_TweakManager = &x150_tweakManager;
}
~CGameGlobalObjects();
void PostInitialize() {
AddPaksAndFactories();
LoadTextureCache();
2018-12-08 05:30:43 +00:00
LoadStringTable();
m_renderer.reset(AllocateRenderer(*xcc_simplePool, *x4_resFactory));
CEnvFxManager::Initialize();
CScriptMazeNode::LoadMazeSeeds();
}
void ResetGameState() {
x134_gameState = std::make_unique<CGameState>();
2018-12-08 05:30:43 +00:00
g_GameState = x134_gameState.get();
}
void StreamInGameState(CBitStreamReader& stream, u32 saveIdx) {
x134_gameState = std::make_unique<CGameState>(stream, saveIdx);
2018-12-08 05:30:43 +00:00
g_GameState = x134_gameState.get();
}
};
2016-04-15 20:42:40 +00:00
#if MP1_USE_BOO
class CGameArchitectureSupport : public boo::IWindowCallback
#else
class CGameArchitectureSupport
#endif
{
2018-12-08 05:30:43 +00:00
friend class CMain;
CMain& m_parent;
CArchitectureQueue x4_archQueue;
CAudioSys x0_audioSys;
CInputGenerator x30_inputGenerator;
CGuiSys x44_guiSys;
CIOWinManager x58_ioWinManager;
2019-04-07 05:14:48 +00:00
s32 x78_gameFrameCount = 0;
2017-01-20 03:53:32 +00:00
2018-12-08 05:30:43 +00:00
enum class EAudioLoadStatus { Loading, Loaded, Uninitialized };
EAudioLoadStatus x88_audioLoadStatus = EAudioLoadStatus::Uninitialized;
std::vector<TToken<CAudioGroupSet>> x8c_pendingAudioGroups;
2016-04-15 20:42:40 +00:00
2018-12-08 05:30:43 +00:00
boo::SWindowRect m_windowRect;
bool m_rectIsDirty;
2017-01-22 21:26:58 +00:00
2018-12-08 05:30:43 +00:00
void destroyed() { x4_archQueue.Push(MakeMsg::CreateRemoveAllIOWins(EArchMsgTarget::IOWinManager)); }
2017-01-22 21:26:58 +00:00
2018-12-08 05:30:43 +00:00
void resized(const boo::SWindowRect& rect) {
m_windowRect = rect;
m_rectIsDirty = true;
}
2017-02-06 03:21:58 +00:00
2018-12-08 05:30:43 +00:00
public:
CGameArchitectureSupport(CMain& parent, boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend);
~CGameArchitectureSupport();
void mouseDown(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) {
x30_inputGenerator.mouseDown(coord, button, mods);
}
void mouseUp(const boo::SWindowCoord& coord, boo::EMouseButton button, boo::EModifierKey mods) {
x30_inputGenerator.mouseUp(coord, button, mods);
}
void mouseMove(const boo::SWindowCoord& coord) { x30_inputGenerator.mouseMove(coord); }
void scroll(const boo::SWindowCoord& coord, const boo::SScrollDelta& scroll) {
x30_inputGenerator.scroll(coord, scroll);
}
void charKeyDown(unsigned long charCode, boo::EModifierKey mods, bool isRepeat);
void charKeyUp(unsigned long charCode, boo::EModifierKey mods) { x30_inputGenerator.charKeyUp(charCode, mods); }
void specialKeyDown(boo::ESpecialKey key, boo::EModifierKey mods, bool isRepeat);
void specialKeyUp(boo::ESpecialKey key, boo::EModifierKey mods);
void modKeyDown(boo::EModifierKey mod, bool isRepeat) { x30_inputGenerator.modKeyDown(mod, isRepeat); }
void modKeyUp(boo::EModifierKey mod) { x30_inputGenerator.modKeyUp(mod); }
void PreloadAudio();
bool LoadAudio();
void UnloadAudio();
void UpdateTicks(float dt);
void Update(float dt);
2018-12-08 05:30:43 +00:00
void Draw();
bool isRectDirty() const { return m_rectIsDirty; }
2018-12-08 05:30:43 +00:00
const boo::SWindowRect& getWindowRect() {
m_rectIsDirty = false;
return m_windowRect;
}
CIOWinManager& GetIOWinManager() { return x58_ioWinManager; }
2016-04-15 20:42:40 +00:00
};
#if MP1_USE_BOO
2018-12-08 05:30:43 +00:00
class CMain : public boo::IApplicationCallback,
public IMain
2016-04-15 20:42:40 +00:00
#else
2016-09-17 06:40:45 +00:00
class CMain : public IMain
2016-04-15 20:42:40 +00:00
#endif
{
2018-12-08 05:30:43 +00:00
friend class CGameArchitectureSupport;
2016-04-15 20:42:40 +00:00
#if MP1_USE_BOO
2018-12-08 05:30:43 +00:00
boo::IWindow* mainWindow;
int appMain(boo::IApplication* app);
void appQuitting(boo::IApplication*) { xe8_b24_finished = true; }
void appFilesOpen(boo::IApplication*, const std::vector<std::string>& paths) {
2019-07-20 04:27:21 +00:00
fmt::print(stderr, fmt("OPENING: "));
2018-12-08 05:30:43 +00:00
for (const std::string& path : paths)
fprintf(stderr, "%s ", path.c_str());
fprintf(stderr, "\n");
}
2016-04-15 20:42:40 +00:00
#endif
2016-08-15 20:58:07 +00:00
private:
2018-12-08 05:30:43 +00:00
struct BooSetter {
BooSetter(boo::IGraphicsDataFactory* factory, boo::IGraphicsCommandQueue* cmdQ,
const boo::ObjToken<boo::ITextureR>& spareTex);
} m_booSetter;
// CMemorySys x6c_memSys;
CTweaks x70_tweaks;
EGameplayResult xe4_gameplayResult;
/* urde addition: these are simply initialized along with everything else */
CGameGlobalObjects x128_globalObjects;
EFlowState x12c_flowState = EFlowState::Default;
u32 x130_[10] = {1000000};
union {
struct {
bool x160_24_finished : 1;
bool x160_25_mfGameBuilt : 1;
bool x160_26_screenFading : 1;
bool x160_27_ : 1;
bool x160_28_manageCard : 1;
bool x160_29_ : 1;
bool x160_30_ : 1;
bool x160_31_cardBusy : 1;
bool x161_24_gameFrameDrawn : 1;
2016-08-15 20:58:07 +00:00
};
2018-12-08 05:30:43 +00:00
u16 _dummy = 0;
};
2016-08-15 20:58:07 +00:00
2018-12-08 05:30:43 +00:00
std::unique_ptr<CGameArchitectureSupport> x164_archSupport;
2016-08-15 20:58:07 +00:00
2018-12-08 05:30:43 +00:00
boo::IWindow* m_mainWindow = nullptr;
2018-12-08 05:30:43 +00:00
hecl::CVarManager* m_cvarMgr = nullptr;
std::unique_ptr<hecl::Console> m_console;
// Warmup state
std::vector<SObjectTag> m_warmupTags;
std::vector<SObjectTag>::iterator m_warmupIt;
bool m_needsWarmupClear = false;
2019-03-09 08:58:27 +00:00
bool m_loadedPersistentResources = false;
2018-12-08 05:30:43 +00:00
bool m_doQuit = false;
2017-10-17 05:51:53 +00:00
#if MP1_VARIABLE_DELTA_TIME
bool m_firstFrame = true;
using delta_clock = std::chrono::high_resolution_clock;
std::chrono::time_point<delta_clock> m_prevFrameTime;
#endif
2018-12-08 05:30:43 +00:00
void InitializeSubsystems();
static void InitializeDiscord();
static void ShutdownDiscord();
static void HandleDiscordReady(const DiscordUser* request);
static void HandleDiscordDisconnected(int errorCode, const char* message);
static void HandleDiscordErrored(int errorCode, const char* message);
2016-04-15 20:42:40 +00:00
2015-08-27 00:23:46 +00:00
public:
2018-12-08 05:30:43 +00:00
CMain(IFactory* resFactory, CSimplePool* resStore, boo::IGraphicsDataFactory* gfxFactory,
boo::IGraphicsCommandQueue* cmdQ, const boo::ObjToken<boo::ITextureR>& spareTex);
void RegisterResourceTweaks();
void AddWorldPaks();
2019-11-21 15:37:08 +00:00
void AddOverridePaks();
2018-12-08 05:30:43 +00:00
void ResetGameState();
void StreamNewGameState(CBitStreamReader&, u32 idx);
void RefreshGameState();
void CheckTweakManagerDebugOptions() {}
void SetMFGameBuilt(bool b) { x160_25_mfGameBuilt = b; }
void SetScreenFading(bool b) { x160_26_screenFading = b; }
bool GetScreenFading() const { return x160_26_screenFading; }
static void UpdateDiscordPresence(CAssetId worldSTRG = {});
// int RsMain(int argc, const boo::SystemChar* argv[]);
void Init(const hecl::Runtime::FileStoreManager& storeMgr, hecl::CVarManager* cvarManager, boo::IWindow* window,
boo::IAudioVoiceEngine* voiceEngine, amuse::IBackendVoiceAllocator& backend) override;
void WarmupShaders() override;
bool Proc() override;
void Draw() override;
void Shutdown() override;
boo::IWindow* GetMainWindow() const override;
2018-12-08 05:30:43 +00:00
void MemoryCardInitializePump();
bool CheckReset() const { return m_doQuit; }
bool CheckTerminate() const { return m_doQuit; }
2018-12-08 05:30:43 +00:00
void DrawDebugMetrics(double, CStopwatch&) {}
void DoPredrawMetrics() {}
void FillInAssetIDs();
bool LoadAudio();
void ShutdownSubsystems();
EGameplayResult GetGameplayResult() const { return xe4_gameplayResult; }
void SetGameplayResult(EGameplayResult wl) { xe4_gameplayResult = wl; }
void SetManageCard(bool v) { x160_28_manageCard = v; }
bool GetCardBusy() const { return x160_31_cardBusy; }
void SetCardBusy(bool v) { x160_31_cardBusy = v; }
void SetGameFrameDrawn() { x161_24_gameFrameDrawn = true; }
static void EnsureWorldPaksReady();
static void EnsureWorldPakReady(CAssetId mlvl);
EFlowState GetFlowState() const override { return x12c_flowState; }
void SetFlowState(EFlowState s) override { x12c_flowState = s; }
2018-12-08 05:30:43 +00:00
void SetX30(bool v) { x160_30_ = v; }
CGameArchitectureSupport* GetArchSupport() const { return x164_archSupport.get(); }
size_t GetExpectedIdSize() const override { return sizeof(u32); }
2018-12-08 05:30:43 +00:00
void quit(hecl::Console*, const std::vector<std::string>&) { m_doQuit = true; }
void Give(hecl::Console*, const std::vector<std::string>&);
2019-02-07 01:26:53 +00:00
void Remove(hecl::Console*, const std::vector<std::string>&);
2018-12-08 05:30:43 +00:00
void God(hecl::Console*, const std::vector<std::string>&);
void Teleport(hecl::Console*, const std::vector<std::string>&);
void ListWorlds(hecl::Console*, const std::vector<std::string>&);
void Warp(hecl::Console*, const std::vector<std::string>&);
hecl::Console* Console() const override { return m_console.get(); }
2018-12-08 05:30:43 +00:00
int m_warpWorldIdx = -1;
TAreaId m_warpAreaId = 0;
u64 m_warpLayerBits = 0;
2019-02-10 04:41:35 +00:00
std::vector<TEditorId> m_warpMemoryRelays;
2015-08-27 00:23:46 +00:00
};
2018-12-08 05:30:43 +00:00
} // namespace MP1
} // namespace urde