From eccf5623106fa26d089504d424453e9656e45672 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Wed, 9 Nov 2022 22:50:18 -0800 Subject: [PATCH] More CCameraManager Former-commit-id: 27e713a50518e6e6a2c5211078a4e4c77536da36 --- asm/MetroidPrime/Cameras/CCameraManager.s | 12 +- .../Cameras/CInterpolationCamera.s | 2 +- asm/MetroidPrime/Player/CPlayer.s | 6 +- include/Kyoto/Audio/CSfxManager.hpp | 1 + include/MetroidPrime/CStateManager.hpp | 3 +- .../MetroidPrime/Cameras/CCameraManager.hpp | 38 +++++- .../MetroidPrime/Cameras/CCameraShakeData.hpp | 6 + include/MetroidPrime/Cameras/CGameCamera.hpp | 1 + include/rstl/list.hpp | 9 +- src/MetroidPrime/Cameras/CCameraManager.cpp | 120 ++++++++++++++++++ 10 files changed, 179 insertions(+), 19 deletions(-) diff --git a/asm/MetroidPrime/Cameras/CCameraManager.s b/asm/MetroidPrime/Cameras/CCameraManager.s index d06e2133..6e6a9da6 100644 --- a/asm/MetroidPrime/Cameras/CCameraManager.s +++ b/asm/MetroidPrime/Cameras/CCameraManager.s @@ -1697,7 +1697,7 @@ SkipBallCameraCinematic__14CCameraManagerFR13CStateManager: /* 8000A738 00007698 A0 05 00 08 */ lhz r0, 8(r5) /* 8000A73C 0000769C B0 01 00 08 */ sth r0, 8(r1) /* 8000A740 000076A0 B0 01 00 0C */ sth r0, 0xc(r1) -/* 8000A744 000076A4 48 00 13 81 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager +/* 8000A744 000076A4 48 00 13 81 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueId lbl_8000A748: /* 8000A748 000076A8 E3 E1 00 28 */ psq_l f31, 40(r1), 0, qr0 /* 8000A74C 000076AC 80 01 00 34 */ lwz r0, 0x34(r1) @@ -1757,7 +1757,7 @@ InterpolateToBallCamera__14CCameraManagerFRC12CTransform4f9TUniqueIdRC9CVector3f /* 8000A818 00007778 A0 05 00 08 */ lhz r0, 8(r5) /* 8000A81C 0000777C B0 01 00 08 */ sth r0, 8(r1) /* 8000A820 00007780 B0 01 00 0C */ sth r0, 0xc(r1) -/* 8000A824 00007784 48 00 12 A1 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager +/* 8000A824 00007784 48 00 12 A1 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueId lbl_8000A828: /* 8000A828 00007788 CB E1 00 48 */ lfd f31, 0x48(r1) /* 8000A82C 0000778C CB C1 00 40 */ lfd f30, 0x40(r1) @@ -1796,7 +1796,7 @@ SetPlayerCamera__14CCameraManagerFR13CStateManager9TUniqueId: /* 8000A8A4 00007804 7F C3 F3 78 */ mr r3, r30 /* 8000A8A8 00007808 38 81 00 08 */ addi r4, r1, 8 /* 8000A8AC 0000780C B0 01 00 08 */ sth r0, 8(r1) -/* 8000A8B0 00007810 48 00 12 15 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager +/* 8000A8B0 00007810 48 00 12 15 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueId lbl_8000A8B4: /* 8000A8B4 00007814 80 01 00 24 */ lwz r0, 0x24(r1) /* 8000A8B8 00007818 83 E1 00 1C */ lwz r31, 0x1c(r1) @@ -3104,8 +3104,8 @@ UpdateSfxListener__14CCameraManagerFR13CStateManager: /* 8000BABC 00008A1C 38 21 00 90 */ addi r1, r1, 0x90 /* 8000BAC0 00008A20 4E 80 00 20 */ blr -.global SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager -SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager: +.global SetCurrentCameraId__14CCameraManagerF9TUniqueId +SetCurrentCameraId__14CCameraManagerF9TUniqueId: /* 8000BAC4 00008A24 A0 04 00 00 */ lhz r0, 0(r4) /* 8000BAC8 00008A28 B0 03 00 00 */ sth r0, 0(r3) /* 8000BACC 00008A2C 4E 80 00 20 */ blr @@ -3455,7 +3455,7 @@ lbl_8000BF60: /* 8000BF84 00008EE4 7F C3 F3 78 */ mr r3, r30 /* 8000BF88 00008EE8 38 81 00 1C */ addi r4, r1, 0x1c /* 8000BF8C 00008EEC B0 01 00 1C */ sth r0, 0x1c(r1) -/* 8000BF90 00008EF0 4B FF FB 35 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager +/* 8000BF90 00008EF0 4B FF FB 35 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueId /* 8000BF94 00008EF4 7F E4 FB 78 */ mr r4, r31 /* 8000BF98 00008EF8 38 61 00 18 */ addi r3, r1, 0x18 /* 8000BF9C 00008EFC 48 04 11 41 */ bl AllocateUniqueId__13CStateManagerFv diff --git a/asm/MetroidPrime/Cameras/CInterpolationCamera.s b/asm/MetroidPrime/Cameras/CInterpolationCamera.s index 1427e723..412599a5 100644 --- a/asm/MetroidPrime/Cameras/CInterpolationCamera.s +++ b/asm/MetroidPrime/Cameras/CInterpolationCamera.s @@ -298,7 +298,7 @@ sub_80265314: /* 80265358 002622B8 38 81 00 08 */ addi r4, r1, 8 /* 8026535C 002622BC B0 01 00 08 */ sth r0, 8(r1) /* 80265360 002622C0 80 7F 08 70 */ lwz r3, 0x870(r31) -/* 80265364 002622C4 4B DA 67 61 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager +/* 80265364 002622C4 4B DA 67 61 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueId lbl_80265368: /* 80265368 002622C8 80 01 00 24 */ lwz r0, 0x24(r1) /* 8026536C 002622CC 83 E1 00 1C */ lwz r31, 0x1c(r1) diff --git a/asm/MetroidPrime/Player/CPlayer.s b/asm/MetroidPrime/Player/CPlayer.s index 0620d0f0..6acaffb9 100644 --- a/asm/MetroidPrime/Player/CPlayer.s +++ b/asm/MetroidPrime/Player/CPlayer.s @@ -9003,7 +9003,7 @@ lbl_800172FC: /* 80017304 00014264 A0 05 00 08 */ lhz r0, 8(r5) /* 80017308 00014268 B0 01 00 18 */ sth r0, 0x18(r1) /* 8001730C 0001426C B0 01 00 1C */ sth r0, 0x1c(r1) -/* 80017310 00014270 4B FF 47 B5 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager +/* 80017310 00014270 4B FF 47 B5 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueId /* 80017314 00014274 80 7E 07 68 */ lwz r3, 0x768(r30) /* 80017318 00014278 7F E4 FB 78 */ mr r4, r31 /* 8001731C 0001427C 38 A0 00 00 */ li r5, 0 @@ -9015,7 +9015,7 @@ lbl_80017328: /* 80017330 00014290 A0 05 00 08 */ lhz r0, 8(r5) /* 80017334 00014294 B0 01 00 10 */ sth r0, 0x10(r1) /* 80017338 00014298 B0 01 00 14 */ sth r0, 0x14(r1) -/* 8001733C 0001429C 4B FF 47 89 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager +/* 8001733C 0001429C 4B FF 47 89 */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueId /* 80017340 000142A0 80 7E 07 68 */ lwz r3, 0x768(r30) /* 80017344 000142A4 7F E4 FB 78 */ mr r4, r31 /* 80017348 000142A8 38 A0 00 01 */ li r5, 1 @@ -9027,7 +9027,7 @@ lbl_80017354: /* 8001735C 000142BC A0 05 00 08 */ lhz r0, 8(r5) /* 80017360 000142C0 B0 01 00 08 */ sth r0, 8(r1) /* 80017364 000142C4 B0 01 00 0C */ sth r0, 0xc(r1) -/* 80017368 000142C8 4B FF 47 5D */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueIdR13CStateManager +/* 80017368 000142C8 4B FF 47 5D */ bl SetCurrentCameraId__14CCameraManagerF9TUniqueId /* 8001736C 000142CC 80 7E 07 68 */ lwz r3, 0x768(r30) /* 80017370 000142D0 7F E4 FB 78 */ mr r4, r31 /* 80017374 000142D4 38 A0 00 01 */ li r5, 1 diff --git a/include/Kyoto/Audio/CSfxManager.hpp b/include/Kyoto/Audio/CSfxManager.hpp index 55b5c14a..a5e5873c 100644 --- a/include/Kyoto/Audio/CSfxManager.hpp +++ b/include/Kyoto/Audio/CSfxManager.hpp @@ -74,6 +74,7 @@ public: static void RemoveEmitter(CSfxHandle handle); static void UpdateEmitter(CSfxHandle handle, const CVector3f& pos, const CVector3f& dir, uchar maxVol); + static void UpdateListener(const CVector3f& pos, const CVector3f& dir, const CVector3f&, const CVector3f&, const uchar); static const short kMaxPriority; // 0xFF static const short kMedPriority; // 0x7F diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index 9d2fd5a6..21ef5b67 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -163,7 +163,8 @@ public: CRandom16* Random() const { return x900_random; } - CObjectList& GetObjectListById(EGameObjectList id) { return *x808_objectLists[id]; } + CObjectList& ObjectListById(EGameObjectList id) { return *x808_objectLists[id]; } + const CObjectList& GetObjectListById(EGameObjectList id) const { return *x808_objectLists[id]; } const CFinalInput& GetFinalInput() const { return xb54_finalInput; } diff --git a/include/MetroidPrime/Cameras/CCameraManager.hpp b/include/MetroidPrime/Cameras/CCameraManager.hpp index 16fece1b..48b46350 100644 --- a/include/MetroidPrime/Cameras/CCameraManager.hpp +++ b/include/MetroidPrime/Cameras/CCameraManager.hpp @@ -21,6 +21,9 @@ class CGameCamera; class CInterpolationCamera; class CStateManager; +#ifdef __MWERKS__ +#pragma cpp_extensions on +#endif class CCameraManager { static float sFirstPersonFOV; static float sThirdPersonFOV; @@ -33,15 +36,29 @@ public: CCameraManager(TUniqueId curCamera); void CreateStandardCameras(CStateManager& mgr); - - CGameCamera& CurrentCamera(CStateManager& mgr) const; + void ThinkCameras(float dt, CStateManager& mgr); + void ResetCameras(CStateManager& mgr); + void RenderCameras(const CStateManager& mgr); + TUniqueId GetCurrentCameraId() const; + + CGameCamera& CurrentCamera(CStateManager& mgr); const CGameCamera& GetCurrentCamera(const CStateManager& mgr) const; + const CGameCamera& GetLastCineCamera(CStateManager& mgr) const; + TUniqueId GetLastCineCameraId() const; + + void SetCurrentCameraId(TUniqueId camId); + + void UpdateSfxListener(CStateManager& mgr); + void UpdateRumble(float dt, CStateManager& mgr); + CFirstPersonCamera* FirstPersonCamera() const /* map */ { return x7c_fpCamera; } const CFirstPersonCamera* GetFirstPersonCamera() const { return x7c_fpCamera; } - void SetCurrentCameraId(TUniqueId camId); + + CTransform4f GetCurrentCameraTransform(const CStateManager& mgr) const; void SetPlayerCamera(CStateManager& mgr, TUniqueId newCamId); void SetFogDensity(float fogDensityTarget, float fogDensitySpeed); bool IsInCinematicCamera() const; + void RemoveCameraShaker(int id); int AddCameraShaker(const CCameraShakeData& data, bool sfx); @@ -74,9 +91,15 @@ private: float x94_fogDensityFactor; float x98_fogDensitySpeed; float x9c_fogDensityFactorTarget; - bool xa0_24_pendingRumble : 1; - bool xa0_25_rumbling : 1; - bool xa0_26_inWater : 1; + union { + struct { + bool xa0_24_pendingRumble : 1; + bool xa0_25_rumbling : 1; + bool xa0_26_inWater : 1; + }; + uchar xa0_flags; + }; + TUniqueId xa2_spindleCamId; TUniqueId xa4_pathCamId; TUniqueId xa6_camHintId; @@ -90,4 +113,7 @@ private: }; CHECK_SIZEOF(CCameraManager, 0x3c0) +#ifdef __MWERKS +#pragma cpp_extensions reset +#endif #endif // _CCAMERAMANAGER diff --git a/include/MetroidPrime/Cameras/CCameraShakeData.hpp b/include/MetroidPrime/Cameras/CCameraShakeData.hpp index 350cf6ae..48d5f899 100644 --- a/include/MetroidPrime/Cameras/CCameraShakeData.hpp +++ b/include/MetroidPrime/Cameras/CCameraShakeData.hpp @@ -27,11 +27,17 @@ private: }; CHECK_SIZEOF(CCameraShakerComponent, 0x3c) +class CStateManager; class CCameraShakeData { public: CCameraShakeData(const CCameraShakeData&); void SetShakerId(int id) { xbc_shakerId = id; } int GetShakerId() const { return xbc_shakerId; } + void Update(float dt, CStateManager& mgr); + + float GetDuration() const { return x0_duration; } + float GetCurTime() const { return x4_curTime; } + const CVector3f& GetPoint() const;// { return xc4_sfxPos; } private: float x0_duration; diff --git a/include/MetroidPrime/Cameras/CGameCamera.hpp b/include/MetroidPrime/Cameras/CGameCamera.hpp index 876f2690..64eed4dd 100644 --- a/include/MetroidPrime/Cameras/CGameCamera.hpp +++ b/include/MetroidPrime/Cameras/CGameCamera.hpp @@ -30,6 +30,7 @@ public: float GetFov() const { return x15c_currentFov; } void SetFov(float fov) { x15c_currentFov = fov; } void SetFovInterpolation(float start, float fov, float time, float delayTime); + void UpdatePerspective(float dt); private: TUniqueId xe8_watchedObject; diff --git a/include/rstl/list.hpp b/include/rstl/list.hpp index d12c79dd..67698992 100644 --- a/include/rstl/list.hpp +++ b/include/rstl/list.hpp @@ -40,16 +40,21 @@ public: erase(begin(), end()); } + size_t size() const { return x14_count; } + bool empty() const { return x14_count == 0; } + iterator begin() { return iterator(x4_start); } const_iterator begin() const { return const_iterator(x4_start); } iterator end() { return iterator(x8_end); } const_iterator end() const { return const_iterator(x8_end); } - void erase(const iterator& start, const iterator& end) { + iterator erase(const iterator& start, const iterator& end) { iterator it = start; while (it != end) { erase(it++); } + + return it; } private: @@ -152,7 +157,7 @@ private: node* x8_end; node* xc_empty_prev; node* x10_empty_next; - uint x14_count; + int x14_count; }; } // namespace rstl diff --git a/src/MetroidPrime/Cameras/CCameraManager.cpp b/src/MetroidPrime/Cameras/CCameraManager.cpp index edce7acd..6aaaeec7 100644 --- a/src/MetroidPrime/Cameras/CCameraManager.cpp +++ b/src/MetroidPrime/Cameras/CCameraManager.cpp @@ -4,6 +4,8 @@ #include "MetroidPrime/Cameras/CFirstPersonCamera.hpp" #include "MetroidPrime/Cameras/CInterpolationCamera.hpp" +#include "MetroidPrime/CRumbleManager.hpp" + #include "MetroidPrime/Player/CPlayer.hpp" #include "MetroidPrime/Tweaks/CTweakGame.hpp" @@ -83,3 +85,121 @@ void CCameraManager::CreateStandardCameras(CStateManager& mgr) { x88_interpCamera = new CInterpolationCamera(interpId, xf); mgr.AddObject(x88_interpCamera); } + +void CCameraManager::ThinkCameras(float dt, CStateManager& mgr) { + CObjectList& objList = mgr.ObjectListById(kOL_GameCamera); + int idx = objList.GetFirstObjectIndex(); + + while (idx != -1) { + CGameCamera* gc = static_cast< CGameCamera* >(objList[idx]); + if (gc != nullptr) { + gc->Think(dt, mgr); + gc->UpdatePerspective(dt); + } + idx = objList.GetNextObjectIndex(idx); + } + + if (!IsInCinematicCamera()) { + return; + } + + if (const CGameCamera* cam = + TCastToConstPtr< CGameCamera >(mgr.GetObjectById(GetLastCineCameraId()))) { + x3bc_curFov = cam->GetFov(); + } +} + +void CCameraManager::ResetCameras(CStateManager& mgr) { + CObjectList& objList = mgr.ObjectListById(kOL_GameCamera); + + CTransform4f xf = mgr.GetPlayer()->CreateTransformFromMovementDirection(); + xf.SetTranslation(mgr.GetPlayer()->GetEyePosition()); + + int idx = objList.GetFirstObjectIndex(); + + while (idx != -1) { + CGameCamera* gc = static_cast< CGameCamera* >(objList[idx]); + if (gc != nullptr) { + gc->Reset(xf, mgr); + } + idx = objList.GetNextObjectIndex(idx); + } +} + +void CCameraManager::RenderCameras(const CStateManager& mgr) { + const CObjectList& objList = mgr.GetObjectListById(kOL_GameCamera); + int idx = objList.GetFirstObjectIndex(); + + while (idx != -1) { + static_cast< const CGameCamera* >(objList[idx])->Render(mgr); + idx = objList.GetNextObjectIndex(idx); + } +} + +TUniqueId CCameraManager::GetCurrentCameraId() const { + if (x4_cineCameras.empty()) { + return x0_curCameraId; + } + + return x4_cineCameras.back(); +} + +TUniqueId CCameraManager::GetLastCineCameraId() const { + if (x4_cineCameras.empty()) { + return kInvalidUniqueId; + } + + return x4_cineCameras.back(); +} + +CGameCamera& CCameraManager::CurrentCamera(CStateManager& mgr) { + return *static_cast< CGameCamera* >(mgr.ObjectById(GetCurrentCameraId())); +} + +const CGameCamera& CCameraManager::GetCurrentCamera(const CStateManager& mgr) const { + return *static_cast< const CGameCamera* >(mgr.GetObjectById(GetCurrentCameraId())); +} + +const CGameCamera& CCameraManager::GetLastCineCamera(CStateManager& mgr) const { + return *static_cast< const CGameCamera* >(mgr.GetObjectById(GetLastCineCameraId())); +} + +void CCameraManager::SetCurrentCameraId(TUniqueId uid) { x0_curCameraId = uid; } + +void CCameraManager::UpdateSfxListener(CStateManager& mgr) { + CTransform4f xf = GetCurrentCameraTransform(mgr); + + CSfxManager::UpdateListener(xf.GetTranslation(), CVector3f::Zero(), xf.GetColumn(kDY), + xf.GetColumn(kDZ), CAudioSys::kMaxVolume); +} + +void CCameraManager::UpdateRumble(float dt, CStateManager& mgr) { + x30_shakeOffset = CVector3f::Zero(); + rstl::list< CCameraShakeData >::iterator it = x14_shakers.begin(); + + while (it != x14_shakers.end()) { + (*it).Update(dt, mgr); + if ((*it).GetCurTime() >= (*it).GetDuration()) { + x14_shakers.erase(it); + ++it; + continue; + } + x30_shakeOffset += (*it).GetPoint(); + ++it; + } + + if (!x14_shakers.empty() && !xa0_25_rumbling && xa0_24_pendingRumble) { + mgr.GetRumbleManager()->Rumble(mgr, kRFX_CameraShake, 1.f, kRP_Two); + xa0_25_rumbling = true; + } + if (x90_rumbleCooldown > 0.f) { + x90_rumbleCooldown -= dt; + } else if (xa0_25_rumbling) { + xa0_24_pendingRumble = false; + xa0_25_rumbling = false; + } + + if (mgr.GetPlayer()->GetCameraState() != CPlayer::kCS_FirstPerson && !IsInCinematicCamera()) { + x30_shakeOffset = CVector3f::Zero(); + } +}