diff --git a/config/RSPE01_01/symbols.txt b/config/RSPE01_01/symbols.txt index 6f71f394..1dfab822 100644 --- a/config/RSPE01_01/symbols.txt +++ b/config/RSPE01_01/symbols.txt @@ -7723,14 +7723,14 @@ commitMail__17RPSysNWC24ManagerFPCwPCwUsPC11RPSysAvatariP16__va_list_struct = .t __dt__17RPSysNWC24ManagerFv = .text:0x801A7530; // type:function size:0x40 __ct__17RPSysNWC24ManagerFPQ23EGG4Heap = .text:0x801A7570; // type:function size:0x68 initialize__17RPSysNWC24ManagerFv = .text:0x801A75D8; // type:function size:0x60 -fn_801A7638 = .text:0x801A7638; // type:function size:0x2C -fn_801A7664 = .text:0x801A7664; // type:function size:0x28 -fn_801A768C = .text:0x801A768C; // type:function size:0x20 -fn_801A76AC = .text:0x801A76AC; // type:function size:0x14 -fn_801A76C0 = .text:0x801A76C0; // type:function size:0xD4 -fn_801A7794 = .text:0x801A7794; // type:function size:0x50 -fn_801A77E4 = .text:0x801A77E4; // type:function size:0x58 -fn_801A783C = .text:0x801A783C; // type:function size:0x58 +Reset__20RPSysParticleManagerFv = .text:0x801A7638; // type:function size:0x2C +SetParticleRotate__20RPSysParticleManagerFRCQ34nw4r4math4VEC3 = .text:0x801A7664; // type:function size:0x28 +SetParticleSize__20RPSysParticleManagerFRCQ34nw4r4math4VEC2 = .text:0x801A768C; // type:function size:0x20 +SetParticleLife__20RPSysParticleManagerFUs = .text:0x801A76AC; // type:function size:0x14 +Calc__20RPSysParticleManagerFv = .text:0x801A76C0; // type:function size:0xD4 +Initialize__20RPSysParticleManagerFPQ34nw4r2ef7EmitterPQ34nw4r2ef15EmitterResource = .text:0x801A7794; // type:function size:0x50 +__dt__20RPSysParticleManagerFv = .text:0x801A77E4; // type:function size:0x58 +__ct__20RPSysParticleManagerFv = .text:0x801A783C; // type:function size:0x58 __ct__Q34nw4r3g3d6ScnRflFP12MEMAllocatorPvPv13RFLResolutionUl = .text:0x801A7894; // type:function size:0xBC scope:global G3dProc__Q34nw4r3g3d6ScnRflFUlUlPv = .text:0x801A7950; // type:function size:0x7D0 scope:global Construct__Q34nw4r3g3d6ScnRflFP12MEMAllocatorPUl13RFLResolutionUlUl = .text:0x801A8120; // type:function size:0xC0 scope:global @@ -18586,7 +18586,7 @@ lbl_803B9E90 = .data:0x803B9E90; // type:object size:0x10 lbl_803B9EA0 = .data:0x803B9EA0; // type:object size:0x10 @19267 = .data:0x803B9EB0; // type:object size:0x9C scope:local __vt__17RPSysNWC24Manager = .data:0x803B9F4C; // type:object size:0xC -lbl_803B9F58 = .data:0x803B9F58; // type:object size:0x38 +__vt__20RPSysParticleManager = .data:0x803B9F58; // type:object size:0x38 __vt__Q34nw4r3g3d6ScnRfl = .data:0x803B9F90; // type:object size:0x34 scope:global lbl_803B9FC8 = .data:0x803B9FC8; // type:object size:0x10 lbl_803B9FD8 = .data:0x803B9FD8; // type:object size:0x18 diff --git a/include/Pack/RPKernel.h b/include/Pack/RPKernel.h index 38dae13f..435f9ff7 100644 --- a/include/Pack/RPKernel.h +++ b/include/Pack/RPKernel.h @@ -34,6 +34,7 @@ #include #include #include +#include #include #include #include diff --git a/include/Pack/RPKernel/RPSysParticleManager.h b/include/Pack/RPKernel/RPSysParticleManager.h new file mode 100644 index 00000000..2e2883e8 --- /dev/null +++ b/include/Pack/RPKernel/RPSysParticleManager.h @@ -0,0 +1,93 @@ +#ifndef RP_KERNEL_PARTICLE_MANAGER_H +#define RP_KERNEL_PARTICLE_MANAGER_H +#include + +#include +#include + +//! @addtogroup rp_kernel +//! @{ + +/** + * @brief Particle manager + */ +class RPSysParticleManager : public nw4r::ef::ParticleManager { +public: + /** + * @brief Constructor + */ + RPSysParticleManager(); + + /** + * @brief Destructor + */ + virtual ~RPSysParticleManager() override; // at 0x20 + + /** + * @brief Prepares this particle manager for creation + * + * @param pParent Parent emitter + * @param pResource Emitter resource data + * @return Success + */ + virtual bool + Initialize(nw4r::ef::Emitter* pParent, + nw4r::ef::EmitterResource* pResource) override; // at 0x10 + + /** + * @brief Updates the particles' state and applies any modifiers + */ + virtual void Calc() override; // at 0x18 + + /** + * @brief Sets the life of all active particles + * + * @param life New life + */ + virtual void SetParticleLife(u16 life); // at 0x24 + + /** + * @brief Sets the size of all active particles + * + * @param rSize New size + */ + virtual void SetParticleSize(const nw4r::math::VEC2& rSize); // at 0x28 + + /** + * @brief Sets the rotation of all active particles + * + * @param rRotate New rotation + */ + virtual void SetParticleRotate(const nw4r::math::VEC3& rRotate); // at 0x2C + +private: + /** + * @brief Particle modifier flags + */ + enum { + EFlag_ModifyLife = 1 << 0, //!< Life modifier is set + EFlag_ModifySize = 1 << 1, //!< Size modifier is set + EFlag_ModifyRotate = 1 << 2, //!< Rotate modifier is set + }; + +private: + /** + * @brief Resets all particle modifiers + */ + virtual void Reset(); // at 0x30 + +private: + //! Which modifiers have been set + u32 mModifyFlags; // at 0xBC + + //! Particle life modifier + u16 mModifyLife; // at 0xC0 + //! Particle size modifier + nw4r::math::VEC2 mModifySize; // at 0xC4 + //! Particle rotation modifier + nw4r::math::VEC3 mModifyRotate; +}; + +//! @} + +#endif diff --git a/include/nw4r/ef/ef_particle.h b/include/nw4r/ef/ef_particle.h index 13371318..9ace6154 100644 --- a/include/nw4r/ef/ef_particle.h +++ b/include/nw4r/ef/ef_particle.h @@ -6,7 +6,6 @@ #include #include #include - #include #include @@ -87,6 +86,10 @@ class Particle : public ReferencedObject { const EmitterInheritSetting* pSetting, Particle* pReferencePtcl); // at 0x10 + ParticleParameter* GetParticleParameter() { + return &mParameter; + } + void Draw_GetColor(int layer, GXColor* pColorPri, GXColor* pColorSec); void GetColor(int layer, int index, GXColor* pColor) { diff --git a/src/Pack/RPKernel/RPSysNWC24Manager.cpp b/src/Pack/RPKernel/RPSysNWC24Manager.cpp index e543c02f..8e97185d 100644 --- a/src/Pack/RPKernel/RPSysNWC24Manager.cpp +++ b/src/Pack/RPKernel/RPSysNWC24Manager.cpp @@ -19,7 +19,7 @@ BOOL RPSysNWC24Manager::sSuccess = true; */ void RPSysNWC24Manager::initialize() { s32 err = NWC24SuspendScheduler(); - if (err >= NWC24_OK) { + if (err >= 0) { return; } diff --git a/src/Pack/RPKernel/RPSysParticleManager.cpp b/src/Pack/RPKernel/RPSysParticleManager.cpp new file mode 100644 index 00000000..5d3f9264 --- /dev/null +++ b/src/Pack/RPKernel/RPSysParticleManager.cpp @@ -0,0 +1,126 @@ +#include + +/** + * @brief Constructor + */ +RPSysParticleManager::RPSysParticleManager() : mModifyFlags(0) { + Reset(); +} + +/** + * @brief Destructor + */ +RPSysParticleManager::~RPSysParticleManager() {} + +/** + * @brief Prepares this particle manager for creation + * + * @param pParent Parent emitter + * @param pResource Emitter resource data + * @return Success + */ +bool RPSysParticleManager::Initialize(nw4r::ef::Emitter* pParent, + nw4r::ef::EmitterResource* pResource) { + bool success = nw4r::ef::ParticleManager::Initialize(pParent, pResource); + + Reset(); + return success; +} + +/** + * @brief Updates the particles' state and applies any modifiers + */ +void RPSysParticleManager::Calc() { + nw4r::ef::ParticleManager::Calc(); + + if (mModifyFlags == 0) { + return; + } + + nw4r::ef::Particle* pPrev = NULL; + + nw4r::ef::Particle* pIt = static_cast( + nw4r::ut::List_GetFirst(&GetParticleList()->mActiveList)); + + for (; pIt != NULL; + pIt = static_cast( + nw4r::ut::List_GetNext(&GetParticleList()->mActiveList, pIt))) { + + if (pIt->mTick != 1) { + continue; + } + + if (pIt->GetLifeStatus() == + nw4r::ef::ReferencedObject::NW4R_EF_LS_WAIT || + pIt->GetLifeStatus() == + nw4r::ef::ReferencedObject::NW4R_EF_LS_CLOSING) { + + continue; + } + + if (mModifyFlags & EFlag_ModifyLife) { + pIt->mLife = mModifyLife; + } + + nw4r::ef::ParticleParameter* pParameter = pIt->GetParticleParameter(); + if (pParameter == NULL) { + continue; + } + + if (mModifyFlags & EFlag_ModifySize) { + pParameter->mSize = mModifySize; + } + + if (mModifyFlags & EFlag_ModifyRotate) { + pParameter->mRotate = mModifyRotate; + } + + pPrev = pIt; + } +} + +/** + * @brief Sets the life of all active particles + * + * @param life New life + */ +void RPSysParticleManager::SetParticleLife(u16 life) { + mModifyFlags |= EFlag_ModifyLife; + mModifyLife = life; +} + +/** + * @brief Sets the size of all active particles + * + * @param rSize New size + */ +void RPSysParticleManager::SetParticleSize(const nw4r::math::VEC2& rSize) { + mModifyFlags |= EFlag_ModifySize; + mModifySize = rSize; +} + +/** + * @brief Sets the rotation of all active particles + * + * @param rRotate New rotation + */ +void RPSysParticleManager::SetParticleRotate(const nw4r::math::VEC3& rRotate) { + mModifyFlags |= EFlag_ModifyRotate; + mModifyRotate = rRotate; +} + +/** + * @brief Resets all particle modifiers + */ +void RPSysParticleManager::Reset() { + mModifyFlags = 0; + + mModifyLife = 0; + + mModifySize.x = 1.0f; + mModifySize.y = 1.0f; + + mModifyRotate.x = 0.0f; + mModifyRotate.y = 0.0f; + mModifyRotate.z = 0.0f; +}