diff --git a/asm/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.s b/asm/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.s index b9a693f0..581afad9 100644 --- a/asm/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.s +++ b/asm/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.s @@ -1,6 +1,6 @@ .include "macros.inc" -.comm lbl_80572134, 0xC, 4 +.comm skScaleFactor__24CScriptCameraPitchVolume, 0xC, 4 .section .ctors, "wa" lbl_ctor: @@ -9,8 +9,8 @@ lbl_ctor: .section .data .balign 8 -.global lbl_803E7A70 -lbl_803E7A70: +.global __vt__24CScriptCameraPitchVolume +__vt__24CScriptCameraPitchVolume: # ROM: 0x3E4A70 .4byte 0 .4byte 0 @@ -63,9 +63,9 @@ __dt__24CScriptCameraPitchVolumeFv: /* 802264E8 00223448 93 C1 00 08 */ stw r30, 8(r1) /* 802264EC 0022344C 7C 7E 1B 79 */ or. r30, r3, r3 /* 802264F0 00223450 41 82 00 28 */ beq lbl_80226518 -/* 802264F4 00223454 3C A0 80 3E */ lis r5, lbl_803E7A70@ha +/* 802264F4 00223454 3C A0 80 3E */ lis r5, __vt__24CScriptCameraPitchVolume@ha /* 802264F8 00223458 38 80 00 00 */ li r4, 0 -/* 802264FC 0022345C 38 05 7A 70 */ addi r0, r5, lbl_803E7A70@l +/* 802264FC 0022345C 38 05 7A 70 */ addi r0, r5, __vt__24CScriptCameraPitchVolume@l /* 80226500 00223460 90 1E 00 00 */ stw r0, 0(r30) /* 80226504 00223464 4B E2 F1 ED */ bl __dt__6CActorFv /* 80226508 00223468 7F E0 07 35 */ extsh. r0, r31 @@ -337,12 +337,12 @@ Accept__24CScriptCameraPitchVolumeFR8IVisitor: /* 802268BC 0022381C 38 61 00 94 */ addi r3, r1, 0x94 /* 802268C0 00223820 38 80 FF FF */ li r4, -1 /* 802268C4 00223824 4B EF 01 89 */ bl __dt__10CModelDataFv -/* 802268C8 00223828 3C 80 80 3E */ lis r4, lbl_803E7A70@ha -/* 802268CC 0022382C 3C 60 80 57 */ lis r3, lbl_80572134@ha -/* 802268D0 00223830 38 04 7A 70 */ addi r0, r4, lbl_803E7A70@l +/* 802268C8 00223828 3C 80 80 3E */ lis r4, __vt__24CScriptCameraPitchVolume@ha +/* 802268CC 0022382C 3C 60 80 57 */ lis r3, skScaleFactor__24CScriptCameraPitchVolume@ha +/* 802268D0 00223830 38 04 7A 70 */ addi r0, r4, __vt__24CScriptCameraPitchVolume@l /* 802268D4 00223834 7F A4 EB 78 */ mr r4, r29 /* 802268D8 00223838 90 18 00 00 */ stw r0, 0(r24) -/* 802268DC 0022383C 3B 23 21 34 */ addi r25, r3, lbl_80572134@l +/* 802268DC 0022383C 3B 23 21 34 */ addi r25, r3, skScaleFactor__24CScriptCameraPitchVolume@l /* 802268E0 00223840 38 78 00 E8 */ addi r3, r24, 0xe8 /* 802268E4 00223844 38 A1 00 20 */ addi r5, r1, 0x20 /* 802268E8 00223848 C0 3C 00 08 */ lfs f1, 8(r28) @@ -359,8 +359,8 @@ Accept__24CScriptCameraPitchVolumeFR8IVisitor: /* 80226914 00223874 D0 01 00 20 */ stfs f0, 0x20(r1) /* 80226918 00223878 48 0A F6 7D */ bl __ct__6COBBoxFRC12CTransform4fRC9CVector3f /* 8022691C 0022387C C0 1E 00 00 */ lfs f0, 0(r30) -/* 80226920 00223880 3C 60 80 57 */ lis r3, lbl_80572134@ha -/* 80226924 00223884 38 A3 21 34 */ addi r5, r3, lbl_80572134@l +/* 80226920 00223880 3C 60 80 57 */ lis r3, skScaleFactor__24CScriptCameraPitchVolume@ha +/* 80226924 00223884 38 A3 21 34 */ addi r5, r3, skScaleFactor__24CScriptCameraPitchVolume@l /* 80226928 00223888 38 80 00 00 */ li r4, 0 /* 8022692C 0022388C D0 18 01 24 */ stfs f0, 0x124(r24) /* 80226930 00223890 7F 03 C3 78 */ mr r3, r24 @@ -396,8 +396,8 @@ Accept__24CScriptCameraPitchVolumeFR8IVisitor: .global __sinit_CScriptCameraPitchVolume_cpp __sinit_CScriptCameraPitchVolume_cpp: /* 802269A4 00223904 C0 02 B4 B8 */ lfs f0, lbl_805AD1D8@sda21(r2) -/* 802269A8 00223908 3C 60 80 57 */ lis r3, lbl_80572134@ha -/* 802269AC 0022390C D4 03 21 34 */ stfsu f0, lbl_80572134@l(r3) +/* 802269A8 00223908 3C 60 80 57 */ lis r3, skScaleFactor__24CScriptCameraPitchVolume@ha +/* 802269AC 0022390C D4 03 21 34 */ stfsu f0, skScaleFactor__24CScriptCameraPitchVolume@l(r3) /* 802269B0 00223910 D0 03 00 04 */ stfs f0, 4(r3) /* 802269B4 00223914 D0 03 00 08 */ stfs f0, 8(r3) /* 802269B8 00223918 4E 80 00 20 */ blr diff --git a/configure.py b/configure.py index 6bdfe51c..39e4b3d2 100755 --- a/configure.py +++ b/configure.py @@ -325,7 +325,7 @@ LIBS = [ "MetroidPrime/Enemies/CBabygoth", "MetroidPrime/Enemies/CEyeBall", "MetroidPrime/CIkChain", - "MetroidPrime/ScriptObjects/CScriptCameraPitchVolume", + ["MetroidPrime/ScriptObjects/CScriptCameraPitchVolume", True], "MetroidPrime/RumbleFxTable", "MetroidPrime/Enemies/CElitePirate", ["MetroidPrime/CRumbleManager", True], diff --git a/include/MetroidPrime/Cameras/CFirstPersonCamera.hpp b/include/MetroidPrime/Cameras/CFirstPersonCamera.hpp index 1cb60271..ee9d616d 100644 --- a/include/MetroidPrime/Cameras/CFirstPersonCamera.hpp +++ b/include/MetroidPrime/Cameras/CFirstPersonCamera.hpp @@ -5,6 +5,17 @@ class CFirstPersonCamera : public CGameCamera { public: + void SetScriptPitchId(TUniqueId uid) { x1c4_pitchId = uid; } + +private: + float x188_orbitCameraSpeed; + bool x18c_lockCamera; + CTransform4f x190_gunFollowXf; + float x1c0_pitch; + TUniqueId x1c4_pitchId; + bool x1c6_24_deferBallTransitionProcessing : 1; + CVector3f x1c8_closeInVec; + float x1d4_closeInTimer; }; #endif // _CFIRSTPERSONCAMERA diff --git a/include/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.hpp b/include/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.hpp new file mode 100644 index 00000000..503bd31c --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.hpp @@ -0,0 +1,38 @@ +#ifndef _CSCRIPTCAMERAPITCHVOLUME +#define _CSCRIPTCAMERAPITCHVOLUME + +#include "MetroidPrime/CActor.hpp" + +#include "Collision/COBBox.hpp" +#include "Kyoto/Math/CRelAngle.hpp" + +class CScriptCameraPitchVolume : public CActor { +public: + CScriptCameraPitchVolume(TUniqueId, bool, const rstl::string&, const CEntityInfo&, + const CVector3f&, const CTransform4f&, const CRelAngle&, + const CRelAngle&, float); + ~CScriptCameraPitchVolume(); + + void Accept(IVisitor& visitor) override; + void Think(float, CStateManager&) override; + rstl::optional_object< CAABox > GetTouchBounds() const override; + void Touch(CActor&, CStateManager&) override; + // float GetUpPitch() const { return x124_upPitch; } + // float GetDownPitch() const { return x128_downPitch; } + // const CVector3f& GetScale() const { return x12c_scale; } + float GetMaxInterpolationDistance() const { return x138_maxInterpDistance; } + void Entered(CStateManager&); + void Exited(CStateManager&); + +private: + static const CVector3f skScaleFactor; + COBBox xe8_obbox; + CRelAngle x124_upPitch; + CRelAngle x128_downPitch; + CVector3f x12c_scale; + float x138_maxInterpDistance; + bool x13c_24_entered : 1; + bool x13c_25_occupied : 1; +}; + +#endif // _CSCRIPTCAMERAPITCHVOLUME diff --git a/obj_files.mk b/obj_files.mk index 5229e977..d64dc1f4 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -290,7 +290,7 @@ METROIDPRIME :=\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CBabygoth.o\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CEyeBall.o\ $(BUILD_DIR)/asm/MetroidPrime/CIkChain.o\ - $(BUILD_DIR)/asm/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.o\ + $(BUILD_DIR)/src/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.o\ $(BUILD_DIR)/asm/MetroidPrime/RumbleFxTable.o\ $(BUILD_DIR)/asm/MetroidPrime/Enemies/CElitePirate.o\ $(BUILD_DIR)/src/MetroidPrime/CRumbleManager.o\ diff --git a/src/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.cpp b/src/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.cpp new file mode 100644 index 00000000..e9f8aae1 --- /dev/null +++ b/src/MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.cpp @@ -0,0 +1,68 @@ +#include "MetroidPrime/ScriptObjects/CScriptCameraPitchVolume.hpp" + +#include "MetroidPrime/CActorParameters.hpp" +#include "MetroidPrime/CStateManager.hpp" +#include "MetroidPrime/Cameras/CCameraManager.hpp" +#include "MetroidPrime/Cameras/CFirstPersonCamera.hpp" +#include "MetroidPrime/Player/CPlayer.hpp" + +const CVector3f CScriptCameraPitchVolume::skScaleFactor(0.5f, 0.5f, 0.5f); + +CScriptCameraPitchVolume::CScriptCameraPitchVolume(TUniqueId uid, bool active, + const rstl::string& name, + const CEntityInfo& info, const CVector3f& scale, + const CTransform4f& xf, const CRelAngle& upPitch, + const CRelAngle& downPitch, + float maxInterpDistance) +: CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(kMT_Trigger), + CActorParameters::None(), kInvalidUniqueId) +, xe8_obbox(xf, CVector3f::ByElementMultiply(scale, skScaleFactor)) +, x124_upPitch(upPitch) +, x128_downPitch(downPitch) +, x12c_scale(CVector3f::ByElementMultiply(scale, skScaleFactor)) +, x138_maxInterpDistance(maxInterpDistance) +, x13c_24_entered(false) +, x13c_25_occupied(false) {} + +void CScriptCameraPitchVolume::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +rstl::optional_object< CAABox > CScriptCameraPitchVolume::GetTouchBounds() const { + return xe8_obbox.CalculateAABox(CTransform4f::Identity()); +} + +void CScriptCameraPitchVolume::Touch(CActor& act, CStateManager& mgr) { + if (const CPlayer* player = TCastToConstPtr< CPlayer >(act)) { + rstl::optional_object< CAABox > box = act.GetTouchBounds(); + if (box) { + COBBox box2(COBBox::FromAABox(*box, CTransform4f::Identity())); + x13c_24_entered = xe8_obbox.OBBIntersectsBox(box2); + } + } +} + +void CScriptCameraPitchVolume::Think(float, CStateManager& mgr) { + if (!GetActive()) { + return; + } + + if (x13c_24_entered && !x13c_25_occupied) { + Entered(mgr); + } + if (!x13c_24_entered && x13c_25_occupied) { + Exited(mgr); + } + + x13c_24_entered = false; +} + +void CScriptCameraPitchVolume::Entered(CStateManager& mgr) { + x13c_25_occupied = true; + mgr.CameraManager()->FirstPersonCamera()->SetScriptPitchId(GetUniqueId()); +} + +void CScriptCameraPitchVolume::Exited(CStateManager& mgr) { + x13c_25_occupied = false; + mgr.CameraManager()->FirstPersonCamera()->SetScriptPitchId(kInvalidUniqueId); +} + +CScriptCameraPitchVolume::~CScriptCameraPitchVolume() {}