Add CIceBeam

This commit is contained in:
Henrique Gemignani Passos Lima 2022-11-24 18:48:00 +02:00
parent 7de5f08127
commit 5bdc5643af
No known key found for this signature in database
GPG Key ID: E224F951761145F8
5 changed files with 193 additions and 15 deletions

View File

@ -3,8 +3,8 @@
.section .data .section .data
.balign 8 .balign 8
.global lbl_803DF7E8 .global __vt__8CIceBeam
lbl_803DF7E8: __vt__8CIceBeam:
# ROM: 0x3DC7E8 # ROM: 0x3DC7E8
.4byte 0 .4byte 0
.4byte 0 .4byte 0
@ -14,13 +14,13 @@ lbl_803DF7E8:
.4byte PreRenderGunFx__8CIceBeamFRC13CStateManagerRC12CTransform4f .4byte PreRenderGunFx__8CIceBeamFRC13CStateManagerRC12CTransform4f
.4byte PostRenderGunFx__8CIceBeamFRC13CStateManagerRC12CTransform4f .4byte PostRenderGunFx__8CIceBeamFRC13CStateManagerRC12CTransform4f
.4byte UpdateGunFx__8CIceBeamFbfRC13CStateManagerRC12CTransform4f .4byte UpdateGunFx__8CIceBeamFbfRC13CStateManagerRC12CTransform4f
.4byte Fire__8CIceBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId .4byte Fire__8CIceBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff
.4byte EnableFx__8CIceBeamFb .4byte EnableFx__8CIceBeamFb
.4byte EnableSecondaryFx__8CIceBeamFQ210CGunWeapon16ESecondaryFxType .4byte EnableSecondaryFx__8CIceBeamFQ210CGunWeapon16ESecondaryFxType
.4byte Draw__10CGunWeaponCFbRC13CStateManagerRC12CTransform4fRC11CModelFlagsPC12CActorLights .4byte Draw__10CGunWeaponCFbRC13CStateManagerRC12CTransform4fRC11CModelFlagsPC12CActorLights
.4byte DrawMuzzleFx__10CGunWeaponCFRC13CStateManager .4byte DrawMuzzleFx__10CGunWeaponCFRC13CStateManager
.4byte Update__8CIceBeamFfR13CStateManager .4byte Update__8CIceBeamFfR13CStateManager
.4byte Load__8CIceBeamFb .4byte Load__8CIceBeamFR13CStateManagerb
.4byte Unload__8CIceBeamFR13CStateManager .4byte Unload__8CIceBeamFR13CStateManager
.4byte IsLoaded__8CIceBeamCFv .4byte IsLoaded__8CIceBeamCFv
.4byte 0 .4byte 0
@ -247,8 +247,8 @@ Unload__8CIceBeamFR13CStateManager:
/* 800E11BC 000DE11C 38 21 00 10 */ addi r1, r1, 0x10 /* 800E11BC 000DE11C 38 21 00 10 */ addi r1, r1, 0x10
/* 800E11C0 000DE120 4E 80 00 20 */ blr /* 800E11C0 000DE120 4E 80 00 20 */ blr
.global Load__8CIceBeamFb .global Load__8CIceBeamFR13CStateManagerb
Load__8CIceBeamFb: Load__8CIceBeamFR13CStateManagerb:
/* 800E11C4 000DE124 94 21 FF F0 */ stwu r1, -0x10(r1) /* 800E11C4 000DE124 94 21 FF F0 */ stwu r1, -0x10(r1)
/* 800E11C8 000DE128 7C 08 02 A6 */ mflr r0 /* 800E11C8 000DE128 7C 08 02 A6 */ mflr r0
/* 800E11CC 000DE12C 90 01 00 14 */ stw r0, 0x14(r1) /* 800E11CC 000DE12C 90 01 00 14 */ stw r0, 0x14(r1)
@ -271,8 +271,8 @@ Load__8CIceBeamFb:
/* 800E1210 000DE170 38 21 00 10 */ addi r1, r1, 0x10 /* 800E1210 000DE170 38 21 00 10 */ addi r1, r1, 0x10
/* 800E1214 000DE174 4E 80 00 20 */ blr /* 800E1214 000DE174 4E 80 00 20 */ blr
.global Fire__8CIceBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId .global Fire__8CIceBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff
Fire__8CIceBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueId: Fire__8CIceBeamFbfQ212CPlayerState12EChargeStageRC12CTransform4fR13CStateManager9TUniqueIdff:
/* 800E1218 000DE178 94 21 FF E0 */ stwu r1, -0x20(r1) /* 800E1218 000DE178 94 21 FF E0 */ stwu r1, -0x20(r1)
/* 800E121C 000DE17C 7C 08 02 A6 */ mflr r0 /* 800E121C 000DE17C 7C 08 02 A6 */ mflr r0
/* 800E1220 000DE180 90 01 00 24 */ stw r0, 0x24(r1) /* 800E1220 000DE180 90 01 00 24 */ stw r0, 0x24(r1)
@ -695,9 +695,9 @@ __dt__8CIceBeamFv:
/* 800E17F8 000DE758 93 C1 00 08 */ stw r30, 8(r1) /* 800E17F8 000DE758 93 C1 00 08 */ stw r30, 8(r1)
/* 800E17FC 000DE75C 7C 7E 1B 79 */ or. r30, r3, r3 /* 800E17FC 000DE75C 7C 7E 1B 79 */ or. r30, r3, r3
/* 800E1800 000DE760 41 82 00 D0 */ beq lbl_800E18D0 /* 800E1800 000DE760 41 82 00 D0 */ beq lbl_800E18D0
/* 800E1804 000DE764 3C 60 80 3E */ lis r3, lbl_803DF7E8@ha /* 800E1804 000DE764 3C 60 80 3E */ lis r3, __vt__8CIceBeam@ha
/* 800E1808 000DE768 34 1E 02 44 */ addic. r0, r30, 0x244 /* 800E1808 000DE768 34 1E 02 44 */ addic. r0, r30, 0x244
/* 800E180C 000DE76C 38 03 F7 E8 */ addi r0, r3, lbl_803DF7E8@l /* 800E180C 000DE76C 38 03 F7 E8 */ addi r0, r3, __vt__8CIceBeam@l
/* 800E1810 000DE770 90 1E 00 00 */ stw r0, 0(r30) /* 800E1810 000DE770 90 1E 00 00 */ stw r0, 0(r30)
/* 800E1814 000DE774 41 82 00 24 */ beq lbl_800E1838 /* 800E1814 000DE774 41 82 00 24 */ beq lbl_800E1838
/* 800E1818 000DE778 80 7E 02 44 */ lwz r3, 0x244(r30) /* 800E1818 000DE778 80 7E 02 44 */ lwz r3, 0x244(r30)
@ -772,9 +772,9 @@ __ct__8CIceBeamFUi11EWeaponType9TUniqueId14EMaterialTypesRC9CVector3f:
/* 800E1908 000DE868 38 C1 00 08 */ addi r6, r1, 8 /* 800E1908 000DE868 38 C1 00 08 */ addi r6, r1, 8
/* 800E190C 000DE86C B0 01 00 08 */ sth r0, 8(r1) /* 800E190C 000DE86C B0 01 00 08 */ sth r0, 8(r1)
/* 800E1910 000DE870 48 0D B8 A1 */ bl __ct__10CGunWeaponFUi11EWeaponType9TUniqueId14EMaterialTypesRC9CVector3f /* 800E1910 000DE870 48 0D B8 A1 */ bl __ct__10CGunWeaponFUi11EWeaponType9TUniqueId14EMaterialTypesRC9CVector3f
/* 800E1914 000DE874 3C 60 80 3E */ lis r3, lbl_803DF7E8@ha /* 800E1914 000DE874 3C 60 80 3E */ lis r3, __vt__8CIceBeam@ha
/* 800E1918 000DE878 3C 80 80 3D */ lis r4, lbl_803CE598@ha /* 800E1918 000DE878 3C 80 80 3D */ lis r4, lbl_803CE598@ha
/* 800E191C 000DE87C 38 03 F7 E8 */ addi r0, r3, lbl_803DF7E8@l /* 800E191C 000DE87C 38 03 F7 E8 */ addi r0, r3, __vt__8CIceBeam@l
/* 800E1920 000DE880 38 61 00 1C */ addi r3, r1, 0x1c /* 800E1920 000DE880 38 61 00 1C */ addi r3, r1, 0x1c
/* 800E1924 000DE884 90 1F 00 00 */ stw r0, 0(r31) /* 800E1924 000DE884 90 1F 00 00 */ stw r0, 0(r31)
/* 800E1928 000DE888 38 84 E5 98 */ addi r4, r4, lbl_803CE598@l /* 800E1928 000DE888 38 84 E5 98 */ addi r4, r4, lbl_803CE598@l

View File

@ -132,7 +132,7 @@ LIBS = [
"MetroidPrime/Weapons/CPlasmaBeam", "MetroidPrime/Weapons/CPlasmaBeam",
["MetroidPrime/Weapons/CPowerBeam", False], ["MetroidPrime/Weapons/CPowerBeam", False],
"MetroidPrime/Weapons/CWaveBeam", "MetroidPrime/Weapons/CWaveBeam",
"MetroidPrime/Weapons/CIceBeam", ["MetroidPrime/Weapons/CIceBeam", False],
["MetroidPrime/CScriptMailbox", False], ["MetroidPrime/CScriptMailbox", False],
["MetroidPrime/ScriptObjects/CScriptRelay", True], ["MetroidPrime/ScriptObjects/CScriptRelay", True],
["MetroidPrime/ScriptObjects/CScriptSpawnPoint", False], ["MetroidPrime/ScriptObjects/CScriptSpawnPoint", False],

View File

@ -83,6 +83,7 @@ public:
static void ShutDown(); static void ShutDown();
void SetGlobalOrientAndTrans(const CTransform4f& xf); void SetGlobalOrientAndTrans(const CTransform4f& xf);
static void SetSubtractBlend(bool subtract) { sSubtractBlend = subtract; }
public: public:
TLockedToken< CGenDescription > x1c_genDesc; TLockedToken< CGenDescription > x1c_genDesc;
@ -160,6 +161,8 @@ public:
float x330_LFOR; float x330_LFOR;
float x334_LSLA; float x334_LSLA;
CColor x338_moduColor; CColor x338_moduColor;
static bool sSubtractBlend;
}; };
CHECK_SIZEOF(CElementGen, 0x340) CHECK_SIZEOF(CElementGen, 0x340)

View File

@ -9,10 +9,35 @@ class CIceBeam : public CGunWeapon {
public: public:
CIceBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId, CIceBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId,
EMaterialTypes playerMaterial, const CVector3f& scale); EMaterialTypes playerMaterial, const CVector3f& scale);
~CIceBeam(); ~CIceBeam() override;
// CGunWeapon
void PreRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) override;
void PostRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) override;
void UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr,
const CTransform4f& xf) override;
void Update(float dt, CStateManager& mgr) override;
void Fire(bool underwater, float dt, CPlayerState::EChargeStage chargeState,
const CTransform4f& xf, CStateManager& mgr, TUniqueId homingTarget, float chargeFactor1,
float chargeFactor2) override;
void Load(CStateManager& mgr, bool subtypeBasePose) override;
void Unload(CStateManager& mgr) override;
bool IsLoaded() const override;
void EnableFx(bool enable) override;
void EnableSecondaryFx(ESecondaryFxType type) override;
private: private:
uchar x21c_pad[0x30]; TCachedToken< CGenDescription > x21c_iceSmoke;
TCachedToken< CGenDescription > x228_ice2nd1;
TCachedToken< CGenDescription > x234_ice2nd2;
rstl::single_ptr< CElementGen > x240_smokeGen;
rstl::single_ptr< CElementGen > x244_chargeFx;
bool x248_24_loaded : 1;
bool x248_25_inEndFx : 1;
void ReInitVariables();
}; };
CHECK_SIZEOF(CIceBeam, 0x24c) CHECK_SIZEOF(CIceBeam, 0x24c)

View File

@ -0,0 +1,150 @@
#include "MetroidPrime/Weapons/CIceBeam.hpp"
#include "MetroidPrime/CStateManager.hpp"
#include "MetroidPrime/SFX/Weapons.h"
#include "Kyoto/Audio/CSfxHandle.hpp"
#include "Kyoto/Particles/CElementGen.hpp"
CIceBeam::CIceBeam(CAssetId characterId, EWeaponType type, TUniqueId playerId,
EMaterialTypes playerMaterial, const CVector3f& scale)
: CGunWeapon(characterId, type, playerId, playerMaterial, scale)
, x21c_iceSmoke(gpSimplePool->GetObj("IceSmoke"))
, x228_ice2nd1(gpSimplePool->GetObj("Ice2nd_1"))
, x234_ice2nd2(gpSimplePool->GetObj("Ice2nd_2"))
, x248_24_loaded(false)
, x248_25_inEndFx(false) {}
CIceBeam::~CIceBeam() {}
void CIceBeam::ReInitVariables() {
x240_smokeGen = nullptr;
x244_chargeFx = nullptr;
x248_24_loaded = false;
x248_25_inEndFx = false;
x1cc_enabledSecondaryEffect = kSFT_None;
}
void CIceBeam::PreRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) {
// Empty
}
void CIceBeam::PostRenderGunFx(const CStateManager& mgr, const CTransform4f& xf) {
bool subtractBlend = mgr.GetThermalDrawFlag() == kTD_Hot;
if (subtractBlend)
CElementGen::SetSubtractBlend(true);
if (x240_smokeGen.get())
x240_smokeGen->Render();
if (x1cc_enabledSecondaryEffect != kSFT_None && x244_chargeFx.get())
x244_chargeFx->Render();
CGunWeapon::PostRenderGunFx(mgr, xf);
if (subtractBlend)
CElementGen::SetSubtractBlend(false);
}
static const char* LBEAM = "LBEAM";
void CIceBeam::UpdateGunFx(bool shotSmoke, float dt, const CStateManager& mgr,
const CTransform4f& xf) {
if (x240_smokeGen.get()) {
CTransform4f beamLoc = x10_solidModelData->GetScaledLocatorTransform(rstl::string_l(LBEAM));
x240_smokeGen->SetTranslation(beamLoc.GetTranslation());
x240_smokeGen->SetOrientation(beamLoc.GetRotation());
x240_smokeGen->Update(dt);
}
if (x244_chargeFx.get()) {
if (x248_25_inEndFx && x244_chargeFx->IsSystemDeletable()) {
x1cc_enabledSecondaryEffect = kSFT_None;
x244_chargeFx = nullptr;
}
if (x1cc_enabledSecondaryEffect != kSFT_None) {
if (x248_25_inEndFx) {
x244_chargeFx->SetTranslation(xf.GetTranslation());
x244_chargeFx->SetOrientation(xf.GetRotation());
} else {
x244_chargeFx->SetGlobalOrientAndTrans(xf);
}
x244_chargeFx->Update(dt);
}
}
CGunWeapon::UpdateGunFx(shotSmoke, dt, mgr, xf);
}
void CIceBeam::Update(float dt, CStateManager& mgr) {
CGunWeapon::Update(dt, mgr);
if (!x248_24_loaded) {
x248_24_loaded = x21c_iceSmoke.IsLoaded() && x228_ice2nd1.IsLoaded() && x234_ice2nd2.IsLoaded();
if (x248_24_loaded) {
x240_smokeGen = new CElementGen(x21c_iceSmoke);
x240_smokeGen->SetGlobalScale(x4_scale);
x240_smokeGen->SetParticleEmission(false);
}
}
}
void CIceBeam::Fire(bool underwater, float dt, CPlayerState::EChargeStage chargeState,
const CTransform4f& xf, CStateManager& mgr, TUniqueId homingTarget,
float chargeFactor1, float chargeFactor2) {
static ushort soundId[2] = {SFXwpn_fire_ice_normal, SFXwpn_fire_ice_charged};
CGunWeapon::Fire(underwater, dt, chargeState, xf, mgr, homingTarget, chargeFactor1,
chargeFactor2);
NWeaponTypes::play_sfx(soundId[size_t(chargeState)], underwater, false, 0x4a);
}
void CIceBeam::Load(CStateManager& mgr, bool subtypeBasePose) {
CGunWeapon::Load(mgr, subtypeBasePose);
x21c_iceSmoke.Lock();
x228_ice2nd1.Lock();
x234_ice2nd2.Lock();
x248_25_inEndFx = false;
}
void CIceBeam::Unload(CStateManager& mgr) {
CGunWeapon::Unload(mgr);
x234_ice2nd2.Unlock();
x228_ice2nd1.Unlock();
x21c_iceSmoke.Unlock();
ReInitVariables();
}
bool CIceBeam::IsLoaded() const { return CGunWeapon::IsLoaded() && x248_24_loaded; }
void CIceBeam::EnableSecondaryFx(ESecondaryFxType type) {
switch (type) {
case kSFT_CancelCharge:
case kSFT_None:
if (x1cc_enabledSecondaryEffect == kSFT_None)
break;
default:
switch (type) {
case kSFT_None:
case kSFT_ToCombo:
case kSFT_CancelCharge:
if (!x248_25_inEndFx) {
x244_chargeFx = new CElementGen(x234_ice2nd2);
x244_chargeFx->SetGlobalScale(x4_scale);
x248_25_inEndFx = true;
x1cc_enabledSecondaryEffect = kSFT_CancelCharge;
}
break;
case kSFT_Charge:
x244_chargeFx = new CElementGen(x228_ice2nd1);
x244_chargeFx->SetGlobalScale(x4_scale);
x1cc_enabledSecondaryEffect = type;
x248_25_inEndFx = false;
break;
}
break;
}
}
void CIceBeam::EnableFx(bool enable) {
if (x240_smokeGen.get())
x240_smokeGen->SetParticleEmission(enable);
}