Add CFlameWarp

This commit is contained in:
Henrique Gemignani Passos Lima 2022-11-27 03:43:52 +02:00
parent 147e46d2e8
commit 318c1e0b7f
No known key found for this signature in database
GPG Key ID: E224F951761145F8
7 changed files with 229 additions and 21 deletions

View File

@ -3,8 +3,8 @@
.section .data
.balign 8
.global lbl_803E51C8
lbl_803E51C8:
.global __vt__10CFlameWarp
__vt__10CFlameWarp:
# ROM: 0x3E21C8
.4byte 0
.4byte 0
@ -42,8 +42,8 @@ IsActivated__10CFlameWarpFv:
/* 801B4F6C 001B1ECC 54 03 CF FE */ rlwinm r3, r0, 0x19, 0x1f, 0x1f
/* 801B4F70 001B1ED0 4E 80 00 20 */ blr
.global sub_801b4f74
sub_801b4f74:
.global ResetPosition__10CFlameWarpFRC9CVector3f
ResetPosition__10CFlameWarpFRC9CVector3f:
/* 801B4F74 001B1ED4 38 A3 00 08 */ addi r5, r3, 8
/* 801B4F78 001B1ED8 7C A6 2B 78 */ mr r6, r5
/* 801B4F7C 001B1EDC 48 00 00 20 */ b lbl_801B4F9C
@ -105,7 +105,7 @@ lbl_801B503C:
/* 801B5044 001B1FA4 90 01 00 8C */ stw r0, 0x8c(r1)
/* 801B5048 001B1FA8 90 01 00 90 */ stw r0, 0x90(r1)
/* 801B504C 001B1FAC 90 01 00 94 */ stw r0, 0x94(r1)
/* 801B5050 001B1FB0 48 00 09 7D */ bl sub_801b59cc
/* 801B5050 001B1FB0 48 00 09 7D */ bl "reserve__Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>Fi"
/* 801B5054 001B1FB4 C0 22 A9 4C */ lfs f1, lbl_805AC66C@sda21(r2)
/* 801B5058 001B1FB8 3B 60 00 00 */ li r27, 0
/* 801B505C 001B1FBC C0 02 A9 50 */ lfs f0, lbl_805AC670@sda21(r2)
@ -174,7 +174,7 @@ lbl_801B5128:
/* 801B5148 001B20A8 41 82 00 08 */ beq lbl_801B5150
/* 801B514C 001B20AC 54 A4 08 3C */ slwi r4, r5, 1
lbl_801B5150:
/* 801B5150 001B20B0 48 00 08 7D */ bl sub_801b59cc
/* 801B5150 001B20B0 48 00 08 7D */ bl "reserve__Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>Fi"
lbl_801B5154:
/* 801B5154 001B20B4 80 01 00 8C */ lwz r0, 0x8c(r1)
/* 801B5158 001B20B8 80 61 00 94 */ lwz r3, 0x94(r1)
@ -383,7 +383,7 @@ lbl_801B5454:
/* 801B5478 001B23D8 90 01 00 18 */ stw r0, 0x18(r1)
/* 801B547C 001B23DC 90 01 00 1C */ stw r0, 0x1c(r1)
/* 801B5480 001B23E0 90 A1 00 24 */ stw r5, 0x24(r1)
/* 801B5484 001B23E4 48 00 03 C1 */ bl sub_801b5844
/* 801B5484 001B23E4 48 00 03 C1 */ bl "sort<Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>,8Comparer>__4rstlFQ24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>8Comparer"
/* 801B5488 001B23E8 3C 60 38 E4 */ lis r3, 0x38E38E39@ha
/* 801B548C 001B23EC 3B 7E 00 08 */ addi r27, r30, 8
/* 801B5490 001B23F0 38 03 8E 39 */ addi r0, r3, 0x38E38E39@l
@ -523,9 +523,9 @@ __dt__10CFlameWarpFv:
/* 801B567C 001B25DC 93 C1 00 08 */ stw r30, 8(r1)
/* 801B5680 001B25E0 7C 7E 1B 79 */ or. r30, r3, r3
/* 801B5684 001B25E4 41 82 00 88 */ beq lbl_801B570C
/* 801B5688 001B25E8 3C 60 80 3E */ lis r3, lbl_803E51C8@ha
/* 801B5688 001B25E8 3C 60 80 3E */ lis r3, __vt__10CFlameWarp@ha
/* 801B568C 001B25EC 34 1E 00 04 */ addic. r0, r30, 4
/* 801B5690 001B25F0 38 03 51 C8 */ addi r0, r3, lbl_803E51C8@l
/* 801B5690 001B25F0 38 03 51 C8 */ addi r0, r3, __vt__10CFlameWarp@l
/* 801B5694 001B25F4 90 1E 00 00 */ stw r0, 0(r30)
/* 801B5698 001B25F8 41 82 00 58 */ beq lbl_801B56F0
/* 801B569C 001B25FC 80 BE 00 04 */ lwz r5, 4(r30)
@ -575,9 +575,9 @@ __ct__10CFlameWarpFfRC9CVector3fb:
/* 801B5728 001B2688 3C C0 80 3F */ lis r6, __vt__5CWarp@ha
/* 801B572C 001B268C 39 03 00 08 */ addi r8, r3, 8
/* 801B5730 001B2690 38 06 E2 F8 */ addi r0, r6, __vt__5CWarp@l
/* 801B5734 001B2694 3C C0 80 3E */ lis r6, lbl_803E51C8@ha
/* 801B5734 001B2694 3C C0 80 3E */ lis r6, __vt__10CFlameWarp@ha
/* 801B5738 001B2698 90 03 00 00 */ stw r0, 0(r3)
/* 801B573C 001B269C 38 E6 51 C8 */ addi r7, r6, lbl_803E51C8@l
/* 801B573C 001B269C 38 E6 51 C8 */ addi r7, r6, __vt__10CFlameWarp@l
/* 801B5740 001B26A0 38 00 00 03 */ li r0, 3
/* 801B5744 001B26A4 90 E3 00 00 */ stw r7, 0(r3)
/* 801B5748 001B26A8 38 C0 00 09 */ li r6, 9
@ -648,8 +648,8 @@ lbl_801B57B8:
/* 801B583C 001B279C 98 03 00 A0 */ stb r0, 0xa0(r3)
/* 801B5840 001B27A0 4E 80 00 20 */ blr
.global sub_801b5844
sub_801b5844:
.global "sort<Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>,8Comparer>__4rstlFQ24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>8Comparer"
"sort<Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>,8Comparer>__4rstlFQ24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>8Comparer":
/* 801B5844 001B27A4 94 21 FF C0 */ stwu r1, -0x40(r1)
/* 801B5848 001B27A8 7C 08 02 A6 */ mflr r0
/* 801B584C 001B27AC 90 01 00 44 */ stw r0, 0x44(r1)
@ -739,14 +739,14 @@ lbl_801B5978:
/* 801B5984 001B28E4 38 81 00 10 */ addi r4, r1, 0x10
/* 801B5988 001B28E8 90 A1 00 10 */ stw r5, 0x10(r1)
/* 801B598C 001B28EC 90 01 00 14 */ stw r0, 0x14(r1)
/* 801B5990 001B28F0 4B FF FE B5 */ bl sub_801b5844
/* 801B5990 001B28F0 4B FF FE B5 */ bl "sort<Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>,8Comparer>__4rstlFQ24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>8Comparer"
/* 801B5994 001B28F4 80 BF 00 00 */ lwz r5, 0(r31)
/* 801B5998 001B28F8 38 61 00 0C */ addi r3, r1, 0xc
/* 801B599C 001B28FC 80 01 00 28 */ lwz r0, 0x28(r1)
/* 801B59A0 001B2900 38 81 00 08 */ addi r4, r1, 8
/* 801B59A4 001B2904 90 A1 00 08 */ stw r5, 8(r1)
/* 801B59A8 001B2908 90 01 00 0C */ stw r0, 0xc(r1)
/* 801B59AC 001B290C 4B FF FE 99 */ bl sub_801b5844
/* 801B59AC 001B290C 4B FF FE 99 */ bl "sort<Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>,8Comparer>__4rstlFQ24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>Q24rstl128pointer_iterator<Q24rstl10pair<f,Uc>,Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>,Q24rstl17rmemory_allocator>8Comparer"
lbl_801B59B0:
/* 801B59B0 001B2910 80 01 00 44 */ lwz r0, 0x44(r1)
/* 801B59B4 001B2914 83 E1 00 3C */ lwz r31, 0x3c(r1)
@ -756,8 +756,8 @@ lbl_801B59B0:
/* 801B59C4 001B2924 38 21 00 40 */ addi r1, r1, 0x40
/* 801B59C8 001B2928 4E 80 00 20 */ blr
.global sub_801b59cc
sub_801b59cc:
.global "reserve__Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>Fi"
"reserve__Q24rstl54vector<Q24rstl10pair<f,Uc>,Q24rstl17rmemory_allocator>Fi":
/* 801B59CC 001B292C 94 21 FF D0 */ stwu r1, -0x30(r1)
/* 801B59D0 001B2930 7C 08 02 A6 */ mflr r0
/* 801B59D4 001B2934 90 01 00 34 */ stw r0, 0x34(r1)

View File

@ -997,7 +997,7 @@ Reset__13CFlameThrowerFR13CStateManagerb:
/* 80198290 001951F0 D0 01 00 08 */ stfs f0, 8(r1)
/* 80198294 001951F4 D0 21 00 0C */ stfs f1, 0xc(r1)
/* 80198298 001951F8 D0 41 00 10 */ stfs f2, 0x10(r1)
/* 8019829C 001951FC 48 01 CC D9 */ bl sub_801b4f74
/* 8019829C 001951FC 48 01 CC D9 */ bl ResetPosition__10CFlameWarpFRC9CVector3f
/* 801982A0 00195200 48 00 00 34 */ b lbl_801982D4
lbl_801982A4:
/* 801982A4 00195204 80 7E 03 48 */ lwz r3, 0x348(r30)

View File

@ -264,7 +264,7 @@ LIBS = [
["MetroidPrime/Enemies/CBurstFire", True],
"MetroidPrime/Enemies/CFlaahgra",
"MetroidPrime/Player/CPlayerEnergyDrain",
"MetroidPrime/CFlameWarp",
["MetroidPrime/CFlameWarp", False],
"MetroidPrime/Weapons/CIceImpact",
["MetroidPrime/GameObjectLists", True],
"MetroidPrime/Weapons/CAuxWeapon",

View File

@ -22,6 +22,8 @@ public:
// IsFacing__6CPlaneCFRC9CVector3f
float ClipLineSegment(const CVector3f& start, const CVector3f& end) const;
float PointToPlaneDist(const CVector3f& pos) const { return CVector3f::Dot(GetNormal(), pos) - xc_constant; }
private:
CUnitVector3f x0_normal;
float xc_constant;

View File

@ -1,18 +1,24 @@
#ifndef _CWARP
#define _CWARP
#include "Kyoto/SObjectTag.hpp"
#include "rstl/vector.hpp"
class CParticle;
class CColor;
class CVector3f;
class CWarp {
public:
virtual ~CWarp();
virtual bool UpdateWarp() = 0;
virtual void ModifyParticles(const rstl::vector< CParticle >& particles) = 0;
virtual void ModifyParticles(int particleCount, int stripe, int*, CVector3f* particlePos,
CVector3f* particlePrevPos, CVector3f* particleVelocity,
CColor* color, float* lineLengthOrSize, float* lineWidthOrRota) = 0;
virtual void Activate(bool) = 0;
virtual bool IsActivated() = 0;
virtual int Get4CharID() = 0;
virtual FourCC Get4CharID() = 0;
};
#endif // _CWARP

View File

@ -0,0 +1,54 @@
#ifndef _CFLAMEWARP
#define _CFLAMEWARP
#include "Kyoto/Particles/CWarp.hpp"
#include "Kyoto/Math/CAABox.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "rstl/reserved_vector.hpp"
class CStateManager;
class CColor;
class CFlameWarp : public CWarp {
public:
CFlameWarp(float maxInfluenceDist, const CVector3f& warpPoint, bool collisionWarp);
~CFlameWarp() override;
const rstl::reserved_vector< CVector3f, 9 >& GetCollisionPoints() const {
return x4_collisionPoints;
}
float GetMinSize() const { return x90_minSize; }
float GetMaxSize() const { return x94_maxSize; }
void SetWarpPoint(const CVector3f& p) { x74_warpPoint = p; }
void SetFloatingPoint(const CVector3f& p) { x80_floatingPoint = p; }
const CVector3f& GetFloatingPoint() const { return x80_floatingPoint; }
void SetMaxDistSq(float d) { x8c_maxDistSq = d; }
void SetStateManager(CStateManager& mgr) { x9c_stateMgr = &mgr; }
bool UpdateWarp() override;
void ModifyParticles(int particleCount, int stripe, int*, CVector3f* particlePos,
CVector3f* particlePrevPos, CVector3f* particleVelocity,
CColor* color, float* lineLengthOrSize, float* lineWidthOrRota) override;
void Activate(bool val) override { xa0_24_activated = val; }
bool IsActivated() override;
bool IsProcessed() const { return xa0_26_processed; }
FourCC Get4CharID() override;
void ResetPosition(const CVector3f& pos);
CAABox CalculateBounds() const;
private:
rstl::reserved_vector< CVector3f, 9 > x4_collisionPoints;
CVector3f x74_warpPoint;
CVector3f x80_floatingPoint;
float x8c_maxDistSq;
float x90_minSize;
float x94_maxSize;
float x98_maxInfluenceDistSq;
CStateManager* x9c_stateMgr;
bool xa0_24_activated : 1;
bool xa0_25_collisionWarp : 1;
bool xa0_26_processed : 1;
};
#endif // _CFLAMEWARP

View File

@ -0,0 +1,146 @@
#include "MetroidPrime/CFlameWarp.hpp"
#include "MetroidPrime/CStateManager.hpp"
#include "Collision/CMaterialFilter.hpp"
#include "Collision/CRayCastResult.hpp"
#include "Kyoto/Graphics/CColor.hpp"
#include "rstl/algorithm.hpp"
#include "rstl/pair.hpp"
#include "rstl/vector.hpp"
CFlameWarp::CFlameWarp(float maxInfluenceDist, const CVector3f& warpPoint, bool collisionWarp)
: x4_collisionPoints(warpPoint)
, x74_warpPoint(warpPoint)
, x80_floatingPoint(warpPoint)
, x8c_maxDistSq(0.f)
, x90_minSize(FLT_MAX)
, x94_maxSize(FLT_MIN)
, x98_maxInfluenceDistSq(maxInfluenceDist * maxInfluenceDist)
, x9c_stateMgr(nullptr)
, xa0_24_activated(false)
, xa0_25_collisionWarp(collisionWarp)
, xa0_26_processed(false) {}
CFlameWarp::~CFlameWarp() {}
bool CFlameWarp::UpdateWarp() { return xa0_24_activated; }
class Comparer {
public:
bool operator()(const rstl::pair< float, uchar >& left,
const rstl::pair< float, uchar >& right) const {
return left.first < right.first;
}
};
void CFlameWarp::ModifyParticles(int particleCount, int stripe, int*, CVector3f* particlePos,
CVector3f* particlePrevPos, CVector3f* particleVelocity,
CColor* color, float* lineLengthOrSize, float* lineWidthOrRota) {
if (x9c_stateMgr == nullptr || particleCount < 9) {
return;
}
rstl::vector< rstl::pair< float, uchar > > vec;
vec.reserve(particleCount);
x90_minSize = FLT_MAX;
x94_maxSize = FLT_MIN;
float maxTransp = 0.f;
int idx = 0;
for (int i = 0; i < particleCount; ++i) {
CVector3f& partPos = particlePos[idx];
const float transp = 1.f - color[idx].GetAlpha();
if (transp > maxTransp) {
const float distSq = (partPos - x74_warpPoint).MagSquared();
if (distSq > x8c_maxDistSq && distSq < x98_maxInfluenceDistSq) {
x8c_maxDistSq = distSq;
maxTransp = transp;
x80_floatingPoint = partPos;
}
}
if (lineLengthOrSize[idx] < x90_minSize) {
x90_minSize = lineLengthOrSize[idx];
}
if (lineLengthOrSize[idx] > x94_maxSize) {
x94_maxSize = lineLengthOrSize[idx];
}
vec.push_back(rstl::pair< float, uchar >(0.f, i));
if (xa0_25_collisionWarp) {
CVector3f& prevPos = particlePrevPos[idx];
CVector3f& partVel = particleVelocity[idx];
const CVector3f delta = partPos - prevPos;
if (delta.MagSquared() >= 0.0011920929f) {
const CVector3f deltaNorm = delta.AsNormalized();
const CVector3f behindPos = prevPos - deltaNorm * 5.f;
const CVector3f fullDelta = partPos - behindPos;
float fullDeltaMag = fullDelta.Magnitude();
const CRayCastResult result = x9c_stateMgr->RayStaticIntersection(
behindPos, deltaNorm, fullDeltaMag,
CMaterialFilter::MakeIncludeExclude(CMaterialList(kMT_Solid),
CMaterialList(kMT_ProjectilePassthrough)));
if (result.IsValid()) {
const float dist = result.GetPlane().PointToPlaneDist(partPos);
if (dist <= 0.f) {
partPos -= dist * result.GetPlane().GetNormal();
if (CVector3f::Dot(result.GetPlane().GetNormal(), partVel) < 0.f) {
const CVector3f prevStepPos = partPos - partVel;
partPos += (-result.GetPlane().PointToPlaneDist(prevStepPos) /
CVector3f::Dot(partVel, result.GetPlane().GetNormal()) -
1.f) *
partVel;
partVel -= partVel * 0.001f;
}
}
}
}
}
idx += stripe;
}
rstl::sort(vec.begin(), vec.end(), Comparer());
int vecIdx = 0;
const int pitch = particleCount / 9;
for (int i = 0; i < x4_collisionPoints.capacity(); ++i) {
CVector3f& partPos = particlePos[int(vec[vecIdx].second) * stripe];
x4_collisionPoints[i] = partPos;
if (i > 0) {
const CVector3f delta = x4_collisionPoints[i] - x4_collisionPoints[i - 1];
if (delta.Magnitude() < 0.0011920929f) {
x4_collisionPoints[i] += delta.AsNormalized() * 0.0011920929f;
}
}
vecIdx += pitch * 8;
}
x4_collisionPoints[0] = x74_warpPoint;
x80_floatingPoint = x4_collisionPoints[8];
xa0_26_processed = true;
}
void CFlameWarp::ResetPosition(const CVector3f& pos) {
rstl::reserved_vector< CVector3f, 9 >::iterator it;
for (it = x4_collisionPoints.begin(); it != x4_collisionPoints.end(); ++it) {
*it = pos;
}
xa0_26_processed = false;
}
bool CFlameWarp::IsActivated() { return xa0_24_activated; }
FourCC CFlameWarp::Get4CharID() { return 'FWRP'; }