From 141d88c0f7f3b2426aa32c2aefb13a35c0ea8303 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 22 Sep 2024 23:56:21 -0600 Subject: [PATCH] More CCameraManager progress --- config/GM8E01_00/symbols.txt | 8 +- config/GM8E01_01/symbols.txt | 8 +- include/Kyoto/Audio/CSfxManager.hpp | 1 + include/MetroidPrime/Cameras/CBallCamera.hpp | 3 + .../MetroidPrime/Cameras/CCameraManager.hpp | 11 +- .../MetroidPrime/Cameras/CCameraShakeData.hpp | 13 +- .../Cameras/CFirstPersonCamera.hpp | 21 ++- include/MetroidPrime/Cameras/CGameCamera.hpp | 1 + .../Cameras/CInterpolationCamera.hpp | 6 + include/MetroidPrime/Player/CPlayer.hpp | 2 + .../ScriptObjects/CScriptCameraHint.hpp | 43 +++++ include/rstl/pointer_iterator.hpp | 17 +- include/rstl/vector.hpp | 9 +- src/MetroidPrime/Cameras/CCameraManager.cpp | 155 +++++++++++++++++- .../ScriptObjects/CScriptCameraShaker.cpp | 4 +- 15 files changed, 267 insertions(+), 35 deletions(-) create mode 100644 include/MetroidPrime/ScriptObjects/CScriptCameraHint.hpp diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index 313282cc..8bec0e91 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -145,9 +145,9 @@ GetGlobalCameraTranslation__14CCameraManagerCFRC13CStateManager = .text:0x8000A9 GetCurrentCameraTransform__14CCameraManagerCFRC13CStateManager = .text:0x8000A968; // type:function size:0x68 scope:global RemoveCameraShaker__14CCameraManagerFi = .text:0x8000A9D0; // type:function size:0x50 scope:global AddCameraShaker__14CCameraManagerFRC16CCameraShakeDatab = .text:0x8000AA20; // type:function size:0x1F0 scope:global -fn_8000AC10 = .text:0x8000AC10; // type:function size:0x28 -fn_8000AC38 = .text:0x8000AC38; // type:function size:0x70 -fn_8000ACA8 = .text:0x8000ACA8; // type:function size:0x84 +push_back__Q24rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>FRC16CCameraShakeData = .text:0x8000AC10; // type:function size:0x28 +do_insert_before__Q24rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>FPQ34rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>4nodeRC16CCameraShakeData = .text:0x8000AC38; // type:function size:0x70 +create_node__Q24rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>FPQ34rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>4nodePQ34rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>4nodeRC16CCameraShakeData = .text:0x8000ACA8; // type:function size:0x84 __dt__16CCameraShakeDataFv = .text:0x8000AD2C; // type:function size:0x7C scope:global __ct__16CCameraShakeDataFRC16CCameraShakeData = .text:0x8000ADA8; // type:function size:0x1A8 scope:global __dt__22CCameraShakerComponentFv = .text:0x8000AF50; // type:function size:0x48 scope:global @@ -10887,7 +10887,7 @@ Accept__20CInterpolationCameraFR8IVisitor = .text:0x80264FEC; // type:function s ProcessInput__20CInterpolationCameraFRC11CFinalInputR13CStateManager = .text:0x80265024; // type:function size:0x4 scope:global Think__20CInterpolationCameraFfR13CStateManager = .text:0x80265028; // type:function size:0x2EC scope:global fn_80265314 = .text:0x80265314; // type:function size:0x6C -SetInterpolation__20CInterpolationCameraFRC12CTransform4fRC9CVector3ffff9TUniqueIdbR13CStateManager = .text:0x80265380; // type:function size:0x158 scope:global +SetInterpolation__20CInterpolationCameraFRC12CTransform4f9CVector3ffff9TUniqueIdbR13CStateManager = .text:0x80265380; // type:function size:0x158 scope:global InterpolateSinusoidal__20CInterpolationCameraFR12CTransform4fRC9CVector3fRC9CVector3fff = .text:0x802654D8; // type:function size:0x3E8 scope:global InterpolateWithDistance__20CInterpolationCameraFR12CTransform4fRC9CVector3fRC9CVector3ffffff = .text:0x802658C0; // type:function size:0x54C scope:global Reset__20CInterpolationCameraFRC12CTransform4fR13CStateManager = .text:0x80265E0C; // type:function size:0x4 scope:global diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index d47d2667..41f64549 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -145,9 +145,9 @@ GetGlobalCameraTranslation__14CCameraManagerCFRC13CStateManager = .text:0x8000A9 GetCurrentCameraTransform__14CCameraManagerCFRC13CStateManager = .text:0x8000A9E4; // type:function size:0x68 scope:global RemoveCameraShaker__14CCameraManagerFi = .text:0x8000AA4C; // type:function size:0x50 scope:global AddCameraShaker__14CCameraManagerFRC16CCameraShakeDatab = .text:0x8000AA9C; // type:function size:0x1F0 scope:global -fn_8000AC10 = .text:0x8000AC8C; // type:function size:0x28 scope:global -fn_8000AC38 = .text:0x8000ACB4; // type:function size:0x70 scope:global -fn_8000ACA8 = .text:0x8000AD24; // type:function size:0x84 scope:global +push_back__Q24rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>FRC16CCameraShakeData = .text:0x8000AC8C; // type:function size:0x28 scope:global +do_insert_before__Q24rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>FPQ34rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>4nodeRC16CCameraShakeData = .text:0x8000ACB4; // type:function size:0x70 scope:global +create_node__Q24rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>FPQ34rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>4nodePQ34rstl51list<16CCameraShakeData,Q24rstl17rmemory_allocator>4nodeRC16CCameraShakeData = .text:0x8000AD24; // type:function size:0x84 scope:global __dt__16CCameraShakeDataFv = .text:0x8000ADA8; // type:function size:0x7C scope:global __ct__16CCameraShakeDataFRC16CCameraShakeData = .text:0x8000AE24; // type:function size:0x1A8 scope:global __dt__22CCameraShakerComponentFv = .text:0x8000AFCC; // type:function size:0x48 scope:global @@ -10899,7 +10899,7 @@ Accept__20CInterpolationCameraFR8IVisitor = .text:0x80265068; // type:function s ProcessInput__20CInterpolationCameraFRC11CFinalInputR13CStateManager = .text:0x802650A0; // type:function size:0x4 scope:global Think__20CInterpolationCameraFfR13CStateManager = .text:0x802650A4; // type:function size:0x2EC scope:global fn_80265314 = .text:0x80265390; // type:function size:0x6C scope:global -SetInterpolation__20CInterpolationCameraFRC12CTransform4fRC9CVector3ffff9TUniqueIdbR13CStateManager = .text:0x802653FC; // type:function size:0x158 scope:global +SetInterpolation__20CInterpolationCameraFRC12CTransform4f9CVector3ffff9TUniqueIdbR13CStateManager = .text:0x802653FC; // type:function size:0x158 scope:global InterpolateSinusoidal__20CInterpolationCameraFR12CTransform4fRC9CVector3fRC9CVector3fff = .text:0x80265554; // type:function size:0x3E8 scope:global InterpolateWithDistance__20CInterpolationCameraFR12CTransform4fRC9CVector3fRC9CVector3ffffff = .text:0x8026593C; // type:function size:0x54C scope:global Reset__20CInterpolationCameraFRC12CTransform4fR13CStateManager = .text:0x80265E88; // type:function size:0x4 scope:global diff --git a/include/Kyoto/Audio/CSfxManager.hpp b/include/Kyoto/Audio/CSfxManager.hpp index 32f7c957..dcd17af0 100644 --- a/include/Kyoto/Audio/CSfxManager.hpp +++ b/include/Kyoto/Audio/CSfxManager.hpp @@ -206,6 +206,7 @@ public: static ushort TranslateSFXID(ushort); static void PitchBend(CSfxHandle handle, int pitch); + static void SetDuration(CSfxHandle handle, float duration); static ushort GetReverbAmount(); static CSfxHandle SfxStart(ushort id, short vol, short pan, bool useAcoustics, diff --git a/include/MetroidPrime/Cameras/CBallCamera.hpp b/include/MetroidPrime/Cameras/CBallCamera.hpp index a9f48f4b..16473482 100644 --- a/include/MetroidPrime/Cameras/CBallCamera.hpp +++ b/include/MetroidPrime/Cameras/CBallCamera.hpp @@ -159,6 +159,9 @@ public: void SetLookAtOffset(CVector3f vec) { x1b4_lookAtOffset = vec; } void SetChaseLookAtOffset(CVector3f vec) { x410_chaseLookAtOffset = vec; } void SetWorldOffset(CVector3f vec); // TODO + EBallCameraState GetState() const { return x400_state; } + void SetState(EBallCameraState state); + void ApplyCameraHint(CStateManager& mgr); private: struct SFailsafeState { diff --git a/include/MetroidPrime/Cameras/CCameraManager.hpp b/include/MetroidPrime/Cameras/CCameraManager.hpp index 2466ce0b..0ba51e45 100644 --- a/include/MetroidPrime/Cameras/CCameraManager.hpp +++ b/include/MetroidPrime/Cameras/CCameraManager.hpp @@ -20,6 +20,7 @@ class CFinalInput; class CFirstPersonCamera; class CGameCamera; class CInterpolationCamera; +class CScriptCameraHint; class CScriptWater; class CStateManager; @@ -72,7 +73,15 @@ public: int AddCameraShaker(const CCameraShakeData& data, bool sfx); void RemoveCameraShaker(int id); CTransform4f GetCurrentCameraTransform(const CStateManager& mgr) const; - // GetGlobalCameraTranslation__14CCameraManagerCFRC13CStateManager + CVector3f GetGlobalCameraTranslation(const CStateManager& mgr) const; + bool IsInFirstPersonCamera() const; + bool IsInterpolationCameraActive() const; + bool ShouldBypassInterpolationCamera() const; + void InterpolateToBallCamera(const CTransform4f& xf, TUniqueId camId, const CVector3f& lookPos, + float maxTime, float positionSpeed, float rotationSpeed, + bool sinusoidal, CStateManager& mgr); + void SkipBallCameraCinematic(CStateManager& mgr); + void ApplyCameraHint(const CScriptCameraHint& hint, CStateManager& mgr); // SetSpecialCameras__14CCameraManagerFR18CFirstPersonCameraR11CBallCamera void SetCurrentFov(float fov) { x3bc_curFov = fov; } diff --git a/include/MetroidPrime/Cameras/CCameraShakeData.hpp b/include/MetroidPrime/Cameras/CCameraShakeData.hpp index 9d77717d..eaf0a224 100644 --- a/include/MetroidPrime/Cameras/CCameraShakeData.hpp +++ b/include/MetroidPrime/Cameras/CCameraShakeData.hpp @@ -6,7 +6,7 @@ #include "Kyoto/Math/CVector3f.hpp" struct SCameraShakePoint { - bool x0_useEnvelope; + uint x0_useEnvelope; float x4_value; float x8_magnitude; float xc_attackTime; @@ -41,7 +41,7 @@ public: virtual ~CCameraShakerComponent() {} private: - bool x4_useModulation; + uint x4_useModulation; SCameraShakePoint x8_am; SCameraShakePoint x20_fm; float x38_value; @@ -60,17 +60,20 @@ public: , x44_shakerY() , x80_shakerZ(true, SCameraShakePoint(false, 0.25f * duration, 0.f, 0.75f * duration, magnitude), SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 2.f)) {} - CCameraShakeData(const CCameraShakeData&); - void SetShakerId(int id) { xbc_shakerId = id; } - int GetShakerId() const { return xbc_shakerId; } + void SetId(int id) { xbc_shakerId = id; } + int GetId() const { return xbc_shakerId; } void Update(float dt, CStateManager& mgr); // GeneratePoint__16CCameraShakeDataFfR9CRandom16 + float GetSomething() const; + float GetSomething2() const; float GetDuration() const { return x0_duration; } float GetCurTime() const { return x4_curTime; } CVector3f GetPoint() const; // { return xc4_sfxPos; } bool Done() const { return x4_curTime >= x0_duration; } + uint GetFlags() const { return xc0_flags; } + const CVector3f& GetSfxPos() const { return xc4_sfxPos; } static CCameraShakeData skChargedShotCameraShakeData; diff --git a/include/MetroidPrime/Cameras/CFirstPersonCamera.hpp b/include/MetroidPrime/Cameras/CFirstPersonCamera.hpp index 11662d33..de277bf0 100644 --- a/include/MetroidPrime/Cameras/CFirstPersonCamera.hpp +++ b/include/MetroidPrime/Cameras/CFirstPersonCamera.hpp @@ -7,9 +7,26 @@ class CFirstPersonCamera : public CGameCamera { public: CFirstPersonCamera(const TUniqueId& uid, const CTransform4f& xf, TUniqueId watchedObj, float orbitCameraSpeed, float fov, float nearz, float farz, float aspect); + + // CEntity + ~CFirstPersonCamera() override; + void Accept(IVisitor& visitor) override; + void PreThink(float dt, CStateManager& mgr) override; + void Think(float dt, CStateManager& mgr) override; + + // CActor + void Render(const CStateManager&) const override; + + // CGameCamera + void ProcessInput(const CFinalInput& input, CStateManager& mgr) override; + void Reset(const CTransform4f& xf, CStateManager& mgr) override; + void SetScriptPitchId(TUniqueId uid) { x1c4_pitchId = uid; } - void ProcessInput(const CFinalInput& input, CStateManager& mgr); - void Reset(const CTransform4f& xf, CStateManager& mgr); + // UpdateElevation__18CFirstPersonCameraFR13CStateManager + // UpdateTransform__18CFirstPersonCameraFR13CStateManagerf + // GetGunFollowTransform__18CFirstPersonCameraCFv + // SetLockCamera__18CFirstPersonCameraFb + void SkipCinematic(); private: float x188_orbitCameraSpeed; diff --git a/include/MetroidPrime/Cameras/CGameCamera.hpp b/include/MetroidPrime/Cameras/CGameCamera.hpp index 784c095e..4eed3fb4 100644 --- a/include/MetroidPrime/Cameras/CGameCamera.hpp +++ b/include/MetroidPrime/Cameras/CGameCamera.hpp @@ -30,6 +30,7 @@ public: // ConvertToScreenSpace__11CGameCameraCFRC9CVector3f // ValidateCameraTransform__11CGameCameraFRC12CTransform4fRC12CTransform4f // ShouldTryRender__11CGameCameraCFv + void SkipFovInterpolation(); TUniqueId GetWatchedObject() const { return xe8_watchedObject; } float GetFov() const { return x15c_currentFov; } diff --git a/include/MetroidPrime/Cameras/CInterpolationCamera.hpp b/include/MetroidPrime/Cameras/CInterpolationCamera.hpp index 9d24353d..74eed195 100644 --- a/include/MetroidPrime/Cameras/CInterpolationCamera.hpp +++ b/include/MetroidPrime/Cameras/CInterpolationCamera.hpp @@ -6,9 +6,15 @@ class CInterpolationCamera : public CGameCamera { public: CInterpolationCamera(TUniqueId uid, const CTransform4f& xf); + // CGameCamera void ProcessInput(const CFinalInput&, CStateManager& mgr) override; void Reset(const CTransform4f&, CStateManager& mgr) override; + + void SetInterpolation(const CTransform4f& xf, CVector3f lookPos, float maxTime, + float positionSpeed, float rotationSpeed, TUniqueId targetId, + bool sinusoidal, CStateManager& mgr); + private: TUniqueId x188_targetId; float x18c_time; diff --git a/include/MetroidPrime/Player/CPlayer.hpp b/include/MetroidPrime/Player/CPlayer.hpp index c867c94c..5a39c970 100644 --- a/include/MetroidPrime/Player/CPlayer.hpp +++ b/include/MetroidPrime/Player/CPlayer.hpp @@ -213,6 +213,8 @@ public: void RemoveOrbitDisableSource(TUniqueId uid); void ResetAimTargetPrediction(TUniqueId target); void DoSfxEffects(CSfxHandle sfx); + void UnFreeze(CStateManager& mgr); + void UpdateCinematicState(CStateManager& mgr); CPlayerGun* PlayerGun() { return x490_gun.get(); } const CPlayerGun* GetPlayerGun() const { return x490_gun.get(); } diff --git a/include/MetroidPrime/ScriptObjects/CScriptCameraHint.hpp b/include/MetroidPrime/ScriptObjects/CScriptCameraHint.hpp new file mode 100644 index 00000000..648228b9 --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CScriptCameraHint.hpp @@ -0,0 +1,43 @@ +#ifndef _CSCRIPTCAMERAHINT +#define _CSCRIPTCAMERAHINT + +#include "MetroidPrime/CActor.hpp" +#include "MetroidPrime/Cameras/CBallCamera.hpp" +#include "MetroidPrime/Cameras/CCameraHint.hpp" +#include "MetroidPrime/TGameTypes.hpp" + +#include "Kyoto/Math/CTransform4f.hpp" + +#include "rstl/reserved_vector.hpp" + +class CCameraSpring; + +class CScriptCameraHint : public CActor { +public: + CScriptCameraHint(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, + const CTransform4f& xf, bool active, int priority, + CBallCamera::EBallCameraBehaviour behavior, int overrideFlags, float minDist, + float maxDist, float backwardsDist, const CCameraSpring&, const CCameraSpring&, + float, const CVector3f&, const CVector3f&, float); + + // CEntity + ~CScriptCameraHint() override; + void Accept(IVisitor& visitor) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + + // GetOverrideFlags__17CScriptCameraHintCFv + // GetBehaviourType__17CScriptCameraHintCFv + int GetPriority() const { return xe8_priority; } + // OverrideCameraInfo__17CScriptCameraHintFP11CBallCamera + +private: + int xe8_priority; + CCameraHint xec_hint; + rstl::reserved_vector< TUniqueId, 8 > x150_helpers; + TUniqueId x164_delegatedCamera; + bool x166_inactive; + CTransform4f x168_origXf; +}; +CHECK_SIZEOF(CScriptCameraHint, 0x198) + +#endif // _CSCRIPTCAMERAHINT diff --git a/include/rstl/pointer_iterator.hpp b/include/rstl/pointer_iterator.hpp index 8918526d..9705f24a 100644 --- a/include/rstl/pointer_iterator.hpp +++ b/include/rstl/pointer_iterator.hpp @@ -37,12 +37,10 @@ public: return *this; } const_pointer_iterator operator+(int v) const { - const_pointer_iterator it = *this; - return it += v; + return const_pointer_iterator(this->current + v); } const_pointer_iterator operator-(int v) const { - const_pointer_iterator it = *this; - return it -= v; + return const_pointer_iterator(this->current - v); } difference_type operator-(const const_pointer_iterator& other) const { return this->current - other.current; @@ -77,9 +75,8 @@ public: typedef typename base::iterator_category iterator_category; typedef typename base::value_type value_type; - pointer_iterator() : const_pointer_iterator< T, Vec, Alloc >(nullptr) {} - pointer_iterator(T* begin) : const_pointer_iterator< T, Vec, Alloc >(begin) {} - void operator=(const T& other) { rstl::construct(this->current, other); } + pointer_iterator() : base(nullptr) {} + pointer_iterator(T* begin) : base(begin) {} T& operator*() { return *this->current; } // TODO map says const, but breaks CScriptMazeNode::GenerateObjects T* operator->() { return this->current; } @@ -104,12 +101,10 @@ public: return *this; } pointer_iterator operator+(int v) const { - pointer_iterator it = *this; - return it += v; + return pointer_iterator(current + v); } pointer_iterator operator-(int v) const { - pointer_iterator it = *this; - return it -= v; + return pointer_iterator(current - v); } // HACK: non-const operator- is required to match vector::insert difference_type operator-(const pointer_iterator& other) { return this->current - other.current; } diff --git a/include/rstl/vector.hpp b/include/rstl/vector.hpp index 20f8e8de..25abc99f 100644 --- a/include/rstl/vector.hpp +++ b/include/rstl/vector.hpp @@ -3,6 +3,7 @@ #include "types.h" +#include "rstl/iterator.hpp" #include "rstl/pointer_iterator.hpp" #include "rstl/rmemory_allocator.hpp" @@ -215,17 +216,17 @@ typename vector< T, Alloc >::iterator vector< T, Alloc >::erase(iterator it) { return erase(it, it + 1); } +// TODO nonmatching (CCameraManager::RemoveCinemaCamera) template < typename T, typename Alloc > typename vector< T, Alloc >::iterator vector< T, Alloc >::erase(iterator first, iterator last) { destroy(first, last); + iterator start = begin(); - int newCount = rstl::distance(first, start); + int newCount = start - first; iterator moved = start + newCount; - for (iterator it = last; it != end(); ++it) { + for (iterator it = last; it != end(); ++moved, ++newCount, ++it) { construct(&*moved, *it); - ++moved; - ++newCount; } x4_count = newCount; diff --git a/src/MetroidPrime/Cameras/CCameraManager.cpp b/src/MetroidPrime/Cameras/CCameraManager.cpp index 0cca9fa0..5eb3e547 100644 --- a/src/MetroidPrime/Cameras/CCameraManager.cpp +++ b/src/MetroidPrime/Cameras/CCameraManager.cpp @@ -1,22 +1,28 @@ #include "MetroidPrime/Cameras/CCameraManager.hpp" -#include "MetroidPrime/CFluidPlaneCPU.hpp" -#include "MetroidPrime/CRumbleManager.hpp" #include "MetroidPrime/Cameras/CBallCamera.hpp" +#include "MetroidPrime/ScriptObjects/CScriptCameraHint.hpp" #include "MetroidPrime/Cameras/CCinematicCamera.hpp" #include "MetroidPrime/Cameras/CFirstPersonCamera.hpp" #include "MetroidPrime/Cameras/CGameCamera.hpp" #include "MetroidPrime/Cameras/CInterpolationCamera.hpp" +#include "MetroidPrime/CExplosion.hpp" +#include "MetroidPrime/CFluidPlaneCPU.hpp" +#include "MetroidPrime/CRumbleManager.hpp" #include "MetroidPrime/Player/CPlayer.hpp" +#include "MetroidPrime/Player/CPlayerGun.hpp" #include "MetroidPrime/ScriptObjects/CScriptWater.hpp" +#include "MetroidPrime/SFX/Misc.h" #include "MetroidPrime/Tweaks/CTweakGame.hpp" #include "MetroidPrime/Tweaks/CTweakPlayer.hpp" +#include "MetroidPrime/Weapons/CWeapon.hpp" #include "Kyoto/Audio/CSfxManager.hpp" #include "Kyoto/Graphics/CGraphics.hpp" #include "Kyoto/Input/CFinalInput.hpp" #include "rstl/algorithm.hpp" +#include "rstl/math.hpp" float CCameraManager::sFirstPersonFOV = 55.f; float CCameraManager::sThirdPersonFOV = 60.f; @@ -325,3 +331,148 @@ void CCameraManager::RemoveCinemaCamera(TUniqueId uid, CStateManager& mgr) { x4_cineCameras.erase(it); } } + +// TODO nonmatching: regswap +void CCameraManager::EnterCinematic(CStateManager& mgr) { + mgr.Player()->PlayerGun()->CancelFiring(mgr); + mgr.Player()->UnFreeze(mgr); + + CObjectList& objList = mgr.ObjectListById(kOL_All); + int idx = objList.GetFirstObjectIndex(); + while (idx != -1) { + if (CExplosion* explosion = TCastToPtr< CExplosion >(objList[idx])) { + mgr.DeleteObjectRequest(explosion->GetUniqueId()); + } else if (CWeapon* weapon = TCastToPtr< CWeapon >(objList[idx])) { + if (weapon->GetActive() && + (weapon->GetAttribField() & kPA_KeepInCinematic) != kPA_KeepInCinematic) { + CPatterned* patterned = TCastToPtr< CPatterned >(mgr.ObjectById(weapon->GetOwnerId())); + CPlayer* player = TCastToPtr< CPlayer >(mgr.ObjectById(weapon->GetOwnerId())); + if (patterned || player) { + mgr.DeleteObjectRequest(weapon->GetUniqueId()); + } + } + } + idx = objList.GetNextObjectIndex(idx); + } +} + +void CCameraManager::SkipCinematic(CStateManager& mgr) { + CCinematicCamera* ent = static_cast< CCinematicCamera* >(mgr.ObjectById(GetCurrentCameraId())); + while (ent) { + ent->SetActive(false); + ent->WasDeactivated(mgr); + ent = TCastToPtr< CCinematicCamera >(&CurrentCamera(mgr)); + } + mgr.Player()->UpdateCinematicState(mgr); + x7c_fpCamera->SkipCinematic(); +} + +// TODO: nonmatching +int CCameraManager::AddCameraShaker(const CCameraShakeData& data, bool sfx) { + CCameraShakeData shakeData = data; + shakeData.SetId(++x2c_lastShakeId); + x14_shakers.push_back(shakeData); + if (xa0_24_pendingRumble != true) { + xa0_24_pendingRumble = true; + x90_rumbleCooldown = 0.5f; + } + float duration = data.GetDuration(); + if (sfx && duration > 0.f) { + float component1 = data.GetSomething2(); + float component2 = data.GetSomething(); + if (component2 > component1) { + component1 = component2; + } + float volF = CMath::Clamp(100.f, component1 * 9.f + 100.f, 127.f); + uchar vol = static_cast< uchar >(volF); + CSfxHandle sfxHandle; + if (data.GetFlags() & 0x1) { + CVector3f pos = data.GetSfxPos(); + sfxHandle = + CSfxManager::AddEmitter(SFXamb_x_rumble_lp_00, pos, CVector3f::Zero(), vol, false, false); + } else { + sfxHandle = + CSfxManager::SfxStart(SFXamb_x_rumble_lp_00, vol, 64, false, CSfxManager::kMedPriority); + } + CSfxManager::SetDuration(sfxHandle, duration); + } + return x2c_lastShakeId; +} + +void CCameraManager::RemoveCameraShaker(int id) { + rstl::list< CCameraShakeData >::iterator it = x14_shakers.begin(); + while (it != x14_shakers.end()) { + if (it->GetId() == id) { + x14_shakers.erase(it); + return; + } + ++it; + } +} + +CTransform4f CCameraManager::GetCurrentCameraTransform(const CStateManager& mgr) const { + return GetCurrentCamera(mgr).GetTransform() * CTransform4f::Translate(x30_shakeOffset); +} + +CVector3f CCameraManager::GetGlobalCameraTranslation(const CStateManager& mgr) const { + return GetCurrentCamera(mgr).GetTransform().Rotate(x30_shakeOffset); +} + +bool CCameraManager::IsInCinematicCamera() const { return !x4_cineCameras.empty(); } + +bool CCameraManager::IsInFirstPersonCamera() const { + return x0_curCameraId == x7c_fpCamera->GetUniqueId(); +} + +bool CCameraManager::IsInterpolationCameraActive() const { return x88_interpCamera->GetActive(); } + +bool CCameraManager::ShouldBypassInterpolationCamera() const { return false; } + +void CCameraManager::SetPlayerCamera(CStateManager& mgr, TUniqueId uid) { + if (!x88_interpCamera->GetActive()) { + return; + } + x88_interpCamera->SetActive(false); + x80_ballCamera->SkipFovInterpolation(); + if (!ShouldBypassInterpolationCamera()) { + SetCurrentCameraId(uid); + } +} + +void CCameraManager::InterpolateToBallCamera(const CTransform4f& xf, TUniqueId camId, + const CVector3f& lookPos, float maxTime, + float positionSpeed, float rotationSpeed, + bool sinusoidal, CStateManager& mgr) { + if (IsInFirstPersonCamera()) { + return; + } + x88_interpCamera->SetInterpolation(xf, lookPos, maxTime, positionSpeed, rotationSpeed, camId, + sinusoidal, mgr); + if (!ShouldBypassInterpolationCamera()) { + SetCurrentCameraId(x88_interpCamera->GetUniqueId()); + } +} + +void CCameraManager::SkipBallCameraCinematic(CStateManager& mgr) { + if (IsInCinematicCamera()) { + x80_ballCamera->TeleportCamera(GetLastCineCamera(mgr).GetTransform(), mgr); + x80_ballCamera->SetFovInterpolation(GetLastCineCamera(mgr).GetFov(), x80_ballCamera->GetFov(), + 1.f, 0.f); + SkipCinematic(mgr); + SetCurrentCameraId(x80_ballCamera->GetUniqueId()); + } +} + +void CCameraManager::ApplyCameraHint(const CScriptCameraHint& hint, CStateManager& mgr) { + if (x80_ballCamera->GetState() == CBallCamera::kBCS_ToBall) { + x80_ballCamera->SetState(CBallCamera::kBCS_Default); + mgr.Player()->SetCameraState(CPlayer::kCS_Ball, mgr); + } + + CScriptCameraHint* oldHint = TCastToPtr(mgr.ObjectById(xa6_camHintId)); + xa6_camHintId = hint.GetUniqueId(); + xa8_hintPriority = hint.GetPriority(); + + CTransform4f camXf = GetCurrentCameraTransform(mgr); + x80_ballCamera->ApplyCameraHint(mgr); +} diff --git a/src/MetroidPrime/ScriptObjects/CScriptCameraShaker.cpp b/src/MetroidPrime/ScriptObjects/CScriptCameraShaker.cpp index 495919df..52ab625f 100644 --- a/src/MetroidPrime/ScriptObjects/CScriptCameraShaker.cpp +++ b/src/MetroidPrime/ScriptObjects/CScriptCameraShaker.cpp @@ -20,14 +20,14 @@ void CScriptCameraShaker::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId ob CGameArea::EOcclusionState occState = area.IsLoaded() ? area.GetOcclusionState() : CGameArea::kOS_Occluded; if (occState != CGameArea::kOS_Occluded) { - x34_shakeData.SetShakerId(stateMgr.CameraManager()->AddCameraShaker(x34_shakeData, false)); + x34_shakeData.SetId(stateMgr.CameraManager()->AddCameraShaker(x34_shakeData, false)); } } break; } case kSM_Deactivate: { if (GetActive()) - stateMgr.CameraManager()->RemoveCameraShaker(x34_shakeData.GetShakerId()); + stateMgr.CameraManager()->RemoveCameraShaker(x34_shakeData.GetId()); break; } default: