Add CEntity

This commit is contained in:
Henrique Gemignani Passos Lima 2023-08-07 03:47:16 +03:00
parent 064705b8e2
commit 227d3d2a4d
No known key found for this signature in database
GPG Key ID: E224F951761145F8
9 changed files with 444 additions and 15 deletions

View File

@ -1,3 +1,6 @@
MetroidPrime/CEntity.cpp:
.text start:0x80047E5C end:0x800484D4
MetroidPrime/Player/CPlayerState.cpp:
.text start:0x80084864 end:0x80086410

View File

@ -512,7 +512,7 @@ fn_8001C690 = .text:0x8001C690; // type:function size:0x54
fn_8001C6E4 = .text:0x8001C6E4; // type:function size:0x130
fn_8001C814 = .text:0x8001C814; // type:function size:0x68 align:0x4
fn_8001C87C = .text:0x8001C87C; // type:function size:0x58
fn_8001C8D4 = .text:0x8001C8D4; // type:function size:0x54
__dt__Q24rstl48vector<11SConnection,Q24rstl17rmemory_allocator>Fv = .text:0x8001C8D4; // type:function size:0x54
fn_8001C928 = .text:0x8001C928; // type:function size:0x34 align:0x4
fn_8001C95C = .text:0x8001C95C; // type:function size:0x178
fn_8001CAD4 = .text:0x8001CAD4; // type:function size:0x98
@ -1340,16 +1340,16 @@ fn_800478D8 = .text:0x800478D8; // type:function size:0x1D8 align:0x4
fn_80047AB0 = .text:0x80047AB0; // type:function size:0x100
fn_80047BB0 = .text:0x80047BB0; // type:function size:0x1A4
fn_80047D54 = .text:0x80047D54; // type:function size:0x108
fn_80047E5C = .text:0x80047E5C; // type:function size:0xD8
fn_80047F34 = .text:0x80047F34; // type:function size:0x24
fn_80047F58 = .text:0x80047F58; // type:function size:0x10 align:0x4
SearchForSomething__7CEntityFR13CStateManager18EScriptObjectState20EScriptObjectMessage = .text:0x80047E5C; // type:function size:0xD8
GetAreaId__7CEntityCFv = .text:0x80047F34; // type:function size:0x24
SetActive__7CEntityFb = .text:0x80047F58; // type:function size:0x10 align:0x4
fn_80047F68 = .text:0x80047F68; // type:function size:0x80 align:0x4
fn_80047FE8 = .text:0x80047FE8; // type:function size:0x4
fn_80047FEC = .text:0x80047FEC; // type:function size:0x4 align:0x4
fn_80047FF0 = .text:0x80047FF0; // type:function size:0x110
fn_80048100 = .text:0x80048100; // type:function size:0x174 align:0x4
fn_80048274 = .text:0x80048274; // type:function size:0x64
fn_800482D8 = .text:0x800482D8; // type:function size:0xCC
Think__7CEntityFfR13CStateManager = .text:0x80047FE8; // type:function size:0x4
PreThink__7CEntityFfR13CStateManager = .text:0x80047FEC; // type:function size:0x4 align:0x4
SendScriptMsgs__7CEntityF18EScriptObjectStateR13CStateManager20EScriptObjectMessage = .text:0x80047FF0; // type:function size:0x110
AcceptScriptMsg__7CEntityFR13CStateManagerR10CScriptMsg = .text:0x80048100; // type:function size:0x174 align:0x4
__dt__7CEntityFv = .text:0x80048274; // type:function size:0x64
__ct__7CEntityF9TUniqueIdRC11CEntityInfobRCQ24rstl66basic_string<c,Q24rstl14char_traits<c>,Q24rstl17rmemory_allocator> = .text:0x800482D8; // type:function size:0xCC
fn_800483A4 = .text:0x800483A4; // type:function size:0x130
fn_800484D4 = .text:0x800484D4; // type:function size:0x88
fn_8004855C = .text:0x8004855C; // type:function size:0x88 align:0x4
@ -12989,7 +12989,7 @@ fn_802CE278 = .text:0x802CE278; // type:function size:0x54
fn_802CE2CC = .text:0x802CE2CC; // type:function size:0x34
fn_802CE300 = .text:0x802CE300; // type:function size:0x4C
fn_802CE34C = .text:0x802CE34C; // type:function size:0x3C align:0x4
fn_802CE388 = .text:0x802CE388; // type:function size:0x64
Free__7CMemoryFPCv = .text:0x802CE388; // type:function size:0x64
fn_802CE3EC = .text:0x802CE3EC; // type:function size:0xD0
fn_802CE4BC = .text:0x802CE4BC; // type:function size:0x94
fn_802CE550 = .text:0x802CE550; // type:function size:0x3C align:0x4
@ -17933,7 +17933,7 @@ lbl_803B1A40 = .data:0x803B1A40; // type:object size:0x90
jumptable_803B1AD0 = .data:0x803B1AD0; // type:object size:0x54 scope:local
lbl_803B1B24 = .data:0x803B1B24; // type:object size:0xC
lbl_803B1B30 = .data:0x803B1B30; // type:object size:0x10
lbl_803B1B40 = .data:0x803B1B40; // type:object size:0x20
__vt__7CEntity = .data:0x803B1B40; // type:object size:0x20
lbl_803B1B60 = .data:0x803B1B60; // type:object size:0x10
lbl_803B1B70 = .data:0x803B1B70; // type:object size:0x10
lbl_803B1B80 = .data:0x803B1B80; // type:object size:0x10
@ -20295,7 +20295,7 @@ lbl_80419118 = .sbss:0x80419118; // type:object size:0x4 data:4byte
lbl_8041911C = .sbss:0x8041911C; // type:object size:0x4 data:4byte
lbl_80419120 = .sbss:0x80419120; // type:object size:0x4 data:4byte
lbl_80419124 = .sbss:0x80419124; // type:object size:0x2 data:2byte
lbl_80419128 = .sbss:0x80419128; // type:object size:0x4 data:4byte
kInvalidAreaId = .sbss:0x80419128; // type:object size:0x4 data:4byte
lbl_8041912C = .sbss:0x8041912C; // type:object size:0x4 data:4byte
lbl_80419130 = .sbss:0x80419130; // type:object size:0x4 data:4byte
lbl_80419134 = .sbss:0x80419134; // type:object size:0x4 data:4byte

View File

@ -18,6 +18,7 @@ LIBS = [
"mw_version": "1.3.2",
"host": True,
"objects": [
["MetroidPrime/CEntity.cpp", False],
["MetroidPrime/HUD/CHUDMemoParms.cpp", True],
["MetroidPrime/Player/CPlayerState.cpp", False],
],

View File

@ -0,0 +1,138 @@
#ifndef _CINPUTSTREAM
#define _CINPUTSTREAM
#include "types.h"
#include "stddef.h"
class CInputStream;
template < typename T >
struct TType {};
template < typename T >
T cinput_stream_helper(const TType< T >& type, CInputStream& in);
template < typename T >
TType< T > TGetType() {
return TType< T >();
}
class CInputStream {
public:
CInputStream(int len);
CInputStream(const void* ptr, int len, bool owned);
virtual ~CInputStream();
virtual size_t Read(void* dest, size_t len) = 0;
float ReadFloat();
u64 ReadLongLong();
uint ReadLong();
ushort ReadShort();
bool ReadBool();
uchar ReadChar();
uint ReadBits(uint len);
size_t ReadBytes(void* dest, size_t len);
void Get(void* dest, unsigned long len);
template < typename T >
inline T Get(const TType< T >& type = TType< T >()) {
return cinput_stream_helper(type, *this);
}
bool ReadPackedBool() { return ReadBits(1) != 0; }
// TODO: this cast to uint fixes regalloc in
// CIEKeyframeEmitter / rstl::vector(CInputStream&)
// why?
int ReadInt32() { return static_cast< uint >(Get(TType< int >())); }
u16 ReadUint16() { return Get<u16>(); }
uint GetBlockOffset() const { return x4_blockOffset; }
private:
bool GrabAnotherBlock();
bool InternalReadNext();
uint x4_blockOffset;
uint x8_blockLen;
uint xc_len;
uchar* x10_ptr;
bool x14_owned;
uint x18_readPosition;
uint x1c_bitWord;
uint x20_bitOffset;
};
template < typename T >
inline T cinput_stream_helper(const TType< T >& type, CInputStream& in) {
return T(in);
}
template <>
inline bool cinput_stream_helper(const TType< bool >& type, CInputStream& in) {
return in.ReadBool();
}
template <>
inline char cinput_stream_helper(const TType< char >& type, CInputStream& in) {
return in.ReadChar();
}
template <>
inline unsigned char cinput_stream_helper(const TType< unsigned char >& type, CInputStream& in) {
return in.ReadChar();
}
template <>
inline int cinput_stream_helper(const TType< int >& type, CInputStream& in) {
return in.ReadLong();
}
template <>
inline uint cinput_stream_helper(const TType< uint >& type, CInputStream& in) {
return in.ReadLong();
}
template <>
inline unsigned long cinput_stream_helper(const TType< unsigned long >& type, CInputStream& in) {
return in.ReadLong();
}
template <>
inline float cinput_stream_helper(const TType< float >& type, CInputStream& in) {
return in.ReadFloat();
}
template <>
inline short cinput_stream_helper(const TType< short >& type, CInputStream& in) {
return in.ReadShort();
}
template <>
inline ushort cinput_stream_helper(const TType< ushort >& type, CInputStream& in) {
return in.ReadShort();
}
// rstl
#include "rstl/pair.hpp"
template < typename L, typename R >
inline rstl::pair< L, R > cinput_stream_helper(const TType< rstl::pair< L, R > >& type,
CInputStream& in) {
rstl::pair< L, R > result;
result.first = in.Get(TType< L >());
result.second = in.Get(TType< R >());
return result;
}
#include "rstl/vector.hpp"
template < typename T, typename Alloc >
inline rstl::vector< T, Alloc >::vector(CInputStream& in, const Alloc& allocator)
: x4_count(0), x8_capacity(0), xc_items(nullptr) {
int count = in.ReadInt32();
reserve(count);
for (int i = 0; i < count; i++) {
push_back(in.Get(TType< T >()));
}
}
#include "rstl/reserved_vector.hpp"
template < typename T, int N >
inline rstl::reserved_vector< T, N >::reserved_vector(CInputStream& in) : x0_count(in.ReadInt32()) {
for (int i = 0; i < x0_count; i++) {
construct(&data()[i], in.Get(TType< T >()));
}
}
#endif // _CINPUTSTREAM

View File

@ -0,0 +1,54 @@
#ifndef _CENTITY
#define _CENTITY
#include "MetroidPrime/TGameTypes.hpp"
#include "MetroidPrime/CEntityInfo.hpp"
#include "rstl/string.hpp"
#include "rstl/vector.hpp"
class CStateManager;
class CEntity {
public:
virtual ~CEntity();
virtual CEntity* TypesMatch(EEntityType);
virtual void PreThink(float dt, CStateManager& mgr);
virtual void Think(float dt, CStateManager& mgr);
virtual void AcceptScriptMsg(CStateManager& mgr, CScriptMsg&);
virtual void SetActive(const 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 uid; }
TEditorId GetEditorId() const { return editorId; }
TAreaId GetAreaId() const;
TAreaId GetCurrentAreaId() const { return areaId; }
const bool GetActive() const { return active; }
// bool IsScriptingBlocked() const { return scriptingBlocked; }
// might be fake?
rstl::vector< SConnection >& ConnectionList() { return conns; }
const rstl::vector< SConnection >& GetConnectionList() const { return conns; }
static rstl::vector< SConnection > NullConnectionList;
TUniqueId SearchForSomething(CStateManager&, EScriptObjectState, EScriptObjectMessage);
private:
TAreaId areaId;
TUniqueId uid;
TEditorId editorId;
rstl::vector< SConnection > conns;
bool active : 1;
bool notInArea : 1;
bool inGraveyard : 1;
bool scriptingBlocked : 1;
};
#endif // _CENTITY

View File

@ -0,0 +1,95 @@
#ifndef _CENTITYINFO
#define _CENTITYINFO
#include "MetroidPrime/TGameTypes.hpp"
#include "rstl/vector.hpp"
enum EEntityType {
kET_Entity = 0,
kET_Actor = 1,
kET_PhysicsActor = 2,
kET_Ai = 3,
kET_Patterned = 4,
kET_Weapon = 6,
kET_Effect = 7,
kET_GameProjectile = 8,
kET_Bomb = 14,
kET_EnergyProjectile = 19,
kET_Explosion = 22,
kET_GameLight = 26,
kET_HUDBillboardEffect = 28,
kET_Player = 32,
kET_ScriptPlayerActor = 34,
kET_ScriptActorKeyframe = 35,
kET_ScriptCameraShaker = 41,
kET_ScriptCamera = 44,
kET_ScriptColorModulate = 45,
kET_DarkSamusBattleStage = 51,
kET_ScriptDock = 55,
kET_ScriptDoor = 56,
kET_ScriptLayerController = 64,
kET_ScriptPickup = 66,
kET_ScriptPlayerProxy = 69,
kET_ScriptPortalTransition = 72,
kET_Relay = 73,
kET_ScriptSpawnPoint = 79,
kET_ScriptSpecialFunction = 80,
kET_ScriptStreamedMusic = 84,
kET_ScriptTeamAi = 88,
kET_ScriptTrigger = 92,
kET_ScriptWorldTeleporter = 98,
kET_DarkSamus = 111,
kET_PowerBomb = 156,
};
enum EScriptObjectState {
kSS_Active = 0x41435456,
kSS_Inactive = 0x49435456,
kSS_InvalidState = 0xffffffff
};
enum EScriptObjectMessage {
kSM_Activate = 0x41435456,
kSM_Deactivate = 0x44435456,
kSM_ToggleActive = 0x54435456,
kSM_None = 0xffffffff,
};
struct SConnection {
EScriptObjectState state;
EScriptObjectMessage msg;
TEditorId objId;
SConnection(EScriptObjectState state, EScriptObjectMessage msg, TEditorId id)
: state(state), msg(msg), objId(id) {}
};
class CEntityInfo {
TAreaId areaId;
rstl::vector< SConnection > conns;
TEditorId editorId;
public:
CEntityInfo(TAreaId aid, const rstl::vector< SConnection >& conns,
TEditorId eid = kInvalidEditorId);
TAreaId GetAreaId() const { return areaId; }
const rstl::vector< SConnection >& GetConnectionList() const { return conns; }
TEditorId GetEditorId() const { return editorId; }
};
class CScriptMsg {
public:
TUniqueId GetOriginator() { return originator; }
TUniqueId GetId() const { return id; }
EScriptObjectMessage GetMessage() const { return msg; }
EScriptObjectState GetState() const { return state; }
public:
TUniqueId unk;
TUniqueId originator;
TUniqueId id;
EScriptObjectMessage msg;
EScriptObjectState state;
};
#endif // _CENTITYINFO

View File

@ -0,0 +1,73 @@
#ifndef _TGAMETYPES
#define _TGAMETYPES
#include "types.h"
class CInputStream;
class COutputStream;
struct TAreaId;
struct TEditorId;
struct TUniqueId;
extern const TAreaId kInvalidAreaId;
extern const TEditorId kInvalidEditorId;
extern const TUniqueId kInvalidUniqueId;
struct TAreaId {
int value;
TAreaId() : value(-1) {}
TAreaId(int value) : value(value) {}
int Value() const { return value; }
bool operator==(const TAreaId& other) const { return value == other.value; }
bool operator!=(const TAreaId& other) const { return value != other.value; }
};
CHECK_SIZEOF(TAreaId, 0x4)
struct TEditorId {
uint value;
TEditorId(uint value) : value(value) {}
TEditorId(CInputStream& in);
// TODO
uint Value() const { return value & 0x3FFFFFF; }
uint Id() const { return value & 0xffff; }
int AreaNum() const { return (value >> 16) & 0x3ff; }
void PutTo(COutputStream&) const;
bool operator==(const TEditorId& other) const { return Value() == other.Value(); }
bool operator!=(const TEditorId& other) const { return Value() != other.Value(); }
};
CHECK_SIZEOF(TEditorId, 0x4)
struct TUniqueId {
ushort value;
TUniqueId(ushort version, ushort id) : value(((version & 0x3F) << 10) | (id & 0x3FF)) {}
ushort Value() const { return value & 0x3FF; }
ushort 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 { return value < other.value; }
private:
};
CHECK_SIZEOF(TUniqueId, 0x2)
// struct TGameScriptId {
// TEditorId editorId;
// bool b;
// };
// CHECK_SIZEOF(TGameScriptId, 0x8)
typedef ushort TSfxId;
static TSfxId InvalidSfxId = 0xFFFFu;
#define ALIGN_UP(x, a) (((x) + (a - 1)) & ~(a - 1))
#endif // _TGAMETYPES

View File

@ -59,10 +59,10 @@ public:
}
}
vector(CInputStream& in, const Alloc& alloc = Alloc());
~vector() {
~vector(); /* {
destroy(begin(), end());
x0_allocator.deallocate(xc_items);
}
}*/
void reserve(int size);
void resize(int size, const T& in);

View File

@ -0,0 +1,65 @@
#include "MetroidPrime/CEntity.hpp"
rstl::vector< SConnection > CEntity::NullConnectionList;
// CEntityInfo::CEntityInfo(TAreaId aid, const rstl::vector< SConnection >& conns, TEditorId eid)
// : x0_areaId(aid), x4_conns(conns), x14_editorId(eid) {}
CEntity::CEntity(TUniqueId id, const CEntityInfo& info, bool active, const rstl::string& name)
: areaId(info.GetAreaId())
, uid(id)
, editorId(info.GetEditorId())
, conns(info.GetConnectionList())
, active(active)
, inGraveyard(false)
// , scriptingBlocked(false)
, notInArea(areaId == kInvalidAreaId) {}
CEntity::~CEntity() {}
void CEntity::AcceptScriptMsg(CStateManager& mgr, CScriptMsg& msg) {
switch (msg.GetMessage()) {
case kSM_Activate:
if (!active) {
SetActive(true);
SendScriptMsgs(kSS_Active, mgr, kSM_None);
}
break;
case kSM_Deactivate:
if (active) {
SetActive(false);
SendScriptMsgs(kSS_Inactive, mgr, kSM_None);
}
break;
case kSM_ToggleActive: {
CScriptMsg newMsg(msg);
if (!active) {
newMsg.msg = kSM_Deactivate;
}
AcceptScriptMsg(mgr, newMsg);
break;
}
}
}
void CEntity::SendScriptMsgs(EScriptObjectState state, CStateManager& mgr,
EScriptObjectMessage skipMsg) {
rstl::vector< SConnection >::const_iterator it = conns.begin();
for (; it != conns.end(); ++it) {
// if (it->x0_state == state && it->x4_msg != skipMsg) {
// mgr.SendScriptMsg(GetUniqueId(), it->x8_objId, it->x4_msg, state);
// }
}
}
void CEntity::PreThink(float dt, CStateManager& mgr) {}
void CEntity::Think(float dt, CStateManager& mgr) {}
void CEntity::SetActive(const bool active) { this->active = active; }
TAreaId CEntity::GetAreaId() const { return notInArea ? kInvalidAreaId : areaId; }
TUniqueId CEntity::SearchForSomething(CStateManager&, EScriptObjectState, EScriptObjectMessage) {
}