diff --git a/asm/MetroidPrime/ScriptObjects/CScriptTimer.s b/asm/MetroidPrime/ScriptObjects/CScriptTimer.s index a32fdece..17dd8e07 100644 --- a/asm/MetroidPrime/ScriptObjects/CScriptTimer.s +++ b/asm/MetroidPrime/ScriptObjects/CScriptTimer.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803DADD8 -lbl_803DADD8: +.global __vt__12CScriptTimer +__vt__12CScriptTimer: # ROM: 0x3D7DD8 .4byte 0 .4byte 0 @@ -231,9 +231,9 @@ __dt__12CScriptTimerFv: /* 80092A4C 0008F9AC 93 C1 00 08 */ stw r30, 8(r1) /* 80092A50 0008F9B0 7C 7E 1B 79 */ or. r30, r3, r3 /* 80092A54 0008F9B4 41 82 00 28 */ beq lbl_80092A7C -/* 80092A58 0008F9B8 3C A0 80 3E */ lis r5, lbl_803DADD8@ha +/* 80092A58 0008F9B8 3C A0 80 3E */ lis r5, __vt__12CScriptTimer@ha /* 80092A5C 0008F9BC 38 80 00 00 */ li r4, 0 -/* 80092A60 0008F9C0 38 05 AD D8 */ addi r0, r5, lbl_803DADD8@l +/* 80092A60 0008F9C0 38 05 AD D8 */ addi r0, r5, __vt__12CScriptTimer@l /* 80092A64 0008F9C4 90 1E 00 00 */ stw r0, 0(r30) /* 80092A68 0008F9C8 4B FB E8 0D */ bl __dt__7CEntityFv /* 80092A6C 0008F9CC 7F E0 07 35 */ extsh. r0, r31 @@ -272,9 +272,9 @@ lbl_80092A7C: /* 80092AE0 0008FA40 7C 87 23 78 */ mr r7, r4 /* 80092AE4 0008FA44 38 81 00 08 */ addi r4, r1, 8 /* 80092AE8 0008FA48 4B FB E8 3D */ bl "__ct__7CEntityF9TUniqueIdRC11CEntityInfobRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>" -/* 80092AEC 0008FA4C 3C 80 80 3E */ lis r4, lbl_803DADD8@ha +/* 80092AEC 0008FA4C 3C 80 80 3E */ lis r4, __vt__12CScriptTimer@ha /* 80092AF0 0008FA50 7F A3 EB 78 */ mr r3, r29 -/* 80092AF4 0008FA54 38 04 AD D8 */ addi r0, r4, lbl_803DADD8@l +/* 80092AF4 0008FA54 38 04 AD D8 */ addi r0, r4, __vt__12CScriptTimer@l /* 80092AF8 0008FA58 90 1D 00 00 */ stw r0, 0(r29) /* 80092AFC 0008FA5C D3 DD 00 34 */ stfs f30, 0x34(r29) /* 80092B00 0008FA60 D3 DD 00 38 */ stfs f30, 0x38(r29) diff --git a/configure.py b/configure.py index cb892475..1a9126d1 100755 --- a/configure.py +++ b/configure.py @@ -97,7 +97,7 @@ LIBS = [ "MetroidPrime/Weapons/CBomb", "MetroidPrime/Tweaks/CTweakBall", "MetroidPrime/Player/CPlayerState", - "MetroidPrime/ScriptObjects/CScriptTimer", + ["MetroidPrime/ScriptObjects/CScriptTimer", True], "MetroidPrime/Cameras/CCinematicCamera", "MetroidPrime/CAutoMapper", ["MetroidPrime/ScriptObjects/CScriptCounter", True], diff --git a/include/MetroidPrime/ScriptObjects/CScriptTimer.hpp b/include/MetroidPrime/ScriptObjects/CScriptTimer.hpp new file mode 100644 index 00000000..ffe8306f --- /dev/null +++ b/include/MetroidPrime/ScriptObjects/CScriptTimer.hpp @@ -0,0 +1,30 @@ +#ifndef _CSCRIPTTIMER +#define _CSCRIPTTIMER + +#include "MetroidPrime/CEntity.hpp" + +class CScriptTimer : public CEntity { + float x34_time; + float x38_startTime; + float x3c_maxRandDelay; + uchar x40_loop; + bool x41_autoStart; + bool x42_isTiming; + + public: + CScriptTimer(TUniqueId, const rstl::string&, const CEntityInfo&, float, float, bool, bool, bool); + ~CScriptTimer(); + + void Reset(CStateManager&); + void AcceptScriptMsg(EScriptObjectMessage, TUniqueId, CStateManager&); + void ApplyTime(float, CStateManager&); + void Think(float, CStateManager&); + void Accept(IVisitor&); + + bool IsTiming() const { return x42_isTiming; } + void StartTiming(bool isTiming) { + x42_isTiming = isTiming; + } +}; + +#endif // _CSCRIPTTIMER diff --git a/obj_files.mk b/obj_files.mk index 8fdb7af8..2ff4c815 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -64,7 +64,7 @@ METROIDPRIME :=\ $(BUILD_DIR)/asm/MetroidPrime/Weapons/CBomb.o\ $(BUILD_DIR)/asm/MetroidPrime/Tweaks/CTweakBall.o\ $(BUILD_DIR)/asm/MetroidPrime/Player/CPlayerState.o\ - $(BUILD_DIR)/asm/MetroidPrime/ScriptObjects/CScriptTimer.o\ + $(BUILD_DIR)/src/MetroidPrime/ScriptObjects/CScriptTimer.o\ $(BUILD_DIR)/asm/MetroidPrime/Cameras/CCinematicCamera.o\ $(BUILD_DIR)/asm/MetroidPrime/CAutoMapper.o\ $(BUILD_DIR)/src/MetroidPrime/ScriptObjects/CScriptCounter.o\ diff --git a/src/MetroidPrime/ScriptObjects/CScriptTimer.cpp b/src/MetroidPrime/ScriptObjects/CScriptTimer.cpp new file mode 100644 index 00000000..2baa1ae9 --- /dev/null +++ b/src/MetroidPrime/ScriptObjects/CScriptTimer.cpp @@ -0,0 +1,98 @@ +#include "MetroidPrime/ScriptObjects/CScriptTimer.hpp" + +#include "MetroidPrime/CStateManager.hpp" + +CScriptTimer::CScriptTimer(TUniqueId uid, const rstl::string& name, const CEntityInfo& info, + float startTime, float maxRandDelay, bool loop, bool autoStart, + bool active) +: CEntity(uid, info, active, name) +, x34_time(startTime) +, x38_startTime(startTime) +, x3c_maxRandDelay(maxRandDelay) +, x40_loop(loop) +, x41_autoStart(autoStart) +, x42_isTiming(autoStart) {} + +CScriptTimer::~CScriptTimer() {} + +void CScriptTimer::Reset(CStateManager& mgr) { + const float rDt = mgr.GetActiveRandom()->Float(); + x34_time = (x3c_maxRandDelay * rDt) + x38_startTime; +} + +void CScriptTimer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId, + CStateManager& stateMgr) { + switch (msg) { + case kSM_Start: + if (GetActive()) { + StartTiming(true); + } + break; + + case kSM_Stop: + if (GetActive()) { + StartTiming(false); + } + break; + + case kSM_Reset: + if (GetActive()) { + Reset(stateMgr); + if (x41_autoStart) { + StartTiming(true); + } + } + break; + + case kSM_StopAndReset: + if (GetActive()) { + Reset(stateMgr); + StartTiming(false); + } + break; + + + case kSM_ResetAndStart: + if (GetActive()) { + Reset(stateMgr); + StartTiming(true); + } + break; + } + CEntity::AcceptScriptMsg(msg, objId, stateMgr); +} + +void CScriptTimer::ApplyTime(float dt, CStateManager& mgr) { + if (x34_time > 0.f && GetActive()) { + x34_time -= dt; + if (x34_time <= 0.f) { + SendScriptMsgs(kSS_Zero, mgr, kSM_None); + + x42_isTiming = false; + if (!x40_loop) { + return; + } + + Reset(mgr); + if (!x41_autoStart) { + return; + } + + x42_isTiming = true; + } + } +} + +void CScriptTimer::Think(float dt, CStateManager& mgr) { + if (GetActive()) { + bool should = false; + if (IsTiming() && GetActive()) { + should = true; + } + if (should) { + ApplyTime(dt, mgr); + } + } +} + +void CScriptTimer::Accept(IVisitor& visitor) { visitor.Visit(*this); }