From e7ecda7a363d2fb91a84611de6433cecb0aa28f7 Mon Sep 17 00:00:00 2001 From: Luke Street Date: Tue, 4 Oct 2022 20:16:03 -0400 Subject: [PATCH] CScriptSpecialFunction progress & symbol updates Former-commit-id: 84d590be2fab8711a332f4260c4823c784bf6669 --- asm/MetroidPrime/ScriptLoader.s | 10 +- .../ScriptObjects/CScriptSpecialFunction.s | 20 +-- include/Kyoto/Audio/CSfxManager.hpp | 14 +- include/Kyoto/Input/CRumbleGenerator.hpp | 7 +- include/Kyoto/Input/CRumbleVoice.hpp | 26 ++- include/Kyoto/Math/CMath.hpp | 3 +- include/Kyoto/Math/CloseEnough.hpp | 18 +- include/Kyoto/TToken.hpp | 3 +- include/MetroidPrime/CActor.hpp | 6 +- include/MetroidPrime/CMain.hpp | 33 ++-- include/MetroidPrime/CModelData.hpp | 5 + include/MetroidPrime/CRumbleManager.hpp | 10 ++ include/MetroidPrime/CStateManager.hpp | 27 ++- .../ScriptObjects/CScriptSpecialFunction.hpp | 6 +- include/MetroidPrime/TCastTo.hpp | 4 +- include/rstl/optional_object.hpp | 16 +- include/rstl/red_black_tree.hpp | 6 +- include/rstl/vector.hpp | 10 +- libc/float.h | 2 + .../ScriptObjects/CScriptSpecialFunction.cpp | 160 +++++++++--------- 20 files changed, 234 insertions(+), 152 deletions(-) diff --git a/asm/MetroidPrime/ScriptLoader.s b/asm/MetroidPrime/ScriptLoader.s index 1df206d2..5d435d9e 100644 --- a/asm/MetroidPrime/ScriptLoader.s +++ b/asm/MetroidPrime/ScriptLoader.s @@ -3964,7 +3964,7 @@ lbl_800C8844: /* 800C89D8 000C5938 C8 01 00 C0 */ lfd f0, 0xc0(r1) /* 800C89DC 000C593C 93 61 00 28 */ stw r27, 0x28(r1) /* 800C89E0 000C5940 EC 60 18 28 */ fsubs f3, f0, f3 -/* 800C89E4 000C5944 48 08 A1 DD */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypeUsUsUs" +/* 800C89E4 000C5944 48 08 A1 DD */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoiiQ212CPlayerState9EItemTypeUsUsUs" /* 800C89E8 000C5948 7C 7C 1B 78 */ mr r28, r3 lbl_800C89EC: /* 800C89EC 000C594C 7F 20 07 75 */ extsb. r0, r25 @@ -5569,7 +5569,7 @@ lbl_800CA054: /* 800CA1A8 000C7108 C8 01 00 80 */ lfd f0, 0x80(r1) /* 800CA1AC 000C710C 93 61 00 28 */ stw r27, 0x28(r1) /* 800CA1B0 000C7110 EC 40 10 28 */ fsubs f2, f0, f2 -/* 800CA1B4 000C7114 48 08 8A 0D */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypeUsUsUs" +/* 800CA1B4 000C7114 48 08 8A 0D */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoiiQ212CPlayerState9EItemTypeUsUsUs" /* 800CA1B8 000C7118 7C 7D 1B 78 */ mr r29, r3 lbl_800CA1BC: /* 800CA1BC 000C711C 7F 40 07 75 */ extsb. r0, r26 @@ -5919,7 +5919,7 @@ lbl_800CA580: /* 800CA6C0 000C7620 93 41 00 20 */ stw r26, 0x20(r1) /* 800CA6C4 000C7624 93 41 00 24 */ stw r26, 0x24(r1) /* 800CA6C8 000C7628 93 41 00 28 */ stw r26, 0x28(r1) -/* 800CA6CC 000C762C 48 08 84 F5 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypeUsUsUs" +/* 800CA6CC 000C762C 48 08 84 F5 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoiiQ212CPlayerState9EItemTypeUsUsUs" /* 800CA6D0 000C7630 7C 7B 1B 78 */ mr r27, r3 lbl_800CA6D4: /* 800CA6D4 000C7634 7F C0 07 75 */ extsb. r0, r30 @@ -15309,7 +15309,7 @@ lbl_800D2E70: /* 800D3020 000CFF80 93 81 00 20 */ stw r28, 0x20(r1) /* 800D3024 000CFF84 93 81 00 24 */ stw r28, 0x24(r1) /* 800D3028 000CFF88 93 81 00 28 */ stw r28, 0x28(r1) -/* 800D302C 000CFF8C 48 07 FB 95 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypeUsUsUs" +/* 800D302C 000CFF8C 48 07 FB 95 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoiiQ212CPlayerState9EItemTypeUsUsUs" /* 800D3030 000CFF90 7C 7F 1B 78 */ mr r31, r3 lbl_800D3034: /* 800D3034 000CFF94 7F 40 07 75 */ extsb. r0, r26 @@ -15473,7 +15473,7 @@ lbl_800D31AC: /* 800D328C 000D01EC 93 21 00 20 */ stw r25, 0x20(r1) /* 800D3290 000D01F0 93 01 00 24 */ stw r24, 0x24(r1) /* 800D3294 000D01F4 92 E1 00 28 */ stw r23, 0x28(r1) -/* 800D3298 000D01F8 48 07 F9 29 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypeUsUsUs" +/* 800D3298 000D01F8 48 07 F9 29 */ bl "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoiiQ212CPlayerState9EItemTypeUsUsUs" /* 800D329C 000D01FC 7C 7A 1B 78 */ mr r26, r3 lbl_800D32A0: /* 800D32A0 000D0200 38 61 00 44 */ addi r3, r1, 0x44 diff --git a/asm/MetroidPrime/ScriptObjects/CScriptSpecialFunction.s b/asm/MetroidPrime/ScriptObjects/CScriptSpecialFunction.s index b230e807..d24d63ba 100644 --- a/asm/MetroidPrime/ScriptObjects/CScriptSpecialFunction.s +++ b/asm/MetroidPrime/ScriptObjects/CScriptSpecialFunction.s @@ -348,8 +348,8 @@ lbl_8014F3DC: /* 8014F3E8 0014C348 38 21 00 20 */ addi r1, r1, 0x20 /* 8014F3EC 0014C34C 4E 80 00 20 */ blr -.global AddOrUpdateEmitter__22CScriptSpecialFunctionFfR10CSfxHandleUsRC9CVector3fUc -AddOrUpdateEmitter__22CScriptSpecialFunctionFfR10CSfxHandleUsRC9CVector3fUc: +.global AddOrUpdateEmitter__22CScriptSpecialFunctionFfR10CSfxHandleUs9CVector3fUc +AddOrUpdateEmitter__22CScriptSpecialFunctionFfR10CSfxHandleUs9CVector3fUc: /* 8014F3F0 0014C350 94 21 FF C0 */ stwu r1, -0x40(r1) /* 8014F3F4 0014C354 7C 08 02 A6 */ mflr r0 /* 8014F3F8 0014C358 90 01 00 44 */ stw r0, 0x44(r1) @@ -1789,7 +1789,7 @@ lbl_80150874: /* 801508B8 0014D818 90 A1 00 4C */ stw r5, 0x4c(r1) /* 801508BC 0014D81C 90 01 00 50 */ stw r0, 0x50(r1) /* 801508C0 0014D820 A0 B8 01 70 */ lhz r5, 0x170(r24) -/* 801508C4 0014D824 4B FF EB 2D */ bl AddOrUpdateEmitter__22CScriptSpecialFunctionFfR10CSfxHandleUsRC9CVector3fUc +/* 801508C4 0014D824 4B FF EB 2D */ bl AddOrUpdateEmitter__22CScriptSpecialFunctionFfR10CSfxHandleUs9CVector3fUc /* 801508C8 0014D828 38 00 00 00 */ li r0, 0 /* 801508CC 0014D82C 98 01 00 20 */ stb r0, 0x20(r1) /* 801508D0 0014D830 48 00 00 10 */ b lbl_801508E0 @@ -3354,7 +3354,7 @@ lbl_80151E58: /* 80151E9C 0014EDFC 90 C1 00 50 */ stw r6, 0x50(r1) /* 80151EA0 0014EE00 90 01 00 58 */ stw r0, 0x58(r1) /* 80151EA4 0014EE04 90 01 00 5C */ stw r0, 0x5c(r1) -/* 80151EA8 0014EE08 48 00 11 B5 */ bl "sort,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter" /* 80151EAC 0014EE0C 38 C0 00 00 */ li r6, 0 /* 80151EB0 0014EE10 38 E0 00 00 */ li r7, 0 /* 80151EB4 0014EE14 7C C4 33 78 */ mr r4, r6 @@ -4288,8 +4288,8 @@ lbl_80152BA8: /* 80152BB8 0014FB18 38 21 00 10 */ addi r1, r1, 0x10 /* 80152BBC 0014FB1C 4E 80 00 20 */ blr -.global "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypeUsUsUs" -"__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfollQ212CPlayerState9EItemTypeUsUsUs": +.global "__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoiiQ212CPlayerState9EItemTypeUsUsUs" +"__ct__22CScriptSpecialFunctionF9TUniqueIdRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC11CEntityInfoRC12CTransform4fQ222CScriptSpecialFunction16ESpecialFunctionRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>ffffRC9CVector3fRC6CColorbRC11CDamageInfoiiQ212CPlayerState9EItemTypeUsUsUs": /* 80152BC0 0014FB20 94 21 FE 70 */ stwu r1, -0x190(r1) /* 80152BC4 0014FB24 7C 08 02 A6 */ mflr r0 /* 80152BC8 0014FB28 90 01 01 94 */ stw r0, 0x194(r1) @@ -4602,8 +4602,8 @@ lbl_80153040: /* 80153054 0014FFB4 38 21 00 30 */ addi r1, r1, 0x30 /* 80153058 0014FFB8 4E 80 00 20 */ blr -.global "sort,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter" +"sort,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter": /* 8015305C 0014FFBC 94 21 FF 10 */ stwu r1, -0xf0(r1) /* 80153060 0014FFC0 7C 08 02 A6 */ mflr r0 /* 80153064 0014FFC4 90 01 00 F4 */ stw r0, 0xf4(r1) @@ -4822,7 +4822,7 @@ lbl_80153378: /* 80153390 001502F0 90 E1 00 24 */ stw r7, 0x24(r1) /* 80153394 001502F4 90 C1 00 28 */ stw r6, 0x28(r1) /* 80153398 001502F8 90 01 00 2C */ stw r0, 0x2c(r1) -/* 8015339C 001502FC 4B FF FC C1 */ bl "sort,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter" /* 801533A0 00150300 80 FE 00 00 */ lwz r7, 0(r30) /* 801533A4 00150304 38 61 00 20 */ addi r3, r1, 0x20 /* 801533A8 00150308 80 DD 00 00 */ lwz r6, 0(r29) @@ -4832,7 +4832,7 @@ lbl_80153378: /* 801533B8 00150318 90 E1 00 18 */ stw r7, 0x18(r1) /* 801533BC 0015031C 90 C1 00 1C */ stw r6, 0x1c(r1) /* 801533C0 00150320 90 01 00 20 */ stw r0, 0x20(r1) -/* 801533C4 00150324 4B FF FC 99 */ bl "sort,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>,Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter>__4rstlFQ24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q24rstl176pointer_iterator,Q24rstl17rmemory_allocator>Q236@unnamed@CScriptSpecialFunction_cpp@11CRingSorter" lbl_801533C8: /* 801533C8 00150328 BB 41 00 D8 */ lmw r26, 0xd8(r1) /* 801533CC 0015032C 80 01 00 F4 */ lwz r0, 0xf4(r1) diff --git a/include/Kyoto/Audio/CSfxManager.hpp b/include/Kyoto/Audio/CSfxManager.hpp index 1877bff1..033eb850 100644 --- a/include/Kyoto/Audio/CSfxManager.hpp +++ b/include/Kyoto/Audio/CSfxManager.hpp @@ -11,18 +11,20 @@ public: static void RemoveEmitter(CSfxHandle handle); static void UpdateEmitter(CSfxHandle handle, const CVector3f& pos, const CVector3f& dir, uchar maxVol); + + static const s16 kMaxPriority; // 0xFF + static const s16 kMedPriority; // 0x7F + static const int kAllAreas; // 0xFFFF static CSfxHandle AddEmitter(u16 id, const CVector3f& pos, const CVector3f& dir, - bool useAcoustics, bool looped, s16 prio, int areaId); + bool useAcoustics, bool looped, s16 prio = kMedPriority, + int areaId = kAllAreas); static CSfxHandle AddEmitter(u16 id, const CVector3f& pos, const CVector3f& dir, uchar vol, - bool useAcoustics, bool looped, s16 prio, int areaId); + bool useAcoustics, bool looped, s16 prio = kMedPriority, + int areaId = kAllAreas); static void Shutdown(); static u16 TranslateSFXID(u16); static void PitchBend(CSfxHandle handle, int pitch); - - const static s16 kMaxPriority; // 0xff - const static s16 kMedPriority; // 0x7f - const static int kAllAreas; }; #endif diff --git a/include/Kyoto/Input/CRumbleGenerator.hpp b/include/Kyoto/Input/CRumbleGenerator.hpp index 2e2c85c6..0700a89b 100644 --- a/include/Kyoto/Input/CRumbleGenerator.hpp +++ b/include/Kyoto/Input/CRumbleGenerator.hpp @@ -4,12 +4,7 @@ #include "types.h" #include "Kyoto/Input/CRumbleVoice.hpp" - -enum EMotorState { - kMS_Stop, // = PAD_MOTOR_STOP, - kMS_Rumble, // = PAD_MOTOR_RUMBLE, - kMS_StopHard, // = PAD_MOTOR_STOP_HARD, -}; +#include "Kyoto/Input/InputTypes.hpp" class CRumbleGenerator { private: diff --git a/include/Kyoto/Input/CRumbleVoice.hpp b/include/Kyoto/Input/CRumbleVoice.hpp index e092497b..d55ca981 100644 --- a/include/Kyoto/Input/CRumbleVoice.hpp +++ b/include/Kyoto/Input/CRumbleVoice.hpp @@ -6,11 +6,29 @@ #include "rstl/reserved_vector.hpp" #include "rstl/vector.hpp" +enum ERumbleFxId { + kRFX_Zero = 0, + kRFX_One = 1, + kRFX_CameraShake = 6, + kRFX_EscapeSequenceShake = 7, + kRFX_PlayerBump = 11, + kRFX_PlayerGunCharge = 12, + kRFX_PlayerMissileFire = 13, + kRFX_PlayerGrappleFire = 14, + kRFX_PlayerLand = 15, + kRFX_PlayerGrappleSwoosh = 17, + kRFX_IntroBossProjectile = 19, + kRFX_Twenty = 20, + kRFX_TwentyOne = 21, + kRFX_TwentyTwo = 22, + kRFX_TwentyThree = 23 +}; + enum ERumblePriority { - kRP_None, - kRP_One, - kRP_Two, - kRP_Three, + kRP_None = 0, + kRP_One = 1, + kRP_Two = 2, + kRP_Three = 3, }; struct SAdsrData { diff --git a/include/Kyoto/Math/CMath.hpp b/include/Kyoto/Math/CMath.hpp index 3268e2a9..081299d5 100644 --- a/include/Kyoto/Math/CMath.hpp +++ b/include/Kyoto/Math/CMath.hpp @@ -28,6 +28,8 @@ public: return out; } static inline f32 AbsF(f32 v) { return fabs(v); } + static inline f64 AbsD(f64 v) { return fabs(v); } + static inline int AbsI(int v) { return abs(v); } // WrapPi__5CMathFf weak // WrapTwoPi__5CMathFf weak // FastFmod__5CMathFfff weak @@ -51,7 +53,6 @@ public: // GetCatmullRomSplinePoint__5CMathFRC9CVector3fRC9CVector3fRC9CVector3fRC9CVector3ff global // FastSqrtF__5CMathFf weak static double SqrtD(double x); - // AbsD__5CMathFd weak // IsEpsilon__5CMathFfff global // FastMin__5CMathFff weak // FastMax__5CMathFff weak diff --git a/include/Kyoto/Math/CloseEnough.hpp b/include/Kyoto/Math/CloseEnough.hpp index b67260a1..a6c9a1ec 100644 --- a/include/Kyoto/Math/CloseEnough.hpp +++ b/include/Kyoto/Math/CloseEnough.hpp @@ -8,9 +8,21 @@ #include "math.h" -static bool close_enough(const CVector2f& a, const CVector2f& b, f32 epsilon = 0.001f); -static bool close_enough(const CVector3f& a, const CVector3f& b, f32 epsilon = 0.001f); -inline bool close_enough(float a, float b, f32 epsilon = 0.001f) { +struct Real32 { + static inline float Epsilon() { return FLT_EPSILON; } +}; +struct Double { + static inline double Epsilon() { return DBL_EPSILON; } +}; +static inline float vector3_epsilon() { return FLT_EPSILON; } +static inline float vector2_epsilon() { return FLT_EPSILON; } + +static bool close_enough(const CVector2f& a, const CVector2f& b, float epsilon = vector2_epsilon()); +static bool close_enough(const CVector3f& a, const CVector3f& b, float epsilon = vector3_epsilon()); +inline bool close_enough(float a, float b, float epsilon = Real32::Epsilon()) { + return fabs(a - b) < epsilon; +} +inline bool close_enough(double a, double b, double epsilon = Double::Epsilon()) { return fabs(a - b) < epsilon; } diff --git a/include/Kyoto/TToken.hpp b/include/Kyoto/TToken.hpp index 6ba63ae4..a629fda8 100644 --- a/include/Kyoto/TToken.hpp +++ b/include/Kyoto/TToken.hpp @@ -16,7 +16,7 @@ public: TToken(const CToken& token) : CToken(token) {} TToken(T* obj) : CToken(TObjOwnerDerivedFromIObj< T >::GetNewDerivedObject(obj).release()) {} TToken(const rstl::auto_ptr< T >& obj) : CToken(GetIObjObjectFor(obj).release()) {} - + T* GetT() { return reinterpret_cast< T* >(CToken::GetObj()->GetContents()); } T* operator*() { return GetT(); } @@ -55,6 +55,7 @@ public: operator const TToken< T >&() const { return x0_token; } T* operator*() const { return x8_item; } + bool IsLoaded() const { return x0_token.IsLoaded(); } private: TToken< T > x0_token; diff --git a/include/MetroidPrime/CActor.hpp b/include/MetroidPrime/CActor.hpp index 5d3486a6..8d557282 100644 --- a/include/MetroidPrime/CActor.hpp +++ b/include/MetroidPrime/CActor.hpp @@ -258,9 +258,9 @@ public: const CTransform4f& GetTransform() const { return x34_transform; } void SetTransform(const CTransform4f& xf) { x34_transform = xf; - xe4_27_notInSortedLists = true; - xe4_28_transformDirty = true; - xe4_29_actorLightsDirty = true; + SetTransformDirty(true); + SetTransformDirtySpare(true); + SetPreRenderHasMoved(true); } void SetRotation(const CQuaternion& rot) { SetTransform(rot.BuildTransform4f(GetTranslation())); diff --git a/include/MetroidPrime/CMain.hpp b/include/MetroidPrime/CMain.hpp index d69e0569..80ad8b26 100644 --- a/include/MetroidPrime/CMain.hpp +++ b/include/MetroidPrime/CMain.hpp @@ -41,23 +41,22 @@ private: static bool mManagerInstalled; }; -// TODO where? -enum EFlowState { - kFS_None, - kFS_WinBad, - kFS_WinGood, - kFS_WinBest, - kFS_LoseGame, - kFS_Default, - kFS_StateSetter, - kFS_PreFrontEnd, - kFS_FrontEnd, - kFS_Game, - kFS_GameExit, -}; - class CMain { public: + enum ERestartMode { + kRM_None, + kRM_WinBad, + kRM_WinGood, + kRM_WinBest, + kRM_LoseGame, + kRM_Default, + kRM_StateSetter, + kRM_PreFrontEnd, + kRM_FrontEnd, + kRM_Game, + kRM_GameExit, + }; + CMain(); ~CMain(); @@ -78,7 +77,7 @@ public: bool CheckTerminate(); bool CheckReset(); void OpenWindow(); - void SetFlowState(EFlowState s) { x12c_flowState = s; } + void SetRestartMode(ERestartMode s) { x12c_restartMode = s; } void SetMaxSpeed(bool v) { // ? @@ -109,7 +108,7 @@ private: f32 x120_; f32 x124_; CGameGlobalObjects* x128_gameGlobalObjects; - EFlowState x12c_flowState; + ERestartMode x12c_restartMode; rstl::reserved_vector< uint, 10 > x130_frameTimes; int x15c_frameTimeIdx; bool x160_24_finished : 1; diff --git a/include/MetroidPrime/CModelData.hpp b/include/MetroidPrime/CModelData.hpp index 0e36e02c..ebf9a079 100644 --- a/include/MetroidPrime/CModelData.hpp +++ b/include/MetroidPrime/CModelData.hpp @@ -24,6 +24,11 @@ class CModelFlags; // TODO move #include "Kyoto/Math/CQuaternion.hpp" struct SAdvancementDeltas { +public: + const CVector3f& GetOffsetDelta() const { return x0_posDelta; } + const CQuaternion& GetOrientationDelta() const { return xc_rotDelta; } + +private: CVector3f x0_posDelta; CQuaternion xc_rotDelta; }; diff --git a/include/MetroidPrime/CRumbleManager.hpp b/include/MetroidPrime/CRumbleManager.hpp index fed96e36..e064060b 100644 --- a/include/MetroidPrime/CRumbleManager.hpp +++ b/include/MetroidPrime/CRumbleManager.hpp @@ -5,7 +5,17 @@ #include "Kyoto/Input/CRumbleGenerator.hpp" +class CStateManager; +class CVector3f; + class CRumbleManager { +public: + CRumbleManager(); + ~CRumbleManager(); + + void Rumble(CStateManager&, const CVector3f&, ERumbleFxId, float, ERumblePriority); + void Rumble(CStateManager&, ERumbleFxId, float, ERumblePriority); + private: CRumbleGenerator x0_rumbleGenerator; }; diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index 73a47f1a..1a45902e 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -138,6 +138,7 @@ public: } CEnvFxManager* EnvFxManager() { return x880_envFxManager; } const CEnvFxManager* GetEnvFxManager() const { return x880_envFxManager; } + CRumbleManager* GetRumbleManager() { return x88c_rumbleManager; } CRandom16* GetActiveRandom() const { return x900_random; } @@ -162,19 +163,33 @@ public: const CDamageInfo& info, const CMaterialFilter& filter, const CVector3f& knockbackVec); + // State transitions void DeferStateTransition(EStateManagerTransition t); - EStateManagerTransition GetDeferredStateTransition() const { return xf90_deferredTransition; } - void SetBossParams(TUniqueId bossId, float maxEnergy, u32 stringIdx); - void SetPendingOnScreenTex(CAssetId texId, const CVector2i& origin, const CVector2i& extent) { + void EnterMapScreen() { DeferStateTransition(kSMT_MapScreen); } + void EnterPauseScreen() { DeferStateTransition(kSMT_PauseGame); } + void EnterLogBookScreen() { DeferStateTransition(kSMT_LogBook); } + void EnterSaveGameScreen() { DeferStateTransition(kSMT_SaveGame); } + void EnterMessageScreen(uint, float); + bool GetWantsToEnterMapScreen() const { return xf90_deferredTransition == kSMT_MapScreen; } + bool GetWantsToEnterPauseScreen() const { return xf90_deferredTransition == kSMT_PauseGame; } + bool GetWantsToEnterLogBookScreen() const { return xf90_deferredTransition == kSMT_LogBook; } + bool GetWantsToEnterSaveGameScreen() const { return xf90_deferredTransition == kSMT_SaveGame; } + bool GetWantsToEnterMessageScreen() const { + return xf90_deferredTransition == kSMT_MessageScreen; + } + + void SetEnergyBarActorInfo(TUniqueId bossId, float maxEnergy, u32 stringIdx); + void SetPendingOnScreenTex(CAssetId texId, const CVector2i& origin, const CVector2i& extent);/* { xef4_pendingScreenTex.x0_id = texId; xef4_pendingScreenTex.x4_origin = origin; xef4_pendingScreenTex.xc_extent = extent; - } + }*/ const SOnScreenTex& GetPendingScreenTex() const { return xef4_pendingScreenTex; } float IntegrateVisorFog(float f); - void SetShouldQuitGame(bool should) { xf94_25_quitGame = should; } - void SetSkipCinematicSpecialFunction(TUniqueId id) { xf38_skipCineSpecialFunc = id; } + void QuitGame() { xf94_25_quitGame = true; } + bool GetWantsToQuit() const { return xf94_25_quitGame; } + void SetCinematicSkipObject(TUniqueId id) { xf38_skipCineSpecialFunc = id; } void SetInSaveUI(bool b) { xf94_28_inSaveUI = b; } bool GetInSaveUI() const { return xf94_28_inSaveUI; } void SetIsFullThreat(bool v) { xf94_30_fullThreat = v; } diff --git a/include/MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp b/include/MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp index 8c863e8f..4ee73902 100644 --- a/include/MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp +++ b/include/MetroidPrime/ScriptObjects/CScriptSpecialFunction.hpp @@ -115,11 +115,11 @@ private: bool x1e5_24_doSave : 1; bool x1e5_25_playerInArea : 1; bool x1e5_26_displayBillboard : 1; - rstl::optional_object< CToken > x1e8_; // CTexture? + rstl::optional_object< CToken > x1e8_; public: CScriptSpecialFunction(TUniqueId, const rstl::string&, const CEntityInfo&, const CTransform4f&, ESpecialFunction, const rstl::string&, float, float, float, float, - const CVector3f&, const CColor&, bool, const CDamageInfo&, s32, s32, + const CVector3f&, const CColor&, bool, const CDamageInfo&, int, int, CPlayerState::EItemType, u16, u16, u16); void Accept(IVisitor& visitor) override; @@ -148,7 +148,7 @@ public: void DeleteEmitter(CSfxHandle& handle); int GetSpecialEnding(const CStateManager&) const; - void AddOrUpdateEmitter(float pitch, CSfxHandle& handle, u16 id, const CVector3f& pos, uchar vol); + void AddOrUpdateEmitter(float pitch, CSfxHandle& handle, u16 id, CVector3f pos, u8 vol); }; #endif _CSCRIPTSPECIALFUNCTION_HPP diff --git a/include/MetroidPrime/TCastTo.hpp b/include/MetroidPrime/TCastTo.hpp index f4e98aa5..c1cb4e2e 100644 --- a/include/MetroidPrime/TCastTo.hpp +++ b/include/MetroidPrime/TCastTo.hpp @@ -98,11 +98,11 @@ private: }; template < typename T > -inline const T* TCastToConstPtr(const CEntity* p) { +static inline const T* TCastToConstPtr(const CEntity* p) { return TCastToPtr< T >(const_cast< CEntity* >(p)); } template < typename T > -inline const T* TCastToConstPtr(const CEntity& p) { +static inline const T* TCastToConstPtr(const CEntity& p) { return TCastToPtr< T >(const_cast< CEntity& >(p)); } diff --git a/include/rstl/optional_object.hpp b/include/rstl/optional_object.hpp index 37c2a351..e34931ea 100644 --- a/include/rstl/optional_object.hpp +++ b/include/rstl/optional_object.hpp @@ -16,11 +16,21 @@ public: optional_object(const T& item) : m_valid(true) { rstl::construct< T >(m_data, item); } optional_object(const optional_object& other) : m_valid(other.m_valid) { if (other.m_valid) { - rstl::construct< T >(m_data, other.data()); + construct< T >(m_data, other.data()); } } ~optional_object() { clear(); } + optional_object& operator=(const optional_object& other) { + if (this != &other) { + if (other.m_valid) { + assign(other.data()); + } else { + clear(); + } + } + return *this; + } optional_object& operator=(const T& item) { assign(item); return *this; @@ -40,7 +50,7 @@ public: } T& operator*() { return data(); } - T* operator->() { return data(); } + T* operator->() { return &data(); } private: u8 m_data[sizeof(T)]; @@ -48,7 +58,7 @@ private: void assign(const T& item) { if (!m_valid) { - rstl::construct(get_ptr(), item); + construct(get_ptr(), item); m_valid = true; } else { data() = item; diff --git a/include/rstl/red_black_tree.hpp b/include/rstl/red_black_tree.hpp index c0c343a3..2cd50f8a 100644 --- a/include/rstl/red_black_tree.hpp +++ b/include/rstl/red_black_tree.hpp @@ -27,6 +27,8 @@ private: node* mLeft; node* mRight; P mValue; + + P& get_value() { return mValue; } }; struct header {}; @@ -35,12 +37,12 @@ public: node* mNode; const header* mHeader; - const P* operator->() const { return &mNode->mValue; } + const P* operator->() const { return &mNode->get_value(); } bool operator==(const const_iterator& other) const { return mNode == other.mNode && mHeader == other.mHeader; } bool operator!=(const const_iterator& other) const { - return mNode != other.mNode || mHeader != other.mHeader; + return !(*this == other); // mNode != other.mNode || mHeader != other.mHeader; } }; diff --git a/include/rstl/vector.hpp b/include/rstl/vector.hpp index 64ab5945..29ba5b1e 100644 --- a/include/rstl/vector.hpp +++ b/include/rstl/vector.hpp @@ -112,7 +112,15 @@ public: protected: template < typename In > - void insert_into(iterator it, int count, In in); + void insert_into(iterator at, int n, In in);/* { + int insertAt = xc_items + n; + if (x8_capacity < insertAt) { + int newCapacity = x8_capacity != 0 ? x8_capacity * 2 : 4; + T* newData; + x0_allocator.allocate(newData, newCapacity); + + } + }*/ }; template < typename T, typename Alloc > diff --git a/libc/float.h b/libc/float.h index 6294cdfc..ee8b96b6 100644 --- a/libc/float.h +++ b/libc/float.h @@ -9,6 +9,8 @@ extern "C" { #define FLT_EPSILON 1.192092896e-07f #define FLT_MIN 1.175494351e-38f +#define DBL_EPSILON 1.1920929e-07 + #ifdef __cplusplus } #endif diff --git a/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp index 258577df..6977a9f4 100644 --- a/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp +++ b/src/MetroidPrime/ScriptObjects/CScriptSpecialFunction.cpp @@ -4,6 +4,7 @@ #include "MetroidPrime/CAnimData.hpp" #include "MetroidPrime/CEnvFxManager.hpp" #include "MetroidPrime/CMain.hpp" +#include "MetroidPrime/CRumbleManager.hpp" #include "MetroidPrime/CStateManager.hpp" #include "MetroidPrime/CWorld.hpp" #include "MetroidPrime/Cameras/CCameraManager.hpp" @@ -46,8 +47,8 @@ void sort(It first, It last, Cmp cmp) { CScriptSpecialFunction::CScriptSpecialFunction( TUniqueId uid, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf, ESpecialFunction func, const rstl::string& lcName, float f1, float f2, float f3, float f4, - const CVector3f& vec, const CColor& col, bool active, const CDamageInfo& dInfo, s32 aId1, - s32 aId2, CPlayerState::EItemType itemType, u16 sId1, u16 sId2, u16 sId3) + const CVector3f& vec, const CColor& col, bool active, const CDamageInfo& dInfo, int aId1, + int aId2, CPlayerState::EItemType itemType, u16 sId1, u16 sId2, u16 sId3) : CActor(uid, active, name, info, xf, CModelData::CModelDataNull(), CMaterialList(), CActorParameters::None(), kInvalidUniqueId) , xe8_function(func) @@ -198,10 +199,9 @@ void CScriptSpecialFunction::PreRender(CStateManager&, const CFrustumPlanes& fru } } -// constexpr std::array fxTranslation{ -// ERumbleFxId::Twenty, ERumbleFxId::One, ERumbleFxId::TwentyOne, -// ERumbleFxId::TwentyTwo, ERumbleFxId::TwentyThree, ERumbleFxId::Zero, -// }; +static const ERumbleFxId skRumbleFxList[6] = { + kRFX_Twenty, kRFX_One, kRFX_TwentyOne, kRFX_TwentyTwo, kRFX_TwentyThree, kRFX_Zero, +}; namespace { class CRingSorter { @@ -212,7 +212,6 @@ public: bool operator()(const CScriptSpecialFunction::SRingController& a, const CScriptSpecialFunction::SRingController& b) { - const CActor* actA = TCastToConstPtr< CActor >(mgr->GetObjectById(a.x0_id)); const CActor* actB = TCastToConstPtr< CActor >(mgr->GetObjectById(b.x0_id)); if (actA && actB) { @@ -227,9 +226,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId CStateManager& mgr) { if (GetActive() && msg == kSM_Deactivate && xe8_function == kSF_Billboard) { mgr.SetPendingOnScreenTex(CAssetId(), CVector2i(0, 0), CVector2i(0, 0)); - if (x1e8_) { - x1e8_.clear(); - } + x1e8_ = rstl::optional_object_null(); x1e5_26_displayBillboard = false; } CActor::AcceptScriptMsg(msg, uid, mgr); @@ -296,7 +293,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId case kSF_MapStation: { if (msg == kSM_Action) { // TODO - // mgr.MapWorldInfo()->SetMapStationUsed(true); + // mgr.MapWorldInfo()->SetIsMapped(true); // mgr.GetWorld()->GetMapWorld()->RecalculateWorldSphere(*mgr.MapWorldInfo(), // *mgr.GetWorld()); } @@ -324,7 +321,7 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId if (gpGameState->CardSerial() == 0) { SendScriptMsgs(kSS_Closed, mgr, kSM_None); } else { - mgr.DeferStateTransition(kSMT_SaveGame); + mgr.EnterSaveGameScreen(); x1e5_24_doSave = true; } } @@ -409,9 +406,9 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId } case kSF_BossEnergyBar: { if (msg == kSM_Increment) { - mgr.SetBossParams(uid, xfc_float1, u32(x100_float2) + 86); + mgr.SetEnergyBarActorInfo(uid, xfc_float1, u32(x100_float2) + 86); } else if (msg == kSM_Decrement) { - mgr.SetBossParams(kInvalidUniqueId, 0.f, 0); + mgr.SetEnergyBarActorInfo(kInvalidUniqueId, 0.f, 0); } break; } @@ -419,26 +416,26 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId if (msg == kSM_Action) { switch (GetSpecialEnding(mgr)) { case 0: - gpMain->SetFlowState(kFS_WinBad); + gpMain->SetRestartMode(CMain::kRM_WinBad); break; case 1: - gpMain->SetFlowState(kFS_WinGood); + gpMain->SetRestartMode(CMain::kRM_WinGood); break; case 2: - gpMain->SetFlowState(kFS_WinBest); + gpMain->SetRestartMode(CMain::kRM_WinBest); break; } - mgr.SetShouldQuitGame(true); + mgr.QuitGame(); } break; } case kSF_CinematicSkip: { if (msg == kSM_Increment) { if (ShouldSkipCinematic(mgr)) { - mgr.SetSkipCinematicSpecialFunction(GetUniqueId()); + mgr.SetCinematicSkipObject(GetUniqueId()); } } else if (msg == kSM_Decrement) { - mgr.SetSkipCinematicSpecialFunction(kInvalidUniqueId); + mgr.SetCinematicSkipObject(kInvalidUniqueId); gpGameState->SystemOptions().SetCinematicState( rstl::pair< CAssetId, TEditorId >(mgr.GetWorld()->GetWorldAssetId(), GetEditorId()), true); @@ -475,22 +472,30 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId } case kSF_EnvFxDensityController: { if (msg == kSM_Action) { - mgr.EnvFxManager()->SetFxDensity(s32(x100_float2), xfc_float1); + mgr.EnvFxManager()->SetFxDensity(int(x100_float2), xfc_float1); } break; } case kSF_RumbleEffect: - if (msg == kSM_Action) { - const s32 rumbFx = s32(x100_float2); - - // Retro originally did not check the upper bounds, this could potentially cause a crash - // with some runtimes, so let's make sure we're not out of bounds in either direction. - // if (rumbFx < 0 || rumbFx >= 6) { - // break; - // } - - // TODO: add fxTranslation - // mgr.GetRumbleManager().Rumble(mgr, fxTranslation[rumbFx], 1.f, kRP_One); + if (msg != kSM_Action) { + break; + } + int rumbFxIdx = int(x100_float2); + if (rumbFxIdx < 0 || rumbFxIdx >= int(sizeof(skRumbleFxList) / sizeof(ERumbleFxId))) { + break; + } + ERumbleFxId rumbFx = skRumbleFxList[rumbFxIdx]; + uint param3 = x104_float3; + if ((param3 & 1) != 0) { + mgr.GetRumbleManager()->Rumble(mgr, rumbFx, 1.f, kRP_One); + } else { + CVector3f pos = GetTranslation(); + if ((param3 & 2) != 0) { + if (const CActor* act = TCastToConstPtr< CActor >(mgr.GetObjectById(uid))) { + pos = act->GetTranslation(); + } + } + mgr.GetRumbleManager()->Rumble(mgr, pos, rumbFx, xfc_float1, kRP_One); } break; case kSF_InventoryActivator: { @@ -544,14 +549,14 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId mgr.SetPendingOnScreenTex(assetId, CVector2i(int(x104_float3), int(x108_float4)), CVector2i(int(xfc_float1), int(x100_float2))); if (objectTag) { - x1e8_ = gpSimplePool->GetObj(*objectTag); + x1e8_ = gpSimplePool->GetObj(xec_locatorName.data()); + x1e8_->Lock(); x1e5_26_displayBillboard = true; } } else if (msg == kSM_Decrement) { mgr.SetPendingOnScreenTex(kInvalidAssetId, CVector2i(int(x104_float3), int(x108_float4)), CVector2i(int(xfc_float1), int(x100_float2))); - if (x1e8_) - x1e8_.clear(); + x1e8_ = rstl::optional_object_null(); x1e5_26_displayBillboard = false; } break; @@ -572,21 +577,22 @@ void CScriptSpecialFunction::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId break; } case kSF_FogFader: { + float speed = x100_float2; if (msg == kSM_Increment) { - mgr.CameraManager()->SetFogDensity(x100_float2, xfc_float1); + mgr.CameraManager()->SetFogDensity(xfc_float1, speed); } else if (msg == kSM_Decrement) { - mgr.CameraManager()->SetFogDensity(x100_float2, 1.f); + mgr.CameraManager()->SetFogDensity(1.f, speed); } break; } case kSF_EnterLogbook: { if (msg == kSM_Action) { - mgr.DeferStateTransition(kSMT_LogBook); + mgr.EnterLogBookScreen(); } break; } case kSF_Ending: { - if (msg == kSM_Action && GetSpecialEnding(mgr) == u32(xfc_float1)) { + if (msg == kSM_Action && GetSpecialEnding(mgr) == int(xfc_float1)) { SendScriptMsgs(kSS_Zero, mgr, kSM_None); } break; @@ -606,7 +612,7 @@ bool CScriptSpecialFunction::ShouldSkipCinematic(CStateManager& mgr) const { void CScriptSpecialFunction::SkipCinematic(CStateManager& mgr) { SendScriptMsgs(kSS_Zero, mgr, kSM_None); - mgr.SetSkipCinematicSpecialFunction(kInvalidUniqueId); + mgr.SetCinematicSkipObject(kInvalidUniqueId); } void CScriptSpecialFunction::Accept(IVisitor& visitor) { visitor.Visit(*this); } @@ -628,7 +634,7 @@ void CScriptSpecialFunction::ThinkSaveStation(float, CStateManager& mgr) { if (!x1e5_24_doSave) { return; } - if (mgr.GetDeferredStateTransition() != kSMT_SaveGame) { + if (!mgr.GetWantsToEnterSaveGameScreen()) { x1e5_24_doSave = false; if (mgr.GetInSaveUI()) { SendScriptMsgs(kSS_MaxReached, mgr, kSM_None); @@ -755,9 +761,8 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr const CStateManager::TIdListResult& it = mgr.GetIdListForScript(conn->x8_objId); if (it.first != it.second) { - TUniqueId uid = it.first->second; - if (CScriptPlatform* plat = TCastToPtr< CScriptPlatform >(mgr.ObjectById(uid))) { - if (plat->HasModelData() && plat->GetModelData()->GetAnimationData()) { + if (CScriptPlatform* plat = TCastToPtr< CScriptPlatform >(mgr.ObjectById(it.first->second))) { + if (plat->HasAnimation()) { plat->SetControlledAnimation(true); if (!x1e4_24_spinnerInitializedXf) { x13c_spinnerInitialXf = plat->GetTransform(); @@ -768,17 +773,19 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr const float f29 = pointOneByDt * x100_float2; if (mode == kSCM_Zero) { - if (!x1e4_25_spinnerCanMove) { - const CPlayer& pl = *mgr.GetPlayer(); - const CVector3f angVel = pl.GetAngularVelocityOR().GetVector(); - float mag = 0.f; + if (x1e4_25_spinnerCanMove) { + bool isMorphed = + mgr.GetPlayer()->GetMorphballTransitionState() == CPlayer::kMS_Morphed; + const CVector3f angVel = mgr.GetPlayer()->GetAngularVelocityOR().GetVector(); + float mag; if (angVel.CanBeNormalized()) { mag = angVel.Magnitude(); + } else { + mag = 0.f; } - const float spinImpulse = - (pl.GetMorphballTransitionState() == CPlayer::kMS_Morphed ? 0.025f * mag : 0.f); - if (spinImpulse >= x180_) { + const float spinImpulse = (isMorphed ? 0.025f * mag : 0.f); + if (spinImpulse > x180_) { SendScriptMsgs(kSS_Play, mgr, kSM_None); } @@ -788,10 +795,8 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr if (!noBackward) { x138_ -= f29; } - } else { - if (!noBackward) { - x138_ = f28 - twoByDt; - } + } else if (!noBackward) { + x138_ = f28 - twoByDt; } } else if (mode == kSCM_One) { x138_ = (0.01f * x16c_) * xfc_float1 + f28; @@ -814,17 +819,16 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr x138_ += 1.f; } } else { - // TODO: get Clamp to inline here - x138_ = CMath::Clamp(0.f, x138_, 1.f); + x138_ = rstl::min_val(1.f, rstl::max_val(0.f, x138_)); } bool noSfxPlayed = true; f28 = x138_ - f28; // always 0? - if (close_enough(x138_, 1.f, FLT_EPSILON)) { + if (close_enough(x138_, 1.f)) { if (!x1e4_27_sfx3Played) { - if (x174_sfx3 != 0xFFFF) { - CSfxManager::AddEmitter(x174_sfx3, GetTranslation(), CVector3f::Zero(), true, false, - CSfxManager::kMedPriority, CSfxManager::kAllAreas); + if (x174_sfx3 != InvalidSfxId) { + CSfxManager::AddEmitter(x174_sfx3, GetTranslation(), CVector3f::Zero(), true, + false); } x1e4_27_sfx3Played = true; @@ -836,11 +840,11 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr x1e4_27_sfx3Played = false; } - if (close_enough(x138_, 0.f, FLT_EPSILON)) { + if (close_enough(x138_, 0.f)) { if (!x1e4_26_sfx2Played) { - if (x172_sfx2 != 0xFFFF) { - CSfxManager::AddEmitter(x172_sfx2, GetTranslation(), CVector3f::Zero(), true, false, - CSfxManager::kMedPriority, CSfxManager::kAllAreas); + if (x172_sfx2 != InvalidSfxId) { + CSfxManager::AddEmitter(x172_sfx2, GetTranslation(), CVector3f::Zero(), true, + false); } x1e4_26_sfx2Played = true; @@ -855,29 +859,28 @@ void CScriptSpecialFunction::ThinkSpinnerController(float dt, CStateManager& mgr rstl::optional_object< float > unused = x184_.GetAverage(); if (noSfxPlayed) { - if (x170_sfx1 != 0xFFFF) { + if (x170_sfx1 != InvalidSfxId) { + bool b = f28 >= 0.f; if (noSfxPlayed) { - x184_.AddValue(0.f <= f28 ? 100 : 0x7f); + x184_.AddValue(b ? u8(100) : u8(0x7F)); } else { x184_.AddValue(0.f); } - rstl::optional_object< float > volume = x184_.GetAverage(); - float pitch = 0.f <= f28 ? x108_float4 : 1.f; - + const rstl::optional_object< float >& volume = x184_.GetAverage(); + float pitch = b ? x108_float4 : 1.f; AddOrUpdateEmitter(pitch, x178_sfxHandle, x170_sfx1, GetTranslation(), volume.data()); } } else { DeleteEmitter(x178_sfxHandle); } - CAnimData* animData = plat->ModelData()->AnimationData(); + const CAnimData* animData = plat->GetAnimationData(); const float dur = animData->GetAnimationDuration(animData->GetDefaultAnimation()) * x138_; - animData->SetPhase(0.f); - animData->SetPlaybackRate(1.f); - // Redundant copy is needed + plat->AnimationData()->SetPhase(0.f); + plat->AnimationData()->SetPlaybackRate(1.f); SAdvancementDeltas deltas = plat->UpdateAnimation(dur, mgr, true); - plat->SetTransform(x13c_spinnerInitialXf * - deltas.xc_rotDelta.BuildTransform4f(deltas.x0_posDelta)); + plat->SetTransform(x13c_spinnerInitialXf * deltas.GetOrientationDelta().BuildTransform4f( + deltas.GetOffsetDelta())); } } } @@ -1098,10 +1101,9 @@ void CScriptSpecialFunction::ThinkPlayerInArea(float dt, CStateManager& mgr) { } void CScriptSpecialFunction::AddOrUpdateEmitter(float pitch, CSfxHandle& handle, u16 id, - const CVector3f& pos, uchar vol) { + CVector3f pos, u8 vol) { if (!handle) { - handle = CSfxManager::AddEmitter(id, pos, CVector3f::Zero(), vol, true, true, - CSfxManager::kMedPriority, CSfxManager::kAllAreas); + handle = CSfxManager::AddEmitter(id, pos, CVector3f::Zero(), vol, true, true); } else { CSfxManager::UpdateEmitter(handle, pos, CVector3f::Zero(), vol); CSfxManager::PitchBend(handle, static_cast< s16 >(8192.f * pitch + 8192.f));