From bd758edeb956ec11c8902fb2ab86b0068b53b660 Mon Sep 17 00:00:00 2001 From: Henrique Gemignani Passos Lima Date: Sun, 27 Nov 2022 02:26:12 +0200 Subject: [PATCH] Add CExplosion Former-commit-id: 147e46d2e8eaee521e8f6f34d89263a70904fb95 --- asm/Kyoto/Particles/CElementGen.s | 2 +- asm/Kyoto/Particles/CParticleElectric.s | 2 +- asm/Kyoto/Particles/CParticleSwoosh.s | 2 +- asm/MetroidPrime/CExplosion.s | 24 +-- asm/MetroidPrime/Enemies/CPatterned.s | 2 +- configure.py | 2 +- include/Kyoto/CToken.hpp | 3 +- include/Kyoto/Graphics/CCubeModel.hpp | 9 + include/Kyoto/Graphics/CGraphics.hpp | 17 ++ include/Kyoto/Particles/CElementGen.hpp | 2 +- include/Kyoto/Particles/CParticleElectric.hpp | 2 +- include/Kyoto/Particles/CParticleGen.hpp | 6 +- include/MetroidPrime/CExplosion.hpp | 9 +- include/MetroidPrime/CGameArea.hpp | 18 +- include/MetroidPrime/CParticleGenInfo.hpp | 4 +- .../MetroidPrime/CParticleGenInfoGeneric.hpp | 2 +- include/MetroidPrime/CStateManager.hpp | 3 + include/rstl/list.hpp | 30 ++-- include/rstl/string.hpp | 1 - src/MetroidPrime/CExplosion.cpp | 156 ++++++++++++++++++ src/MetroidPrime/CParticleGenInfoGeneric.cpp | 2 +- .../ScriptObjects/CScriptPickup.cpp | 3 +- 22 files changed, 235 insertions(+), 66 deletions(-) create mode 100644 include/Kyoto/Graphics/CCubeModel.hpp create mode 100644 src/MetroidPrime/CExplosion.cpp diff --git a/asm/Kyoto/Particles/CElementGen.s b/asm/Kyoto/Particles/CElementGen.s index 02d08fd9..f08f099d 100644 --- a/asm/Kyoto/Particles/CElementGen.s +++ b/asm/Kyoto/Particles/CElementGen.s @@ -8751,7 +8751,7 @@ lbl_8031F390: /* 8031F3A0 0031C300 38 04 DD 08 */ addi r0, r4, __vt__12CParticleGen@l /* 8031F3A4 0031C304 38 80 FF FF */ li r4, -1 /* 8031F3A8 0031C308 90 1E 00 00 */ stw r0, 0(r30) -/* 8031F3AC 0031C30C 4B D3 B9 25 */ bl __dt__12CParticleGenFv +/* 8031F3AC 0031C30C 4B D3 B9 25 */ bl "__dt__Q24rstl52list,Q24rstl17rmemory_allocator>Fv" lbl_8031F3B0: /* 8031F3B0 0031C310 7F E0 07 35 */ extsh. r0, r31 /* 8031F3B4 0031C314 40 81 00 0C */ ble lbl_8031F3C0 diff --git a/asm/Kyoto/Particles/CParticleElectric.s b/asm/Kyoto/Particles/CParticleElectric.s index 9fd04188..98775101 100644 --- a/asm/Kyoto/Particles/CParticleElectric.s +++ b/asm/Kyoto/Particles/CParticleElectric.s @@ -3909,7 +3909,7 @@ lbl_80361EC0: /* 80361ED0 0035EE30 38 04 DD 08 */ addi r0, r4, __vt__12CParticleGen@l /* 80361ED4 0035EE34 38 80 FF FF */ li r4, -1 /* 80361ED8 0035EE38 90 1E 00 00 */ stw r0, 0(r30) -/* 80361EDC 0035EE3C 4B CF 8D F5 */ bl __dt__12CParticleGenFv +/* 80361EDC 0035EE3C 4B CF 8D F5 */ bl "__dt__Q24rstl52list,Q24rstl17rmemory_allocator>Fv" lbl_80361EE0: /* 80361EE0 0035EE40 7F E0 07 35 */ extsh. r0, r31 /* 80361EE4 0035EE44 40 81 00 0C */ ble lbl_80361EF0 diff --git a/asm/Kyoto/Particles/CParticleSwoosh.s b/asm/Kyoto/Particles/CParticleSwoosh.s index 428c88af..27e8c497 100644 --- a/asm/Kyoto/Particles/CParticleSwoosh.s +++ b/asm/Kyoto/Particles/CParticleSwoosh.s @@ -4884,7 +4884,7 @@ lbl_8032ED98: /* 8032EDA8 0032BD08 38 04 DD 08 */ addi r0, r4, __vt__12CParticleGen@l /* 8032EDAC 0032BD0C 38 80 FF FF */ li r4, -1 /* 8032EDB0 0032BD10 90 1E 00 00 */ stw r0, 0(r30) -/* 8032EDB4 0032BD14 4B D2 BF 1D */ bl __dt__12CParticleGenFv +/* 8032EDB4 0032BD14 4B D2 BF 1D */ bl "__dt__Q24rstl52list,Q24rstl17rmemory_allocator>Fv" lbl_8032EDB8: /* 8032EDB8 0032BD18 7F E0 07 35 */ extsh. r0, r31 /* 8032EDBC 0032BD1C 40 81 00 0C */ ble lbl_8032EDC8 diff --git a/asm/MetroidPrime/CExplosion.s b/asm/MetroidPrime/CExplosion.s index e257e8e5..f2610677 100644 --- a/asm/MetroidPrime/CExplosion.s +++ b/asm/MetroidPrime/CExplosion.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803DA0A8 -lbl_803DA0A8: +.global __vt__10CExplosion +__vt__10CExplosion: # ROM: 0x3D70A8 .4byte 0 .4byte 0 @@ -567,9 +567,9 @@ __dt__10CExplosionFv: /* 8005A850 000577B0 93 C1 00 08 */ stw r30, 8(r1) /* 8005A854 000577B4 7C 7E 1B 79 */ or. r30, r3, r3 /* 8005A858 000577B8 41 82 00 68 */ beq lbl_8005A8C0 -/* 8005A85C 000577BC 3C 60 80 3E */ lis r3, lbl_803DA0A8@ha +/* 8005A85C 000577BC 3C 60 80 3E */ lis r3, __vt__10CExplosion@ha /* 8005A860 000577C0 34 1E 00 E8 */ addic. r0, r30, 0xe8 -/* 8005A864 000577C4 38 03 A0 A8 */ addi r0, r3, lbl_803DA0A8@l +/* 8005A864 000577C4 38 03 A0 A8 */ addi r0, r3, __vt__10CExplosion@l /* 8005A868 000577C8 90 1E 00 00 */ stw r0, 0(r30) /* 8005A86C 000577CC 41 82 00 24 */ beq lbl_8005A890 /* 8005A870 000577D0 80 7E 00 E8 */ lwz r3, 0xe8(r30) @@ -603,8 +603,8 @@ lbl_8005A8C0: /* 8005A8D4 00057834 38 21 00 10 */ addi r1, r1, 0x10 /* 8005A8D8 00057838 4E 80 00 20 */ blr -.global "__ct__10CExplosionFRC31TLockedToken<20CElectricDescription>9TUniqueIdbRC11CEntityInfoRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC12CTransform4fUiRC9CVector3fRC6CColor" -"__ct__10CExplosionFRC31TLockedToken<20CElectricDescription>9TUniqueIdbRC11CEntityInfoRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC12CTransform4fUiRC9CVector3fRC6CColor": +.global "__ct__10CExplosionFRC36TLockedToken<20CElectricDescription>9TUniqueIdbRC11CEntityInfoRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC12CTransform4fUiRC9CVector3fRC6CColor" +"__ct__10CExplosionFRC36TLockedToken<20CElectricDescription>9TUniqueIdbRC11CEntityInfoRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC12CTransform4fUiRC9CVector3fRC6CColor": /* 8005A8DC 0005783C 94 21 FF 80 */ stwu r1, -0x80(r1) /* 8005A8E0 00057840 7C 08 02 A6 */ mflr r0 /* 8005A8E4 00057844 90 01 00 84 */ stw r0, 0x84(r1) @@ -622,9 +622,9 @@ lbl_8005A8C0: /* 8005A914 00057874 7F 88 E3 78 */ mr r8, r28 /* 8005A918 00057878 B0 01 00 08 */ sth r0, 8(r1) /* 8005A91C 0005787C 48 00 04 35 */ bl "__ct__7CEffectF9TUniqueIdRC11CEntityInfobRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC12CTransform4f" -/* 8005A920 00057880 3C 80 80 3E */ lis r4, lbl_803DA0A8@ha +/* 8005A920 00057880 3C 80 80 3E */ lis r4, __vt__10CExplosion@ha /* 8005A924 00057884 3C 60 80 3D */ lis r3, lbl_803CCF78@ha -/* 8005A928 00057888 38 04 A0 A8 */ addi r0, r4, lbl_803DA0A8@l +/* 8005A928 00057888 38 04 A0 A8 */ addi r0, r4, __vt__10CExplosion@l /* 8005A92C 0005788C 3B 00 00 00 */ li r24, 0 /* 8005A930 00057890 90 1A 00 00 */ stw r0, 0(r26) /* 8005A934 00057894 38 83 CF 78 */ addi r4, r3, lbl_803CCF78@l @@ -767,9 +767,9 @@ lbl_8005AADC: /* 8005AB30 00057A90 7F 88 E3 78 */ mr r8, r28 /* 8005AB34 00057A94 B0 01 00 08 */ sth r0, 8(r1) /* 8005AB38 00057A98 48 00 02 19 */ bl "__ct__7CEffectF9TUniqueIdRC11CEntityInfobRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC12CTransform4f" -/* 8005AB3C 00057A9C 3C 80 80 3E */ lis r4, lbl_803DA0A8@ha +/* 8005AB3C 00057A9C 3C 80 80 3E */ lis r4, __vt__10CExplosion@ha /* 8005AB40 00057AA0 3C 60 80 3D */ lis r3, lbl_803CCF78@ha -/* 8005AB44 00057AA4 38 04 A0 A8 */ addi r0, r4, lbl_803DA0A8@l +/* 8005AB44 00057AA4 38 04 A0 A8 */ addi r0, r4, __vt__10CExplosion@l /* 8005AB48 00057AA8 3B 00 00 00 */ li r24, 0 /* 8005AB4C 00057AAC 90 1A 00 00 */ stw r0, 0(r26) /* 8005AB50 00057AB0 38 83 CF 78 */ addi r4, r3, lbl_803CCF78@l @@ -873,8 +873,8 @@ lbl_8005AC20: /* 8005ACC8 00057C28 38 21 00 80 */ addi r1, r1, 0x80 /* 8005ACCC 00057C2C 4E 80 00 20 */ blr -.global __dt__12CParticleGenFv -__dt__12CParticleGenFv: +.global "__dt__Q24rstl52list,Q24rstl17rmemory_allocator>Fv" +"__dt__Q24rstl52list,Q24rstl17rmemory_allocator>Fv": /* 8005ACD0 00057C30 94 21 FF E0 */ stwu r1, -0x20(r1) /* 8005ACD4 00057C34 7C 08 02 A6 */ mflr r0 /* 8005ACD8 00057C38 90 01 00 24 */ stw r0, 0x24(r1) diff --git a/asm/MetroidPrime/Enemies/CPatterned.s b/asm/MetroidPrime/Enemies/CPatterned.s index bc517693..e3de6174 100644 --- a/asm/MetroidPrime/Enemies/CPatterned.s +++ b/asm/MetroidPrime/Enemies/CPatterned.s @@ -5032,7 +5032,7 @@ lbl_8007B214: /* 8007B2FC 0007825C 39 21 00 EC */ addi r9, r1, 0xec /* 8007B300 00078260 38 C0 00 01 */ li r6, 1 /* 8007B304 00078264 39 40 00 00 */ li r10, 0 -/* 8007B308 00078268 4B FD F5 D5 */ bl "__ct__10CExplosionFRC31TLockedToken<20CElectricDescription>9TUniqueIdbRC11CEntityInfoRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC12CTransform4fUiRC9CVector3fRC6CColor" +/* 8007B308 00078268 4B FD F5 D5 */ bl "__ct__10CExplosionFRC36TLockedToken<20CElectricDescription>9TUniqueIdbRC11CEntityInfoRCQ24rstl66basic_string,Q24rstl17rmemory_allocator>RC12CTransform4fUiRC9CVector3fRC6CColor" /* 8007B30C 0007826C 7C 7F 1B 78 */ mr r31, r3 lbl_8007B310: /* 8007B310 00078270 7F 40 07 75 */ extsb. r0, r26 diff --git a/configure.py b/configure.py index af39dd83..7e119af5 100755 --- a/configure.py +++ b/configure.py @@ -76,7 +76,7 @@ LIBS = [ ["MetroidPrime/Tweaks/CTweakParticle", True], "MetroidPrime/Clamp_int", ["MetroidPrime/CArchMsgParmControllerStatus", True], - "MetroidPrime/CExplosion", + ["MetroidPrime/CExplosion", False], ["MetroidPrime/CEffect", True], "MetroidPrime/Cameras/CGameCamera", "MetroidPrime/CGameArea", diff --git a/include/Kyoto/CToken.hpp b/include/Kyoto/CToken.hpp index 3784c3d5..7509dc40 100644 --- a/include/Kyoto/CToken.hpp +++ b/include/Kyoto/CToken.hpp @@ -23,7 +23,8 @@ public: void RemoveRef(); CToken& operator=(const CToken&); bool HasReference() const { return x0_objRef != nullptr; } - FourCC GetReferenceType() { return x0_objRef->GetTag().type; } + const SObjectTag& GetTag() const { return x0_objRef->GetTag(); } + FourCC GetReferenceType() { return GetTag().type; } bool HasLock() { return x4_lockHeld; } diff --git a/include/Kyoto/Graphics/CCubeModel.hpp b/include/Kyoto/Graphics/CCubeModel.hpp new file mode 100644 index 00000000..fd8ae1b8 --- /dev/null +++ b/include/Kyoto/Graphics/CCubeModel.hpp @@ -0,0 +1,9 @@ +#ifndef _CCUBEMODEL +#define _CCUBEMODEL + +class CCubeModel { +public: + static void SetRenderModelBlack(bool v); +}; + +#endif // _CCUBEMODEL diff --git a/include/Kyoto/Graphics/CGraphics.hpp b/include/Kyoto/Graphics/CGraphics.hpp index e3f5b72f..20f3f3d2 100644 --- a/include/Kyoto/Graphics/CGraphics.hpp +++ b/include/Kyoto/Graphics/CGraphics.hpp @@ -9,6 +9,22 @@ #include "Kyoto/Graphics/CTevCombiners.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, +}; + enum ERglTevStage { kTS_Stage0, kTS_Stage1, @@ -156,6 +172,7 @@ public: static void DisableAllLights(); static void SetAmbientColor(const CColor&); + static void SetFog(ERglFogMode mode, float startz, float endz, const CColor& color); static void SetModelMatrix(const CTransform4f& xf); static void SetAlphaCompare(ERglAlphaFunc comp0, u8 ref0, ERglAlphaOp op, ERglAlphaFunc comp1, diff --git a/include/Kyoto/Particles/CElementGen.hpp b/include/Kyoto/Particles/CElementGen.hpp index 1d61ad90..fdc66e49 100644 --- a/include/Kyoto/Particles/CElementGen.hpp +++ b/include/Kyoto/Particles/CElementGen.hpp @@ -64,7 +64,7 @@ public: virtual bool GetParticleEmission() const override; virtual CColor GetModulationColor() const override; virtual bool IsSystemDeletable() const override; - virtual CAABox GetBounds() const override; + virtual rstl::optional_object GetBounds() const override; virtual int GetParticleCount() const override; virtual bool SystemHasLight() const override; virtual CLight GetLight() override; diff --git a/include/Kyoto/Particles/CParticleElectric.hpp b/include/Kyoto/Particles/CParticleElectric.hpp index 87dc61be..127bc2aa 100644 --- a/include/Kyoto/Particles/CParticleElectric.hpp +++ b/include/Kyoto/Particles/CParticleElectric.hpp @@ -31,7 +31,7 @@ public: bool GetParticleEmission() const override; CColor GetModulationColor() const override; bool IsSystemDeletable() const override; - CAABox GetBounds() const override; + rstl::optional_object GetBounds() const override; int GetParticleCount() const override; bool SystemHasLight() const override; CLight GetLight() override; diff --git a/include/Kyoto/Particles/CParticleGen.hpp b/include/Kyoto/Particles/CParticleGen.hpp index 33f7a525..b2a56197 100644 --- a/include/Kyoto/Particles/CParticleGen.hpp +++ b/include/Kyoto/Particles/CParticleGen.hpp @@ -9,6 +9,8 @@ #include "Kyoto/Particles/CWarp.hpp" #include "rstl/list.hpp" +#include "rstl/pair.hpp" +#include "rstl/optional_object.hpp" class CWarp; @@ -35,7 +37,7 @@ public: virtual CColor GetModulationColor() const = 0; virtual float GetGeneratorRate() const { return 1.f; } virtual bool IsSystemDeletable() const = 0; - virtual CAABox GetBounds() const = 0; + virtual rstl::optional_object GetBounds() const = 0; virtual int GetParticleCount() const = 0; virtual bool SystemHasLight() const = 0; virtual CLight GetLight() = 0; @@ -44,7 +46,7 @@ public: virtual uint Get4CharId() const = 0; private: - rstl::list< CWarp > x4_modifiersList; + rstl::list< rstl::pair > x4_modifiersList; }; #endif // _CPARTICLEGEN diff --git a/include/MetroidPrime/CExplosion.hpp b/include/MetroidPrime/CExplosion.hpp index 2f25f3b6..d3eb7bf7 100644 --- a/include/MetroidPrime/CExplosion.hpp +++ b/include/MetroidPrime/CExplosion.hpp @@ -17,6 +17,10 @@ public: const CEntityInfo& info, const rstl::string& name, const CTransform4f& xf, uint flags, const CVector3f& scale, const CColor& color); + CExplosion(const TLockedToken< CElectricDescription >& electric, TUniqueId uid, bool active, + const CEntityInfo& info, const rstl::string& name, const CTransform4f& xf, uint flags, + const CVector3f& scale, const CColor& color); + // CEntity ~CExplosion() override; void Accept(IVisitor& visitor) override; @@ -32,10 +36,7 @@ public: public: rstl::single_ptr< CParticleGen > xe8_particleGen; TUniqueId xec_explosionLight; - union { - const CGenDescription* xf0_particleDesc; - const CElectricDescription* xf0_electricDesc; - }; + uint xf0_sourceId; bool xf4_24_renderThermalHot : 1; bool xf4_25_ : 1; bool xf4_26_renderXray : 1; diff --git a/include/MetroidPrime/CGameArea.hpp b/include/MetroidPrime/CGameArea.hpp index 4a201775..f4eafbe5 100644 --- a/include/MetroidPrime/CGameArea.hpp +++ b/include/MetroidPrime/CGameArea.hpp @@ -6,6 +6,7 @@ #include "MetroidPrime/TGameTypes.hpp" #include "Kyoto/Graphics/CColor.hpp" +#include "Kyoto/Graphics/CGraphics.hpp" #include "Kyoto/IObjectStore.hpp" #include "Kyoto/Math/CAABox.hpp" #include "Kyoto/Math/CTransform4f.hpp" @@ -19,23 +20,6 @@ #include "rstl/single_ptr.hpp" #include "rstl/vector.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: virtual ~IGameArea(); diff --git a/include/MetroidPrime/CParticleGenInfo.hpp b/include/MetroidPrime/CParticleGenInfo.hpp index 058c01b1..4c1e67bd 100644 --- a/include/MetroidPrime/CParticleGenInfo.hpp +++ b/include/MetroidPrime/CParticleGenInfo.hpp @@ -12,7 +12,6 @@ #include "rstl/rc_ptr.hpp" #include "rstl/string.hpp" - enum EParticleGenType { kPGT_Normal, kPGT_Auxiliary }; class CStateManager; @@ -37,7 +36,8 @@ public: virtual void SetGlobalScale(const CVector3f& scale) = 0; virtual void SetParticleEmission(bool isActive, CStateManager& stateMgr) = 0; virtual bool IsSystemDeletable() const = 0; - virtual CAABox GetBounds() const = 0; // This should match CParticleGen::GetBounds result + virtual rstl::optional_object< CAABox > + GetBounds() const = 0; // This should match CParticleGen::GetBounds result virtual bool HasActiveParticles() const = 0; virtual void DestroyParticles() = 0; virtual bool HasLight() const = 0; diff --git a/include/MetroidPrime/CParticleGenInfoGeneric.hpp b/include/MetroidPrime/CParticleGenInfoGeneric.hpp index 4ec0dfee..c1d9cb44 100644 --- a/include/MetroidPrime/CParticleGenInfoGeneric.hpp +++ b/include/MetroidPrime/CParticleGenInfoGeneric.hpp @@ -24,7 +24,7 @@ public: virtual void SetGlobalScale(const CVector3f& scale) override; virtual void SetParticleEmission(bool isActive, CStateManager& stateMgr) override; virtual bool IsSystemDeletable() const override; - virtual CAABox GetBounds() const override; + virtual rstl::optional_object GetBounds() const override; virtual bool HasActiveParticles() const override; virtual void DestroyParticles() override; virtual bool HasLight() const override; diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index 29307da3..d1059814 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -226,6 +226,9 @@ public: void InformListeners(const CVector3f&, EListenNoiseType); + // Fog + void SetupFogForArea(TAreaId area) const; + // void ShowPausedHUDMemo(CAssetId strg, float time); void QueueMessage(int frameCount, CAssetId msg, float f1); diff --git a/include/rstl/list.hpp b/include/rstl/list.hpp index 3c931929..ea8e1543 100644 --- a/include/rstl/list.hpp +++ b/include/rstl/list.hpp @@ -26,11 +26,9 @@ public: , x10_empty_next(reinterpret_cast< node* >(&xc_empty_prev)) , x14_count(0) {} ~list(); - + void push_back(const T& val) { do_insert_before(x8_end, val); } - void clear() { - erase(begin(), end()); - } + void clear() { erase(begin(), end()); } size_t size() const { return x14_count; } bool empty() const { return x14_count == 0; } @@ -56,9 +54,7 @@ private: uchar x8_item[sizeof(T)]; node(node* prev, node* next) : x0_prev(prev), x4_next(next) {} - ~node() { - get_value()->~T(); - } + ~node() { get_value()->~T(); } node* get_prev() const { return x0_prev; } node* get_next() const { return x4_next; } @@ -152,17 +148,17 @@ private: int x14_count; }; -template < typename T, typename Alloc> - list::~list() { - node* cur = x4_start; - while (cur != x8_end) { - node* it = cur; - node* next = cur->get_next(); - cur = next; - destroy(it); - x0_allocator.deallocate(it); - } +template < typename T, typename Alloc > +list< T, Alloc >::~list() { + node* cur = x4_start; + while (cur != x8_end) { + node* it = cur; + node* next = cur->get_next(); + cur = next; + destroy(it); + x0_allocator.deallocate(it); } +} } // namespace rstl diff --git a/include/rstl/string.hpp b/include/rstl/string.hpp index 831f3546..c3d5eaff 100644 --- a/include/rstl/string.hpp +++ b/include/rstl/string.hpp @@ -103,7 +103,6 @@ public: assign(other); return *this; } - basic_string operator+(const basic_string&); basic_string operator+(const _CharTp*); const char* data() const { return x0_ptr; } diff --git a/src/MetroidPrime/CExplosion.cpp b/src/MetroidPrime/CExplosion.cpp new file mode 100644 index 00000000..170c4ce3 --- /dev/null +++ b/src/MetroidPrime/CExplosion.cpp @@ -0,0 +1,156 @@ +#include "MetroidPrime/CExplosion.hpp" + +#include "MetroidPrime/CGameLight.hpp" +#include "MetroidPrime/CStateManager.hpp" +#include "MetroidPrime/Player/CPlayerState.hpp" + +#include "Kyoto/Graphics/CCubeModel.hpp" +#include "Kyoto/Graphics/CGraphics.hpp" +#include "Kyoto/Math/CFrustumPlanes.hpp" +#include "Kyoto/Particles/CElementGen.hpp" +#include "Kyoto/Particles/CGenDescription.hpp" +#include "Kyoto/Particles/CParticleElectric.hpp" +#include "MetaRender/CCubeRenderer.hpp" + +CExplosion::CExplosion(const TLockedToken< CGenDescription >& particle, TUniqueId uid, bool active, + const CEntityInfo& info, const rstl::string& name, const CTransform4f& xf, + uint flags, const CVector3f& scale, const CColor& color) +: CEffect(uid, info, active, name, xf) +, xe8_particleGen(new CElementGen(TToken< CGenDescription >(particle), CElementGen::kMOT_Normal, + flags & 0x2 ? CElementGen::kOSF_Two : CElementGen::kOSF_One)) +, xec_explosionLight(kInvalidUniqueId) +, xf0_sourceId(CToken(particle).GetTag().id) +, xf4_24_renderThermalHot(flags & 0x4) +, xf4_25_(true) +, xf4_26_renderXray(flags & 0x8) +, xf8_time(0.0f) { + SetThermalFlags(flags & 0x1 ? kTF_Cold : kTF_Hot); + xe8_particleGen->SetGlobalTranslation(xf.GetTranslation()); + xe8_particleGen->SetOrientation(xf.GetRotation()); + xe8_particleGen->SetGlobalScale(scale); + xe8_particleGen->SetModulationColor(color); +} + +CExplosion::CExplosion(const TLockedToken< CElectricDescription >& electric, TUniqueId uid, + bool active, const CEntityInfo& info, const rstl::string& name, + const CTransform4f& xf, uint flags, const CVector3f& scale, + const CColor& color) +: CEffect(uid, info, active, name, xf) +, xe8_particleGen(new CParticleElectric(electric)) +, xec_explosionLight(kInvalidUniqueId) +, xf0_sourceId(CToken(electric).GetTag().id) +, xf4_24_renderThermalHot(flags & 0x4) +, xf4_25_(true) +, xf4_26_renderXray(flags & 0x8) +// , xf8_time(0.0f) +{ + SetThermalFlags(flags & 0x1 ? kTF_Cold : kTF_Hot); + xe8_particleGen->SetGlobalTranslation(xf.GetTranslation()); + xe8_particleGen->SetOrientation(xf.GetRotation()); + xe8_particleGen->SetGlobalScale(scale); + xe8_particleGen->SetModulationColor(color); +} + +CExplosion::~CExplosion() {} + +void CExplosion::AddToRenderer(const CFrustumPlanes& frustum, const CStateManager& mgr) const { + if (GetPreRenderClipped()) { + return; + } + + if ((xf4_24_renderThermalHot && mgr.GetThermalDrawFlag() == kTD_Hot) || + (xf4_26_renderXray && mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::kPV_XRay)) { + EnsureRendered(mgr); + } else { + gpRender->AddParticleGen(*xe8_particleGen); + } +} + +void CExplosion::PreRender(CStateManager& mgr, const CFrustumPlanes& frustum) { + CActor::PreRender(mgr, frustum); + SetPreRenderClipped(!xf4_25_ || !frustum.BoxInFrustumPlanes(GetRenderBoundsCached())); +} + +void CExplosion::Think(float dt, CStateManager& mgr) { + if (GetTransformDirtySpare()) { + xe8_particleGen->SetGlobalTranslation(GetTranslation()); + xe8_particleGen->SetOrientation(GetTransform().GetRotation()); + SetTransformDirtySpare(false); + } + xe8_particleGen->Update(dt); + + if (xec_explosionLight != kInvalidUniqueId) { + CGameLight* light = TCastToPtr< CGameLight >(mgr.ObjectById(xec_explosionLight)); + if (light && GetActive()) + light->SetLight(xe8_particleGen->GetLight()); + } + + xf8_time += dt; + + if (xf8_time > 15.f) { + mgr.FreeScriptObject(GetUniqueId()); + } else if (xe8_particleGen->IsSystemDeletable()) { + mgr.FreeScriptObject(GetUniqueId()); + } +} + +void CExplosion::Accept(IVisitor& visitor) { visitor.Visit(*this); } + +void CExplosion::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr) { + switch (msg) { + case kSM_Registered: + if (xe8_particleGen->SystemHasLight()) { + xec_explosionLight = mgr.AllocateUniqueId(); + uint sourceId = xf0_sourceId; + mgr.AddObject(new CGameLight(xec_explosionLight, GetCurrentAreaId(), GetActive(), + rstl::string_l("ExplodePLight_") + GetDebugName(), + GetTransform(), GetUniqueId(), xe8_particleGen->GetLight(), + sourceId, 1, 0.f)); + } + break; + case kSM_Deleted: + if (xec_explosionLight != kInvalidUniqueId) { + mgr.FreeScriptObject(xec_explosionLight); + xec_explosionLight = kInvalidUniqueId; + } + break; + + default: + break; + } + CActor::AcceptScriptMsg(msg, sender, mgr); + + if (xec_explosionLight != kInvalidUniqueId) + mgr.SendScriptMsgAlways(sender, xec_explosionLight, msg); +} + +void CExplosion::CalculateRenderBounds() { + rstl::optional_object< CAABox > bounds = xe8_particleGen->GetBounds(); + if (bounds) { + SetRenderBounds(*bounds); + xf4_25_ = true; + } else { + xf4_25_ = false; + CVector3f pos = GetTransform().GetTranslation(); + SetRenderBounds(CAABox(pos, pos)); + } +} + +void CExplosion::Render(const CStateManager& mgr) const { + if (mgr.GetThermalDrawFlag() == kTD_Hot && xf4_24_renderThermalHot) { + CElementGen::SetSubtractBlend(true); + CCubeModel::SetRenderModelBlack(true); + xe8_particleGen->Render(); + CCubeModel::SetRenderModelBlack(false); + CElementGen::SetSubtractBlend(false); + return; + } + + CElementGen::SetSubtractBlend(!xf4_24_renderThermalHot); + CGraphics::SetFog(kRFM_PerspLin, 0.f, 75.f, CColor::Black()); + xe8_particleGen->Render(); + mgr.SetupFogForArea(GetCurrentAreaId()); + CElementGen::SetSubtractBlend(false); +} + +// bool CExplosion::CanRenderUnsorted(const CStateManager&) const { return false; } diff --git a/src/MetroidPrime/CParticleGenInfoGeneric.cpp b/src/MetroidPrime/CParticleGenInfoGeneric.cpp index e2a58193..c9bd6cce 100644 --- a/src/MetroidPrime/CParticleGenInfoGeneric.cpp +++ b/src/MetroidPrime/CParticleGenInfoGeneric.cpp @@ -125,6 +125,6 @@ bool CParticleGenInfoGeneric::HasActiveParticles() const { return x84_system->GetParticleCount() > 0; } -CAABox CParticleGenInfoGeneric::GetBounds() const { return x84_system->GetBounds(); } +rstl::optional_object CParticleGenInfoGeneric::GetBounds() const { return x84_system->GetBounds(); } bool CParticleGenInfoGeneric::IsSystemDeletable() const { return x84_system->IsSystemDeletable(); } diff --git a/src/MetroidPrime/ScriptObjects/CScriptPickup.cpp b/src/MetroidPrime/ScriptObjects/CScriptPickup.cpp index 014321d6..085eee5a 100644 --- a/src/MetroidPrime/ScriptObjects/CScriptPickup.cpp +++ b/src/MetroidPrime/ScriptObjects/CScriptPickup.cpp @@ -154,10 +154,11 @@ void CScriptPickup::Touch(CActor& act, CStateManager& mgr) { if (x27c_pickupParticleDesc) { if (mgr.GetPlayerState()->GetActiveVisor(mgr) != CPlayerState::kPV_Thermal) { mgr.AddObject(new CExplosion( - *x27c_pickupParticleDesc, mgr.AllocateUniqueId(), true, + TLockedToken< CGenDescription >(*x27c_pickupParticleDesc), mgr.AllocateUniqueId(), true, CEntityInfo(GetCurrentAreaId(), CEntity::NullConnectionList, kInvalidEditorId), rstl::string_l("Explosion - Pickup Effect"), GetTransform(), 0, CVector3f(1.f, 1.f, 1.f), CColor::White())); + } }