diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index 8a50a5d7..511045a6 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -563,7 +563,7 @@ OnMessage__13CMFGameLoaderFRC20CArchitectureMessageR18CArchitectureQueue = .text MakeLoadDependancyList__13CMFGameLoaderFv = .text:0x80023EE4; // type:function size:0x1A8 scope:global __dt__13CMFGameLoaderFv = .text:0x8002408C; // type:function size:0x108 scope:global __ct__13CMFGameLoaderFv = .text:0x80024194; // type:function size:0x1F8 scope:global -IsCameraActiveFlow__7CMFGameFv = .text:0x8002438C; // type:function size:0x24 scope:global +IsCameraActiveFlow__7CMFGameCFv = .text:0x8002438C; // type:function size:0x24 scope:global PlayerDied__7CMFGameFv = .text:0x800243B0; // type:function size:0x1C scope:global UnpauseGame__7CMFGameFv = .text:0x800243CC; // type:function size:0x48 scope:global EnterMessageScreen__7CMFGameFf = .text:0x80024414; // type:function size:0x3C scope:global @@ -573,11 +573,11 @@ PauseGame__7CMFGameFv = .text:0x800244C8; // type:function size:0x3C scope:globa EnterMapScreen__7CMFGameFv = .text:0x80024504; // type:function size:0x60 scope:global Draw__7CMFGameCFv = .text:0x80024564; // type:function size:0x138 scope:global OnMessage__7CMFGameFRC20CArchitectureMessageR18CArchitectureQueue = .text:0x8002469C; // type:function size:0x6D8 scope:global -Touch__7CMFGameFv = .text:0x80024D74; // type:function size:0xF4 scope:global +Touch__7CMFGameCFv = .text:0x80024D74; // type:function size:0xF4 scope:global __dt__7CMFGameFv = .text:0x80024E68; // type:function size:0xD4 scope:global __ct__7CMFGameFQ24rstl25ncrc_ptr<13CStateManager>Q24rstl29ncrc_ptr<17CInGameGuiManager>R18CArchitectureQueue = .text:0x80024F3C; // type:function size:0xE8 scope:global -fn_80025024 = .text:0x80025024; // type:function size:0x5C -fn_80025080 = .text:0x80025080; // type:function size:0x5C +ReleaseData__Q24rstl27rc_ptr<17CInGameGuiManager>Fv = .text:0x80025024; // type:function size:0x5C +ReleaseData__Q24rstl23rc_ptr<13CStateManager>Fv = .text:0x80025080; // type:function size:0x5C __nw__27TOneStatic<13CStateManager>FUlPCcPCc = .text:0x800250DC; // type:function size:0x30 scope:global GetAllocSpace__27TOneStatic<13CStateManager>Fv = .text:0x8002510C; // type:function size:0xC scope:global ReferenceCount__27TOneStatic<13CStateManager>Fv = .text:0x80025118; // type:function size:0x24 scope:global @@ -1049,7 +1049,7 @@ SetupParticleHook__13CStateManagerCFRC6CActor = .text:0x80045088; // type:functi MurderScriptInstanceNames__13CStateManagerFv = .text:0x800450BC; // type:function size:0x128 scope:global HashInstanceName__13CStateManagerFR12CInputStream = .text:0x800451E4; // type:function size:0x94 scope:global SetActorAreaId__13CStateManagerFR6CActor7TAreaId = .text:0x80045278; // type:function size:0x10C scope:global -TouchPlayerActor__13CStateManagerFv = .text:0x80045384; // type:function size:0x54 scope:global +TouchPlayerActor__13CStateManagerCFv = .text:0x80045384; // type:function size:0x54 scope:global TouchSky__13CStateManagerCFv = .text:0x800453D8; // type:function size:0x24 scope:global DrawSpaceWarp__13CStateManagerCFRC9CVector3ff = .text:0x800453FC; // type:function size:0xAC scope:global DrawReflection__13CStateManagerFRC9CVector3f = .text:0x800454A8; // type:function size:0x220 scope:global @@ -6422,7 +6422,7 @@ EnsureStates__17CInGameGuiManagerFR13CStateManager = .text:0x8010740C; // type:f DoStateTransition__17CInGameGuiManagerFR13CStateManager = .text:0x8010747C; // type:function size:0x1C4 scope:global BeginStateTransition__17CInGameGuiManagerF15EInGameGuiStateRC13CStateManager = .text:0x80107640; // type:function size:0x1AC scope:global GetIsGameDraw__17CInGameGuiManagerCFv = .text:0x801077EC; // type:function size:0x10 scope:global -ShowPauseGameHudMessage__17CInGameGuiManagerFRC13CStateManagerUi = .text:0x801077FC; // type:function size:0x2C scope:global +ShowPauseGameHudMessage__17CInGameGuiManagerFRC13CStateManagerUif = .text:0x801077FC; // type:function size:0x2C scope:global PauseGame__17CInGameGuiManagerFRC13CStateManager15EInGameGuiState = .text:0x80107828; // type:function size:0x74 scope:global ProcessControllerInput__17CInGameGuiManagerFRC13CStateManagerRC11CFinalInputR18CArchitectureQueue = .text:0x8010789C; // type:function size:0x1BC scope:global RefreshHudOptions__17CInGameGuiManagerFv = .text:0x80107A58; // type:function size:0x24 scope:global @@ -18029,7 +18029,7 @@ jumptable_803D9944 = .data:0x803D9944; // type:object size:0x44 scope:local lbl_803D9988 = .data:0x803D9988; // type:object size:0x10 data:4byte lbl_803D9998 = .data:0x803D9998; // type:object size:0x1C jumptable_803D99B4 = .data:0x803D99B4; // type:object size:0x20 scope:local -lbl_803D99D4 = .data:0x803D99D4; // type:object size:0x1C +__vt__7CMFGame = .data:0x803D99D4; // type:object size:0x1C lbl_803D99F0 = .data:0x803D99F0; // type:object size:0x1C __vt__40TObjOwnerDerivedFromIObj<12CStringTable> = .data:0x803D9A0C; // type:object size:0xC scope:global lbl_803D9A18 = .data:0x803D9A18; // type:object size:0x1C diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index 7c2b1cdc..b69291d9 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -563,7 +563,7 @@ OnMessage__13CMFGameLoaderFRC20CArchitectureMessageR18CArchitectureQueue = .text MakeLoadDependancyList__13CMFGameLoaderFv = .text:0x80023F60; // type:function size:0x1A8 scope:global __dt__13CMFGameLoaderFv = .text:0x80024108; // type:function size:0x108 scope:global __ct__13CMFGameLoaderFv = .text:0x80024210; // type:function size:0x1F8 scope:global -IsCameraActiveFlow__7CMFGameFv = .text:0x80024408; // type:function size:0x24 scope:global +IsCameraActiveFlow__7CMFGameCFv = .text:0x80024408; // type:function size:0x24 scope:global PlayerDied__7CMFGameFv = .text:0x8002442C; // type:function size:0x1C scope:global UnpauseGame__7CMFGameFv = .text:0x80024448; // type:function size:0x48 scope:global EnterMessageScreen__7CMFGameFf = .text:0x80024490; // type:function size:0x3C scope:global @@ -573,11 +573,11 @@ PauseGame__7CMFGameFv = .text:0x80024544; // type:function size:0x3C scope:globa EnterMapScreen__7CMFGameFv = .text:0x80024580; // type:function size:0x60 scope:global Draw__7CMFGameCFv = .text:0x800245E0; // type:function size:0x138 scope:global OnMessage__7CMFGameFRC20CArchitectureMessageR18CArchitectureQueue = .text:0x80024718; // type:function size:0x6D8 scope:global -Touch__7CMFGameFv = .text:0x80024DF0; // type:function size:0xF4 scope:global +Touch__7CMFGameCFv = .text:0x80024DF0; // type:function size:0xF4 scope:global __dt__7CMFGameFv = .text:0x80024EE4; // type:function size:0xD4 scope:global __ct__7CMFGameFQ24rstl25ncrc_ptr<13CStateManager>Q24rstl29ncrc_ptr<17CInGameGuiManager>R18CArchitectureQueue = .text:0x80024FB8; // type:function size:0xE8 scope:global -fn_80025024 = .text:0x800250A0; // type:function size:0x5C scope:global -fn_80025080 = .text:0x800250FC; // type:function size:0x5C scope:global +ReleaseData__Q24rstl27rc_ptr<17CInGameGuiManager>Fv = .text:0x800250A0; // type:function size:0x5C scope:global +ReleaseData__Q24rstl23rc_ptr<13CStateManager>Fv = .text:0x800250FC; // type:function size:0x5C scope:global __nw__27TOneStatic<13CStateManager>FUlPCcPCc = .text:0x80025158; // type:function size:0x30 scope:global GetAllocSpace__27TOneStatic<13CStateManager>Fv = .text:0x80025188; // type:function size:0xC scope:global ReferenceCount__27TOneStatic<13CStateManager>Fv = .text:0x80025194; // type:function size:0x24 scope:global @@ -1049,7 +1049,7 @@ SetupParticleHook__13CStateManagerCFRC6CActor = .text:0x80045104; // type:functi MurderScriptInstanceNames__13CStateManagerFv = .text:0x80045138; // type:function size:0x128 scope:global HashInstanceName__13CStateManagerFR12CInputStream = .text:0x80045260; // type:function size:0x94 scope:global SetActorAreaId__13CStateManagerFR6CActor7TAreaId = .text:0x800452F4; // type:function size:0x10C scope:global -TouchPlayerActor__13CStateManagerFv = .text:0x80045400; // type:function size:0x54 scope:global +TouchPlayerActor__13CStateManagerCFv = .text:0x80045400; // type:function size:0x54 scope:global TouchSky__13CStateManagerCFv = .text:0x80045454; // type:function size:0x24 scope:global DrawSpaceWarp__13CStateManagerCFRC9CVector3ff = .text:0x80045478; // type:function size:0xAC scope:global DrawReflection__13CStateManagerFRC9CVector3f = .text:0x80045524; // type:function size:0x220 scope:global @@ -6422,7 +6422,7 @@ EnsureStates__17CInGameGuiManagerFR13CStateManager = .text:0x80107488; // type:f DoStateTransition__17CInGameGuiManagerFR13CStateManager = .text:0x801074F8; // type:function size:0x1C4 scope:global BeginStateTransition__17CInGameGuiManagerF15EInGameGuiStateRC13CStateManager = .text:0x801076BC; // type:function size:0x1AC scope:global GetIsGameDraw__17CInGameGuiManagerCFv = .text:0x80107868; // type:function size:0x10 scope:global -ShowPauseGameHudMessage__17CInGameGuiManagerFRC13CStateManagerUi = .text:0x80107878; // type:function size:0x2C scope:global +ShowPauseGameHudMessage__17CInGameGuiManagerFRC13CStateManagerUif = .text:0x80107878; // type:function size:0x2C scope:global PauseGame__17CInGameGuiManagerFRC13CStateManager15EInGameGuiState = .text:0x801078A4; // type:function size:0x74 scope:global ProcessControllerInput__17CInGameGuiManagerFRC13CStateManagerRC11CFinalInputR18CArchitectureQueue = .text:0x80107918; // type:function size:0x1BC scope:global RefreshHudOptions__17CInGameGuiManagerFv = .text:0x80107AD4; // type:function size:0x24 scope:global diff --git a/include/MetroidPrime/CInGameGuiManager.hpp b/include/MetroidPrime/CInGameGuiManager.hpp new file mode 100644 index 00000000..e9de1a15 --- /dev/null +++ b/include/MetroidPrime/CInGameGuiManager.hpp @@ -0,0 +1,29 @@ +#ifndef _CINGUIGUIMANAGER +#define _CINGUIGUIMANAGER + +enum EInGameGuiState { + kIGGS_Zero, + kIGGS_InGame, + kIGGS_MapScreen, + kIGGS_PauseGame, + kIGGS_PauseLogBook, + kIGGS_PauseSaveGame, + kIGGS_PauseHUDMessage, +}; + +class CInGameGuiManager { +public: + CInGameGuiManager(); + ~CInGameGuiManager(); + + bool GetIsGameDraw() const; + + void PreDraw(CStateManager& mgr, bool isCameraActive); + void Draw(const CStateManager& mgr) const; + void PauseGame(const CStateManager& mgr, EInGameGuiState state); + void ShowPauseGameHudMessage(const CStateManager& mgr, CAssetId message, float time); + +private: + char data[0x1fc]; +}; +#endif diff --git a/include/MetroidPrime/CMFGame.hpp b/include/MetroidPrime/CMFGame.hpp new file mode 100644 index 00000000..337b292e --- /dev/null +++ b/include/MetroidPrime/CMFGame.hpp @@ -0,0 +1,62 @@ +#ifndef _CMFGAME_HPP +#define _CMFGAME_HPP + +#include "Kyoto/TOneStatic.hpp" +#include "MetroidPrime/CMainFlow.hpp" +#include "MetroidPrime/TGameTypes.hpp" +#include "rstl/rc_ptr.hpp" +#include "rstl/single_ptr.hpp" + +class CInGameGuiManager; +class CStateManager; + +enum EGameFlowState { + kGFS_InGame = 0, + kGFS_Paused, + kGFS_PlayerDied, + kGFS_CinematicSkip, +}; + +class CGameProfiler { +public: + CGameProfiler(); + ~CGameProfiler() {}; +}; + +class CMFGame : public CIOWin { +public: + CMFGame(rstl::ncrc_ptr< CStateManager > stateManager, + rstl::ncrc_ptr< CInGameGuiManager > guiManager, CArchitectureQueue& architectureQueue); + ~CMFGame() override; + + void Touch() const; + EMessageReturn OnMessage(const CArchitectureMessage&, CArchitectureQueue&) override; + void Draw() const; + + void EnterMapScreen(); + void PauseGame(); + void EnterLogBook(); + void SaveGame(); + void EnterMessageScreen(float time); + void UnpauseGame(); + void PlayerDied(); + + bool IsCameraActiveFlow() const; + +private: + rstl::ncrc_ptr< CStateManager > mStateManager; + rstl::ncrc_ptr< CInGameGuiManager > mGuiManager; + EGameFlowState mFlowState; + float mCineSkipTime; + rstl::single_ptr< CGameProfiler > x24; // Appears to be unused? + TUniqueId mSkippedCineCam; + bool mInitialized : 1; + bool mPlayerAlive : 1; +}; + +class CMFGameLoader : public CIOWin { +public: + CMFGameLoader(); + ~CMFGameLoader() override; +}; +#endif diff --git a/include/MetroidPrime/CMain.hpp b/include/MetroidPrime/CMain.hpp index acbb0dbf..a945e140 100644 --- a/include/MetroidPrime/CMain.hpp +++ b/include/MetroidPrime/CMain.hpp @@ -87,6 +87,10 @@ class CMain { x160_26_screenFading = v; } + void SetGameFlowBuilt(const bool built) { x160_25_mfGameBuilt = built; } + void SetScreenFading(const bool fading) { x160_26_screenFading = fading; } + void SetGameFrameDrawn(const bool drawn) { x161_24_gameFrameDrawn = drawn; } + void SetX30(bool v) { x160_30_ = v; } static void EnsureWorldPaksReady(); diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index 35728b13..3a70ee90 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -119,6 +119,7 @@ class CStateManager : public TOneStatic< CStateManager > { const rstl::ncrc_ptr< CWorldLayerState >&); ~CStateManager(); + void PreRender(); bool RenderLast(const TUniqueId&); void ResetEscapeSequenceTimer(float); void SendScriptMsg(TUniqueId uid, TEditorId target, EScriptObjectMessage msg, @@ -285,6 +286,9 @@ class CStateManager : public TOneStatic< CStateManager > { const SOnScreenTex& GetPendingScreenTex() const { return xef4_pendingScreenTex; } float IntegrateVisorFog(float f) const; + void TouchSky() const; + void TouchPlayerActor() const; + void QuitGame() { xf94_25_quitGame = true; } bool GetWantsToQuit() const { return xf94_25_quitGame; } void SetCinematicSkipObject(TUniqueId id) { xf38_skipCineSpecialFunc = id; } @@ -297,6 +301,8 @@ class CStateManager : public TOneStatic< CStateManager > { uint GetInputFrameIdx() const { return x8d4_inputFrameIdx; } CMapWorldInfo* MapWorldInfo() const { return x8c0_mapWorldInfo.GetPtr(); } + CAssetId GetPauseHUDMessage() const { return xf08_pauseHudMessage; } + void AddActiveFlickerBat(const TUniqueId& uid) { xf3c_activeFlickerBats.push_back(uid); } void RemoveActiveFlickerBat(const TUniqueId& uid) { xf3c_activeFlickerBats.remove(uid); } diff --git a/include/MetroidPrime/DefaultWorld.hpp b/include/MetroidPrime/DefaultWorld.hpp new file mode 100644 index 00000000..2d52cafb --- /dev/null +++ b/include/MetroidPrime/DefaultWorld.hpp @@ -0,0 +1,6 @@ +#ifndef _DEFAULTWORLD +#define _DEFAULTWORLD + +static const SObjectTag skDefaultWorld('MLVL', 0x158EFE17); + +#endif diff --git a/include/rstl/single_ptr.hpp b/include/rstl/single_ptr.hpp index 358a8f42..cb44f7b0 100644 --- a/include/rstl/single_ptr.hpp +++ b/include/rstl/single_ptr.hpp @@ -52,7 +52,7 @@ single_ptr< T >& single_ptr< T >::reset(T* ptr) { return *this = ptr; } -typedef single_ptr< int > unk_singleptr; +typedef single_ptr< char > unk_singleptr; CHECK_SIZEOF(unk_singleptr, 0x4); } // namespace rstl diff --git a/src/MetroidPrime/CFrontEndUI.cpp b/src/MetroidPrime/CFrontEndUI.cpp index ef5a21af..431fb0e5 100644 --- a/src/MetroidPrime/CFrontEndUI.cpp +++ b/src/MetroidPrime/CFrontEndUI.cpp @@ -2,13 +2,13 @@ #include "Kyoto/Basics/RAssertDolphin.hpp" #include "Kyoto/SObjectTag.hpp" #include "MetroidPrime/SFX/FrontEnd.h" +#include "MetroidPrime/DefaultWorld.hpp" struct FEMovie { const char* path; bool loop; }; -static const SObjectTag skDefaultWorld('MLVL', 0x158EFE17); static const FEMovie FEMovies[] = { {"Video/00_first_start.thp", false}, {"Video/01_startloop.thp", true}, diff --git a/src/MetroidPrime/CMFGame.cpp b/src/MetroidPrime/CMFGame.cpp new file mode 100644 index 00000000..2c0eead5 --- /dev/null +++ b/src/MetroidPrime/CMFGame.cpp @@ -0,0 +1,145 @@ +#include "MetroidPrime/CMFGame.hpp" + +#include "Kyoto/Audio/CSfxManager.hpp" +#include "Kyoto/Graphics/CGraphics.hpp" +#include "MetroidPrime/CDecalManager.hpp" +#include "MetroidPrime/CInGameGuiManager.hpp" +#include "MetroidPrime/CMain.hpp" +#include "MetroidPrime/CStateManager.hpp" +#include "MetroidPrime/DefaultWorld.hpp" +#include "MetroidPrime/Player/CMorphBall.hpp" +#include "MetroidPrime/Player/CPlayer.hpp" +#include "MetroidPrime/Player/CPlayerGun.hpp" +#include "rstl/math.hpp" + +CMFGame::CMFGame(rstl::ncrc_ptr< CStateManager > stateManager, + rstl::ncrc_ptr< CInGameGuiManager > guiManager, + CArchitectureQueue& architectureQueue) +: CIOWin(rstl::string_l("CMFGame")) +, mStateManager(stateManager) +, mGuiManager(guiManager) +, mFlowState(kGFS_InGame) +, mSkippedCineCam(kInvalidUniqueId) +, mInitialized(false) +, mPlayerAlive(true) { + gpMain->SetGameFlowBuilt(true); +} + +CMFGame::~CMFGame() { + gpMain->SetGameFlowBuilt(false); + gpMain->SetScreenFading(false); + CDecalManager::Reinitialize(); +} + +void CMFGame::Touch() const { + CStateManager* mgr = &*mStateManager; + mgr->TouchSky(); + mgr->TouchPlayerActor(); + + CPlayer* player = mgr->Player(); + bool touchModel = false; + bool touchBall = false; + bool touchGun = false; + + switch (player->GetMorphballTransitionState()) { + case CPlayer::kMS_Unmorphed: + touchGun = true; + break; + case CPlayer::kMS_Morphed: + touchBall = true; + break; + case CPlayer::kMS_Morphing: + touchBall = true; + touchModel = true; + break; + case CPlayer::kMS_Unmorphing: + touchGun = true; + touchModel = true; + break; + } + + if (touchGun) { + player->GetPlayerGun()->TouchModel(*mgr); + } + + if (touchModel) { + player->ModelData()->Touch(*mgr, 0); + } + + if (touchBall) { + player->GetMorphBall()->TouchModel(*mgr); + } +} + +CIOWin::EMessageReturn CMFGame::OnMessage(const CArchitectureMessage& message, + CArchitectureQueue& queue) {} + +void CMFGame::Draw() const { + if (!mInitialized) { + return; + } + + Touch(); + + if (mGuiManager->GetIsGameDraw()) { + gpMain->SetGameFrameDrawn(true); + mStateManager->PreRender(); + mStateManager->DrawWorld(); + (void)mStateManager->GetPlayer()->IsPlayerDeadEnough(); + } + + mGuiManager->PreDraw(*mStateManager, IsCameraActiveFlow()); + mGuiManager->Draw(*mStateManager); + + if (mFlowState == kGFS_CinematicSkip) { + const float intensity = rstl::min_val(1.f, 1.f - mCineSkipTime); + CCameraFilterPass::DrawFilter(CCameraFilterPass::kFT_Multiply, + CCameraFilterPass::kFS_Fullscreen, + CColor(intensity, intensity, intensity, intensity), nullptr, 1.f); + } +} + +void CMFGame::EnterMapScreen() { + mFlowState = kGFS_Paused; + mGuiManager->PauseGame(*mStateManager, kIGGS_MapScreen); + mStateManager->SetInMapScreen(true); +} + +void CMFGame::PauseGame() { + mFlowState = kGFS_Paused; + mGuiManager->PauseGame(*mStateManager, kIGGS_PauseGame); +} + +void CMFGame::EnterLogBook() { + mFlowState = kGFS_Paused; + mGuiManager->PauseGame(*mStateManager, kIGGS_PauseLogBook); +} + +void CMFGame::SaveGame() { + mFlowState = kGFS_Paused; + mGuiManager->PauseGame(*mStateManager, kIGGS_PauseSaveGame); +} + +void CMFGame::EnterMessageScreen(const float time) { + mFlowState = kGFS_Paused; + mGuiManager->ShowPauseGameHudMessage(*mStateManager, mStateManager->GetPauseHUDMessage(), time); +} + +void CMFGame::UnpauseGame() { + mFlowState = kGFS_InGame; + CSfxManager::SetChannel(CSfxManager::kSC_Game); + mStateManager->DeferStateTransition(kSMT_InGame); +} + +void CMFGame::PlayerDied() { + mFlowState = kGFS_PlayerDied; + mPlayerAlive = false; +} + +bool CMFGame::IsCameraActiveFlow() const { + const bool ret = (mFlowState == kGFS_InGame || mFlowState == kGFS_PlayerDied); + return ret; +} + +CMFGameLoader::CMFGameLoader() : CIOWin(rstl::string_l("CMFGameLoader")) {} +CMFGameLoader::~CMFGameLoader() { CGraphics::SetIsBeginSceneClearFb(true); } \ No newline at end of file