From 1b6a756648cc809414160715093ab0a5744c909a Mon Sep 17 00:00:00 2001 From: Luke Street Date: Sun, 22 Sep 2024 16:58:50 -0600 Subject: [PATCH] CCameraManager progress --- .vscode/c_cpp_properties.json | 1 + .vscode/extensions.json | 1 - .vscode/settings.json | 5 +- config/GM8E01_00/symbols.txt | 4 +- config/GM8E01_01/symbols.txt | 4 +- include/Kyoto/Input/CFinalInput.hpp | 7 +- include/MetroidPrime/CFluidPlane.hpp | 33 +++- include/MetroidPrime/CFluidUVMotion.hpp | 1 + .../MetroidPrime/Cameras/CCameraManager.hpp | 43 +++-- .../MetroidPrime/Cameras/CCameraShakeData.hpp | 4 +- include/MetroidPrime/Cameras/CGameCamera.hpp | 10 +- .../ScriptObjects/CScriptWater.hpp | 51 +++++- include/MetroidPrime/Tweaks/CTweakGame.hpp | 2 +- include/rstl/list.hpp | 2 +- src/MetroidPrime/Cameras/CCameraManager.cpp | 160 +++++++++++++++--- 15 files changed, 280 insertions(+), 48 deletions(-) diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json index 51c9f543..b02ae17c 100644 --- a/.vscode/c_cpp_properties.json +++ b/.vscode/c_cpp_properties.json @@ -5,6 +5,7 @@ "includePath": [ "${workspaceFolder}/include", "${workspaceFolder}/libc", + "${workspaceFolder}/extern/musyx/include", "${workspaceFolder}/build/*/include" ], "cStandard": "c99", diff --git a/.vscode/extensions.json b/.vscode/extensions.json index c3bac0bd..8530d405 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,7 +1,6 @@ { "recommendations": [ "ms-vscode.cpptools", - "xaver.clang-format", "akiramiyakoda.cppincludeguard", "ms-python.black-formatter" ] diff --git a/.vscode/settings.json b/.vscode/settings.json index aae06086..fff8716d 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,11 +1,11 @@ { "[c]": { "files.encoding": "utf8", - "editor.defaultFormatter": "xaver.clang-format" + "editor.defaultFormatter": "ms-vscode.cpptools" }, "[cpp]": { "files.encoding": "utf8", - "editor.defaultFormatter": "xaver.clang-format" + "editor.defaultFormatter": "ms-vscode.cpptools" }, "[python]": { "editor.defaultFormatter": "ms-python.black-formatter" @@ -14,6 +14,7 @@ "clangd.fallbackFlags": [ "-I${workspaceFolder}/include", "-I${workspaceFolder}/libc", + "-I${workspaceFolder}/extern/musyx/include", "-D__MWERKS__", ], "editor.tabSize": 2, diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index 099b6407..313282cc 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -155,12 +155,12 @@ SkipCinematic__14CCameraManagerFR13CStateManager = .text:0x8000AF98; // type:fun EnterCinematic__14CCameraManagerFR13CStateManager = .text:0x8000B058; // type:function size:0x16C scope:global RemoveCinemaCamera__14CCameraManagerF9TUniqueIdR13CStateManager = .text:0x8000B1C4; // type:function size:0x94 scope:global erase__Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>FQ24rstl110pointer_iterator<9TUniqueId,Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator> = .text:0x8000B258; // type:function size:0x4C scope:global -fn_8000B2A4 = .text:0x8000B2A4; // type:function size:0x98 +erase__Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>FQ24rstl110pointer_iterator<9TUniqueId,Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>Q24rstl110pointer_iterator<9TUniqueId,Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator> = .text:0x8000B2A4; // type:function size:0x98 AddCinemaCamera__14CCameraManagerF9TUniqueIdR13CStateManager = .text:0x8000B33C; // type:function size:0x130 scope:global ProcessInput__14CCameraManagerFRC11CFinalInputR13CStateManager = .text:0x8000B46C; // type:function size:0xB0 scope:global SetInsideFluid__14CCameraManagerFb9TUniqueId = .text:0x8000B51C; // type:function size:0x30 scope:global Update__14CCameraManagerFfR13CStateManager = .text:0x8000B54C; // type:function size:0x80 scope:global -SetFogDensity__14CCameraManagerFfff = .text:0x8000B5CC; // type:function size:0x28 scope:global +SetFogDensity__14CCameraManagerFff = .text:0x8000B5CC; // type:function size:0x28 scope:global CalculateFogDensity__14CCameraManagerFR13CStateManagerPC12CScriptWater = .text:0x8000B5F4; // type:function size:0x8C scope:global UpdateFog__14CCameraManagerFfR13CStateManager = .text:0x8000B680; // type:function size:0x1F8 scope:global UpdateRumble__14CCameraManagerFfR13CStateManager = .text:0x8000B878; // type:function size:0x1B0 scope:global diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index 7d26f314..d47d2667 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -155,12 +155,12 @@ SkipCinematic__14CCameraManagerFR13CStateManager = .text:0x8000B014; // type:fun EnterCinematic__14CCameraManagerFR13CStateManager = .text:0x8000B0D4; // type:function size:0x16C scope:global RemoveCinemaCamera__14CCameraManagerF9TUniqueIdR13CStateManager = .text:0x8000B240; // type:function size:0x94 scope:global erase__Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>FQ24rstl110pointer_iterator<9TUniqueId,Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator> = .text:0x8000B2D4; // type:function size:0x4C scope:global -fn_8000B2A4 = .text:0x8000B320; // type:function size:0x98 scope:global +erase__Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>FQ24rstl110pointer_iterator<9TUniqueId,Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>Q24rstl110pointer_iterator<9TUniqueId,Q24rstl45vector<9TUniqueId,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator> = .text:0x8000B320; // type:function size:0x98 scope:global AddCinemaCamera__14CCameraManagerF9TUniqueIdR13CStateManager = .text:0x8000B3B8; // type:function size:0x130 scope:global ProcessInput__14CCameraManagerFRC11CFinalInputR13CStateManager = .text:0x8000B4E8; // type:function size:0xB0 scope:global SetInsideFluid__14CCameraManagerFb9TUniqueId = .text:0x8000B598; // type:function size:0x30 scope:global Update__14CCameraManagerFfR13CStateManager = .text:0x8000B5C8; // type:function size:0x80 scope:global -SetFogDensity__14CCameraManagerFfff = .text:0x8000B648; // type:function size:0x28 scope:global +SetFogDensity__14CCameraManagerFff = .text:0x8000B648; // type:function size:0x28 scope:global CalculateFogDensity__14CCameraManagerFR13CStateManagerPC12CScriptWater = .text:0x8000B670; // type:function size:0x8C scope:global UpdateFog__14CCameraManagerFfR13CStateManager = .text:0x8000B6FC; // type:function size:0x1F8 scope:global UpdateRumble__14CCameraManagerFfR13CStateManager = .text:0x8000B8F4; // type:function size:0x1B0 scope:global diff --git a/include/Kyoto/Input/CFinalInput.hpp b/include/Kyoto/Input/CFinalInput.hpp index 5a0cc261..285d71ac 100644 --- a/include/Kyoto/Input/CFinalInput.hpp +++ b/include/Kyoto/Input/CFinalInput.hpp @@ -42,7 +42,10 @@ public: CFinalInput ScaleAnalogueSticks(float leftDiv, float rightDiv) const; - float DeltaTime() const { return x0_dt; } + float Time() const { return x0_dt; } + void SetTime(float time) { x0_dt = time; } + + int ControllerNumber() const { return x4_controllerIdx; } float ALAUp() const { return xc_anaLeftY > 0.f ? xc_anaLeftY : 0.f; } @@ -182,7 +185,7 @@ public: private: float x0_dt; - uint x4_controllerIdx; + int x4_controllerIdx; float x8_anaLeftX; float xc_anaLeftY; float x10_anaRightX; diff --git a/include/MetroidPrime/CFluidPlane.hpp b/include/MetroidPrime/CFluidPlane.hpp index 734ac44a..88315b3e 100644 --- a/include/MetroidPrime/CFluidPlane.hpp +++ b/include/MetroidPrime/CFluidPlane.hpp @@ -1,9 +1,11 @@ #ifndef _CFLUIDPLANE #define _CFLUIDPLANE +#include "MetroidPrime/CFluidUVMotion.hpp" #include "MetroidPrime/TGameTypes.hpp" #include "Kyoto/Math/CVector3f.hpp" +#include "Kyoto/TToken.hpp" class CScriptWater; class CStateManager; @@ -18,21 +20,46 @@ public: }; class CFluidPlane { - public: - virtual ~CFluidPlane(); + enum EFluidType { + // TODO + }; + CFluidPlane(uint, uint, uint, CFluidPlane::EFluidType, float, const CFluidUVMotion&); + virtual ~CFluidPlane(); virtual void AddRipple(float mag, TUniqueId rippler, const CVector3f& center, CScriptWater& water, CStateManager& mgr); virtual void AddRipple(float intensity, TUniqueId rippler, const CVector3f& center, const CVector3f& velocity, const CScriptWater& water, CStateManager& mgr, const CVector3f& upVec); + // Update__11CFluidPlaneFv -protected: + float GetAlpha() const { return x40_alpha; } + EFluidType GetFluidType() const { return x44_fluidType; } + const CFluidUVMotion& GetUVMotion() const { return x4c_uvMotion; } + // GetColorTexture__11CFluidPlaneCFv + // HasColorTexture__11CFluidPlaneCFv + // GetTexturePattern2__11CFluidPlaneCFv + // HasTexturePattern2__11CFluidPlaneCFv + // GetTexturePattern1__11CFluidPlaneCFv + // HasTexturePattern1__11CFluidPlaneCFv + +// protected: virtual void RenderStripWithRipples(const CFluidPlaneCPURender::SHFieldSample& heights, const unsigned char& flags, float curY, int startYDiv, const CFluidPlaneCPURender::SPatchInfo& info); + CAssetId x4_texPattern1Id; + CAssetId x8_texPattern2Id; + CAssetId xc_texColorId; + rstl::optional_object< TLockedToken< CTexture > > x10_texPattern1; + rstl::optional_object< TLockedToken< CTexture > > x20_texPattern2; + rstl::optional_object< TLockedToken< CTexture > > x30_texColor; + float x40_alpha; + EFluidType x44_fluidType; + float x48_rippleIntensity; + CFluidUVMotion x4c_uvMotion; }; +CHECK_SIZEOF(CFluidPlane, 0xA0); #endif // _CFLUIDPLANE diff --git a/include/MetroidPrime/CFluidUVMotion.hpp b/include/MetroidPrime/CFluidUVMotion.hpp index 3e62cb42..1a164d92 100644 --- a/include/MetroidPrime/CFluidUVMotion.hpp +++ b/include/MetroidPrime/CFluidUVMotion.hpp @@ -59,5 +59,6 @@ public: return x0_fluidLayers; } }; +CHECK_SIZEOF(CFluidUVMotion, 0x54) #endif // _CFLUIDUVMOTION diff --git a/include/MetroidPrime/Cameras/CCameraManager.hpp b/include/MetroidPrime/Cameras/CCameraManager.hpp index 2986b92f..2466ce0b 100644 --- a/include/MetroidPrime/Cameras/CCameraManager.hpp +++ b/include/MetroidPrime/Cameras/CCameraManager.hpp @@ -4,8 +4,8 @@ #include "types.h" #include "MetroidPrime/CGameArea.hpp" -#include "MetroidPrime/TGameTypes.hpp" #include "MetroidPrime/Cameras/CCameraShakeData.hpp" +#include "MetroidPrime/TGameTypes.hpp" #include "Kyoto/Math/CVector3f.hpp" @@ -16,14 +16,17 @@ class CBallCamera; class CCameraShakeData; +class CFinalInput; class CFirstPersonCamera; class CGameCamera; class CInterpolationCamera; +class CScriptWater; class CStateManager; #ifdef __MWERKS__ #pragma cpp_extensions on -#endif +#endif + class CCameraManager { static float sFirstPersonFOV; static float sThirdPersonFOV; @@ -32,6 +35,7 @@ class CCameraManager { static float sAspectRatio; static float lbl_805A6BE4; static float lbl_805A6BE8; + public: CCameraManager(TUniqueId curCamera = kInvalidUniqueId); @@ -40,40 +44,54 @@ public: void ResetCameras(CStateManager& mgr); void RenderCameras(const CStateManager& mgr); TUniqueId GetCurrentCameraId() const; + void SetCurrentCameraId(TUniqueId camId); CGameCamera& CurrentCamera(CStateManager& mgr); const CGameCamera& GetCurrentCamera(const CStateManager& mgr) const; const CGameCamera& GetLastCineCamera(CStateManager& mgr) const; TUniqueId GetLastCineCameraId() const; - void RemoveCinemaCamera(TUniqueId uid, CStateManager& mgr); - void SetCurrentCameraId(TUniqueId camId); - + void Update(float dt, CStateManager& mgr); void UpdateSfxListener(CStateManager& mgr); void UpdateRumble(float dt, CStateManager& mgr); + void UpdateFog(float dt, CStateManager& mgr); + void UpdateCameraHints(float dt, CStateManager& mgr); + float CalculateFogDensity(CStateManager& mgr, const CScriptWater* water); + void SetFogDensity(float fogDensityTarget, float fogDensitySpeed); CFirstPersonCamera* FirstPersonCamera() const /* map */ { return x7c_fpCamera; } const CFirstPersonCamera* GetFirstPersonCamera() const { return x7c_fpCamera; } - CTransform4f GetCurrentCameraTransform(const CStateManager& mgr) const; void SetPlayerCamera(CStateManager& mgr, TUniqueId newCamId); - void SetFogDensity(float fogDensityTarget, float fogDensitySpeed); bool IsInCinematicCamera() const; + void AddCinemaCamera(TUniqueId uid, CStateManager& mgr); + void RemoveCinemaCamera(TUniqueId uid, CStateManager& mgr); + void EnterCinematic(CStateManager& mgr); + void SkipCinematic(CStateManager& mgr); - - void RemoveCameraShaker(int id); int AddCameraShaker(const CCameraShakeData& data, bool sfx); + void RemoveCameraShaker(int id); + CTransform4f GetCurrentCameraTransform(const CStateManager& mgr) const; + // GetGlobalCameraTranslation__14CCameraManagerCFRC13CStateManager + // SetSpecialCameras__14CCameraManagerFR18CFirstPersonCameraR11CBallCamera void SetCurrentFov(float fov) { x3bc_curFov = fov; } - - int GetFluidCounter() const { return x74_fluidCounter; } + int GetFluidCounter() const { return x74_fluidCounter; } + TUniqueId GetFluidId() const { return x78_fluidId; } + // GetInsideFluid__14CCameraManagerCFv + // WasInsideFluid__14CCameraManagerCFv + // SetWasInsideFluid__14CCameraManagerFb + void SetInsideFluid(bool isInside, TUniqueId fluidId); + + void ProcessInput(const CFinalInput& input, CStateManager& mgr); static float DefaultThirdPersonFov(); static float DefaultFirstPersonFov(); static float DefaultNearPlane(); static float DefaultFarPlane(); static float DefaultAspect(); + private: TUniqueId x0_curCameraId; rstl::vector< TUniqueId > x4_cineCameras; @@ -116,5 +134,6 @@ CHECK_SIZEOF(CCameraManager, 0x3c0) #ifdef __MWERKS__ #pragma cpp_extensions reset -#endif +#endif + #endif // _CCAMERAMANAGER diff --git a/include/MetroidPrime/Cameras/CCameraShakeData.hpp b/include/MetroidPrime/Cameras/CCameraShakeData.hpp index 58550e48..9d77717d 100644 --- a/include/MetroidPrime/Cameras/CCameraShakeData.hpp +++ b/include/MetroidPrime/Cameras/CCameraShakeData.hpp @@ -65,10 +65,12 @@ public: void SetShakerId(int id) { xbc_shakerId = id; } int GetShakerId() const { return xbc_shakerId; } void Update(float dt, CStateManager& mgr); + // GeneratePoint__16CCameraShakeDataFfR9CRandom16 float GetDuration() const { return x0_duration; } float GetCurTime() const { return x4_curTime; } - const CVector3f& GetPoint() const; // { return xc4_sfxPos; } + CVector3f GetPoint() const; // { return xc4_sfxPos; } + bool Done() const { return x4_curTime >= x0_duration; } static CCameraShakeData skChargedShotCameraShakeData; diff --git a/include/MetroidPrime/Cameras/CGameCamera.hpp b/include/MetroidPrime/Cameras/CGameCamera.hpp index 094a665b..784c095e 100644 --- a/include/MetroidPrime/Cameras/CGameCamera.hpp +++ b/include/MetroidPrime/Cameras/CGameCamera.hpp @@ -26,12 +26,20 @@ public: virtual void ProcessInput(const CFinalInput&, CStateManager& mgr) = 0; virtual void Reset(const CTransform4f&, CStateManager& mgr) = 0; + // GetPerspectiveMatrix__11CGameCameraCFv + // ConvertToScreenSpace__11CGameCameraCFRC9CVector3f + // ValidateCameraTransform__11CGameCameraFRC12CTransform4fRC12CTransform4f + // ShouldTryRender__11CGameCameraCFv + TUniqueId GetWatchedObject() const { return xe8_watchedObject; } float GetFov() const { return x15c_currentFov; } void SetFov(float fov) { x15c_currentFov = fov; } float GetNearClipDistance() const { return x160_znear; } void SetFovInterpolation(float start, float fov, float time, float delayTime); void UpdatePerspective(float dt); + int GetControllerNumber() const { return x16c_controllerIdx; } + bool DisablesInput() const { return x170_25_disablesInput; } + float GetAspectRatio() const { return x168_aspect; } protected: TUniqueId xe8_watchedObject; @@ -41,7 +49,7 @@ protected: float x160_znear; float x164_zfar; float x168_aspect; - uint x16c_controllerIdx; + int x16c_controllerIdx; mutable bool x170_24_perspDirty : 1; bool x170_25_disablesInput : 1; float x174_delayTime; diff --git a/include/MetroidPrime/ScriptObjects/CScriptWater.hpp b/include/MetroidPrime/ScriptObjects/CScriptWater.hpp index fe04b308..e82c3a02 100644 --- a/include/MetroidPrime/ScriptObjects/CScriptWater.hpp +++ b/include/MetroidPrime/ScriptObjects/CScriptWater.hpp @@ -3,7 +3,9 @@ #include "types.h" +#include "MetroidPrime/CFluidPlane.hpp" #include "MetroidPrime/ScriptObjects/CScriptTrigger.hpp" +#include "MetroidPrime/TGameTypes.hpp" #include "Kyoto/Math/CFrustumPlanes.hpp" #include "Kyoto/TToken.hpp" @@ -12,18 +14,65 @@ #include "rstl/optional_object.hpp" #include "rstl/pair.hpp" #include "rstl/single_ptr.hpp" +#include "rstl/string.hpp" +class CAABox; +class CColor; +class CDamageInfo; class CFluidPlaneCPU; +class CFluidUVMotion; class CGenDescription; +class CStateManager; +class CVector3f; class CScriptWater : public CScriptTrigger { public: - // TODO + CScriptWater(CStateManager&, TUniqueId, const rstl::string&, const CEntityInfo&, const CVector3f&, + const CAABox&, const CDamageInfo&, const CVector3f&, uint, bool, bool, uint, uint, + uint, uint, uint, uint, const CVector3f&, float, float, float, bool, + CFluidPlane::EFluidType, bool, float, const CFluidUVMotion&, float, float, float, + float, float, float, float, float, const CColor&, const CColor&, uint, uint, uint, + uint, int, int, int, float, uint, float, float, float, float, float, float, float, + float, const CColor&, uint, uint, bool, int, int, const uint*); + + // CEntity + ~CScriptWater() override; + void Accept(IVisitor& visitor) override; + void Think(float dt, CStateManager& mgr) override; + void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override; + + // CActor + void PreRender(CStateManager&, const CFrustumPlanes&) override; + void AddToRenderer(const CFrustumPlanes&, const CStateManager&) const override; + void Render(const CStateManager&) const override; + void CalculateRenderBounds() override; + void Touch(CActor&, CStateManager&) override; + EWeaponCollisionResponseTypes GetCollisionResponseType(const CVector3f&, const CVector3f&, + const CWeaponMode&, + int /*EProjectileAttrib?*/) const override; + CAABox GetSortingBounds(const CStateManager&) const override; bool CanRippleAtPoint(const CVector3f&) const; + // UpdateSplashInhabitants__12CScriptWaterFR13CStateManager + // RenderSurface__12CScriptWaterFv CFluidPlaneCPU& FluidPlane() { return *x1b4_fluidPlane; } + const CFluidPlaneCPU& GetFluidPlane() const { return *x1b4_fluidPlane; } + // GetWRSurfacePlane__12CScriptWaterCFv float GetSurfaceZ() const { return GetTriggerBoundsWR().GetMaxPoint().GetZ(); } + const CColor& GetUnderwaterFogColor() const { return x2a8_insideFogColor; } + // GetVisorRunoffEffect__12CScriptWaterCFv + // GetFluidType__12CScriptWaterCFv + // IsMorphing__12CScriptWaterCFv + // SetMorphing__12CScriptWaterFb + // GetFrustumPlanes__12CScriptWaterCFv + // GetSplashIndex__12CScriptWaterCFf + // GetSplashEffect__12CScriptWaterCFf + // GetSplashSound__12CScriptWaterCFf + // GetSplashEffectScale__12CScriptWaterCFf + // GetSplashColor__12CScriptWaterCFv + + // kSplashScales__12CScriptWater private: CFrustumPlanes x150_frustum; diff --git a/include/MetroidPrime/Tweaks/CTweakGame.hpp b/include/MetroidPrime/Tweaks/CTweakGame.hpp index 60286d4b..313747e3 100644 --- a/include/MetroidPrime/Tweaks/CTweakGame.hpp +++ b/include/MetroidPrime/Tweaks/CTweakGame.hpp @@ -35,7 +35,7 @@ public: float GetHardModeDamageMultiplier() const { return x60_hardmodeDamageMult; } float GetHardModeWeaponMultiplier() const { return x64_hardmodeWeaponMult; } -private: +// private: rstl::string x4_worldPrefix; rstl::string x14_defaultRoom; float x24_fov; diff --git a/include/rstl/list.hpp b/include/rstl/list.hpp index 643aa0d1..c0dd1750 100644 --- a/include/rstl/list.hpp +++ b/include/rstl/list.hpp @@ -14,7 +14,7 @@ public: class const_iterator; iterator erase(const iterator& item) { return do_erase(item.get_node()); } -private: +// private: struct node; node* do_erase(node* item); diff --git a/src/MetroidPrime/Cameras/CCameraManager.cpp b/src/MetroidPrime/Cameras/CCameraManager.cpp index 17c9ac80..0cca9fa0 100644 --- a/src/MetroidPrime/Cameras/CCameraManager.cpp +++ b/src/MetroidPrime/Cameras/CCameraManager.cpp @@ -1,18 +1,22 @@ #include "MetroidPrime/Cameras/CCameraManager.hpp" -#include "MetroidPrime/Cameras/CBallCamera.hpp" -#include "MetroidPrime/Cameras/CFirstPersonCamera.hpp" -#include "MetroidPrime/Cameras/CInterpolationCamera.hpp" - +#include "MetroidPrime/CFluidPlaneCPU.hpp" #include "MetroidPrime/CRumbleManager.hpp" - +#include "MetroidPrime/Cameras/CBallCamera.hpp" +#include "MetroidPrime/Cameras/CCinematicCamera.hpp" +#include "MetroidPrime/Cameras/CFirstPersonCamera.hpp" +#include "MetroidPrime/Cameras/CGameCamera.hpp" +#include "MetroidPrime/Cameras/CInterpolationCamera.hpp" #include "MetroidPrime/Player/CPlayer.hpp" - +#include "MetroidPrime/ScriptObjects/CScriptWater.hpp" #include "MetroidPrime/Tweaks/CTweakGame.hpp" #include "MetroidPrime/Tweaks/CTweakPlayer.hpp" #include "Kyoto/Audio/CSfxManager.hpp" #include "Kyoto/Graphics/CGraphics.hpp" +#include "Kyoto/Input/CFinalInput.hpp" + +#include "rstl/algorithm.hpp" float CCameraManager::sFirstPersonFOV = 55.f; float CCameraManager::sThirdPersonFOV = 60.f; @@ -71,14 +75,14 @@ void CCameraManager::CreateStandardCameras(CStateManager& mgr) { TUniqueId fpId = mgr.AllocateUniqueId(); x7c_fpCamera = rs_new CFirstPersonCamera(fpId, xf, plId, gpTweakPlayer->GetOrbitCameraSpeed(), - DefaultFirstPersonFov(), DefaultNearPlane(), - DefaultFarPlane(), DefaultAspect()); + DefaultFirstPersonFov(), DefaultNearPlane(), + DefaultFarPlane(), DefaultAspect()); mgr.AddObject(x7c_fpCamera); mgr.Player()->SetCameraState(CPlayer::kCS_FirstPerson, mgr); SetCurrentCameraId(fpId); TUniqueId ballId = mgr.AllocateUniqueId(); x80_ballCamera = rs_new CBallCamera(ballId, plId, xf, DefaultThirdPersonFov(), DefaultNearPlane(), - DefaultFarPlane(), DefaultAspect()); + DefaultFarPlane(), DefaultAspect()); mgr.AddObject(x80_ballCamera); TUniqueId interpId = mgr.AllocateUniqueId(); @@ -175,17 +179,17 @@ void CCameraManager::UpdateSfxListener(CStateManager& mgr) { void CCameraManager::UpdateRumble(float dt, CStateManager& mgr) { x30_shakeOffset = CVector3f::Zero(); - rstl::list< CCameraShakeData >::iterator it = x14_shakers.begin(); + 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(); + rstl::list< CCameraShakeData >::iterator curr = it; ++it; + curr->Update(dt, mgr); + if (curr->Done()) { + x14_shakers.erase(curr); + } else { + x30_shakeOffset += curr->GetPoint(); + } } if (!x14_shakers.empty() && !xa0_25_rumbling && xa0_24_pendingRumble) { @@ -195,11 +199,129 @@ void CCameraManager::UpdateRumble(float dt, CStateManager& mgr) { if (x90_rumbleCooldown > 0.f) { x90_rumbleCooldown -= dt; } else if (xa0_25_rumbling) { - xa0_24_pendingRumble = false; - xa0_25_rumbling = false; + xa0_25_rumbling = xa0_24_pendingRumble = false; } if (mgr.GetPlayer()->GetCameraState() != CPlayer::kCS_FirstPerson && !IsInCinematicCamera()) { x30_shakeOffset = CVector3f::Zero(); } } + +void CCameraManager::UpdateFog(float dt, CStateManager& mgr) { + if (x98_fogDensitySpeed != 0.f) { + x94_fogDensityFactor += dt * x98_fogDensitySpeed; + if ((x98_fogDensitySpeed > 0.f) ? x94_fogDensityFactor > x9c_fogDensityFactorTarget + : x94_fogDensityFactor < x9c_fogDensityFactorTarget) { + x94_fogDensityFactor = x9c_fogDensityFactorTarget; + x98_fogDensitySpeed = 0.f; + } + } + + CCameraFilterPass& pass = mgr.CameraFilterPass(CStateManager::kCFS_Four); + if (x74_fluidCounter) { + const CScriptWater* water = TCastToConstPtr< CScriptWater >(mgr.GetObjectById(GetFluidId())); + const CGameCamera& camera = GetCurrentCamera(mgr); + if (water) { + const float near = camera.GetNearClipDistance(); + const float far = CalculateFogDensity(mgr, water); + const CColor& color = water->GetUnderwaterFogColor(); + x3c_fog.SetFogExplicit(kRFM_PerspExp, color, CVector2f(near, far)); + if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::kPV_Thermal) { + pass.DisableFilter(0.f); + } else { + pass.SetFilter(CCameraFilterPass::kFT_Multiply, CCameraFilterPass::kFS_Fullscreen, 0.f, + color, kInvalidAssetId); + } + } + xa0_26_inWater = true; + } else if (xa0_26_inWater) { + mgr.CameraManager()->x3c_fog.DisableFog(); + pass.DisableFilter(0.f); + xa0_26_inWater = false; + } + + x3c_fog.Update(dt); +} + +float CCameraManager::CalculateFogDensity(CStateManager& mgr, const CScriptWater* water) { + float density = 1.f - water->GetFluidPlane().GetAlpha(); + if (mgr.GetPlayerState()->HasPowerUp(CPlayerState::kIT_GravitySuit)) { + density = density * gpTweakGame->GetGravityWaterFogDistanceRange() + + gpTweakGame->GetGravityWaterFogDistanceBase(); + } else { + density = + density * gpTweakGame->GetWaterFogDistanceRange() + gpTweakGame->GetWaterFogDistanceBase(); + } + return density * x94_fogDensityFactor; +} + +void CCameraManager::SetFogDensity(float fogDensityTarget, float fogDensitySpeed) { + x9c_fogDensityFactorTarget = fogDensityTarget; + if (x9c_fogDensityFactorTarget < x94_fogDensityFactor) { + x98_fogDensitySpeed = -fogDensitySpeed; + } else { + x98_fogDensitySpeed = fogDensitySpeed; + } +} + +void CCameraManager::Update(float dt, CStateManager& mgr) { + UpdateCameraHints(dt, mgr); + ThinkCameras(dt, mgr); + UpdateSfxListener(mgr); + UpdateRumble(dt, mgr); + UpdateFog(dt, mgr); +} + +void CCameraManager::SetInsideFluid(bool isInside, TUniqueId fluidId) { + if (isInside) { + ++x74_fluidCounter; + x78_fluidId = fluidId; + } else { + --x74_fluidCounter; + } +} + +void CCameraManager::ProcessInput(const CFinalInput& input, CStateManager& mgr) { + CObjectList& objList = mgr.ObjectListById(kOL_GameCamera); + int idx = objList.GetFirstObjectIndex(); + while (idx != -1) { + CGameCamera* camera = reinterpret_cast< CGameCamera* >(objList[idx]); + if (camera != nullptr && camera->GetControllerNumber() == input.ControllerNumber()) { + camera->ProcessInput(input, mgr); + } + idx = objList.GetNextObjectIndex(idx); + } +} + +void CCameraManager::AddCinemaCamera(TUniqueId uid, CStateManager& mgr) { + if (x4_cineCameras.empty()) { + EnterCinematic(mgr); + } + + RemoveCinemaCamera(uid, mgr); + x4_cineCameras.reserve(x4_cineCameras.size() + 1); + x4_cineCameras.push_back(uid); + + if (CCinematicCamera* cam = TCastToPtr< CCinematicCamera >(mgr.ObjectById(uid))) { + // Into player eye + if ((cam->GetFlags() & 0x4) != 0) { + float duration = cam->GetDuration(); + float time = 4.f; + float delayTime = duration - 4.f; + if (delayTime < 0.f) { + delayTime = 0.f; + time = duration; + } + cam->SetFovInterpolation(cam->GetFov(), sFirstPersonFOV, time, delayTime); + } + } +} + +// TODO nonmatching +void CCameraManager::RemoveCinemaCamera(TUniqueId uid, CStateManager& mgr) { + rstl::vector< TUniqueId >::iterator it = + rstl::find(x4_cineCameras.begin(), x4_cineCameras.end(), uid); + if (it != x4_cineCameras.end()) { + x4_cineCameras.erase(it); + } +}