Start matching CScriptPlatform; more CScriptMazeNode

Former-commit-id: 135d63412c
This commit is contained in:
Luke Street 2022-09-18 01:55:13 -04:00
parent ad6fd10f21
commit 41a2efa884
30 changed files with 984 additions and 90 deletions

View File

@ -1,7 +1,7 @@
---
BasedOnStyle: LLVM
IndentWidth: 2
ColumnLimit: 140
ColumnLimit: 100
---
Language: Cpp
DerivePointerAlignment: false

3
.gitignore vendored
View File

@ -11,3 +11,6 @@ tools/mwcc_compiler/*
!tools/mwcc_compiler/.gitkeep
*.bat
include/lmgr326b.dll
.idea/
.vscode/
versions/

View File

@ -0,0 +1,24 @@
#ifndef _CCOLLIDABLEAABOX_HPP
#define _CCOLLIDABLEAABOX_HPP
#include "types.h"
#include "Collision/CCollisionPrimitive.hpp"
class CCollidableAABox : public CCollisionPrimitive {
public:
// TODO
u32 GetTableIndex() const override;
CAABox CalculateAABox(const CTransform4f&) const override;
CAABox CalculateLocalAABox() const override;
FourCC GetPrimType() const override;
~CCollidableAABox() override;
CRayCastResult CastRayInternal(const CInternalRayCastStructure&) const;
private:
CAABox x10_aabb;
};
CHECK_SIZEOF(CCollidableAABox, 0x28)
#endif

View File

@ -0,0 +1,36 @@
#ifndef _CCOLLISIONPRIMITIVE_HPP
#define _CCOLLISIONPRIMITIVE_HPP
#include "types.h"
#include "Collision/CMaterialList.hpp"
#include "Kyoto/IObjectStore.hpp"
#include "Kyoto/Math/CAABox.hpp"
#include "Kyoto/Math/CTransform4f.hpp"
class CRayCastResult;
class CInternalRayCastStructure;
class CCollisionPrimitive {
public:
CCollisionPrimitive(const CMaterialList& list);
virtual u32 GetTableIndex() const = 0;
virtual void SetMaterial(const CMaterialList&);
virtual const CMaterialList& GetMaterial() const;
virtual CAABox CalculateAABox(const CTransform4f&) const = 0;
virtual CAABox CalculateLocalAABox() const = 0;
virtual FourCC GetPrimType() const = 0;
virtual ~CCollisionPrimitive();
virtual CRayCastResult CastRayInternal(const CInternalRayCastStructure&) const = 0;
private:
uint x4_;
CMaterialList x8_material;
};
CHECK_SIZEOF(CCollisionPrimitive, 0x10)
inline CCollisionPrimitive::~CCollisionPrimitive() {}
#endif

View File

@ -73,12 +73,33 @@ class CMaterialList {
public:
CMaterialList() : value(0) {}
CMaterialList(const EMaterialTypes& material) : value(0) { value |= u64(1) << material; }
// TODO
CMaterialList(const EMaterialTypes& m1, const EMaterialTypes& m2);
CMaterialList(const EMaterialTypes& m1, const EMaterialTypes& m2, const EMaterialTypes& m3);
CMaterialList(const EMaterialTypes& m1, const EMaterialTypes& m2, const EMaterialTypes& m3, const EMaterialTypes& m4);
CMaterialList(const EMaterialTypes& m1, const EMaterialTypes& m2, const EMaterialTypes& m3, const EMaterialTypes& m4,
const EMaterialTypes& m5);
CMaterialList(const EMaterialTypes& m1, const EMaterialTypes& m2) : value(0) {
value |= u64(1) << m1;
value |= u64(1) << m2;
}
CMaterialList(const EMaterialTypes& m1, const EMaterialTypes& m2, const EMaterialTypes& m3)
: value(0) {
value |= u64(1) << m1;
value |= u64(1) << m2;
value |= u64(1) << m3;
}
CMaterialList(const EMaterialTypes& m1, const EMaterialTypes& m2, const EMaterialTypes& m3,
const EMaterialTypes& m4)
: value(0) {
value |= u64(1) << m1;
value |= u64(1) << m2;
value |= u64(1) << m3;
value |= u64(1) << m4;
}
CMaterialList(const EMaterialTypes& m1, const EMaterialTypes& m2, const EMaterialTypes& m3,
const EMaterialTypes& m4, const EMaterialTypes& m5)
: value(0) {
value |= u64(1) << m1;
value |= u64(1) << m2;
value |= u64(1) << m3;
value |= u64(1) << m4;
value |= u64(1) << m5;
}
CMaterialList(u64 value) : value(value) {}
void Add(EMaterialTypes material) { value |= u64(1) << material; }

View File

@ -0,0 +1,27 @@
#ifndef _CRAYCASTRESULT_HPP
#define _CRAYCASTRESULT_HPP
#include "types.h"
#include "Kyoto/Math/CPlane.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "Collision/CMaterialList.hpp"
class CRayCastResult {
public:
enum EInvalid {
kI_Invalid,
kI_Valid,
};
private:
f32 x0_t;
CVector3f x4_point;
CPlane x10_plane;
EInvalid x20_invalid;
CMaterialList x28_material;
};
CHECK_SIZEOF(CRayCastResult, 0x30)
#endif

View File

@ -0,0 +1,20 @@
#ifndef _CMATRIX3F_HPP
#define _CMATRIX3F_HPP
#include "types.h"
#include "Kyoto/Math/CVector3f.hpp"
class CMatrix3f {
public:
// TODO
private:
// TODO maybe individual f32s
CVector3f m0;
CVector3f m1;
CVector3f m2;
};
CHECK_SIZEOF(CMatrix3f, 0x24);
#endif

View File

@ -0,0 +1,17 @@
#ifndef _CNUQUATERNION_HPP
#define _CNUQUATERNION_HPP
#include "types.h"
class CNUQuaternion {
public:
CNUQuaternion(f32 w, f32 x, f32 y, f32 z) : w(w), x(x), y(y), z(z) {}
private:
f32 w;
f32 x;
f32 y;
f32 z;
};
#endif

View File

@ -0,0 +1,18 @@
#ifndef _CPLANE_HPP
#define _CPLANE_HPP
#include "types.h"
class CPlane {
public:
// TODO
private:
f32 x;
f32 y;
f32 z;
f32 w;
};
CHECK_SIZEOF(CPlane, 0x10)
#endif

View File

@ -6,12 +6,21 @@
class CQuaternion {
public:
CQuaternion(f32 w, f32 x, f32 y, f32 z) : w(w), x(x), y(y), z(z) {}
// CQuaternion(const CQuaternion& other)
// : w(other.w)
// , x(other.x)
// , y(other.y)
// , z(other.z) {}
static const CQuaternion& NoRotation() { return sNoRotation; }
private:
f32 w;
f32 x;
f32 y;
f32 z;
static const CQuaternion sNoRotation;
};
#endif

View File

@ -209,7 +209,7 @@ public:
CActor(TUniqueId uid, bool active, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf, const CModelData& mData,
const CMaterialList& list, const CActorParameters& params, TUniqueId nextDrawNode);
~CActor();
~CActor() override;
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override;
void SetActive(bool active) override;
@ -249,8 +249,15 @@ public:
void DrawTouchBounds() const;
bool IsModelOpaque(const CStateManager& mgr) const;
void RenderInternal(const CStateManager& mgr) const;
void SetMaterialFilter(const CMaterialFilter& filter);
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;
}
CVector3f GetTranslation() const { return x34_transform.GetTranslation(); }
void SetTranslation(const CVector3f& vec);
@ -276,6 +283,9 @@ public:
const CModelFlags& GetModelFlags() const { return xb4_drawFlags; }
void SetModelFlags(const CModelFlags& flags) { xb4_drawFlags = flags; }
const CMaterialList& GetMaterialList() const { return x68_material; }
CMaterialList& MaterialList() { return x68_material; }
bool GetTransformDirty() const { return xe4_27_notInSortedLists; }
bool GetTransformDirtySpare() const { return xe4_28_transformDirty; }
bool GetPreRenderHasMoved() const { return xe4_29_actorLightsDirty; }

View File

@ -3,8 +3,8 @@
#include "types.h"
#include "Kyoto/IObjectStore.hpp"
#include "Kyoto/Graphics/CColor.hpp"
#include "Kyoto/IObjectStore.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "rstl/auto_ptr.hpp"
@ -112,6 +112,8 @@ public:
bool IsHotInThermal() const { return x58_25_thermalHeat; }
bool ForceRenderUnsorted() const { return x58_26_renderUnsorted; }
bool NoSortThermal() const { return x58_27_noSortThermal; }
f32 GetFadeInTime() const { return x5c_fadeInTime; }
f32 GetFadeOutTime() const { return x60_fadeOutTime; }
static CActorParameters None();

View File

@ -33,6 +33,13 @@ public:
};
void PreRender();
void EnableLooping(bool v) {
x220_25_loop = v;
x220_24_animating = true;
}
void SetIsAnimating(bool v) {
x220_24_animating = v;
}
void SetParticleEffectState(const rstl::string& name, bool active, CStateManager& mgr) {
x120_particleDB.SetParticleEffectState(name, active, mgr);
}

View File

@ -0,0 +1,21 @@
#ifndef _CAXISANGLE_HPP
#define _CAXISANGLE_HPP
#include "types.h"
#include "Kyoto/Math/CVector3f.hpp"
class CAxisAngle {
public:
CAxisAngle(f32 x, f32 y, f32 z) : x(x), y(y), z(z) {}
CAxisAngle(const CAxisAngle& other) : x(other.x), y(other.y), z(other.z) {}
static const CAxisAngle& Identity();
private:
// maybe CUnitVector3f?
f32 x, y, z;
};
CHECK_SIZEOF(CAxisAngle, 0xc)
#endif

View File

@ -0,0 +1,46 @@
#ifndef _CDAMAGEVULNERABILITY_HPP
#define _CDAMAGEVULNERABILITY_HPP
#include "types.h"
enum EVulnerability {
kVN_Weak,
kVN_Normal,
kVN_Deflect,
kVN_Immune,
kVN_PassThrough,
kVN_DirectWeak,
kVN_DirectNormal,
kVN_DirectImmune,
};
enum EDeflectionType {
kDT_None,
kDT_One,
kDT_Two,
kDT_Three,
kDT_Four,
};
class CInputStream;
class CDamageVulnerability {
public:
CDamageVulnerability(CInputStream& in);
CDamageVulnerability(EVulnerability, EVulnerability, EVulnerability, EVulnerability,
EVulnerability, EVulnerability, EVulnerability, EVulnerability,
EVulnerability, EVulnerability, EDeflectionType);
// TODO
private:
EVulnerability x0_normal[15];
EVulnerability x3c_charged[4];
EVulnerability x4c_combo[4];
EDeflectionType x5c_deflect;
EDeflectionType x60_chargedDeflect;
EDeflectionType x64_comboDeflect;
};
CHECK_SIZEOF(CDamageVulnerability, 0x68)
#endif

View File

@ -15,14 +15,17 @@ class CEntity {
public:
virtual ~CEntity();
virtual void Accept(IVisitor& visitor) = 0;
virtual void PreThink(float dt, CStateManager& mgr);
virtual void Think(float dt, CStateManager& mgr);
virtual void PreThink(f32 dt, CStateManager& mgr);
virtual void Think(f32 dt, CStateManager& mgr);
virtual void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr);
virtual void SetActive(bool active);
CEntity(TUniqueId id, const CEntityInfo& info, bool active, const rstl::string& name);
void SendScriptMsgs(EScriptObjectState state, CStateManager& mgr, EScriptObjectMessage msg);
static inline void SendScriptMsg(CStateManager& mgr, CEntity* to, TUniqueId sender, EScriptObjectMessage msg) {
mgr.SendScriptMsg(to, sender, msg);
}
TUniqueId GetUniqueId() const { return x8_uid; }
TAreaId GetAreaId() const;
bool GetActive() const { return x30_24_active; }

View File

@ -0,0 +1,17 @@
#ifndef _CHEALTHINFO_HPP
#define _CHEALTHINFO_HPP
#include "types.h"
class CHealthInfo {
public:
CHealthInfo(f32 hp, f32 resist);
// TODO
private:
f32 x0_health;
f32 x4_knockbackResistance;
};
CHECK_SIZEOF(CHealthInfo, 0x8)
#endif

View File

@ -8,15 +8,15 @@
#define kMaxObjects 1024
enum EGameObjectList {
kGOL_Invalid = -1,
kGOL_All,
kGOL_Actor,
kGOL_PhysicsActor,
kGOL_GameCamera,
kGOL_GameLight,
kGOL_ListeningAi,
kGOL_AiWaypoint,
kGOL_PlatformAndDoor,
kOL_Invalid = -1,
kOL_All,
kOL_Actor,
kOL_PhysicsActor,
kOL_GameCamera,
kOL_GameLight,
kOL_ListeningAi,
kOL_AiWaypoint,
kOL_PlatformAndDoor,
};
class CEntity;
@ -30,7 +30,9 @@ class CObjectList {
public:
CObjectList(EGameObjectList list);
bool IsQualified(CEntity& ent);
virtual bool IsQualified(CEntity& ent);
void AddObject(CEntity& ent);
void RemoveObject(TUniqueId uid);
CEntity* GetObjectById();
@ -42,11 +44,21 @@ public:
const CEntity* GetValidObjectByIndex(int idx) const;
int size() const { return mCount; }
int GetFirstObjectIndex() const { return mFirstId; }
int GetNextObjectIndex(int idx) const {
if (idx != -1) {
return mObjects[idx].mNext;
} else {
return -1;
}
}
private:
SObjectListEntry mObjects[1024];
EGameObjectList mListType;
s16 mFirstId = -1;
s16 mCount = 0;
s16 mFirstId;
s16 mCount;
};
CHECK_SIZEOF(CObjectList, 0x200c)
#endif // __COBJECTLIST_HPP__

View File

@ -0,0 +1,108 @@
#ifndef _CPHYSICSACTOR_HPP
#define _CPHYSICSACTOR_HPP
#include "types.h"
#include "MetroidPrime/CActor.hpp"
#include "MetroidPrime/CAxisAngle.hpp"
#include "Kyoto/Math/CAABox.hpp"
#include "Kyoto/Math/CMatrix3f.hpp"
#include "Kyoto/Math/CNUQuaternion.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "Collision/CCollidableAABox.hpp"
#include "rstl/optional_object.hpp"
struct SMoverData {
CVector3f x0_velocity;
CAxisAngle xc_angularVelocity;
CVector3f x18_momentum;
CAxisAngle x24_;
f32 x30_mass;
SMoverData(f32 mass, const CVector3f& velocity, const CAxisAngle& angularVelocity,
const CVector3f& momentum, const CAxisAngle& unk)
: x0_velocity(velocity)
, xc_angularVelocity(angularVelocity)
, x18_momentum(momentum)
, x24_(unk)
, x30_mass(mass) {}
};
class CMotionState {
public:
// TODO
private:
CVector3f x0_translation;
CNUQuaternion xc_orientation;
CVector3f x1c_velocity;
CAxisAngle x28_angularMomentum;
};
CHECK_SIZEOF(CMotionState, 0x34)
class CCollisionInfoList;
class CPhysicsActor : public CActor {
public:
CPhysicsActor(TUniqueId uid, bool active, const rstl::string& name, const CEntityInfo& info,
const CTransform4f& xf, const CModelData& mData, const CMaterialList& matList,
const CAABox& aabb, const SMoverData& moverData, const CActorParameters& actParams,
f32 stepUp, f32 stepDown);
~CPhysicsActor() override;
// CActor
CVector3f GetOrbitPosition(const CStateManager& mgr) const override;
CVector3f GetAimPosition(const CStateManager& mgr, f32 val) const override;
// CPhysicsActor
virtual const CCollisionPrimitive* GetCollisionPrimitive() const;
virtual CTransform4f GetPrimitiveTransform() const;
virtual void CollidedWith(TUniqueId id, const CCollisionInfoList& list, CStateManager& mgr);
virtual f32 GetStepUpHeight() const;
virtual f32 GetStepDownHeight() const;
virtual f32 GetWeight() const;
CAABox GetBoundingBox() const;
bool GetMovable() const { return xf8_24_movable; }
void SetMovable(bool v) { xf8_24_movable = v; }
private:
f32 xe8_mass;
f32 xec_massRecip;
f32 xf0_inertiaTensor;
f32 xf4_inertiaTensorRecip;
bool xf8_24_movable : 1;
bool xf8_25_angularEnabled : 1;
bool xf9_standardCollider;
CVector3f xfc_constantForce;
CAxisAngle x108_angularMomentum;
CMatrix3f x114_;
CVector3f x138_velocity;
CAxisAngle x144_angularVelocity;
CVector3f x150_momentum;
CVector3f x15c_force;
CVector3f x168_impulse;
CAxisAngle x174_torque;
CAxisAngle x180_angularImpulse;
CVector3f x18c_moveImpulse;
CAxisAngle x198_moveAngularImpulse;
CAABox x1a4_baseBoundingBox;
CCollidableAABox x1c0_collisionPrimitive;
CVector3f x1e8_primitiveOffset;
CMotionState x1f4_lastNonCollidingState;
rstl::optional_object< CVector3f > x228_lastFloorPlaneNormal;
f32 x238_maximumCollisionVelocity;
f32 x23c_stepUpHeight;
f32 x240_stepDownHeight;
f32 x244_restitutionCoefModifier;
f32 x248_collisionAccuracyModifier;
uint x24c_numTicksStuck;
uint x250_numTicksPartialUpdate;
};
CHECK_SIZEOF(CPhysicsActor, 0x258)
#endif

View File

@ -3,7 +3,9 @@
#include "types.h"
#include "Kyoto/CRandom16.hpp"
#include "MetroidPrime/CEntityInfo.hpp"
#include "MetroidPrime/CObjectList.hpp"
#include "MetroidPrime/TGameTypes.hpp"
#include "rstl/auto_ptr.hpp"
@ -31,6 +33,7 @@ class CWeaponMgr;
class CWorld;
class CWorldTransManager;
class CEntity;
class CMazeState;
namespace SL {
class CSortedListManager;
@ -49,6 +52,10 @@ public:
const CEntity* GetObjectById(TUniqueId uid) const;
TUniqueId GetIdForScript(TEditorId eid) const;
CMazeState* CurrentMaze();
const CMazeState* GetCurrentMaze() const;
void SetCurrentMaze(const rstl::single_ptr<CMazeState>& maze);
CCameraManager* CameraManager() { return x870_cameraManager; }
const CCameraManager* GetCameraManager() const { return x870_cameraManager; }
CPlayerState* PlayerState() { return x8b8_playerState.GetPtr(); }
@ -57,6 +64,9 @@ public:
const CWorld* GetWorld() const { return x850_world.get(); }
CActorModelParticles* ActorModelParticles() { return x884_actorModelParticles.get(); }
const CActorModelParticles* GetActorModelParticles() const { return x884_actorModelParticles.get(); }
CRandom16* GetActiveRandom() const { return x900_random; }
CObjectList& GetObjectListById(EGameObjectList id) { return *x808_objectLists[id]; }
f32 GetThermalColdScale1() const { return xf24_thermColdScale1; }
f32 GetThermalColdScale2() const { return xf28_thermColdScale2; }
@ -64,6 +74,14 @@ public:
bool IsGeneratingObject() const { return xf94_26_generatingObject; }
void SetIsGeneratingObject(bool gen) { xf94_26_generatingObject = gen; }
inline TUniqueId GenerateObjectInline(TEditorId eid) {
bool wasGeneratingObject = IsGeneratingObject();
SetIsGeneratingObject(true);
TUniqueId objUid = GenerateObject(eid).second;
SetIsGeneratingObject(wasGeneratingObject);
return objUid;
}
private:
u16 x0_nextFreeIndex;
rstl::reserved_vector< u16, 1024 > x8_objectIndexArray;
@ -87,7 +105,9 @@ private:
rstl::rc_ptr< CScriptMailbox > x8bc_mailbox;
rstl::rc_ptr< CMapWorldInfo > x8c0_mapWorldInfo;
rstl::rc_ptr< CWorldTransManager > x8c4_worldTransManager;
u8 pad2[0x658];
u8 pad2[0x38];
CRandom16* x900_random;
u8 pad4[0x61c];
f32 xf24_thermColdScale1;
f32 xf28_thermColdScale2;
u8 pad3[0x6c];

View File

@ -64,7 +64,7 @@ public:
void GenerateObstacles();
SMazeCell& GetCell(uint col, uint row);
SMazeCell& GetCell2(uint col, uint row); // ????
const SMazeCell& GetCell(uint col, uint row) const;
SMazeCell& GetCellInline(uint col, uint row) { return x4_cells[col + row * skMazeCols]; } // ????
inline SMazeCell& GetCell(uint idx) { return x4_cells[idx]; }
};
@ -77,14 +77,10 @@ public:
void Accept(IVisitor& visitor) override;
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override;
void Think(float dt, CStateManager& mgr) override;
void Think(f32 dt, CStateManager& mgr) override;
static void LoadMazeSeeds();
static inline void SendScriptMsg(CStateManager& mgr, CEntity* to, TUniqueId sender, EScriptObjectMessage msg) {
mgr.SendScriptMsg(to, sender, msg);
}
private:
enum ESide {
Invalid = -1,
@ -98,7 +94,7 @@ private:
int xec_row;
ESide xf0_side;
TUniqueId xf4_gateEffectId;
float xf8_msgTimer;
f32 xf8_msgTimer;
TUniqueId xfc_actorId;
CVector3f x100_actorPos;
TUniqueId x10c_triggerId;

View File

@ -0,0 +1,96 @@
#ifndef _CSCRIPTPLATFORM_HPP
#define _CSCRIPTPLATFORM_HPP
#include "types.h"
#include "MetroidPrime/CDamageVulnerability.hpp"
#include "MetroidPrime/CHealthInfo.hpp"
#include "MetroidPrime/CPhysicsActor.hpp"
#include "Kyoto/CRandom16.hpp"
#include "Kyoto/Math/CQuaternion.hpp"
#include "Kyoto/Math/CVector3f.hpp"
#include "rstl/auto_ptr.hpp"
#include "rstl/optional_object.hpp"
#include "rstl/vector.hpp"
class CCollidableOBBTreeGroup;
class CCollidableOBBTreeGroupContainer;
class CFluidPlane;
struct SRiders {
TUniqueId x0_uid;
f32 x4_decayTimer;
CTransform4f x8_transform;
};
class CScriptPlatform : public CPhysicsActor {
public:
CScriptPlatform(
TUniqueId uid, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf,
const CModelData& mData, const CActorParameters& actParams, const CAABox& aabb, f32 speed,
bool detectCollision, f32 xrayAlpha, bool active, const CHealthInfo& hInfo,
const CDamageVulnerability& dVuln,
const rstl::optional_object< TLockedToken< CCollidableOBBTreeGroupContainer > >& dcln,
bool rainSplashes, uint maxRainSplashes, uint rainGenRate);
// CEntity
~CScriptPlatform() override;
void Accept(IVisitor& visitor) override;
void PreThink(f32 dt, CStateManager& mgr) override;
void Think(f32 dt, CStateManager& mgr) override;
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) override;
// CActor
void PreRender(CStateManager&, const CFrustumPlanes&) override;
void Render(const CStateManager&) const override;
CHealthInfo* HealthInfo(CStateManager&) override;
const CDamageVulnerability* GetDamageVulnerability() const override;
rstl::optional_object< CAABox > GetTouchBounds() const override;
CVector3f GetOrbitPosition(const CStateManager&) const override;
CVector3f GetAimPosition(const CStateManager&, float) const override;
CAABox GetSortingBounds(const CTransform4f&) const override;
// CPhysicsActor
const CCollisionPrimitive* GetCollisionPrimitive() const override;
CTransform4f GetPrimitiveTransform() const override;
// CScriptPlatform
virtual void SplashThink(const CAABox&, const CFluidPlane&, float, CStateManager&) const;
virtual CQuaternion Move(float, CStateManager&);
private:
TUniqueId x258_currentWaypoint;
TUniqueId x25a_targetWaypoint;
f32 x25c_currentSpeed;
f32 x260_moveDelay;
f32 x264_collisionRecoverDelay;
f32 x268_fadeInTime;
f32 x26c_fadeOutTime;
CVector3f x270_dragDelta;
CQuaternion x27c_rotDelta;
CHealthInfo x28c_initialHealth;
CHealthInfo x294_health;
CDamageVulnerability x29c_damageVuln;
rstl::optional_object< TLockedToken< CCollidableOBBTreeGroupContainer > > x304_treeGroupContainer;
rstl::single_ptr< CCollidableOBBTreeGroup > x314_treeGroup;
rstl::vector< SRiders > x318_riders;
rstl::vector< SRiders > x328_slavesStatic;
rstl::vector< SRiders > x338_slavesDynamic;
f32 x348_xrayAlpha;
uint x34c_maxRainSplashes;
uint x350_rainGenRate;
TUniqueId x354_boundsTrigger;
bool x356_24_dead : 1;
bool x356_25_controlledAnimation : 1;
bool x356_26_detectCollision : 1;
bool x356_27_squishedRider : 1;
bool x356_28_rainSplashes : 1;
bool x356_29_setXrayDrawFlags : 1;
bool x356_30_disableXrayAlpha : 1;
bool x356_31_xrayFog : 1;
};
CHECK_SIZEOF(CScriptPlatform, 0x358)
#endif

View File

@ -3,6 +3,9 @@
#include "types.h"
class CInputStream;
class COutputStream;
struct TAreaId;
struct TEditorId;
struct TUniqueId;
@ -26,9 +29,14 @@ CHECK_SIZEOF(TAreaId, 0x4)
struct TEditorId {
uint value;
TEditorId() : value(-1) {}
TEditorId(uint value) : value(value) {}
TEditorId(CInputStream& in);
// TODO
uint Value() const { return value; }
uint Id() const { return value; }
uint AreaNum() const { return value; }
void PutTo(COutputStream&) const;
bool operator==(const TEditorId& other) const { return value == other.value; }
bool operator!=(const TEditorId& other) const { return value != other.value; }
@ -36,22 +44,19 @@ struct TEditorId {
CHECK_SIZEOF(TEditorId, 0x4)
struct TUniqueId {
union {
struct {
u16 version : 6;
u16 id : 10;
};
u16 value;
};
TUniqueId() : value(-1) {}
TUniqueId(u16 value) : value(value) {}
u16 Value() const { return value; }
TUniqueId(u16 version, u16 id) : value(((version & 0x3F) << 10) | (id & 0x3FF)) {}
u16 Value() const { return value & 0x3FF; }
u16 Version() const { return (value >> 10) & 0x3F; }
bool operator==(const TUniqueId& other) const { return value == other.value; }
bool operator!=(const TUniqueId& other) const { return value != other.value; }
bool operator<(const TUniqueId& other) const; // TODO
private:
};
CHECK_SIZEOF(TUniqueId, 0x2)
// CHECK_SIZEOF(TUniqueId, 0x2)
typedef u16 TSfxId;
static TSfxId InvalidSfxId = 0xFFFFu;

View File

@ -0,0 +1,40 @@
#ifndef _CCOLLIDABLEOBBTREEGROUP_HPP
#define _CCOLLIDABLEOBBTREEGROUP_HPP
#include "types.h"
#include "Collision/CCollisionPrimitive.hpp"
#include "rstl/auto_ptr.hpp"
#include "rstl/vector.hpp"
class COBBTree;
class CCollidableOBBTreeGroupContainer {
friend class CCollidableOBBTreeGroup;
rstl::vector< rstl::auto_ptr< COBBTree > > x0_trees;
rstl::vector< CAABox > x10_aabbs;
CAABox x20_aabox;
public:
CCollidableOBBTreeGroupContainer(CInputStream& in);
CCollidableOBBTreeGroupContainer(const CVector3f&, const CVector3f&);
};
class CCollidableOBBTreeGroup : public CCollisionPrimitive {
public:
CCollidableOBBTreeGroup(CCollidableOBBTreeGroupContainer* container,
const CMaterialList& matList);
u32 GetTableIndex() const override;
CAABox CalculateAABox(const CTransform4f&) const override;
CAABox CalculateLocalAABox() const override;
FourCC GetPrimType() const override;
~CCollidableOBBTreeGroup() override {}
CRayCastResult CastRayInternal(const CInternalRayCastStructure&) const override;
private:
CCollidableOBBTreeGroupContainer* x10_container;
};
#endif

View File

@ -1,6 +1,8 @@
#ifndef _RSTL_MATH_HPP
#define _RSTL_MATH_HPP
#include "rstl/pointer_iterator.hpp"
namespace rstl {
template < typename T >
inline const T& min_val(const T& a, const T& b) {
@ -11,5 +13,17 @@ template <typename T>
inline const T& max_val(const T& a, const T& b) {
return (a < b) ? b : a;
}
template < class Iter, class T >
inline Iter find(Iter first, Iter last, const T& val) {
return find(first, last, val, typename Iter::iterator_category());
}
template < class Iter, class T >
inline Iter find(Iter first, Iter last, const T& val, input_iterator_tag) {
while (first != last && !(*first == val))
++first;
return first;
}
} // namespace rstl
#endif // _RSTL_MATH_HPP

View File

@ -9,8 +9,13 @@ namespace rstl {
template < typename T >
class optional_object {
public:
optional_object() : x4_valid(false) {}
optional_object(const T& item) : x0_item(item), x4_valid(true) {}
optional_object() : m_valid(false) {}
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());
}
}
~optional_object() { clear(); }
optional_object& operator=(const T& item) {
@ -18,24 +23,30 @@ public:
return *this;
}
T& data() { return x0_item; }
T* get_ptr() { return &x0_item; }
operator bool() const { return x4_valid; }
T& data() { return *get_ptr(); }
const T& data() const { return *get_ptr(); }
T* get_ptr() { return reinterpret_cast< T* >(m_data); }
const T* get_ptr() const { return reinterpret_cast< const T* >(m_data); }
bool valid() const { return m_valid; }
operator bool() const { return m_valid; } // replace with valid()?
void clear() {
rstl::destroy(&x0_item);
x4_valid = false;
if (m_valid) {
rstl::destroy(get_ptr());
}
m_valid = false;
}
T& operator*() { return data(); }
T* operator->() { return data(); }
private:
T x0_item;
bool x4_valid;
u8 m_data[sizeof(T)];
bool m_valid;
void assign(const T& item) {
if (!x4_valid) {
if (!m_valid) {
rstl::construct(get_ptr(), item);
x4_valid = true;
m_valid = true;
} else {
data() = item;
}

View File

@ -6,16 +6,24 @@
#include "rstl/construct.hpp"
namespace rstl {
struct input_iterator_tag {};
struct output_iterator_tag {};
struct forward_iterator_tag : public input_iterator_tag {};
struct bidirectional_iterator_tag : public forward_iterator_tag {};
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
template < typename T, typename Vec, typename Alloc >
class const_pointer_iterator {
protected:
const T* current;
public:
typedef random_access_iterator_tag iterator_category;
const_pointer_iterator() : current(nullptr) {}
const_pointer_iterator(const T* begin) : current(begin) {}
void operator++() { ++current; }
void operator--() { --current; }
const_pointer_iterator& operator++() { ++current; return *this; }
const_pointer_iterator& operator--() { --current; return *this; }
T* get_pointer() const { return const_cast< T* >(current); }
const T& operator*() const { return *get_pointer(); }
const T* operator->() const { return get_pointer(); }
@ -46,6 +54,8 @@ public:
rstl::destroy(get_pointer());
}
}
pointer_iterator& operator++() { ++current; return *this; }
pointer_iterator& operator--() { --current; return *this; }
friend pointer_iterator operator+(const pointer_iterator& x, int v) { return pointer_iterator(x.get_pointer() + v); }
friend pointer_iterator operator-(const pointer_iterator& x, int v) { return pointer_iterator(x.get_pointer() - v); }

View File

@ -24,6 +24,11 @@ public:
bool null() const { return x0_ptr == nullptr; }
T& operator*() { return *x0_ptr; }
const T& operator*() const { return *x0_ptr; }
T* release() {
T* ptr = x0_ptr;
x0_ptr = nullptr;
return ptr;
}
};
typedef single_ptr< void > unk_singleptr;

View File

@ -2,6 +2,9 @@
#include "Kyoto/CResFactory.hpp"
#include "MetroidPrime/CActorParameters.hpp"
#include "MetroidPrime/CObjectList.hpp"
#include "rstl/algorithm.hpp"
uint CScriptMazeNode::sMazeSeeds[300];
@ -79,8 +82,7 @@ void CMazeState::Reset(int seed) {
SMazeCell& CMazeState::GetCell(uint col, uint row) { return x4_cells[col + row * skMazeCols]; }
// ????
SMazeCell& CMazeState::GetCell2(uint col, uint row) { return x4_cells[col + row * skMazeCols]; }
const SMazeCell& CMazeState::GetCell(uint col, uint row) const { return x4_cells[col + row * skMazeCols]; }
static inline int GetRandom(CRandom16& rand, int offset) {
int tmp = rand.Next();
@ -156,7 +158,6 @@ void CMazeState::GenerateObstacles() {
puddle2Idx++;
}
} else {
// SMazeCell& cell = GetCellInline(curCol, curRow);
GetCellInline(curCol, curRow).x1_24_puddle = true;
switch (side) {
case kS_Top:
@ -178,6 +179,7 @@ void CMazeState::GenerateObstacles() {
}
}
}
#undef GetCellInline
idx++;
prevCol = curCol;
@ -247,10 +249,10 @@ CScriptMazeNode::CScriptMazeNode(TUniqueId uid, const rstl::string& name, const
void CScriptMazeNode::Accept(IVisitor& visitor) { visitor.Visit(*this); }
static inline TUniqueId GenerateObject(CStateManager& mgr, const SConnection& conn) {
static inline TUniqueId GenerateObject(CStateManager& mgr, const TEditorId& eid) {
bool wasGeneratingObject = mgr.IsGeneratingObject();
mgr.SetIsGeneratingObject(true);
TUniqueId objUid = mgr.GenerateObject(conn.x8_objId).second;
TUniqueId objUid = mgr.GenerateObject(eid).second;
mgr.SetIsGeneratingObject(wasGeneratingObject);
return objUid;
}
@ -267,12 +269,18 @@ void CScriptMazeNode::GenerateObjects(CStateManager& mgr) {
CScriptEffect* scriptEffect = TCastToPtr< CScriptEffect >(ent);
CScriptActor* scriptActor = TCastToPtr< CScriptActor >(ent);
CScriptTrigger* scriptTrigger = TCastToPtr< CScriptTrigger >(ent);
if ((scriptEffect || scriptActor || scriptTrigger) && (!scriptEffect || !x13c_25_hasGate)) {
// TUniqueId objUid = GenerateObject(mgr, *conn);
bool wasGeneratingObject = mgr.IsGeneratingObject();
mgr.SetIsGeneratingObject(true);
TUniqueId objUid = mgr.GenerateObject(conn->x8_objId).second;
mgr.SetIsGeneratingObject(wasGeneratingObject);
if (!scriptEffect && !scriptActor && !scriptTrigger) {
continue;
}
if (scriptEffect && x13c_25_hasGate) {
continue;
}
// TUniqueId objUid = GenerateObject(mgr, conn->x8_objId);
TUniqueId objUid = GenerateObject(mgr, conn->x8_objId);
// bool wasGeneratingObject = mgr.IsGeneratingObject();
// mgr.SetIsGeneratingObject(true);
// TUniqueId objUid = mgr.GenerateObject(conn->x8_objId).second;
// mgr.SetIsGeneratingObject(wasGeneratingObject);
if (CActor* actor = static_cast< CActor* >(mgr.ObjectById(objUid))) {
mgr.SendScriptMsg(actor, GetUniqueId(), kSM_Activate);
if (scriptEffect) {
@ -290,7 +298,6 @@ void CScriptMazeNode::GenerateObjects(CStateManager& mgr) {
}
}
}
}
void CScriptMazeNode::Reset(CStateManager& mgr) {
mgr.FreeScriptObject(x11c_effectId);
@ -307,8 +314,185 @@ void CScriptMazeNode::SendScriptMsgs(CStateManager& mgr, EScriptObjectMessage ms
SendScriptMsg(mgr, mgr.ObjectById(xf4_gateEffectId), GetUniqueId(), msg);
}
template < typename Iter, typename T >
static inline Iter contains(Iter it, Iter end, const T& value) {
for (; it != end && *it != value; ++it) {
}
return it;
}
template < typename T >
static inline bool contains(const rstl::vector< T >& vec, typename rstl::vector< T >::const_iterator end, const T& value) {
return rstl::find< rstl::vector< T >::const_iterator, T >(vec.begin(), end, value) != end;
}
void CScriptMazeNode::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) {
// TODO
if (GetActive()) {
switch (msg) {
case kSM_InitializedInArea: {
if (mgr.CurrentMaze() == nullptr) {
rstl::single_ptr< CMazeState > maze = new CMazeState(skEnterCol, skEnterRow, skTargetCol, skTargetRow);
maze->Reset(sMazeSeeds[mgr.GetActiveRandom()->Next() % 300]);
maze->Initialize();
maze->GenerateObstacles();
mgr.SetCurrentMaze(maze.release());
}
break;
}
case kSM_Action: {
bool shouldGenObjs = false;
if (const CMazeState* maze = mgr.CurrentMaze()) {
const SMazeCell& cell = maze->GetCell(xe8_col, xec_row);
if (xf0_side == CMazeState::kS_Top && cell.x0_24_openTop) {
if (cell.x0_28_gateTop) {
shouldGenObjs = true;
x13c_25_hasGate = true;
}
} else if (xf0_side == CMazeState::kS_Right && cell.x0_25_openRight) {
if (cell.x0_29_gateRight) {
shouldGenObjs = true;
x13c_25_hasGate = true;
}
} else {
shouldGenObjs = true;
}
if (shouldGenObjs) {
GenerateObjects(mgr);
}
if (xf0_side == CMazeState::kS_Right && cell.x1_24_puddle) {
x13c_24_hasPuddle = true;
}
if (x13c_25_hasGate) {
#ifndef NON_MATCHING
// Unused
CTransform4f xf = GetTransform();
#endif
rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin();
for (; conn != GetConnectionList().end(); ++conn) {
if (conn->x0_state != kSS_Modify || conn->x4_msg != kSM_Activate) {
continue;
}
// TUniqueId genObj = GenerateObject(mgr, conn->x8_objId);
bool wasGeneratingObject = mgr.IsGeneratingObject();
mgr.SetIsGeneratingObject(true);
TUniqueId genObj = mgr.GenerateObject(conn->x8_objId).second;
mgr.SetIsGeneratingObject(wasGeneratingObject);
xf4_gateEffectId = genObj;
if (CActor* actor = TCastToPtr< CActor >(mgr.ObjectById(genObj))) {
actor->SetTranslation(GetTranslation() + x120_effectPos);
mgr.SendScriptMsg(actor, GetUniqueId(), kSM_Activate);
}
break;
}
}
if (x13c_24_hasPuddle) {
int count = 0;
rstl::vector< SConnection >::const_iterator conn = GetConnectionList().begin();
for (; conn != GetConnectionList().end(); ++conn) {
if ((conn->x0_state == kSS_Closed || conn->x0_state == kSS_DeactivateState) && conn->x4_msg == kSM_Activate) {
count++;
}
}
x12c_puddleObjectIds.reserve(count);
conn = GetConnectionList().begin();
for (; conn != GetConnectionList().end(); ++conn) {
if ((conn->x0_state == kSS_Closed || conn->x0_state == kSS_DeactivateState) && conn->x4_msg == kSM_Activate) {
// TUniqueId genObj = GenerateObject(mgr, conn->x8_objId);
bool wasGeneratingObject = mgr.IsGeneratingObject();
mgr.SetIsGeneratingObject(true);
TUniqueId genObj = mgr.GenerateObject(conn->x8_objId).second;
mgr.SetIsGeneratingObject(wasGeneratingObject);
x12c_puddleObjectIds.push_back(genObj);
if (CActor* actor = TCastToPtr< CActor >(mgr.ObjectById(genObj))) {
actor->SetTransform(GetTransform());
if (conn->x0_state == kSS_Closed) {
mgr.SendScriptMsg(actor, GetUniqueId(), kSM_Activate);
}
}
}
}
}
}
break;
}
case kSM_SetToZero: {
CMazeState* maze = mgr.CurrentMaze();
if (x13c_24_hasPuddle && maze != nullptr) {
rstl::vector< TUniqueId >::const_iterator pend = x12c_puddleObjectIds.end();
rstl::vector< TUniqueId >::const_iterator pit =
rstl::find< rstl::vector< TUniqueId >::const_iterator, TUniqueId >(x12c_puddleObjectIds.begin(), pend, uid);
if (pit != pend) {
// if (contains(x12c_puddleObjectIds, x12c_puddleObjectIds.end(), uid)) {
rstl::vector< TUniqueId >::const_iterator it = x12c_puddleObjectIds.begin();
for (; it != x12c_puddleObjectIds.end(); ++it) {
if (CEntity* ent = mgr.ObjectById(*it)) {
if (!ent->GetActive()) {
mgr.SendScriptMsg(ent, GetUniqueId(), kSM_Activate);
} else {
mgr.FreeScriptObject(ent->GetUniqueId());
}
}
}
CObjectList& list = mgr.GetObjectListById(kOL_All);
int objIdx = list.GetFirstObjectIndex();
while (objIdx != -1) {
if (CScriptMazeNode* node = TCastToPtr< CScriptMazeNode >(list[objIdx])) {
if (node->xe8_col == xe8_col - 1 && node->xec_row == xec_row && node->xf0_side == CMazeState::kS_Right) {
SMazeCell& cell = maze->GetCell(xe8_col - 1, xec_row);
if (!cell.x0_25_openRight) {
cell.x0_25_openRight = true;
node->Reset(mgr);
node->x13c_25_hasGate = false;
}
}
if (node->xe8_col == xe8_col && node->xec_row == xec_row && node->xf0_side == CMazeState::kS_Right) {
SMazeCell& cell = maze->GetCell(xe8_col, xec_row);
if (!cell.x0_25_openRight) {
cell.x0_25_openRight = true;
node->Reset(mgr);
node->x13c_25_hasGate = false;
}
}
if (node->xe8_col == xe8_col && node->xec_row == xec_row && node->xf0_side == CMazeState::kS_Top) {
SMazeCell& cell = maze->GetCell(xe8_col, xec_row);
if (!cell.x0_24_openTop) {
cell.x0_24_openTop = true;
node->Reset(mgr);
node->x13c_25_hasGate = false;
}
}
if (node->xe8_col == xe8_col && node->xec_row == xec_row + 1 && node->xf0_side == CMazeState::kS_Top) {
SMazeCell& cell = maze->GetCell(xe8_col, xec_row + 1);
if (!cell.x0_24_openTop) {
cell.x0_24_openTop = true;
node->Reset(mgr);
node->x13c_25_hasGate = false;
}
}
}
objIdx = list.GetNextObjectIndex(objIdx);
}
}
}
break;
}
case kSM_Deleted: {
if (mgr.GetCurrentMaze()) {
mgr.SetCurrentMaze(nullptr);
}
Reset(mgr);
break;
}
case kSM_Deactivate: {
Reset(mgr);
break;
}
}
}
CEntity::AcceptScriptMsg(msg, uid, mgr);
}
void CScriptMazeNode::Think(float dt, CStateManager& mgr) {

View File

@ -0,0 +1,112 @@
#include "MetroidPrime/ScriptObjects/CScriptPlatform.hpp"
#include "MetroidPrime/CActorParameters.hpp"
#include "MetroidPrime/CAnimData.hpp"
#include "Kyoto/Graphics/CGX.hpp"
#include "WorldFormat/CCollidableOBBTreeGroup.hpp"
#ifndef TARGET_PC
struct GXData {
u16 cpSRreg;
u16 cpCRreg;
};
extern GXData* __GXData;
static inline void write_bp_cmd(u32 cmd) {
GXWGFifo.u8 = GX_LOAD_BP_REG;
GXWGFifo.u32 = cmd;
__GXData->cpCRreg = 0;
}
#endif
void CGX::update_fog(uint flags) {
if (sGXState.x53_fogType == 0) {
return;
}
if ((sGXState.x56_blendMode & 0xE0) == (flags & 0xE0)) {
return;
}
if ((flags & 0xE0) == 0x20) {
#ifdef TARGET_PC
static const GXColor sGXClear = {0, 0, 0, 0};
GXSetFogColor(sGXClear);
#else
write_bp_cmd(0xf2000000);
#endif
} else {
#ifdef TARGET_PC
GXSetFogColor(sGXState.x24c_fogParams.x10_fogColor);
#else
write_bp_cmd((sGXState.x24c_fogParams.x10_fogColor.b) |
(sGXState.x24c_fogParams.x10_fogColor.g << 8) |
(sGXState.x24c_fogParams.x10_fogColor.r << 16) | 0xf2000000);
#endif
}
}
CScriptPlatform::CScriptPlatform(
TUniqueId uid, const rstl::string& name, const CEntityInfo& info, const CTransform4f& xf,
const CModelData& mData, const CActorParameters& actParams, const CAABox& aabb, f32 speed,
bool detectCollision, f32 xrayAlpha, bool active, const CHealthInfo& hInfo,
const CDamageVulnerability& dVuln,
const rstl::optional_object< TLockedToken< CCollidableOBBTreeGroupContainer > >& dcln,
bool rainSplashes, uint maxRainSplashes, uint rainGenRate)
: CPhysicsActor(uid, active, name, info, xf, mData,
CMaterialList(kMT_Solid, kMT_Immovable, kMT_Platform, kMT_Occluder), aabb,
SMoverData(15000.f, CVector3f::Zero(), CAxisAngle::Identity(), CVector3f::Zero(),
CAxisAngle::Identity()),
actParams, 0.3f, 0.1f)
, x258_currentWaypoint(kInvalidUniqueId)
, x25a_targetWaypoint(kInvalidUniqueId)
, x25c_currentSpeed(speed)
, x260_moveDelay(0.f)
, x264_collisionRecoverDelay(0.f)
, x268_fadeInTime(actParams.GetFadeInTime())
, x26c_fadeOutTime(actParams.GetFadeOutTime())
, x270_dragDelta(CVector3f::Zero())
, x27c_rotDelta(CQuaternion::NoRotation())
, x28c_initialHealth(hInfo)
, x294_health(hInfo)
, x29c_damageVuln(dVuln)
, x304_treeGroupContainer(dcln)
, x314_treeGroup(nullptr)
, x348_xrayAlpha(xrayAlpha)
, x34c_maxRainSplashes(maxRainSplashes)
, x350_rainGenRate(rainGenRate)
, x354_boundsTrigger(kInvalidUniqueId)
, x356_24_dead(false)
, x356_25_controlledAnimation(false)
, x356_26_detectCollision(detectCollision)
, x356_27_squishedRider(false)
, x356_28_rainSplashes(rainSplashes)
, x356_29_setXrayDrawFlags(false)
, x356_30_disableXrayAlpha(false)
, x356_31_xrayFog(true) {
SetMaterialFilter(CMaterialFilter::MakeIncludeExclude(
CMaterialList(kMT_Solid),
CMaterialList(kMT_NoStaticCollision, kMT_NoPlatformCollision, kMT_Platform)));
SetMovable(false);
if (HasAnimation()) {
AnimationData()->EnableLooping(true);
AnimationData()->SetIsAnimating(true);
}
if (x304_treeGroupContainer) {
x314_treeGroup = new CCollidableOBBTreeGroup(**x304_treeGroupContainer, GetMaterialList());
}
}
CScriptPlatform::~CScriptPlatform() {}
rstl::optional_object< CAABox > CScriptPlatform::GetTouchBounds() const {
if (GetActive()) {
if (!x314_treeGroup.null()) {
return x314_treeGroup->CalculateAABox(GetTransform());
} else {
return GetBoundingBox();
}
} else {
return rstl::optional_object< CAABox >();
}
}