Add CCameraManager

Former-commit-id: 50a6575c49
This commit is contained in:
Phillip Stephens 2022-11-06 16:20:46 -08:00
parent c20c3e399c
commit 404b4276fe
11 changed files with 226 additions and 69 deletions

View File

@ -77,28 +77,28 @@ lbl_805A9DC0:
.section .sdata
.balign 8
.global lbl_805A6BD0
lbl_805A6BD0:
.global sFirstPersonFOV__14CCameraManager
sFirstPersonFOV__14CCameraManager:
# ROM: 0x3F4570
.4byte 0x425C0000
.global lbl_805A6BD4
lbl_805A6BD4:
.global sThirdPersonFOV__14CCameraManager
sThirdPersonFOV__14CCameraManager:
# ROM: 0x3F4574
.4byte 0x42700000
.global lbl_805A6BD8
lbl_805A6BD8:
.global sNearPlane__14CCameraManager
sNearPlane__14CCameraManager:
# ROM: 0x3F4578
.float 0.2
.global lbl_805A6BDC
lbl_805A6BDC:
.global sFarPlane__14CCameraManager
sFarPlane__14CCameraManager:
# ROM: 0x3F457C
.4byte 0x443B8000
.global lbl_805A6BE0
lbl_805A6BE0:
.global sAspectRatio__14CCameraManager
sAspectRatio__14CCameraManager:
# ROM: 0x3F4580
.4byte 0x3FB5C28F
@ -2641,7 +2641,7 @@ lbl_8000B3E0:
/* 8000B440 000083A0 FC 60 08 90 */ fmr f3, f1
lbl_8000B444:
/* 8000B444 000083A4 C0 23 01 5C */ lfs f1, 0x15c(r3)
/* 8000B448 000083A8 C0 4D 80 10 */ lfs f2, lbl_805A6BD0@sda21(r13)
/* 8000B448 000083A8 C0 4D 80 10 */ lfs f2, sFirstPersonFOV__14CCameraManager@sda21(r13)
/* 8000B44C 000083AC 48 04 FA CD */ bl SetFovInterpolation__11CGameCameraFffff
lbl_8000B450:
/* 8000B450 000083B0 80 01 00 34 */ lwz r0, 0x34(r1)
@ -2754,7 +2754,7 @@ Update__14CCameraManagerFfR13CStateManager:
/* 8000B5C4 00008524 38 21 00 20 */ addi r1, r1, 0x20
/* 8000B5C8 00008528 4E 80 00 20 */ blr
.global SetFogDensity__14CCameraManagerFfFf
.global SetFogDensity__14CCameraManagerFfff
SetFogDensity__14CCameraManagerFfFf:
/* 8000B5CC 0000852C D0 23 00 9C */ stfs f1, 0x9c(r3)
/* 8000B5D0 00008530 C0 23 00 9C */ lfs f1, 0x9c(r3)
@ -3534,27 +3534,27 @@ lbl_8000C06C:
.global DefaultAspect__14CCameraManagerFv
DefaultAspect__14CCameraManagerFv:
/* 8000C0B8 00009018 C0 2D 80 20 */ lfs f1, lbl_805A6BE0@sda21(r13)
/* 8000C0B8 00009018 C0 2D 80 20 */ lfs f1, sAspectRatio__14CCameraManager@sda21(r13)
/* 8000C0BC 0000901C 4E 80 00 20 */ blr
.global DefaultFarPlane__14CCameraManagerFv
DefaultFarPlane__14CCameraManagerFv:
/* 8000C0C0 00009020 C0 2D 80 1C */ lfs f1, lbl_805A6BDC@sda21(r13)
/* 8000C0C0 00009020 C0 2D 80 1C */ lfs f1, sFarPlane__14CCameraManager@sda21(r13)
/* 8000C0C4 00009024 4E 80 00 20 */ blr
.global DefaultNearPlane__14CCameraManagerFv
DefaultNearPlane__14CCameraManagerFv:
/* 8000C0C8 00009028 C0 2D 80 18 */ lfs f1, lbl_805A6BD8@sda21(r13)
/* 8000C0C8 00009028 C0 2D 80 18 */ lfs f1, sNearPlane__14CCameraManager@sda21(r13)
/* 8000C0CC 0000902C 4E 80 00 20 */ blr
.global DefaultFirstPersonFov__14CCameraManagerFv
DefaultFirstPersonFov__14CCameraManagerFv:
/* 8000C0D0 00009030 C0 2D 80 10 */ lfs f1, lbl_805A6BD0@sda21(r13)
/* 8000C0D0 00009030 C0 2D 80 10 */ lfs f1, sFirstPersonFOV__14CCameraManager@sda21(r13)
/* 8000C0D4 00009034 4E 80 00 20 */ blr
.global DefaultThirdPersonFov__14CCameraManagerFv
DefaultThirdPersonFov__14CCameraManagerFv:
/* 8000C0D8 00009038 C0 2D 80 14 */ lfs f1, lbl_805A6BD4@sda21(r13)
/* 8000C0D8 00009038 C0 2D 80 14 */ lfs f1, sThirdPersonFOV__14CCameraManager@sda21(r13)
/* 8000C0DC 0000903C 4E 80 00 20 */ blr
.global __ct__14CCameraManagerF9TUniqueId
@ -3640,7 +3640,7 @@ __ct__14CCameraManagerF9TUniqueId:
/* 8000C218 00009178 88 1F 03 B8 */ lbz r0, 0x3b8(r31)
/* 8000C21C 0000917C 51 60 36 72 */ rlwimi r0, r11, 6, 0x19, 0x19
/* 8000C220 00009180 98 1F 03 B8 */ stb r0, 0x3b8(r31)
/* 8000C224 00009184 C0 0D 80 14 */ lfs f0, lbl_805A6BD4@sda21(r13)
/* 8000C224 00009184 C0 0D 80 14 */ lfs f0, sThirdPersonFOV__14CCameraManager@sda21(r13)
/* 8000C228 00009188 D0 1F 03 BC */ stfs f0, 0x3bc(r31)
/* 8000C22C 0000918C D0 A1 00 08 */ stfs f5, 8(r1)
/* 8000C230 00009190 D0 A1 00 0C */ stfs f5, 0xc(r1)
@ -3668,9 +3668,9 @@ __ct__14CCameraManagerF9TUniqueId:
/* 8000C288 000091E8 EC 21 10 28 */ fsubs f1, f1, f2
/* 8000C28C 000091EC EC 00 10 28 */ fsubs f0, f0, f2
/* 8000C290 000091F0 EC 01 00 24 */ fdivs f0, f1, f0
/* 8000C294 000091F4 D0 0D 80 20 */ stfs f0, lbl_805A6BE0@sda21(r13)
/* 8000C294 000091F4 D0 0D 80 20 */ stfs f0, sAspectRatio__14CCameraManager@sda21(r13)
/* 8000C298 000091F8 C0 04 00 24 */ lfs f0, 0x24(r4)
/* 8000C29C 000091FC D0 0D 80 10 */ stfs f0, lbl_805A6BD0@sda21(r13)
/* 8000C29C 000091FC D0 0D 80 10 */ stfs f0, sFirstPersonFOV__14CCameraManager@sda21(r13)
/* 8000C2A0 00009200 83 E1 00 3C */ lwz r31, 0x3c(r1)
/* 8000C2A4 00009204 80 01 00 44 */ lwz r0, 0x44(r1)
/* 8000C2A8 00009208 7C 08 03 A6 */ mtlr r0

View File

@ -39,7 +39,7 @@ LIBS = [
"objects": [
["MetroidPrime/main", False],
"MetroidPrime/IRenderer",
"MetroidPrime/Cameras/CCameraManager",
["MetroidPrime/Cameras/CCameraManager", False],
["MetroidPrime/CControlMapper", True],
"MetroidPrime/Cameras/CFirstPersonCamera",
["MetroidPrime/CObjectList", True],

View File

@ -3,6 +3,7 @@
#include "types.h"
#include "Kyoto/Audio/CAudioSys.hpp"
#include "Kyoto/Audio/CSfxHandle.hpp"
struct _SND_REVSTD_DELAYLINE {
@ -84,6 +85,10 @@ public:
static CSfxHandle AddEmitter(ushort id, const CVector3f& pos, const CVector3f& dir, uchar vol,
bool useAcoustics, bool looped, short prio = kMedPriority,
int areaId = kAllAreas);
static void AddListener(ESfxChannels channel, const CVector3f& pos, const CVector3f& dir,
const CVector3f& vec1, const CVector3f& vec2, float f1, float f2,
uint w1, uchar maxVolume, float f3);
static void Shutdown();
static ushort TranslateSFXID(ushort);

View File

@ -116,6 +116,16 @@ enum ERglCullMode {
kCM_All = GX_CULL_ALL,
};
struct CViewport {
int mLeft;
int mTop;
int mWidth;
int mHeight;
float mHalfWidth;
float mHalfHeight;
};
class CTimeProvider;
class CGraphics {
@ -132,6 +142,7 @@ public:
static void StreamVertex(const float*);
static void StreamEnd();
static const CViewport& GetViewport() { return mViewport; }
static const CTransform4f& GetViewMatrix() { return mViewMatrix; }
static const CTransform4f& GetModelMatrix() { return mModelMatrix; }
static void SetBrightness(float b) { mBrightness = b; }
@ -165,6 +176,7 @@ public:
private:
static CTransform4f mViewMatrix;
static CTransform4f mModelMatrix;
static CViewport mViewport;
static float mBrightness;
};

View File

@ -3,49 +3,10 @@
#include "types.h"
#include "Kyoto/Graphics/CColor.hpp"
#include "Kyoto/Math/CVector2f.hpp"
enum ERglFogMode {
kRFM_None = GX_FOG_NONE,
kRFM_PerspLin = GX_FOG_PERSP_LIN,
kRFM_PerspExp = GX_FOG_PERSP_EXP,
kRFM_PerspExp2 = GX_FOG_ORTHO_EXP2,
kRFM_PerspRevExp = GX_FOG_PERSP_REVEXP,
kRFM_PerspRevExp2 = GX_FOG_PERSP_REVEXP2,
kRFM_OrthoLin = GX_FOG_ORTHO_LIN,
kRFM_OrthoExp = GX_FOG_ORTHO_EXP,
kRFM_OrthoExp2 = GX_FOG_ORTHO_EXP2,
kRFM_OrthoRevExp = GX_FOG_ORTHO_REVEXP,
kRFM_OrthoRevExp2 = GX_FOG_ORTHO_REVEXP2,
};
class CAreaFog {
private:
ERglFogMode x0_fogMode;
CVector2f x4_rangeCur;
CVector2f xc_rangeTarget;
CVector2f x14_rangeDelta;
CColor x1c_colorCur;
unkptr x20_;
unkptr x24_;
CColor x28_colorTarget;
unkptr x2c_;
unkptr x30_;
float x34_colorDelta;
public:
void SetCurrent() const;
void Update(float dt);
void RollFogOut(float rangeDelta, float colorDelta, const CColor& color);
void FadeFog(ERglFogMode, const CColor& color, const CVector2f& vec1, float,
const CVector2f& vec2);
void SetFogExplicit(ERglFogMode mode, const CColor& color, const CVector2f& range);
bool IsFogDisabled() const;
void DisableFog();
};
CHECK_SIZEOF(CAreaFog, 0x38)
#endif

View File

@ -5,15 +5,35 @@
#include "MetroidPrime/TGameTypes.hpp"
#include "Kyoto/Graphics/CColor.hpp"
#include "Kyoto/IObjectStore.hpp"
#include "Kyoto/Math/CAABox.hpp"
#include "Kyoto/Math/CTransform4f.hpp"
#include "Kyoto/Math/CVector2f.hpp"
#include "rstl/auto_ptr.hpp"
#include "rstl/list.hpp"
#include "rstl/pair.hpp"
#include "rstl/rc_ptr.hpp"
#include "rstl/single_ptr.hpp"
#include "rstl/vector.hpp"
#include "rstl/optional_object.hpp"
enum ERglFogMode {
kRFM_None = GX_FOG_NONE,
kRFM_PerspLin = GX_FOG_PERSP_LIN,
kRFM_PerspExp = GX_FOG_PERSP_EXP,
kRFM_PerspExp2 = GX_FOG_ORTHO_EXP2,
kRFM_PerspRevExp = GX_FOG_PERSP_REVEXP,
kRFM_PerspRevExp2 = GX_FOG_PERSP_REVEXP2,
kRFM_OrthoLin = GX_FOG_ORTHO_LIN,
kRFM_OrthoExp = GX_FOG_ORTHO_EXP,
kRFM_OrthoExp2 = GX_FOG_ORTHO_EXP2,
kRFM_OrthoRevExp = GX_FOG_ORTHO_REVEXP,
kRFM_OrthoRevExp2 = GX_FOG_ORTHO_REVEXP2,
};
class IGameArea {
public:
@ -32,10 +52,35 @@ class Dock;
class CToken;
class IDvdRequest;
class CScriptAreaAttributes;
class CAreaFog;
class CGameArea : public IGameArea {
public:
class CAreaFog {
private:
ERglFogMode x0_fogMode;
CVector2f x4_rangeCur;
CVector2f xc_rangeTarget;
CVector2f x14_rangeDelta;
CColor x1c_colorCur;
unkptr x20_;
unkptr x24_;
CColor x28_colorTarget;
unkptr x2c_;
unkptr x30_;
float x34_colorDelta;
public:
CAreaFog();
void SetCurrent() const;
void Update(float dt);
void RollFogOut(float rangeDelta, float colorDelta, const CColor& color);
void FadeFog(ERglFogMode, const CColor& color, const CVector2f& vec1, float,
const CVector2f& vec2);
void SetFogExplicit(ERglFogMode mode, const CColor& color, const CVector2f& range);
bool IsFogDisabled() const;
void DisableFog();
};
~CGameArea();
const CTransform4f& IGetTM() const override;
CAssetId IGetStringTableAssetId() const override;
@ -91,8 +136,8 @@ public:
struct CPostConstructed {
uchar x0_pad[0x10c4];
rstl::single_ptr<CAreaFog> x10c4_areaFog;
rstl::optional_object<void*> x10c8_sclyBuf; // was rstl::optional_object<void*>
rstl::single_ptr< CAreaFog > x10c4_areaFog;
rstl::optional_object< void* > x10c8_sclyBuf; // was rstl::optional_object<void*>
u32 x10d0_sclySize;
const u8* x10d4_firstMatPtr;
const CScriptAreaAttributes* x10d8_areaAttributes;
@ -103,11 +148,12 @@ public:
const CAreaFog* GetAreaFog() const { return x12c_postConstructed->x10c4_areaFog.get(); }
CAreaFog* AreaFog() { return x12c_postConstructed->x10c4_areaFog.get(); }
EOcclusionState GetOcclusionState() const { return x12c_postConstructed->x10dc_occlusionState; }
private:
uchar x110_pad[0x1c];
rstl::single_ptr<CPostConstructed> x12c_postConstructed;
rstl::single_ptr< CPostConstructed > x12c_postConstructed;
};
//CHECK_SIZEOF(CGamearea::CAreaFog, 0x38)
#endif // _CGAMEAREA

View File

@ -3,8 +3,9 @@
#include "types.h"
#include "MetroidPrime/CAreaFog.hpp"
#include "MetroidPrime/CGameArea.hpp"
#include "MetroidPrime/TGameTypes.hpp"
#include "MetroidPrime/Cameras/CCameraShakeData.hpp"
#include "Kyoto/Math/CVector3f.hpp"
@ -21,11 +22,23 @@ class CInterpolationCamera;
class CStateManager;
class CCameraManager {
static float sFirstPersonFOV;
static float sThirdPersonFOV;
static float sNearPlane;
static float sFarPlane;
static float sAspectRatio;
static float lbl_805A6BE4;
static float lbl_805A6BE8;
public:
CCameraManager(TUniqueId curCamera);
void CreateStandardCameras(CStateManager& mgr);
CGameCamera& CurrentCamera(CStateManager& mgr) const;
const CGameCamera& GetCurrentCamera(const CStateManager& mgr) const;
CFirstPersonCamera* FirstPersonCamera() const /* map */ { return x7c_fpCamera; }
const CFirstPersonCamera* GetFirstPersonCamera() const { return x7c_fpCamera; }
void SetCurrentCameraId(TUniqueId camId);
void SetPlayerCamera(CStateManager& mgr, TUniqueId newCamId);
void SetFogDensity(float fogDensityTarget, float fogDensitySpeed);
bool IsInCinematicCamera() const;
@ -33,17 +46,23 @@ public:
void RemoveCameraShaker(int id);
int AddCameraShaker(const CCameraShakeData& data, bool sfx);
static float DefaultThirdPersonFov();
void SetCurrentFov(float fov) { x3bc_curFov = fov; }
int GetFluidCounter() const { return x74_fluidCounter; }
static float DefaultThirdPersonFov();
static float DefaultFirstPersonFov();
static float DefaultNearPlane();
static float DefaultFarPlane();
static float DefaultAspect();
private:
TUniqueId x0_curCameraId;
rstl::vector< TUniqueId > x4_cineCameras;
rstl::list< CCameraShakeData > x14_shakers;
uint x2c_lastShakeId;
CVector3f x30_shakeOffset;
CAreaFog x3c_fog;
CGameArea::CAreaFog x3c_fog;
int x74_fluidCounter;
TUniqueId x78_fluidId;
CFirstPersonCamera* x7c_fpCamera;

View File

@ -5,7 +5,11 @@
class CFirstPersonCamera : public CGameCamera {
public:
CFirstPersonCamera(const TUniqueId& uid, const CTransform4f& xf, TUniqueId watchedObj,
float orbitCameraSpeed, float fov, float nearz, float farz, float aspect);
void SetScriptPitchId(TUniqueId uid) { x1c4_pitchId = uid; }
void ProcessInput(const CFinalInput& input, CStateManager& mgr);
void Reset(const CTransform4f& xf, CStateManager& mgr);
private:
float x188_orbitCameraSpeed;

View File

@ -0,0 +1,24 @@
#ifndef _CINTERPOLATIONCAMERA
#define _CINTERPOLATIONCAMERA
#include "MetroidPrime/Cameras/CGameCamera.hpp"
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;
private:
TUniqueId x188_targetId;
float x18c_time;
float x190_maxTime;
CTransform4f x194_;
CVector3f x1c4_lookPos;
float x1d0_positionSpeed;
float x1d4_rotationSpeed;
bool x1d8_24_sinusoidal : 1;
float x1dc_closeInAngle;
};
#endif // _CINTERPOLATIONCAMERA

View File

@ -175,7 +175,7 @@ public:
// CPlayer
virtual bool IsTransparent();
CVector3f GetBallPosition() const;
CVector3f GetEyePosition() const;
float GetEyeHeight() const;
@ -214,6 +214,7 @@ public:
bool IsInFreeLook() const { return x3dc_inFreeLook; }
bool GetFreeLookStickState() const { return x3de_lookAnalogHeld; }
EPlayerCameraState GetCameraState() const { return x2f4_cameraState; }
void SetCameraState(EPlayerCameraState state, CStateManager& mgr);
EGunHolsterState GetGunHolsterState() const { return x498_gunHolsterState; }
NPlayer::EPlayerMovementState GetPlayerMovementState() const { return x258_movementState; }

View File

@ -0,0 +1,85 @@
#include "MetroidPrime/Cameras/CCameraManager.hpp"
#include "MetroidPrime/Cameras/CBallCamera.hpp"
#include "MetroidPrime/Cameras/CFirstPersonCamera.hpp"
#include "MetroidPrime/Cameras/CInterpolationCamera.hpp"
#include "MetroidPrime/Player/CPlayer.hpp"
#include "MetroidPrime/Tweaks/CTweakGame.hpp"
#include "MetroidPrime/Tweaks/CTweakPlayer.hpp"
#include "Kyoto/Audio/CSfxManager.hpp"
#include "Kyoto/Graphics/CGraphics.hpp"
float CCameraManager::sFirstPersonFOV = 55.f;
float CCameraManager::sThirdPersonFOV = 60.f;
float CCameraManager::sNearPlane = 0.2f;
float CCameraManager::sFarPlane = 750.f;
float CCameraManager::sAspectRatio = 1.42f;
float CCameraManager::lbl_805A6BE4 = 100.f;
float CCameraManager::lbl_805A6BE8 = 127.f;
CCameraManager::CCameraManager(TUniqueId curCamera)
: x0_curCameraId(curCamera)
, x2c_lastShakeId(0)
, x30_shakeOffset(CVector3f::Zero())
, x74_fluidCounter(0)
, x78_fluidId(kInvalidUniqueId)
, x7c_fpCamera(nullptr)
, x80_ballCamera(nullptr)
, x84_rumbleId(0)
, x88_interpCamera(nullptr)
, x8c_(-1)
, x90_rumbleCooldown(0.f)
, x94_fogDensityFactor(1.f)
, x98_fogDensitySpeed(0.f)
, x9c_fogDensityFactorTarget(1.f)
, xa0_24_pendingRumble(false)
, xa0_25_rumbling(false)
, xa0_26_inWater(false)
, xa2_spindleCamId(kInvalidUniqueId)
, xa4_pathCamId(kInvalidUniqueId)
, xa6_camHintId(kInvalidUniqueId)
, xa8_hintPriority(1000)
, x3b8_24_(false)
, x3b8_25_(false)
, x3bc_curFov(sThirdPersonFOV) {
CSfxManager::AddListener(CSfxManager::kSC_Game, CVector3f::Zero(), CVector3f::Zero(),
CVector3f(1.f, 0.f, 0.f), CVector3f(0.f, 0.f, 1.f), 50.f, 50.f, 1,
CAudioSys::kMaxVolume, 1000.f);
sAspectRatio = (float)CGraphics::GetViewport().mWidth / CGraphics::GetViewport().mHeight;
sFirstPersonFOV = gpTweakGame->GetFirstPersonFOV();
}
float CCameraManager::DefaultThirdPersonFov() { return sThirdPersonFOV; }
float CCameraManager::DefaultFirstPersonFov() { return sFirstPersonFOV; }
float CCameraManager::DefaultNearPlane() { return sNearPlane; }
float CCameraManager::DefaultFarPlane() { return sFarPlane; }
float CCameraManager::DefaultAspect() { return sAspectRatio; }
void CCameraManager::CreateStandardCameras(CStateManager& mgr) {
TUniqueId plId = mgr.GetPlayer()->GetUniqueId();
CTransform4f xf = CTransform4f::Identity();
xf.SetTranslation(mgr.GetPlayer()->GetEyePosition());
TUniqueId fpId = mgr.AllocateUniqueId();
x7c_fpCamera = new CFirstPersonCamera(fpId, xf, plId, gpTweakPlayer->GetOrbitCameraSpeed(),
DefaultFirstPersonFov(), DefaultNearPlane(),
DefaultFarPlane(), DefaultAspect());
mgr.AddObject(x7c_fpCamera);
mgr.Player()->SetCameraState(CPlayer::kCS_FirstPerson, mgr);
SetCurrentCameraId(fpId);
TUniqueId ballId = mgr.AllocateUniqueId();
x80_ballCamera = new CBallCamera(ballId, plId, xf, DefaultThirdPersonFov(), DefaultNearPlane(),
DefaultFarPlane(), DefaultAspect());
mgr.AddObject(x80_ballCamera);
TUniqueId interpId = mgr.AllocateUniqueId();
x88_interpCamera = new CInterpolationCamera(interpId, xf);
mgr.AddObject(x88_interpCamera);
}