From 56328c3e4da7940d58ff7fa757ffc67509c4a208 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Fri, 17 Feb 2017 16:19:50 -1000 Subject: [PATCH] Lots of CMFGame integration --- DataSpec/DNAMP1/HINT.hpp | 6 +- Runtime/Audio/CMakeLists.txt | 1 + Runtime/Audio/CMidiManager.cpp | 11 + Runtime/Audio/CMidiManager.hpp | 15 ++ Runtime/AutoMapper/CAutoMapper.cpp | 10 + Runtime/CArchitectureMessage.hpp | 11 +- Runtime/CGameHintInfo.cpp | 20 +- Runtime/CGameHintInfo.hpp | 13 +- Runtime/CGameOptions.cpp | 71 ++++++- Runtime/CGameOptions.hpp | 9 +- Runtime/CGameState.hpp | 1 + Runtime/CPlayerState.cpp | 2 +- Runtime/CPlayerState.hpp | 4 +- Runtime/CStateManager.cpp | 55 ++++- Runtime/CStateManager.hpp | 43 +++- Runtime/Camera/CCameraManager.cpp | 15 ++ Runtime/Camera/CCameraManager.hpp | 2 + Runtime/Camera/CCinematicCamera.cpp | 9 +- Runtime/Camera/CCinematicCamera.hpp | 5 +- Runtime/Camera/CFirstPersonCamera.cpp | 9 +- Runtime/Camera/CFirstPersonCamera.hpp | 2 +- Runtime/GameGlobalObjects.cpp | 1 + Runtime/GameGlobalObjects.hpp | 1 + Runtime/Input/CInputGenerator.hpp | 33 +++ Runtime/Input/CRumbleGenerator.hpp | 9 +- Runtime/MP1/CInGameGuiManager.cpp | 190 ++++++++++++++++- Runtime/MP1/CInGameGuiManager.hpp | 45 +++- Runtime/MP1/CInventoryScreen.cpp | 27 +++ Runtime/MP1/CInventoryScreen.hpp | 43 ++++ Runtime/MP1/CMFGame.cpp | 255 ++++++++++++++++++++++- Runtime/MP1/CMFGame.hpp | 34 ++- Runtime/MP1/CMainFlow.cpp | 8 +- Runtime/MP1/CMakeLists.txt | 1 + Runtime/MP1/CMessageScreen.cpp | 14 ++ Runtime/MP1/CMessageScreen.hpp | 4 +- Runtime/MP1/CPauseScreen.cpp | 5 + Runtime/MP1/CPauseScreen.hpp | 13 ++ Runtime/MP1/CSamusHud.cpp | 5 + Runtime/MP1/CSamusHud.hpp | 3 + Runtime/MP1/MP1.cpp | 9 +- Runtime/MP1/MP1.hpp | 11 +- Runtime/Weapon/CPlayerGun.cpp | 5 + Runtime/Weapon/CPlayerGun.hpp | 7 +- Runtime/World/CGameArea.cpp | 13 ++ Runtime/World/CGameArea.hpp | 3 +- Runtime/World/CMorphBall.hpp | 1 + Runtime/World/CPlayer.cpp | 11 + Runtime/World/CPlayer.hpp | 7 +- Runtime/World/CScriptSpecialFunction.cpp | 15 ++ Runtime/World/CScriptSpecialFunction.hpp | 2 + Runtime/World/CWorld.cpp | 9 +- Runtime/World/CWorld.hpp | 3 +- 52 files changed, 1017 insertions(+), 84 deletions(-) create mode 100644 Runtime/Audio/CMidiManager.cpp create mode 100644 Runtime/Audio/CMidiManager.hpp create mode 100644 Runtime/MP1/CInventoryScreen.cpp create mode 100644 Runtime/MP1/CInventoryScreen.hpp diff --git a/DataSpec/DNAMP1/HINT.hpp b/DataSpec/DNAMP1/HINT.hpp index 0eea5ecef..cc4e54e64 100644 --- a/DataSpec/DNAMP1/HINT.hpp +++ b/DataSpec/DNAMP1/HINT.hpp @@ -18,10 +18,10 @@ struct HINT : BigYAML { DECL_YAML String<-1> name; - Value unknown1; - Value fadeInTime; + Value immediateTime; + Value normalTime; UniqueID32 stringID; - Value unknown2; + Value continueDelayTime; struct Location : BigYAML { DECL_YAML diff --git a/Runtime/Audio/CMakeLists.txt b/Runtime/Audio/CMakeLists.txt index 6742ee89b..d83202cd0 100644 --- a/Runtime/Audio/CMakeLists.txt +++ b/Runtime/Audio/CMakeLists.txt @@ -2,6 +2,7 @@ set(AUDIO_SOURCES CAudioSys.hpp CAudioSys.cpp CAudioGroupSet.hpp CAudioGroupSet.cpp CSfxManager.hpp CSfxManager.cpp + CMidiManager.hpp CMidiManager.cpp CStaticAudioPlayer.hpp CStaticAudioPlayer.cpp CStreamAudioManager.hpp CStreamAudioManager.cpp g721.c g721.h) diff --git a/Runtime/Audio/CMidiManager.cpp b/Runtime/Audio/CMidiManager.cpp new file mode 100644 index 000000000..f4397017a --- /dev/null +++ b/Runtime/Audio/CMidiManager.cpp @@ -0,0 +1,11 @@ +#include "CMidiManager.hpp" + +namespace urde +{ + +void CMidiManager::StopAll() +{ + +} + +} diff --git a/Runtime/Audio/CMidiManager.hpp b/Runtime/Audio/CMidiManager.hpp new file mode 100644 index 000000000..cb8b2853a --- /dev/null +++ b/Runtime/Audio/CMidiManager.hpp @@ -0,0 +1,15 @@ +#ifndef __URDE_CMIDIMANAGER_HPP__ +#define __URDE_CMIDIMANAGER_HPP__ + +namespace urde +{ + +class CMidiManager +{ +public: + static void StopAll(); +}; + +} + +#endif // __URDE_CMIDIMANAGER_HPP__ diff --git a/Runtime/AutoMapper/CAutoMapper.cpp b/Runtime/AutoMapper/CAutoMapper.cpp index 0bbd7448d..0b415e0fe 100644 --- a/Runtime/AutoMapper/CAutoMapper.cpp +++ b/Runtime/AutoMapper/CAutoMapper.cpp @@ -13,4 +13,14 @@ bool CAutoMapper::CheckLoadComplete() return false; } +void CAutoMapper::UnmuteAllLoopedSounds() +{ + +} + +void CAutoMapper::OnNewInGameGuiState(EInGameGuiState, const CStateManager&) +{ + +} + } diff --git a/Runtime/CArchitectureMessage.hpp b/Runtime/CArchitectureMessage.hpp index 6f98f93a8..3a6f234af 100644 --- a/Runtime/CArchitectureMessage.hpp +++ b/Runtime/CArchitectureMessage.hpp @@ -28,8 +28,8 @@ enum class EArchMsgType SetGameState = 6, ControllerStatus = 7, QuitGameplay = 8, - UpdateBegin = 10, - FrameBegin = 11, + FrameBegin = 10, + FrameEnd = 11, /* URDE messages, we start at 255 */ ApplicationExit = 255, }; @@ -165,11 +165,16 @@ public: { return *msg.GetParm(); } - static CArchitectureMessage CreateFrameBegin(EArchMsgTarget target, const int& a) + static CArchitectureMessage CreateFrameBegin(EArchMsgTarget target, const s32& a) { return CArchitectureMessage(target, EArchMsgType::FrameBegin, std::make_shared(a)); } + static CArchitectureMessage CreateFrameEnd(EArchMsgTarget target, const s32& a) + { + return CArchitectureMessage(target, EArchMsgType::FrameEnd, + std::make_shared(a)); + } /* URDE Messages */ static CArchitectureMessage CreateApplicationExit(EArchMsgTarget target) { diff --git a/Runtime/CGameHintInfo.cpp b/Runtime/CGameHintInfo.cpp index 78ad81b67..5f0030d0e 100644 --- a/Runtime/CGameHintInfo.cpp +++ b/Runtime/CGameHintInfo.cpp @@ -1,5 +1,7 @@ #include "CGameHintInfo.hpp" #include "CToken.hpp" +#include "CMemoryCardSys.hpp" +#include "GameGlobalObjects.hpp" namespace urde { @@ -14,10 +16,10 @@ CGameHintInfo::CGameHintInfo(CInputStream& in, s32 version) CGameHintInfo::CGameHint::CGameHint(CInputStream& in, s32 version) : x0_name(in.readString()) -, x10_(in.readFloatBig()) -, x14_fadeInTime(in.readFloatBig()) +, x10_immediateTime(in.readFloatBig()) +, x14_normalTime(in.readFloatBig()) , x18_stringId(in.readUint32Big()) -, x1c_time(3.f * float(version <= 0 ? 1 : in.readUint32Big())) +, x1c_continueDelayTime(3.f * float(version <= 0 ? 1 : in.readUint32Big())) { u32 locationCount = in.readUint32Big(); x20_locations.reserve(locationCount); @@ -33,6 +35,18 @@ CGameHintInfo::SHintLocation::SHintLocation(CInputStream& in, s32) { } +int CGameHintInfo::FindHintIndex(const char* str) +{ + int idx = 0; + for (const CGameHintInfo::CGameHint& hint : g_MemoryCardSys->GetHints()) + { + if (!hint.GetName().compare(str)) + return idx; + ++idx; + } + return -1; +} + CFactoryFnReturn FHintFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer, CObjectReference*) { in.readUint32Big(); diff --git a/Runtime/CGameHintInfo.hpp b/Runtime/CGameHintInfo.hpp index 5514dd7f7..163e07cf8 100644 --- a/Runtime/CGameHintInfo.hpp +++ b/Runtime/CGameHintInfo.hpp @@ -21,17 +21,17 @@ public: class CGameHint { std::string x0_name; - float x10_; - float x14_fadeInTime; + float x10_immediateTime; + float x14_normalTime; ResId x18_stringId; - float x1c_time; + float x1c_continueDelayTime; std::vector x20_locations; public: CGameHint(CInputStream&, s32); - float GetTime() const { return x1c_time; } - float GetFadeInTime() const { return x14_fadeInTime; } - float GetX10() const { return x10_; } + float GetNormalTime() const { return x14_normalTime; } + float GetImmediateTime() const { return x10_immediateTime; } + float GetContinueDelayTime() const { return x1c_continueDelayTime; } const std::string& GetName() const { return x0_name; } ResId GetStringID() const { return x18_stringId; } const std::vector& GetLocations() const { return x20_locations; } @@ -42,6 +42,7 @@ private: public: CGameHintInfo(CInputStream&, s32); const std::vector& GetHints() const { return x0_hints; } + static int FindHintIndex(const char* str); }; CFactoryFnReturn FHintFactory(const SObjectTag&, CInputStream&, const CVParamTransfer, CObjectReference*); diff --git a/Runtime/CGameOptions.cpp b/Runtime/CGameOptions.cpp index f7d1b7730..d9bddf7c6 100644 --- a/Runtime/CGameOptions.cpp +++ b/Runtime/CGameOptions.cpp @@ -564,7 +564,7 @@ void CHintOptions::SetNextHintTime() if (x10_nextHintIdx == -1) return; x0_hintStates[x10_nextHintIdx].x4_time = - g_MemoryCardSys->GetHints()[x10_nextHintIdx].GetTime() + 5.f; + g_MemoryCardSys->GetHints()[x10_nextHintIdx].GetContinueDelayTime() + 5.f; } void CHintOptions::InitializeMemoryState() @@ -573,4 +573,73 @@ void CHintOptions::InitializeMemoryState() x0_hintStates.resize(hints.size()); } +const CHintOptions::SHintState* CHintOptions::GetCurrentDisplayedHint() const +{ + if (!g_GameState->GameOptions().GetIsHintSystemEnabled()) + return nullptr; + + if (x10_nextHintIdx == -1) + return nullptr; + + const SHintState& hintState = x0_hintStates[x10_nextHintIdx]; + const CGameHintInfo::CGameHint& hint = g_MemoryCardSys->GetHints()[x10_nextHintIdx]; + if (hintState.x4_time >= hint.GetContinueDelayTime()) + return nullptr; + + if (hintState.x4_time < 3.f) + return &hintState; + + if (!hintState.x8_flag) + return &hintState; + + return nullptr; +} + +void CHintOptions::DelayHint(const char* name) +{ + int idx = CGameHintInfo::FindHintIndex(name); + if (idx == -1) + return; + + if (x10_nextHintIdx == idx) + { + for (SHintState& state : x0_hintStates) + state.x4_time += 60.f; + + } + + x0_hintStates[idx].x0_state = EHintState::Delayed; +} + +void CHintOptions::ActivateImmediateHintTimer(const char* name) +{ + int idx = CGameHintInfo::FindHintIndex(name); + if (idx == -1) + return; + + SHintState& hintState = x0_hintStates[idx]; + const CGameHintInfo::CGameHint& hint = g_MemoryCardSys->GetHints()[idx]; + if (hintState.x0_state != EHintState::Zero) + return; + + hintState.x0_state = EHintState::One; + hintState.x4_time = hint.GetImmediateTime(); +} + +void CHintOptions::ActivateContinueDelayHintTimer(const char* name) +{ + int idx = x10_nextHintIdx; + if (idx != 0) + idx = CGameHintInfo::FindHintIndex(name); + if (idx == -1) + return; + + SHintState& hintState = x0_hintStates[idx]; + const CGameHintInfo::CGameHint& hint = g_MemoryCardSys->GetHints()[idx]; + if (hintState.x0_state != EHintState::Two) + return; + + hintState.x4_time = hint.GetContinueDelayTime(); +} + } diff --git a/Runtime/CGameOptions.hpp b/Runtime/CGameOptions.hpp index fec3b254a..d2150c560 100644 --- a/Runtime/CGameOptions.hpp +++ b/Runtime/CGameOptions.hpp @@ -185,7 +185,8 @@ public: { Zero, One, - Two + Two, + Delayed }; struct SHintState { @@ -196,6 +197,8 @@ public: SHintState() = default; SHintState(EHintState state, float time, bool flag) : x0_state(state), x4_time(time), x8_flag(flag) {} + + bool CanContinue() const { return x4_time / 3.f <= 1.f; } }; private: std::vector x0_hintStates; @@ -206,6 +209,10 @@ public: void PutTo(CBitStreamWriter& writer) const; void SetNextHintTime(); void InitializeMemoryState(); + const SHintState* GetCurrentDisplayedHint() const; + void DelayHint(const char* name); + void ActivateImmediateHintTimer(const char* name); + void ActivateContinueDelayHintTimer(const char* name); }; } diff --git a/Runtime/CGameState.hpp b/Runtime/CGameState.hpp index 244e0a65a..2815d490e 100644 --- a/Runtime/CGameState.hpp +++ b/Runtime/CGameState.hpp @@ -58,6 +58,7 @@ public: void SetAreaId(TAreaId aid) { x4_areaId = aid; } TAreaId GetCurrentAreaId() const { return x4_areaId; } ResId GetDesiredAreaAssetId() const { return x10_desiredAreaAssetId; } + void SetDesiredAreaAssetId(ResId id) { x10_desiredAreaAssetId = id; } const std::shared_ptr& RelayTracker() const { return x8_relayTracker; } const std::shared_ptr& MapWorldInfo() const { return xc_mapWorldInfo; } const std::shared_ptr& GetLayerState() const { return x14_layerState; } diff --git a/Runtime/CPlayerState.cpp b/Runtime/CPlayerState.cpp index ee42c5370..eb47d9341 100644 --- a/Runtime/CPlayerState.cpp +++ b/Runtime/CPlayerState.cpp @@ -62,7 +62,7 @@ const char* PowerUpNames[41]= CPlayerState::CPlayerState() : x188_staticIntf(5) { - x0_24_ = true; + x0_24_alive = true; x24_powerups.resize(41); } diff --git a/Runtime/CPlayerState.hpp b/Runtime/CPlayerState.hpp index 25459615e..a9e859cd8 100644 --- a/Runtime/CPlayerState.hpp +++ b/Runtime/CPlayerState.hpp @@ -111,7 +111,7 @@ private: }; union { - struct { bool x0_24_ : 1; bool x0_25_ : 1; bool x0_26_fusion : 1; }; + struct { bool x0_24_alive : 1; bool x0_25_ : 1; bool x0_26_fusion : 1; }; u32 dummy = 0; }; @@ -139,6 +139,7 @@ public: void SetIsFusionEnabled(bool val) { x0_26_fusion = val; } bool IsFusionEnabled() const { return x0_26_fusion; } EPlayerSuit GetCurrentSuit() const; + EPlayerSuit GetCurrentSuitRaw() const { return x20_currentSuit; } EBeamId GetCurrentBeam() const { return x8_currentBeam; } bool CanVisorSeeFog(const CStateManager& stateMgr) const; EPlayerVisor GetCurrentVisor() const { return x14_currentVisor; } @@ -168,6 +169,7 @@ public: void InitializePowerUp(EItemType type, u32 capacity); u32 GetLogScans() const { return x180_logScans; } u32 GetTotalLogScans() const { return x184_totalLogScans; } + bool IsPlayerAlive() const { return x0_24_alive; } void InitializeScanTimes(); const rstl::reserved_vector, 846>& GetScanTimes() const { return x170_scanTimes; } CPlayerState(); diff --git a/Runtime/CStateManager.cpp b/Runtime/CStateManager.cpp index ea6ff4824..d059db0e7 100644 --- a/Runtime/CStateManager.cpp +++ b/Runtime/CStateManager.cpp @@ -24,6 +24,7 @@ #include "Particle/CGenDescription.hpp" #include "CMemoryCardSys.hpp" #include "TCastTo.hpp" +#include "World/CScriptSpecialFunction.hpp" #include @@ -268,7 +269,23 @@ void CStateManager::AddDrawableActor(const CActor& actor, const zeus::CVector3f& IRenderer::EDrawableSorting::SortedCallback); } -void CStateManager::SpecialSkipCinematic() {} +bool CStateManager::SpecialSkipCinematic() +{ + if (xf38_skipCineSpecialFunc == kInvalidUniqueId) + return false; + + CScriptSpecialFunction* ent = static_cast(ObjectById(xf38_skipCineSpecialFunc)); + if (!ent || !ent->ShouldSkipCinematic(*this)) + return false; + + bool hadRandom = x900_activeRandom != nullptr; + SetActiveRandomToDefault(); + x870_cameraManager->SkipCinematic(*this); + ent->SkipCinematic(*this); + x900_activeRandom = hadRandom ? &x8fc_random : nullptr; + + return true; +} void CStateManager::GetVisAreaId() const {} @@ -622,12 +639,12 @@ void CStateManager::Update(float dt) {} void CStateManager::UpdateGameState() {} -void CStateManager::FrameBegin() {} +void CStateManager::FrameBegin(s32 frameCount) {} void CStateManager::InitializeState(ResId mlvlId, TAreaId aid, ResId mreaId) { bool hadRandom = x900_activeRandom != nullptr; - x900_activeRandom = &x8fc_random; + SetActiveRandomToDefault(); if (xb3c_initPhase == InitPhase::LoadWorld) { @@ -700,9 +717,9 @@ void CStateManager::InitializeState(ResId mlvlId, TAreaId aid, ResId mreaId) x870_cameraManager->ResetCameras(*this); if (!hadRandom) - x900_activeRandom = nullptr; + ClearActiveRandom(); else - x900_activeRandom = &x8fc_random; + SetActiveRandomToDefault(); x880_envFxManager->AsyncLoadResources(*this); } @@ -853,6 +870,34 @@ TUniqueId CStateManager::AllocateUniqueId() return ((ourIndex | ((x8_idArr[ourIndex]) << 10)) & 0xFFFF); } +void CStateManager::DeferStateTransition(EStateManagerTransition t) +{ + if (t == EStateManagerTransition::InGame) + { + if (xf90_deferredTransition != EStateManagerTransition::InGame) + { + x850_world->SetPauseState(false); + xf90_deferredTransition = EStateManagerTransition::InGame; + } + } + else + { + if (xf90_deferredTransition == EStateManagerTransition::InGame) + { + x850_world->SetPauseState(true); + xf90_deferredTransition = t; + } + } +} + +bool CStateManager::CanShowMapScreen() const +{ + const CHintOptions::SHintState* curDispHint = g_GameState->HintOptions().GetCurrentDisplayedHint(); + if (!curDispHint || curDispHint->CanContinue()) + return true; + return false; +} + std::pair CStateManager::CalculateScanCompletionRate() const { u32 num = 0; diff --git a/Runtime/CStateManager.hpp b/Runtime/CStateManager.hpp index 0b3507d4b..344e834f8 100644 --- a/Runtime/CStateManager.hpp +++ b/Runtime/CStateManager.hpp @@ -65,6 +65,16 @@ struct SOnScreenTex zeus::CVector2i xc_extent; }; +enum class EStateManagerTransition +{ + InGame, + MapScreen, + PauseGame, + LogBook, + SaveGame, + MessageScreen +}; + class CStateManager { friend class MP1::CMFGameLoader; @@ -172,7 +182,7 @@ class CStateManager }; SOnScreenTex xef4_pendingScreenTex; - ResId xf08_ = -1; + ResId xf08_pauseHudMessage = -1; float xf0c_ = 0.f; float xf10_ = 0.f; float xf14_ = 0.f; @@ -184,7 +194,7 @@ class CStateManager float xf2c_ = 1.f; float xf30_ = 1.f; u32 xf34_ = 2; - TUniqueId xf38_ = kInvalidUniqueId; + TUniqueId xf38_skipCineSpecialFunc = kInvalidUniqueId; std::list xf3c_; u32 xf50_ = 0; std::list xf54_; @@ -195,23 +205,23 @@ class CStateManager TUniqueId xf74_lastTrigger = kInvalidUniqueId; TUniqueId xf76_lastRelay = kInvalidUniqueId; - float xf78_ = 0.f; + float xf78_hudMessageTime = 0.f; u32 xf7c_ = 0; - u32 xf80_ = 0; + u32 xf80_hudMessageFrameCount = 0; ResId xf84_ = -1; ResId xf88_ = -1; float xf8c_ = 0.f; - u32 xf90_ = 0; + EStateManagerTransition xf90_deferredTransition = EStateManagerTransition::InGame; union { struct { bool xf94_24_ : 1; - bool xf94_25_ : 1; + bool xf94_25_quitGame : 1; bool xf94_26_generatingObject : 1; - bool xf94_27_ : 1; - bool xf94_28_ : 1; + bool xf94_27_inMapScreen : 1; + bool xf94_28_inSaveUI : 1; bool xf94_29_ : 1; bool xf94_30_ : 1; }; @@ -232,7 +242,7 @@ public: bool RenderLast(TUniqueId); void AddDrawableActorPlane(const CActor& actor, const zeus::CPlane&, const zeus::CAABox& aabb) const; void AddDrawableActor(const CActor& actor, const zeus::CVector3f& vec, const zeus::CAABox& aabb) const; - void SpecialSkipCinematic(); + bool SpecialSkipCinematic(); void GetVisAreaId() const; void GetWeaponIdCount(TUniqueId, EWeaponType); void RemoveWeaponId(TUniqueId, EWeaponType); @@ -299,7 +309,7 @@ public: void ProcessInput(const CFinalInput& input); void Update(float dt); void UpdateGameState(); - void FrameBegin(); + void FrameBegin(s32 frameCount); void InitializeState(ResId mlvlId, TAreaId aid, ResId mreaId); void CreateStandardGameObjects(); const std::unique_ptr& GetObjectList() const { return x80c_allObjs; } @@ -336,9 +346,22 @@ public: const rstl::reserved_vector& list) const; void UpdateObjectInLists(CEntity&); TUniqueId AllocateUniqueId(); + void DeferStateTransition(EStateManagerTransition t); + EStateManagerTransition GetDeferredStateTransition() const { return xf90_deferredTransition; } + bool CanShowMapScreen() const; + TUniqueId GetSkipCinematicSpecialFunction() const { return xf38_skipCineSpecialFunc; } + void SetSkipCinematicSpecialFunction(TUniqueId id) { xf38_skipCineSpecialFunc = id; } + float GetHUDMessageTime() const { return xf78_hudMessageTime; } + ResId GetPauseHUDMessage() const { return xf08_pauseHudMessage; } + void IncrementHUDMessageFrameCounter() { ++xf80_hudMessageFrameCount; } + bool ShouldQuitGame() const { return xf94_25_quitGame; } + void SetInSaveUI(bool b) { xf94_28_inSaveUI = b; } + void SetInMapScreen(bool b) { xf94_27_inMapScreen = b; } const std::shared_ptr& GetPlayerState() const {return x8b8_playerState;} CRandom16* GetActiveRandom() {return x900_activeRandom;} + void SetActiveRandomToDefault() { x900_activeRandom = &x8fc_random; } + void ClearActiveRandom() { x900_activeRandom = nullptr; } CRumbleManager& GetRumbleManager() {return *x88c_rumbleManager;} CCameraFilterPass& GetCameraFilterPass(int idx) {return xb84_camFilterPasses[idx];} diff --git a/Runtime/Camera/CCameraManager.cpp b/Runtime/Camera/CCameraManager.cpp index 3c4b3fa1c..84b773f73 100644 --- a/Runtime/Camera/CCameraManager.cpp +++ b/Runtime/Camera/CCameraManager.cpp @@ -14,6 +14,7 @@ #include "Particle/CGenDescription.hpp" #include "CObjectList.hpp" #include "TCastTo.hpp" +#include "CCinematicCamera.hpp" namespace urde { @@ -153,6 +154,20 @@ const CEntity* CCameraManager::GetCurrentCamera(const CStateManager& stateMgr) c return camList->GetObjectById(GetCurrentCameraId()); } +void CCameraManager::SkipCinematic(CStateManager& stateMgr) +{ + TUniqueId camId = GetCurrentCameraId(); + CCinematicCamera* ent = static_cast(stateMgr.ObjectById(camId)); + while (ent) + { + ent->SetActive(false); + ent->WasDeactivated(stateMgr); + ent = TCastToPtr(GetCurrentCamera(stateMgr)).GetPtr(); + } + stateMgr.GetPlayer().UpdateCinematicState(stateMgr); + x7c_fpCamera->SkipCinematic(); +} + float CCameraManager::sub80009148() const { const zeus::CVector3f uVec = x7c_fpCamera->GetTransform().upVector(); diff --git a/Runtime/Camera/CCameraManager.hpp b/Runtime/Camera/CCameraManager.hpp index 3d2c33105..f5b0ef09c 100644 --- a/Runtime/Camera/CCameraManager.hpp +++ b/Runtime/Camera/CCameraManager.hpp @@ -97,6 +97,8 @@ public: return kInvalidUniqueId; } + void SkipCinematic(CStateManager& stateMgr); + CFirstPersonCamera* GetFirstPersonCamera() { return x7c_fpCamera; } CBallCamera* GetBallCamera() { return x80_ballCamera; } CBallCamera* BallCamera(CStateManager&) const; diff --git a/Runtime/Camera/CCinematicCamera.cpp b/Runtime/Camera/CCinematicCamera.cpp index 0253f7edb..5618387a0 100644 --- a/Runtime/Camera/CCinematicCamera.cpp +++ b/Runtime/Camera/CCinematicCamera.cpp @@ -6,8 +6,8 @@ namespace urde CCinematicCamera::CCinematicCamera(TUniqueId uid, const std::string& name, const CEntityInfo& info, const zeus::CTransform& xf, bool active, float, float a, float b, float c, float d, - u32 e) -: CGameCamera(uid, active, name, info, xf, a, b, c, d, kInvalidUniqueId, e & 0x20, 0) + u32 w1) +: CGameCamera(uid, active, name, info, xf, a, b, c, d, kInvalidUniqueId, w1 & 0x20, 0), x21c_w1(w1) { } @@ -19,4 +19,9 @@ void CCinematicCamera::Accept(IVisitor& visitor) void CCinematicCamera::ProcessInput(const CFinalInput&, CStateManager& mgr) {} void CCinematicCamera::Reset(const zeus::CTransform&, CStateManager& mgr) {} + +void CCinematicCamera::WasDeactivated(CStateManager& mgr) +{ + +} } diff --git a/Runtime/Camera/CCinematicCamera.hpp b/Runtime/Camera/CCinematicCamera.hpp index 530039765..b1665d94b 100644 --- a/Runtime/Camera/CCinematicCamera.hpp +++ b/Runtime/Camera/CCinematicCamera.hpp @@ -8,13 +8,16 @@ namespace urde class CCinematicCamera : public CGameCamera { + u32 x21c_w1; public: CCinematicCamera(TUniqueId, const std::string& name, const CEntityInfo& info, - const zeus::CTransform& xf, bool, float, float, float, float, float, u32); + const zeus::CTransform& xf, bool, float, float, float, float, float, u32 w1); void Accept(IVisitor& visitor); void ProcessInput(const CFinalInput&, CStateManager& mgr); void Reset(const zeus::CTransform&, CStateManager& mgr); + u32 GetW1() const { return x21c_w1; } + void WasDeactivated(CStateManager& mgr); }; } diff --git a/Runtime/Camera/CFirstPersonCamera.cpp b/Runtime/Camera/CFirstPersonCamera.cpp index 0e9df6339..659d89410 100644 --- a/Runtime/Camera/CFirstPersonCamera.cpp +++ b/Runtime/Camera/CFirstPersonCamera.cpp @@ -19,11 +19,18 @@ CFirstPersonCamera::CFirstPersonCamera(TUniqueId uid, const zeus::CTransform& xf { } +void CFirstPersonCamera::PreThink(float, CStateManager&) {} + +void CFirstPersonCamera::Think(float, CStateManager&) +{ + +} + void CFirstPersonCamera::ProcessInput(const CFinalInput&, CStateManager& mgr) {} void CFirstPersonCamera::Reset(const zeus::CTransform&, CStateManager& mgr) {} -void CFirstPersonCamera::sub800E318() +void CFirstPersonCamera::SkipCinematic() { x1c8_ = zeus::CVector3f::skZero; x1d4_ = 0.f; diff --git a/Runtime/Camera/CFirstPersonCamera.hpp b/Runtime/Camera/CFirstPersonCamera.hpp index 768fb0b9f..67f610a13 100644 --- a/Runtime/Camera/CFirstPersonCamera.hpp +++ b/Runtime/Camera/CFirstPersonCamera.hpp @@ -32,7 +32,7 @@ public: void ProcessInput(const CFinalInput&, CStateManager& mgr); void Reset(const zeus::CTransform&, CStateManager& mgr); - void sub800E318(); + void SkipCinematic(); zeus::CTransform GetGunFollowTransform(); void UpdateTransform(CStateManager&, float dt); void UpdateElevation(CStateManager&); diff --git a/Runtime/GameGlobalObjects.cpp b/Runtime/GameGlobalObjects.cpp index bc738c447..d6e250503 100644 --- a/Runtime/GameGlobalObjects.cpp +++ b/Runtime/GameGlobalObjects.cpp @@ -17,6 +17,7 @@ class CGameState* g_GameState = nullptr; class CInGameTweakManagerBase* g_TweakManager = nullptr; class CBooRenderer* g_Renderer = nullptr; class CStringTable* g_MainStringTable = nullptr; +class CInputGenerator* g_InputGenerator = nullptr; ITweakGame* g_tweakGame = nullptr; ITweakPlayer* g_tweakPlayer = nullptr; diff --git a/Runtime/GameGlobalObjects.hpp b/Runtime/GameGlobalObjects.hpp index 647a61c83..c6b9a569d 100644 --- a/Runtime/GameGlobalObjects.hpp +++ b/Runtime/GameGlobalObjects.hpp @@ -31,6 +31,7 @@ extern class CGameState* g_GameState; extern class CInGameTweakManagerBase* g_TweakManager; extern class CBooRenderer* g_Renderer; extern class CStringTable* g_MainStringTable; +extern class CInputGenerator* g_InputGenerator; using ITweakGame = DataSpec::ITweakGame; using ITweakPlayer = DataSpec::ITweakPlayer; diff --git a/Runtime/Input/CInputGenerator.hpp b/Runtime/Input/CInputGenerator.hpp index bf117893d..b71ae6bd8 100644 --- a/Runtime/Input/CInputGenerator.hpp +++ b/Runtime/Input/CInputGenerator.hpp @@ -10,6 +10,21 @@ namespace urde { class CArchitectureQueue; +enum class EIOPort +{ + Zero, + One, + Two, + Three +}; + +enum class EMotorState +{ + Stop, + Rumble, + StopHard +}; + class CInputGenerator : public boo::DeviceFinder { enum class EStatusChange @@ -172,6 +187,24 @@ public: if (smashAdapter.get() == device) smashAdapter.reset(nullptr); } + void SetMotorState(EIOPort port, EMotorState state) + { + if (smashAdapter) + { + switch (state) + { + case EMotorState::Stop: + smashAdapter->stopRumble(unsigned(port)); + break; + case EMotorState::Rumble: + smashAdapter->startRumble(unsigned(port)); + break; + case EMotorState::StopHard: + smashAdapter->stopRumble(unsigned(port), true); + break; + } + } + } /* This is where the game thread enters */ void Update(float dt, CArchitectureQueue& queue); diff --git a/Runtime/Input/CRumbleGenerator.hpp b/Runtime/Input/CRumbleGenerator.hpp index b0cddbb2a..9c06bbc81 100644 --- a/Runtime/Input/CRumbleGenerator.hpp +++ b/Runtime/Input/CRumbleGenerator.hpp @@ -2,14 +2,7 @@ #define CRUMBLEGENERATOR_HPP #include "CRumbleVoice.hpp" - -enum class EIOPort -{ - Zero, - One, - Two, - Three -}; +#include "CInputGenerator.hpp" namespace urde { diff --git a/Runtime/MP1/CInGameGuiManager.cpp b/Runtime/MP1/CInGameGuiManager.cpp index 8fd4edc16..e1ab087ed 100644 --- a/Runtime/MP1/CInGameGuiManager.cpp +++ b/Runtime/MP1/CInGameGuiManager.cpp @@ -9,6 +9,12 @@ #include "GuiSys/CGuiModel.hpp" #include "AutoMapper/CAutoMapper.hpp" #include "Particle/CGenDescription.hpp" +#include "Audio/CSfxManager.hpp" +#include "CPauseScreen.hpp" +#include "CSamusHud.hpp" +#include "CInventoryScreen.hpp" +#include "CPauseScreen.hpp" +#include "Input/CInputGenerator.hpp" namespace urde { @@ -71,6 +77,141 @@ bool CInGameGuiManager::CheckDGRPLoadComplete() const } void CInGameGuiManager::BeginStateTransition(EInGameGuiState state, CStateManager& stateMgr) +{ + if (x1c0_nextState == state) + return; + + x1bc_prevState = x1c0_nextState; + x1c0_nextState = state; + + switch (state) + { + case EInGameGuiState::InGame: + { + CSfxManager::SetChannel(CSfxManager::ESfxChannels::Game); + x4c_saveUI.reset(); + x38_autoMapper->UnmuteAllLoopedSounds(); + break; + } + case EInGameGuiState::PauseHUDMessage: + { + x44_messageScreen = std::make_unique(x124_pauseGameHudMessage, x128_pauseGameHudTime); + break; + } + case EInGameGuiState::PauseSaveGame: + { + x4c_saveUI = std::make_unique(ESaveContext::InGame, g_GameState->GetCardSerial()); + break; + } + default: + { + if (x1bc_prevState >= EInGameGuiState::Zero && x1bc_prevState <= EInGameGuiState::InGame) + x1f8_26_deferTransition = true; + break; + } + } + + x3c_pauseScreen->OnNewInGameGuiState(state, stateMgr); + if (!x1f8_26_deferTransition) + DoStateTransition(stateMgr); + +} + +void CInGameGuiManager::EnsureStates(CStateManager& stateMgr) +{ + if (x1f8_26_deferTransition) + { + if (!x3c_pauseScreen->GetX50_25()) + { + DestroyAreaTextures(stateMgr); + x1f8_26_deferTransition = false; + DoStateTransition(stateMgr); + } + } +} + +void CInGameGuiManager::DoStateTransition(CStateManager& stateMgr) +{ + x34_samusHud->OnNewInGameGuiState(x1c0_nextState, stateMgr); + x38_autoMapper->OnNewInGameGuiState(x1c0_nextState, stateMgr); + + bool needsLock; + switch (x1c0_nextState) + { + case EInGameGuiState::PauseGame: + case EInGameGuiState::PauseLogBook: + if (!x48_inventoryScreen) + { + auto pState = stateMgr.GetPlayerState(); + CPlayerState::EPlayerSuit suit = pState->GetCurrentSuitRaw(); + int suitResIdx; + if (pState->IsFusionEnabled()) + { + switch (suit) + { + case CPlayerState::EPlayerSuit::Phazon: + suitResIdx = 7; + break; + case CPlayerState::EPlayerSuit::Gravity: + suitResIdx = 6; + break; + case CPlayerState::EPlayerSuit::Varia: + suitResIdx = 5; + break; + default: + suitResIdx = 4; + break; + } + } + else + { + switch (suit) + { + case CPlayerState::EPlayerSuit::Phazon: + suitResIdx = 3; + break; + case CPlayerState::EPlayerSuit::Gravity: + suitResIdx = 2; + break; + case CPlayerState::EPlayerSuit::Varia: + suitResIdx = 1; + break; + default: + suitResIdx = 0; + break; + } + } + + int w1 = x1c0_nextState == EInGameGuiState::PauseLogBook ? 0 : 2; + CDependencyGroup* suitGrp = x5c_pauseScreenDGRPs[suitResIdx].GetObj(); + x48_inventoryScreen = std::make_unique(w1, *suitGrp, *suitGrp); + } + + case EInGameGuiState::MapScreen: + case EInGameGuiState::PauseSaveGame: + case EInGameGuiState::PauseHUDMessage: + needsLock = true; + break; + default: + needsLock = false; + break; + } + + for (CToken& tok : xe8_pauseResources) + { + if (needsLock) + tok.Lock(); + else + tok.Unlock(); + } +} + +void CInGameGuiManager::DestroyAreaTextures(CStateManager& stateMgr) +{ + +} + +void CInGameGuiManager::TryReloadAreaTextures() { } @@ -90,7 +231,7 @@ CInGameGuiManager::CInGameGuiManager(CStateManager& stateMgr, x1f4_player74c = stateMgr.GetPlayer().Get74C(); x1f8_25_ = true; - x1f8_27_ = true; + x1f8_27_inSaveUI = true; xc8_inGameGuiDGRPs.reserve(14); for (int i=0 ; i<14 ; ++i) @@ -154,7 +295,7 @@ bool CInGameGuiManager::CheckLoadComplete(CStateManager& stateMgr) zeus::CMatrix3f mtx(x170_camRotate); x18c_camXf = zeus::CTransform(mtx, x180_camOffset); - BeginStateTransition(EInGameGuiState::One, stateMgr); + BeginStateTransition(EInGameGuiState::InGame, stateMgr); x18_loadPhase = ELoadPhase::Done; } case ELoadPhase::Done: @@ -167,5 +308,50 @@ bool CInGameGuiManager::CheckLoadComplete(CStateManager& stateMgr) } } +void CInGameGuiManager::Update(CStateManager& stateMgr, float dt, CArchitectureQueue& archQueue, bool) +{ + EnsureStates(stateMgr); +} + +void CInGameGuiManager::ProcessControllerInput(CStateManager& stateMgr, const CFinalInput& input, + CArchitectureQueue& archQueue) +{ + +} + +void CInGameGuiManager::PreDraw(CStateManager& stateMgr) +{ + +} + +void CInGameGuiManager::Draw(CStateManager& stateMgr) +{ + +} + +void CInGameGuiManager::ShowPauseGameHudMessage(CStateManager& stateMgr, ResId pauseMsg, float time) +{ + x124_pauseGameHudMessage = pauseMsg; + x128_pauseGameHudTime = time; + PauseGame(stateMgr, EInGameGuiState::PauseHUDMessage); +} + +void CInGameGuiManager::PauseGame(CStateManager& stateMgr, EInGameGuiState state) +{ + g_InputGenerator->SetMotorState(EIOPort::Zero, EMotorState::Stop); + CSfxManager::SetChannel(CSfxManager::ESfxChannels::PauseScreen); + BeginStateTransition(state, stateMgr); +} + +void CInGameGuiManager::StartFadeIn() +{ + +} + +bool CInGameGuiManager::GetIsGameDraw() const +{ + return x3c_pauseScreen->GetX50_25(); +} + } } diff --git a/Runtime/MP1/CInGameGuiManager.hpp b/Runtime/MP1/CInGameGuiManager.hpp index 58d1cc17c..b4524e541 100644 --- a/Runtime/MP1/CInGameGuiManager.hpp +++ b/Runtime/MP1/CInGameGuiManager.hpp @@ -5,14 +5,13 @@ #include "CRandom16.hpp" #include "CPlayerVisor.hpp" #include "CFaceplateDecoration.hpp" -#include "CSamusHud.hpp" -#include "CPauseScreen.hpp" #include "CSamusFaceReflection.hpp" #include "CMessageScreen.hpp" #include "CSaveGameScreen.hpp" #include "Camera/CCameraFilter.hpp" #include "CStateManager.hpp" #include "DataSpec/DNACommon/Tweaks/ITweakGui.hpp" +#include "CInventoryScreen.hpp" namespace urde { @@ -27,11 +26,19 @@ class CAutoMapper; namespace MP1 { +class CPauseScreen; +class CSamusHud; +class CInventoryScreen; enum class EInGameGuiState { Zero, - One + InGame, + MapScreen, + PauseGame, + PauseLogBook, + PauseSaveGame, + PauseHUDMessage }; class CInGameGuiManager @@ -59,15 +66,17 @@ class CInGameGuiManager std::unique_ptr x38_autoMapper; std::unique_ptr x3c_pauseScreen; std::unique_ptr x40_samusReflection; - std::unique_ptr x44_; - u32 x48_ = 0; + std::unique_ptr x44_messageScreen; + std::unique_ptr x48_inventoryScreen; std::unique_ptr x4c_saveUI; TLockedToken x50_deathDot; std::vector> x5c_pauseScreenDGRPs; std::vector> xc8_inGameGuiDGRPs; std::vector xd8_; - std::vector xe8_; + std::vector xe8_pauseResources; CCameraFilterPass xf8_camFilter; + ResId x124_pauseGameHudMessage = -1; + float x128_pauseGameHudTime = 0.f; std::list x12c_; u32 x140_ = 0; CGuiWidget* x144_basewidget_automapper = nullptr; @@ -79,8 +88,8 @@ class CInGameGuiManager zeus::CQuaternion x170_camRotate; zeus::CVector3f x180_camOffset; zeus::CTransform x18c_camXf; - u32 x1bc_ = 0; - u32 x1c0_ = 0; + EInGameGuiState x1bc_prevState = EInGameGuiState::Zero; + EInGameGuiState x1c0_nextState = EInGameGuiState::Zero; SOnScreenTex x1c4_onScreenTex; float x1d8_ = 0.f; TLockedToken x1dc_onScreenTexTok; // Used to be heap-allocated @@ -97,8 +106,8 @@ class CInGameGuiManager { bool x1f8_24_ : 1; bool x1f8_25_ : 1; - bool x1f8_26_ : 1; - bool x1f8_27_ : 1; + bool x1f8_26_deferTransition : 1; + bool x1f8_27_inSaveUI : 1; }; u32 _dummy = 0; }; @@ -106,10 +115,26 @@ class CInGameGuiManager static std::vector> LockPauseScreenDependencies(); bool CheckDGRPLoadComplete() const; void BeginStateTransition(EInGameGuiState state, CStateManager& stateMgr); + void EnsureStates(CStateManager& stateMgr); + void DoStateTransition(CStateManager& stateMgr); + void DestroyAreaTextures(CStateManager& stateMgr); + void TryReloadAreaTextures(); public: CInGameGuiManager(CStateManager& stateMgr, CArchitectureQueue& archQueue); bool CheckLoadComplete(CStateManager& stateMgr); + void Update(CStateManager& stateMgr, float dt, CArchitectureQueue& archQueue, bool); + void ProcessControllerInput(CStateManager& stateMgr, const CFinalInput& input, + CArchitectureQueue& archQueue); + void PreDraw(CStateManager& stateMgr); + void Draw(CStateManager& stateMgr); + void ShowPauseGameHudMessage(CStateManager& stateMgr, ResId pauseMsg, float time); + void PauseGame(CStateManager& stateMgr, EInGameGuiState state); + void StartFadeIn(); + bool WasInGame() const { return x1bc_prevState >= EInGameGuiState::Zero && x1bc_prevState <= EInGameGuiState::InGame; } + bool IsInGame() const { return x1c0_nextState >= EInGameGuiState::Zero && x1c0_nextState <= EInGameGuiState::InGame; } + bool IsInSaveUI() const { return x1f8_27_inSaveUI; } + bool GetIsGameDraw() const; }; } diff --git a/Runtime/MP1/CInventoryScreen.cpp b/Runtime/MP1/CInventoryScreen.cpp new file mode 100644 index 000000000..ed0a1c885 --- /dev/null +++ b/Runtime/MP1/CInventoryScreen.cpp @@ -0,0 +1,27 @@ +#include "CInventoryScreen.hpp" +#include "GameGlobalObjects.hpp" +#include "CSimplePool.hpp" +#include "Audio/CSfxManager.hpp" + +namespace urde +{ +namespace MP1 +{ + +CInventoryScreen::CInventoryScreen(u32 w1, + const CDependencyGroup& suitDgrp, + const CDependencyGroup& ballDgrp) +: x0_w1(w1), x14_strgPauseScreen(g_SimplePool->GetObj("STRG_PauseScreen")), + x20_suitDgrp(suitDgrp), x24_ballDgrp(ballDgrp), + x28_pauseScreenInstructions(g_SimplePool->GetObj("FRME_PauseScreenInstructions")), + x54_frmePauseScreenId(g_ResFactory->GetResourceIdByName("FRME_PauseScreen")->id) +{ + SObjectTag frmeTag(FOURCC('FRME'), x54_frmePauseScreenId); + x58_frmePauseScreenBufSz = g_ResFactory->ResourceSize(frmeTag); + ProjectResourceFactoryBase& resFac = static_cast(*g_ResFactory); + x60_loadTok = resFac.LoadResourceAsync(frmeTag, x5c_frmePauseScreenBuf); + CSfxManager::SfxStart(1435, 1.f, 0.f, false, 0x7f, false, kInvalidAreaId); +} + +} +} diff --git a/Runtime/MP1/CInventoryScreen.hpp b/Runtime/MP1/CInventoryScreen.hpp new file mode 100644 index 000000000..b5eb17457 --- /dev/null +++ b/Runtime/MP1/CInventoryScreen.hpp @@ -0,0 +1,43 @@ +#ifndef __URDE_CINVENTORYSCREEN_HPP__ +#define __URDE_CINVENTORYSCREEN_HPP__ + +#include "CInGameGuiManager.hpp" +#include "Editor/ProjectResourceFactoryBase.hpp" + +namespace urde +{ +class CDependencyGroup; + +namespace MP1 +{ + +class CInventoryScreen +{ + u32 x0_w1; + TLockedToken x14_strgPauseScreen; + const CDependencyGroup& x20_suitDgrp; + const CDependencyGroup& x24_ballDgrp; + TLockedToken x28_pauseScreenInstructions; + u32 x34_ = 0; + u32 x38_ = 0; + u32 x3c_ = 0; + u32 x40_ = 0; + u32 x48_ = 0; + u32 x4c_ = 0; + u32 x50_ = 0; + ResId x54_frmePauseScreenId; + u32 x58_frmePauseScreenBufSz; + std::unique_ptr x5c_frmePauseScreenBuf; + std::shared_ptr x60_loadTok; + u32 x64_ = 0; + u32 x78_ = 0; + rstl::reserved_vector x7c_; + +public: + CInventoryScreen(u32 w1, const CDependencyGroup& suitDgrp, const CDependencyGroup& ballDgrp); +}; + +} +} + +#endif // __URDE_CINVENTORYSCREEN_HPP__ diff --git a/Runtime/MP1/CMFGame.cpp b/Runtime/MP1/CMFGame.cpp index 95e15e97c..54866b999 100644 --- a/Runtime/MP1/CMFGame.cpp +++ b/Runtime/MP1/CMFGame.cpp @@ -7,6 +7,11 @@ #include "MP1.hpp" #include "Character/CCharLayoutInfo.hpp" #include "AutoMapper/CAutoMapper.hpp" +#include "CSamusHud.hpp" +#include "CPauseScreen.hpp" +#include "TCastTo.hpp" +#include "Audio/CMidiManager.hpp" +#include "Camera/CCinematicCamera.hpp" namespace urde { @@ -17,18 +22,262 @@ CMFGame::CMFGame(const std::weak_ptr& stateMgr, const std::weak_p const CArchitectureQueue&) : CMFGameBase("CMFGame"), x14_stateManager(stateMgr.lock()), x18_guiManager(guiMgr.lock()) { - x2a_25_ = true; - //g_Main->x160_25_ = true; + x2a_25_samusAlive = true; + static_cast(*g_Main).SetMFGameBuilt(true); } CIOWin::EMessageReturn CMFGame::OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue) { + switch (msg.GetType()) + { + case EArchMsgType::FrameBegin: + x14_stateManager->FrameBegin(msg.GetParm()->x4_parm); + break; + case EArchMsgType::TimerTick: + { + bool wasInitialized = x2a_24_initialized; + x2a_24_initialized = true; + float dt = MakeMsg::GetParmTimerTick(msg).x4_parm; + switch (x1c_flowState) + { + case EGameFlowState::CinematicSkip: + { + x20_cineSkipTime += dt; + const CEntity* cam = x14_stateManager->GetCameraManager()->GetCurrentCamera(*x14_stateManager); + TCastToConstPtr cineCam = cam; + if ((x20_cineSkipTime >= 1.f && x14_stateManager->SpecialSkipCinematic()) || !cineCam || + (cineCam->GetW1() & 0x10 && x28_skippedCineCam != cineCam->GetUniqueId())) + { + static_cast(*g_Main).SetScreenFading(false); + x1c_flowState = EGameFlowState::InGame; + x18_guiManager->StartFadeIn(); + x28_skippedCineCam = kInvalidUniqueId; + break; + } + } + case EGameFlowState::InGame: + { + x14_stateManager->SetActiveRandomToDefault(); + switch (x14_stateManager->GetDeferredStateTransition()) + { + case EStateManagerTransition::InGame: + x14_stateManager->Update(dt); + if (!x14_stateManager->ShouldQuitGame()) + break; + //CGraphics::SetIsBeginSceneClearFb(); + break; + case EStateManagerTransition::MapScreen: + EnterMapScreen(); + break; + case EStateManagerTransition::PauseGame: + PauseGame(); + break; + case EStateManagerTransition::LogBook: + EnterLogBook(); + break; + case EStateManagerTransition::SaveGame: + SaveGame(); + break; + case EStateManagerTransition::MessageScreen: + EnterMessageScreen(x14_stateManager->GetHUDMessageTime()); + break; + } + + if (x2a_25_samusAlive && !x14_stateManager->GetPlayerState()->IsPlayerAlive()) + { + PlayerDied(); + } + x14_stateManager->ClearActiveRandom(); + break; + } + case EGameFlowState::Paused: + { + if (x18_guiManager->WasInGame() && x18_guiManager->IsInGame()) + { + x14_stateManager->SetInSaveUI(x18_guiManager->IsInSaveUI()); + UnpauseGame(); + if (x14_stateManager->GetPauseHUDMessage() != -1) + x14_stateManager->IncrementHUDMessageFrameCounter(); + } + break; + } + case EGameFlowState::SamusDied: + { + if (x14_stateManager->GetPlayer().IsPlayerDeadEnough()) + { + static_cast(*g_Main).SetFlowState(EFlowState::Four); + queue.Push(MakeMsg::CreateQuitGameplay(EArchMsgTarget::Game)); + } + else + { + x14_stateManager->SetActiveRandomToDefault(); + x14_stateManager->Update(dt); + x14_stateManager->ClearActiveRandom(); + } + } + default: break; + } + + x18_guiManager->Update(*x14_stateManager, dt, queue, IsCameraActiveFlow()); + if (!wasInitialized) + g_GameState->GetWorldTransitionManager()->EndTransition(); + + return EMessageReturn::Exit; + } + case EArchMsgType::UserInput: + { + if (!x2a_24_initialized) + break; + const CFinalInput& input = MakeMsg::GetParmUserInput(msg).x4_parm; + if (x1c_flowState == EGameFlowState::InGame) + { + if (input.ControllerIdx() == 0) + { + const CEntity* cam = x14_stateManager->GetCameraManager()->GetCurrentCamera(*x14_stateManager); + TCastToConstPtr cineCam = cam; + if (input.PStart()) + { + if (cineCam && x14_stateManager->GetSkipCinematicSpecialFunction() != kInvalidUniqueId) + { + CMidiManager::StopAll(); + x28_skippedCineCam = cineCam->GetUniqueId(); + x1c_flowState = EGameFlowState::CinematicSkip; + x20_cineSkipTime = 0.f; + } + else if (!cineCam) + { + x14_stateManager->DeferStateTransition(EStateManagerTransition::PauseGame); + } + } + else if (input.PZ() && !cineCam && x14_stateManager->CanShowMapScreen()) + { + x14_stateManager->DeferStateTransition(EStateManagerTransition::MapScreen); + } + } + + x14_stateManager->SetActiveRandomToDefault(); + x14_stateManager->ProcessInput(input); + x14_stateManager->ClearActiveRandom(); + } + x18_guiManager->ProcessControllerInput(*x14_stateManager, input, queue); + break; + } + case EArchMsgType::FrameEnd: + { + x14_stateManager->FrameEnd(); + if (x14_stateManager->ShouldQuitGame()) + queue.Push(MakeMsg::CreateQuitGameplay(EArchMsgTarget::Game)); + break; + } + case EArchMsgType::QuitGameplay: + return EMessageReturn::RemoveIOWin; + default: break; + } + return EMessageReturn::Normal; } +void CMFGame::Touch() +{ + x14_stateManager->TouchSky(); + x14_stateManager->TouchPlayerActor(); + + bool gunVisible = false; + bool ballVisible = false; + bool samusVisible = false; + CPlayer& player = x14_stateManager->GetPlayer(); + switch (player.GetMorphballTransitionState()) + { + case CPlayer::EPlayerMorphBallState::Unmorphed: + gunVisible = true; + break; + case CPlayer::EPlayerMorphBallState::Morphed: + ballVisible = true; + break; + case CPlayer::EPlayerMorphBallState::Morphing: + ballVisible = true; + samusVisible = true; + break; + case CPlayer::EPlayerMorphBallState::Unmorphing: + gunVisible = true; + samusVisible = true; + break; + } + + if (gunVisible) + player.GetPlayerGun()->TouchModel(*x14_stateManager); + if (samusVisible) + player.ModelData()->Touch(*x14_stateManager, 0); + if (ballVisible) + player.GetMorphBall()->TouchModel(*x14_stateManager); +} + void CMFGame::Draw() const { + if (!x2a_24_initialized) + return; + const_cast(*this).Touch(); + if (x18_guiManager->GetIsGameDraw()) + { + static_cast(*g_Main).SetGameFrameDrawn(); + x14_stateManager->PreRender(); + x14_stateManager->DrawWorld(); + x14_stateManager->GetPlayer().IsPlayerDeadEnough(); + } + + x18_guiManager->PreDraw(*x14_stateManager); + x18_guiManager->Draw(*x14_stateManager); + + if (x1c_flowState == EGameFlowState::CinematicSkip) + { + float c = std::min(1.f, 1.f - x20_cineSkipTime); + const_cast(m_fadeToBlack).draw(zeus::CColor{c, c, c, c}); + } +} + +void CMFGame::PlayerDied() +{ + x1c_flowState = EGameFlowState::SamusDied; + x2a_25_samusAlive = false; +} + +void CMFGame::UnpauseGame() +{ + x1c_flowState = EGameFlowState::InGame; + CSfxManager::SetChannel(CSfxManager::ESfxChannels::Game); + x14_stateManager->DeferStateTransition(EStateManagerTransition::InGame); +} + +void CMFGame::EnterMessageScreen(float time) +{ + x1c_flowState = EGameFlowState::Paused; + x18_guiManager->ShowPauseGameHudMessage(*x14_stateManager, x14_stateManager->GetPauseHUDMessage(), time); +} + +void CMFGame::SaveGame() +{ + x1c_flowState = EGameFlowState::Paused; + x18_guiManager->PauseGame(*x14_stateManager, EInGameGuiState::PauseSaveGame); +} + +void CMFGame::EnterLogBook() +{ + x1c_flowState = EGameFlowState::Paused; + x18_guiManager->PauseGame(*x14_stateManager, EInGameGuiState::PauseLogBook); +} + +void CMFGame::PauseGame() +{ + x1c_flowState = EGameFlowState::Paused; + x18_guiManager->PauseGame(*x14_stateManager, EInGameGuiState::PauseGame); +} + +void CMFGame::EnterMapScreen() +{ + x1c_flowState = EGameFlowState::Paused; + x18_guiManager->PauseGame(*x14_stateManager, EInGameGuiState::MapScreen); + x14_stateManager->SetInMapScreen(true); } CMFGameLoader::CMFGameLoader() : CMFGameLoaderBase("CMFGameLoader") @@ -150,7 +399,7 @@ CIOWin::EMessageReturn CMFGameLoader::OnMessage(const CArchitectureMessage& msg, x2c_25_transitionFinished = wtMgr->IsTransitionFinished(); return EMessageReturn::Exit; } - case EArchMsgType::FrameBegin: + case EArchMsgType::FrameEnd: { if (x2c_25_transitionFinished) { diff --git a/Runtime/MP1/CMFGame.hpp b/Runtime/MP1/CMFGame.hpp index 5b07d0f38..0b97975cb 100644 --- a/Runtime/MP1/CMFGame.hpp +++ b/Runtime/MP1/CMFGame.hpp @@ -3,6 +3,7 @@ #include "CMFGameBase.hpp" #include "CInGameGuiManager.hpp" +#include "Graphics/Shaders/CColoredQuadFilter.hpp" namespace urde { @@ -13,27 +14,52 @@ class CToken; namespace MP1 { +enum class EGameFlowState +{ + InGame = 0, + Paused, + SamusDied, + CinematicSkip +}; + class CMFGame : public CMFGameBase { std::shared_ptr x14_stateManager; std::shared_ptr x18_guiManager; - u32 x1c_ = 0; + EGameFlowState x1c_flowState = EGameFlowState::InGame; + float x20_cineSkipTime; u32 x24_ = 0; - TUniqueId x28_ = kInvalidUniqueId; + TUniqueId x28_skippedCineCam = kInvalidUniqueId; union { struct { - bool x2a_24_ : 1; - bool x2a_25_ : 1; + bool x2a_24_initialized : 1; + bool x2a_25_samusAlive : 1; }; u8 _dummy = 0; }; + + CColoredQuadFilter m_fadeToBlack = {CCameraFilterPass::EFilterType::Multiply}; + + bool IsCameraActiveFlow() const + { + return (x1c_flowState == EGameFlowState::InGame || x1c_flowState == EGameFlowState::SamusDied); + } + public: CMFGame(const std::weak_ptr& stateMgr, const std::weak_ptr& guiMgr, const CArchitectureQueue&); CIOWin::EMessageReturn OnMessage(const CArchitectureMessage& msg, CArchitectureQueue& queue); + void Touch(); void Draw() const; + void PlayerDied(); + void UnpauseGame(); + void EnterMessageScreen(float time); + void SaveGame(); + void EnterLogBook(); + void PauseGame(); + void EnterMapScreen(); }; class CMFGameLoader : public CMFGameLoaderBase diff --git a/Runtime/MP1/CMainFlow.cpp b/Runtime/MP1/CMainFlow.cpp index 2a08ad4b9..b1783bcd1 100644 --- a/Runtime/MP1/CMainFlow.cpp +++ b/Runtime/MP1/CMainFlow.cpp @@ -24,13 +24,13 @@ void CMainFlow::AdvanceGameState(CArchitectureQueue& queue) switch (x14_gameState) { case EClientFlowStates::Game: - CMainFlow::SetGameState(EClientFlowStates::GameExit, queue); + SetGameState(EClientFlowStates::GameExit, queue); break; case EClientFlowStates::PreFrontEnd: - CMainFlow::SetGameState(EClientFlowStates::FrontEnd, queue); + SetGameState(EClientFlowStates::FrontEnd, queue); break; case EClientFlowStates::FrontEnd: - CMainFlow::SetGameState(EClientFlowStates::Game, queue); + SetGameState(EClientFlowStates::Game, queue); break; case EClientFlowStates::GameExit: { @@ -40,7 +40,7 @@ void CMainFlow::AdvanceGameState(CArchitectureQueue& queue) main->SetX30(true); } case EClientFlowStates::Unspecified: - CMainFlow::SetGameState(EClientFlowStates::PreFrontEnd, queue); + SetGameState(EClientFlowStates::PreFrontEnd, queue); break; } } diff --git a/Runtime/MP1/CMakeLists.txt b/Runtime/MP1/CMakeLists.txt index be3a29018..0cdb35ad8 100644 --- a/Runtime/MP1/CMakeLists.txt +++ b/Runtime/MP1/CMakeLists.txt @@ -33,6 +33,7 @@ set(MP1_SOURCES CSamusHud.hpp CSamusHud.cpp CPauseScreen.hpp CPauseScreen.cpp CFaceplateDecoration.hpp CFaceplateDecoration.cpp + CInventoryScreen.hpp CInventoryScreen.cpp MP1.hpp MP1.cpp ${MP1_PLAT_SOURCES} ${MP1_WORLD_SOURCES}) diff --git a/Runtime/MP1/CMessageScreen.cpp b/Runtime/MP1/CMessageScreen.cpp index e69de29bb..e0f40c905 100644 --- a/Runtime/MP1/CMessageScreen.cpp +++ b/Runtime/MP1/CMessageScreen.cpp @@ -0,0 +1,14 @@ +#include "CMessageScreen.hpp" + +namespace urde +{ +namespace MP1 +{ + +CMessageScreen::CMessageScreen(ResId msg, float time) +{ + +} + +} +} diff --git a/Runtime/MP1/CMessageScreen.hpp b/Runtime/MP1/CMessageScreen.hpp index 00acdab7f..62eba8918 100644 --- a/Runtime/MP1/CMessageScreen.hpp +++ b/Runtime/MP1/CMessageScreen.hpp @@ -1,6 +1,8 @@ #ifndef __URDE_CMESSAGESCREEN_HPP__ #define __URDE_CMESSAGESCREEN_HPP__ +#include "RetroTypes.hpp" + namespace urde { namespace MP1 @@ -9,7 +11,7 @@ namespace MP1 class CMessageScreen { public: - CMessageScreen(); + CMessageScreen(ResId msg, float time); }; } diff --git a/Runtime/MP1/CPauseScreen.cpp b/Runtime/MP1/CPauseScreen.cpp index fe3f15d54..2d05850db 100644 --- a/Runtime/MP1/CPauseScreen.cpp +++ b/Runtime/MP1/CPauseScreen.cpp @@ -15,5 +15,10 @@ bool CPauseScreen::CheckLoadComplete() return false; } +void CPauseScreen::OnNewInGameGuiState(EInGameGuiState state, CStateManager& stateMgr) +{ + +} + } } diff --git a/Runtime/MP1/CPauseScreen.hpp b/Runtime/MP1/CPauseScreen.hpp index e46623876..dc46ecd19 100644 --- a/Runtime/MP1/CPauseScreen.hpp +++ b/Runtime/MP1/CPauseScreen.hpp @@ -1,6 +1,8 @@ #ifndef __URDE_CPAUSESCREEN_HPP__ #define __URDE_CPAUSESCREEN_HPP__ +#include "CInGameGuiManager.hpp" + namespace urde { namespace MP1 @@ -8,9 +10,20 @@ namespace MP1 class CPauseScreen { + union + { + struct + { + bool x50_24_ : 1; + bool x50_25_ : 1; + }; + u32 _dummy = 0; + }; public: CPauseScreen(); bool CheckLoadComplete(); + void OnNewInGameGuiState(EInGameGuiState state, CStateManager& stateMgr); + bool GetX50_25() const { return x50_25_; } }; } diff --git a/Runtime/MP1/CSamusHud.cpp b/Runtime/MP1/CSamusHud.cpp index 263964d60..8ccf7b3ac 100644 --- a/Runtime/MP1/CSamusHud.cpp +++ b/Runtime/MP1/CSamusHud.cpp @@ -15,6 +15,11 @@ bool CSamusHud::CheckLoadComplete(CStateManager& stateMgr) return false; } +void CSamusHud::OnNewInGameGuiState(EInGameGuiState state, CStateManager& stateMgr) +{ + +} + void CSamusHud::Touch() { diff --git a/Runtime/MP1/CSamusHud.hpp b/Runtime/MP1/CSamusHud.hpp index e52123972..3e9ecaeb2 100644 --- a/Runtime/MP1/CSamusHud.hpp +++ b/Runtime/MP1/CSamusHud.hpp @@ -1,6 +1,8 @@ #ifndef __URDE_CSAMUSHUD_HPP__ #define __URDE_CSAMUSHUD_HPP__ +#include "CInGameGuiManager.hpp" + namespace urde { class CGuiFrame; @@ -16,6 +18,7 @@ class CSamusHud public: CSamusHud(CStateManager& stateMgr); bool CheckLoadComplete(CStateManager& stateMgr); + void OnNewInGameGuiState(EInGameGuiState state, CStateManager& stateMgr); void Touch(); }; diff --git a/Runtime/MP1/MP1.cpp b/Runtime/MP1/MP1.cpp index 0414ceb63..b17d0eb6e 100644 --- a/Runtime/MP1/MP1.cpp +++ b/Runtime/MP1/MP1.cpp @@ -42,6 +42,7 @@ CGameArchitectureSupport::CGameArchitectureSupport(CMain& parent, g_GuiSys = &x44_guiSys; x30_inputGenerator.startScanning(); + g_InputGenerator = &x30_inputGenerator; CAudioSys::SysSetVolume(0x7f); CAudioSys::SetDefaultVolumeScale(0x75); @@ -68,6 +69,7 @@ CGameArchitectureSupport::CGameArchitectureSupport(CMain& parent, void CGameArchitectureSupport::UpdateTicks() { + x4_archQueue.Push(MakeMsg::CreateFrameBegin(EArchMsgTarget::Game, x78_gameFrameCount)); x4_archQueue.Push(MakeMsg::CreateTimerTick(EArchMsgTarget::Game, 1.f / 60.f)); } @@ -75,7 +77,7 @@ void CGameArchitectureSupport::Update() { g_GameState->GetWorldTransitionManager()->TouchModels(); x30_inputGenerator.Update(1 / 60.f, x4_archQueue); - x4_archQueue.Push(MakeMsg::CreateFrameBegin(EArchMsgTarget::Game, x78_)); + x4_archQueue.Push(MakeMsg::CreateFrameEnd(EArchMsgTarget::Game, x78_gameFrameCount)); x58_ioWinManager.PumpMessages(x4_archQueue); } @@ -171,6 +173,11 @@ void CGameArchitectureSupport::UnloadAudio() void CGameArchitectureSupport::Draw() { x58_ioWinManager.Draw(); + if (m_parent.x161_24_gameFrameDrawn) + { + ++x78_gameFrameCount; + m_parent.x161_24_gameFrameDrawn = false; + } } CGameArchitectureSupport::~CGameArchitectureSupport() diff --git a/Runtime/MP1/MP1.hpp b/Runtime/MP1/MP1.hpp index c49691149..83c06f1ff 100644 --- a/Runtime/MP1/MP1.hpp +++ b/Runtime/MP1/MP1.hpp @@ -111,7 +111,7 @@ class CGameArchitectureSupport CInputGenerator x30_inputGenerator; CGuiSys x44_guiSys; CIOWinManager x58_ioWinManager; - s32 x78_; + s32 x78_gameFrameCount; enum class EAudioLoadStatus { @@ -222,14 +222,14 @@ private: struct { bool x160_24_finished : 1; - bool x160_25_ : 1; - bool x160_26_ : 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_ : 1; + bool x161_24_gameFrameDrawn : 1; }; u16 _dummy = 0; }; @@ -249,6 +249,8 @@ public: void ResetGameState(); void StreamNewGameState(CBitStreamReader&, u32 idx); void CheckTweakManagerDebugOptions() {} + void SetMFGameBuilt(bool b) { x160_25_mfGameBuilt = b; } + void SetScreenFading(bool b) { x160_26_screenFading = b; } //int RsMain(int argc, const boo::SystemChar* argv[]); void Init(const hecl::Runtime::FileStoreManager& storeMgr, @@ -287,6 +289,7 @@ public: 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; } EFlowState GetFlowState() const { return x12c_flowState; } void SetFlowState(EFlowState s) { x12c_flowState = s; } diff --git a/Runtime/Weapon/CPlayerGun.cpp b/Runtime/Weapon/CPlayerGun.cpp index 33c76df29..7a3b052dc 100644 --- a/Runtime/Weapon/CPlayerGun.cpp +++ b/Runtime/Weapon/CPlayerGun.cpp @@ -30,4 +30,9 @@ void CPlayerGun::AsyncLoadSuit(CStateManager& mgr) x740_grappleArm->AsyncLoadSuit(mgr); } +void CPlayerGun::TouchModel(CStateManager& stateMgr) +{ + +} + } diff --git a/Runtime/Weapon/CPlayerGun.hpp b/Runtime/Weapon/CPlayerGun.hpp index 4815a608f..5b10804d9 100644 --- a/Runtime/Weapon/CPlayerGun.hpp +++ b/Runtime/Weapon/CPlayerGun.hpp @@ -61,7 +61,7 @@ class CPlayerGun u32 x2fc_ = 0; u32 x300_ = 0; u32 x304_ = 0; - u32 x308_ = 3; + u32 x308_bombCount = 3; u32 x30c_ = 0; u32 x310_ = 0; u32 x314_ = 0; @@ -75,14 +75,14 @@ class CPlayerGun u32 x334_ = 0; u32 x338_ = 0; u32 x33c_ = 0; - float x340_ = 0.f; + float x340_chargeTime = 0.f; float x344_ = 0.f; float x348_ = 0.f; float x34c_ = 0.f; float x350_ = 0.f; float x354_; float x358_; - float x35c_ = 0.f; + float x35c_bombTime = 0.f; float x360_ = 0.f; float x364_ = 0.f; float x368_ = 0.f; @@ -200,6 +200,7 @@ public: CPlayerGun(TUniqueId id); void AsyncLoadSuit(CStateManager& mgr); + void TouchModel(CStateManager& stateMgr); }; } diff --git a/Runtime/World/CGameArea.cpp b/Runtime/World/CGameArea.cpp index 594f47fe2..5643bb713 100644 --- a/Runtime/World/CGameArea.cpp +++ b/Runtime/World/CGameArea.cpp @@ -441,6 +441,19 @@ const zeus::CTransform& CGameArea::IGetTM() const return xc_transform; } +void CGameArea::SetPauseState(bool paused) +{ + if (xf0_26_tokensReady) + return; + xf0_27_paused = paused; + if (!paused) + return; + + for (CToken& tok : xdc_tokens) + if (!tok.IsLoaded()) + tok.Unlock(); +} + void CGameArea::SetXRaySpeedAndTarget(float f1, float f2) { x12c_postConstructed->x112c_xraySpeed = f1; diff --git a/Runtime/World/CGameArea.hpp b/Runtime/World/CGameArea.hpp index 089f4ee1e..99b386de2 100644 --- a/Runtime/World/CGameArea.hpp +++ b/Runtime/World/CGameArea.hpp @@ -104,7 +104,7 @@ class CGameArea : public IGameArea bool xf0_24_postConstructed : 1; bool xf0_25_active : 1; bool xf0_26_tokensReady : 1; - bool xf0_27_ : 1; + bool xf0_27_paused : 1; bool xf0_28_ : 1; }; u8 _dummy = 0; @@ -261,6 +261,7 @@ public: bool IsFinishedOccluding() const; void ReadDependencyList(); + void SetPauseState(bool paused); bool IGetScriptingMemoryAlways() const; TAreaId IGetAreaId() const; diff --git a/Runtime/World/CMorphBall.hpp b/Runtime/World/CMorphBall.hpp index d779f38f2..436cb412c 100644 --- a/Runtime/World/CMorphBall.hpp +++ b/Runtime/World/CMorphBall.hpp @@ -30,6 +30,7 @@ public: }; private: CPlayer& x0_player; + float x1DE8_boostTime = 0.f; public: CMorphBall(CPlayer& player, float); diff --git a/Runtime/World/CPlayer.cpp b/Runtime/World/CPlayer.cpp index 517ea23db..e049a9055 100644 --- a/Runtime/World/CPlayer.cpp +++ b/Runtime/World/CPlayer.cpp @@ -312,6 +312,17 @@ float CPlayer::GetWeight() const { return 0.f; } float CPlayer::GetDampedClampedVelocityWR() const { return 0.f; } +void CPlayer::UpdateCinematicState(CStateManager& mgr) +{ + if (mgr.GetCameraManager()->IsInCinematicCamera()) + { + switch (x2f4_cameraState) + { + + } + } +} + void CPlayer::Touch() {} void CPlayer::CVisorSteam::SetSteam(float a, float b, float c, ResId d, bool e) diff --git a/Runtime/World/CPlayer.hpp b/Runtime/World/CPlayer.hpp index 57bfb07f7..34efb63c8 100644 --- a/Runtime/World/CPlayer.hpp +++ b/Runtime/World/CPlayer.hpp @@ -79,12 +79,12 @@ private: }; zeus::CVector3f x1b4_; TUniqueId x1c4_ = kInvalidUniqueId; - // std::vector<> x258_; + u32 x258_jumpState = 0; TUniqueId x26c_ = kInvalidUniqueId; float x270_ = 0.f; CPlayerEnergyDrain x274_ = CPlayerEnergyDrain(4); float x288_ = 0.f; - float x28c_ = 0.f; + float x28c_sjTimer = 0.f; float x290_ = 0.f; float x294_ = 0.f; u32 x298_ = 0; @@ -410,6 +410,9 @@ public: float GetDampedClampedVelocityWR() const; const CVisorSteam& GetVisorSteam() const { return x7a0_visorSteam; } float Get74C() const { return x74c_; } + void UpdateCinematicState(CStateManager& mgr); + CPlayerGun* GetPlayerGun() const { return x490_gun.get(); } + CMorphBall* GetMorphBall() const { return x768_morphball.get(); } void Touch(); const std::unique_ptr& GetCameraBob() const { return x76c_cameraBob; } diff --git a/Runtime/World/CScriptSpecialFunction.cpp b/Runtime/World/CScriptSpecialFunction.cpp index 3cffd215e..54cf10a44 100644 --- a/Runtime/World/CScriptSpecialFunction.cpp +++ b/Runtime/World/CScriptSpecialFunction.cpp @@ -3,6 +3,9 @@ #include "CActorParameters.hpp" #include "Audio/CSfxManager.hpp" #include "TCastTo.hpp" +#include "GameGlobalObjects.hpp" +#include "CGameState.hpp" +#include "CStateManager.hpp" namespace urde { @@ -65,4 +68,16 @@ void CScriptSpecialFunction::Render(const CStateManager &) const { } + +void CScriptSpecialFunction::SkipCinematic(CStateManager& stateMgr) +{ + SendScriptMsgs(EScriptObjectState::Zero, stateMgr, EScriptObjectMessage::None); + stateMgr.SetSkipCinematicSpecialFunction(kInvalidUniqueId); +} + +bool CScriptSpecialFunction::ShouldSkipCinematic(CStateManager& stateMgr) const +{ + return g_GameState->SystemOptions().GetCinematicState(stateMgr.GetWorld()->IGetWorldAssetId(), GetEditorId()); +} + } diff --git a/Runtime/World/CScriptSpecialFunction.hpp b/Runtime/World/CScriptSpecialFunction.hpp index 7a31f884d..1ca56c45f 100644 --- a/Runtime/World/CScriptSpecialFunction.hpp +++ b/Runtime/World/CScriptSpecialFunction.hpp @@ -130,6 +130,8 @@ public: void ThinkSpinnerController(float, CStateManager&, ESpinnerControllerMode); void ThinkObjectFollowLocator(float, CStateManager&); void ThinkChaffTarget(float, CStateManager&); + + bool ShouldSkipCinematic(CStateManager& stateMgr) const; }; } diff --git a/Runtime/World/CWorld.cpp b/Runtime/World/CWorld.cpp index 145f37a68..768a5c41e 100644 --- a/Runtime/World/CWorld.cpp +++ b/Runtime/World/CWorld.cpp @@ -506,12 +506,19 @@ void CWorld::TravelToArea(TAreaId aid, CStateManager& mgr, bool skipLoadOther) ++toStreamCount; } - if (!toStreamCount && otherLoadArea && !x70_25_) + if (!toStreamCount && otherLoadArea && !x70_25_paused) otherLoadArea->StartStreamIn(mgr); GetMapWorld()->SetWhichMapAreasLoaded(*this, aid, 3); } +void CWorld::SetPauseState(bool paused) +{ + for (CGameArea* headArea = x4c_chainHeads[2] ; headArea != skGlobalEnd ; headArea = headArea->x130_next) + headArea->SetPauseState(paused); + x70_25_paused = paused; +} + bool CWorld::ICheckWorldComplete() { return CheckWorldComplete(nullptr, kInvalidAreaId, -1); } std::string CWorld::IGetDefaultAudioTrack() const { return x84_defAudioTrack; } diff --git a/Runtime/World/CWorld.hpp b/Runtime/World/CWorld.hpp index 9dbd3aaaa..29a5027b6 100644 --- a/Runtime/World/CWorld.hpp +++ b/Runtime/World/CWorld.hpp @@ -135,7 +135,7 @@ private: struct { bool x70_24_ : 1; - bool x70_25_ : 1; + bool x70_25_paused : 1; bool x70_26_ : 1; bool x70_27_ : 1; }; @@ -155,6 +155,7 @@ public: bool CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId); bool ScheduleAreaToLoad(CGameArea* area, CStateManager& mgr); void TravelToArea(TAreaId aid, CStateManager& mgr, bool); + void SetPauseState(bool paused); CWorld(IObjectStore& objStore, IFactory& resFactory, ResId mlvlId); bool DoesAreaExist(TAreaId area) const;