mirror of
https://github.com/isledecomp/isle.git
synced 2026-01-24 00:31:16 +00:00
Merge branch 'master' into more-skateboard-functions
This commit is contained in:
commit
bb323cfdeb
@ -18,15 +18,16 @@ struct AnimInfo {
|
||||
char* m_animName; // 0x00
|
||||
MxU32 m_objectId; // 0x04
|
||||
MxS16 m_unk0x08; // 0x08
|
||||
MxU8 m_unk0x0a; // 0x0a
|
||||
MxBool m_unk0x0a; // 0x0a
|
||||
MxU8 m_unk0x0b; // 0x0b
|
||||
MxU8 m_unk0x0c; // 0x0c
|
||||
MxU8 m_unk0x0d; // 0x0d
|
||||
MxU32 m_unk0x10[4]; // 0x10
|
||||
MxU8 m_modelCount; // 0x20
|
||||
MxS16 m_unk0x22; // 0x22
|
||||
ModelInfo* m_models; // 0x24
|
||||
MxU8 m_unk0x28; // 0x28
|
||||
MxU8 m_unk0x29; // 0x29
|
||||
MxBool m_unk0x29; // 0x29
|
||||
MxS8 m_unk0x2a[3]; // 0x2a
|
||||
};
|
||||
|
||||
|
||||
@ -37,10 +37,10 @@ struct Vehicle {
|
||||
// SIZE 0x18
|
||||
struct Unknown0x3c {
|
||||
LegoROI* m_roi; // 0x00
|
||||
MxU32 m_id; // 0x04
|
||||
MxS32 m_characterId; // 0x04
|
||||
undefined m_unk0x08[0x08]; // 0x08
|
||||
float m_unk0x10; // 0x10
|
||||
undefined m_unk0x14; // 0x14
|
||||
MxBool m_unk0x14; // 0x14
|
||||
};
|
||||
|
||||
// VTABLE: LEGO1 0x100d8c18
|
||||
@ -67,10 +67,10 @@ class LegoAnimationManager : public MxCore {
|
||||
}
|
||||
|
||||
void Reset(MxBool p_und);
|
||||
void FUN_1005ef10();
|
||||
void FUN_1005f0b0();
|
||||
void FUN_1005f6d0(MxBool);
|
||||
void FUN_1005f700(MxBool);
|
||||
void Suspend();
|
||||
void Resume();
|
||||
void FUN_1005f6d0(MxBool p_unk0x400);
|
||||
void FUN_1005f700(MxBool p_unk0x3a);
|
||||
MxResult LoadScriptInfo(MxS32 p_scriptIndex);
|
||||
MxBool FindVehicle(const char* p_name, MxU32& p_index);
|
||||
MxResult ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info);
|
||||
@ -80,13 +80,13 @@ class LegoAnimationManager : public MxCore {
|
||||
MxResult FUN_10060dc0(
|
||||
IsleScript::Script p_objectId,
|
||||
MxMatrix* p_matrix,
|
||||
undefined p_param3,
|
||||
MxBool p_param3,
|
||||
undefined p_param4,
|
||||
undefined4 p_param5,
|
||||
undefined p_param6,
|
||||
LegoROI* p_roi,
|
||||
MxBool p_param6,
|
||||
MxBool p_param7,
|
||||
MxBool p_param8,
|
||||
undefined p_param9
|
||||
MxBool p_param9
|
||||
);
|
||||
void FUN_10061010(undefined4);
|
||||
void FUN_100617c0(MxS32, MxU16&, MxU16&);
|
||||
@ -108,21 +108,25 @@ class LegoAnimationManager : public MxCore {
|
||||
void Init();
|
||||
MxResult FUN_100605e0(
|
||||
MxU32 p_index,
|
||||
MxU8 p_unk0x0a,
|
||||
MxBool p_unk0x0a,
|
||||
MxMatrix* p_matrix,
|
||||
undefined,
|
||||
undefined4,
|
||||
undefined,
|
||||
MxBool,
|
||||
MxBool,
|
||||
undefined
|
||||
MxBool p_bool1,
|
||||
LegoROI* p_roi,
|
||||
MxBool p_bool2,
|
||||
MxBool p_bool3,
|
||||
MxBool p_bool4,
|
||||
MxBool p_bool5
|
||||
);
|
||||
MxResult FUN_100609f0(MxU32 p_objectId, MxMatrix* p_matrix, MxBool p_und1, MxBool p_und2);
|
||||
void DeleteAnimations();
|
||||
MxS8 GetCharacterIndex(const char* p_name);
|
||||
MxBool FUN_100623a0(AnimInfo& p_info);
|
||||
void FUN_10062580(AnimInfo& p_info);
|
||||
MxBool FUN_10062710(AnimInfo& p_info);
|
||||
void FUN_10063aa0();
|
||||
void FUN_100648f0(LegoTranInfo*, MxLong);
|
||||
|
||||
MxU32 m_scriptIndex; // 0x08
|
||||
MxS32 m_scriptIndex; // 0x08
|
||||
MxU16 m_animCount; // 0x0c
|
||||
MxU16 m_unk0x0e; // 0x0e
|
||||
MxU16 m_unk0x10; // 0x10
|
||||
@ -136,10 +140,10 @@ class LegoAnimationManager : public MxCore {
|
||||
MxLong m_unk0x30[2]; // 0x30
|
||||
MxBool m_unk0x38; // 0x38
|
||||
MxBool m_unk0x39; // 0x39
|
||||
undefined m_unk0x3a; // 0x3a
|
||||
MxBool m_unk0x3a; // 0x3a
|
||||
Unknown0x3c m_unk0x3c[40]; // 0x3c
|
||||
undefined4 m_unk0x3fc; // 0x3fc
|
||||
MxU8 m_unk0x400; // 0x400
|
||||
MxBool m_unk0x400; // 0x400
|
||||
undefined m_unk0x401; // 0x401
|
||||
MxU8 m_unk0x402; // 0x402
|
||||
MxLong m_unk0x404; // 0x404
|
||||
@ -151,10 +155,10 @@ class LegoAnimationManager : public MxCore {
|
||||
undefined4 m_unk0x41c; // 0x41c
|
||||
AnimState* m_animState; // 0x420
|
||||
LegoROIList* m_unk0x424; // 0x424
|
||||
undefined m_unk0x428; // 0x428
|
||||
undefined m_unk0x429; // 0x429
|
||||
MxBool m_unk0x428; // 0x428
|
||||
MxBool m_unk0x429; // 0x429
|
||||
undefined m_unk0x42a; // 0x42a
|
||||
undefined m_unk0x42b; // 0x42b
|
||||
MxBool m_suspended; // 0x42b
|
||||
undefined4 m_unk0x42c; // 0x42c
|
||||
undefined m_unk0x430; // 0x430
|
||||
undefined4 m_unk0x434[2]; // 0x434
|
||||
|
||||
@ -40,7 +40,7 @@ struct LegoCharacter {
|
||||
MxU32 m_refCount; // 0x04
|
||||
};
|
||||
|
||||
struct LegoCharacterData;
|
||||
struct LegoCharacterInfo;
|
||||
|
||||
typedef map<char*, LegoCharacter*, LegoCharacterComparator> LegoCharacterMap;
|
||||
|
||||
@ -64,8 +64,8 @@ class LegoCharacterManager {
|
||||
void FUN_10083f10(LegoROI* p_roi);
|
||||
MxBool FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_textureInfo);
|
||||
LegoExtraActor* GetActor(const char* p_key);
|
||||
LegoCharacterData* GetData(const char* p_key);
|
||||
LegoCharacterData* GetData(LegoROI* p_roi);
|
||||
LegoCharacterInfo* GetInfo(const char* p_key);
|
||||
LegoCharacterInfo* GetInfo(LegoROI* p_roi);
|
||||
MxBool SwitchHat(LegoROI* p_roi);
|
||||
MxU32 FUN_10085140(LegoROI* p_roi, MxBool p_und);
|
||||
LegoROI* FUN_10085210(const char* p_name, const char* p_lodName, MxBool p_createEntity);
|
||||
|
||||
@ -8,7 +8,7 @@ class LegoExtraActor;
|
||||
class LegoROI;
|
||||
|
||||
// SIZE 0x108
|
||||
struct LegoCharacterData {
|
||||
struct LegoCharacterInfo {
|
||||
// SIZE 0x18
|
||||
struct Part {
|
||||
MxU8* m_unk0x00; // 0x00
|
||||
@ -45,7 +45,34 @@ struct LegoCharacterLOD {
|
||||
float m_up[3]; // 0x4c
|
||||
};
|
||||
|
||||
extern LegoCharacterData g_characterDataInit[66];
|
||||
enum LegoCharacterLODs {
|
||||
c_topLOD,
|
||||
c_bodyLOD,
|
||||
c_infohatLOD,
|
||||
c_infogronLOD,
|
||||
c_headLOD,
|
||||
c_armlftLOD,
|
||||
c_armrtLOD,
|
||||
c_clawlftLOD,
|
||||
c_clawrtLOD,
|
||||
c_leglftLOD,
|
||||
c_legrtLOD
|
||||
};
|
||||
|
||||
enum LegoCharacterParts {
|
||||
c_bodyPart,
|
||||
c_infohatPart,
|
||||
c_infogronPart,
|
||||
c_headPart,
|
||||
c_armlftPart,
|
||||
c_armrtPart,
|
||||
c_clawlftPart,
|
||||
c_clawrtPart,
|
||||
c_leglftPart,
|
||||
c_legrtPart
|
||||
};
|
||||
|
||||
extern LegoCharacterInfo g_characterInfoInit[66];
|
||||
extern LegoCharacterLOD g_characterLODs[11];
|
||||
|
||||
#endif // LEGOCHARACTERS_H
|
||||
|
||||
@ -4,6 +4,7 @@
|
||||
#include "decomp.h"
|
||||
#include "mxgeometry/mxmatrix.h"
|
||||
|
||||
struct AnimInfo;
|
||||
class LegoAnimMMPresenter;
|
||||
|
||||
// SIZE 0x78
|
||||
@ -30,7 +31,7 @@ struct LegoTranInfo {
|
||||
m_unk0x2c.SetIdentity();
|
||||
}
|
||||
|
||||
undefined4 m_unk0x00; // 0x00
|
||||
AnimInfo* m_animInfo; // 0x00
|
||||
MxU32 m_index; // 0x04
|
||||
LegoROI* m_unk0x08; // 0x08
|
||||
MxMatrix* m_unk0x0c; // 0x0c
|
||||
|
||||
@ -64,10 +64,4 @@ void PlayMusic(JukeboxScript::Script p_script);
|
||||
void SetIsWorldActive(MxBool p_isWorldActive);
|
||||
void DeleteObjects(MxAtomId* p_id, MxS32 p_first, MxS32 p_last);
|
||||
|
||||
// FUNCTION: LEGO1 0x10015890
|
||||
inline MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction)
|
||||
{
|
||||
return LegoOmni::GetInstance()->StartActionIfUnknown0x13c(p_dsAction);
|
||||
}
|
||||
|
||||
#endif // MISC_H
|
||||
|
||||
@ -80,7 +80,7 @@ void Radio::Stop()
|
||||
if (m_state->IsActive()) {
|
||||
LegoWorld* world = CurrentWorld();
|
||||
|
||||
MxControlPresenter* presenter = (MxControlPresenter*) world->Find(world->GetAtom(), 18);
|
||||
MxControlPresenter* presenter = (MxControlPresenter*) world->Find(world->GetAtom(), IsleScript::c_Radio_Ctl);
|
||||
|
||||
if (presenter) {
|
||||
presenter->VTable0x6c(0);
|
||||
|
||||
@ -158,8 +158,8 @@ void LegoAnimationManager::Reset(MxBool p_und)
|
||||
m_animState->SetFlag();
|
||||
}
|
||||
|
||||
undefined unk0x42b = m_unk0x42b;
|
||||
FUN_1005ef10();
|
||||
MxBool suspended = m_suspended;
|
||||
Suspend();
|
||||
|
||||
if (m_tranInfoList != NULL) {
|
||||
delete m_tranInfoList;
|
||||
@ -172,22 +172,93 @@ void LegoAnimationManager::Reset(MxBool p_und)
|
||||
DeleteAnimations();
|
||||
Init();
|
||||
|
||||
m_unk0x42b = unk0x42b;
|
||||
m_suspended = suspended;
|
||||
m_unk0x428 = m_unk0x3a;
|
||||
m_unk0x429 = m_unk0x400;
|
||||
m_unk0x42a = m_unk0x402;
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x1005ef10
|
||||
void LegoAnimationManager::FUN_1005ef10()
|
||||
// FUNCTION: LEGO1 0x1005ef10
|
||||
// FUNCTION: BETA10 0x1003fc7a
|
||||
void LegoAnimationManager::Suspend()
|
||||
{
|
||||
// TODO
|
||||
m_animState = (AnimState*) GameState()->GetState("AnimState");
|
||||
if (m_animState == NULL) {
|
||||
m_animState = (AnimState*) GameState()->CreateState("AnimState");
|
||||
}
|
||||
|
||||
if (m_scriptIndex == 0) {
|
||||
m_animState->FUN_10065240(m_animCount, m_anims, m_unk0x3fc);
|
||||
}
|
||||
|
||||
if (!m_suspended) {
|
||||
m_suspended = TRUE;
|
||||
m_unk0x428 = m_unk0x3a;
|
||||
m_unk0x429 = m_unk0x400;
|
||||
m_unk0x42a = m_unk0x402;
|
||||
m_unk0x402 = 0;
|
||||
|
||||
FUN_10061010(0);
|
||||
|
||||
MxS32 i;
|
||||
for (i = 0; i < (MxS32) _countof(m_unk0x3c); i++) {
|
||||
LegoROI* roi = m_unk0x3c[i].m_roi;
|
||||
|
||||
if (roi != NULL) {
|
||||
LegoPathActor* actor = CharacterManager()->GetActor(roi->GetName());
|
||||
|
||||
if (actor != NULL && actor->GetController() != NULL) {
|
||||
actor->GetController()->FUN_10046770(actor);
|
||||
actor->ClearController();
|
||||
}
|
||||
|
||||
CharacterManager()->FUN_10083db0(roi);
|
||||
}
|
||||
|
||||
if (m_unk0x3c[i].m_unk0x14) {
|
||||
m_unk0x3c[i].m_unk0x14 = FALSE;
|
||||
|
||||
MxS32 vehicleId = g_characters[m_unk0x3c[i].m_characterId].m_vehicleId;
|
||||
if (vehicleId >= 0) {
|
||||
g_vehicles[vehicleId].m_unk0x05 = FALSE;
|
||||
|
||||
LegoROI* roi = Lego()->FindROI(g_vehicles[vehicleId].m_name);
|
||||
if (roi != NULL) {
|
||||
roi->SetVisibility(FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_unk0x3c[i].m_roi = NULL;
|
||||
m_unk0x3c[i].m_characterId = -1;
|
||||
m_unk0x3c[i].m_unk0x10 = -1.0f;
|
||||
}
|
||||
|
||||
m_unk0x18 = 0;
|
||||
m_unk0x1a = 0;
|
||||
m_unk0x3a = FALSE;
|
||||
m_unk0x400 = FALSE;
|
||||
m_unk0x414 = 0;
|
||||
m_unk0x401 = 0;
|
||||
|
||||
for (i = 0; i < (MxS32) _countof(g_characters); i++) {
|
||||
g_characters[i].m_unk0x04 = FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x1005f0b0
|
||||
void LegoAnimationManager::FUN_1005f0b0()
|
||||
// FUNCTION: LEGO1 0x1005f0b0
|
||||
// FUNCTION: BETA10 0x1003fefe
|
||||
void LegoAnimationManager::Resume()
|
||||
{
|
||||
// TODO
|
||||
if (m_suspended) {
|
||||
m_unk0x408 = m_unk0x40c = m_unk0x404 = Timer()->GetTime();
|
||||
m_unk0x410 = 5000;
|
||||
m_unk0x3a = m_unk0x428;
|
||||
m_unk0x400 = m_unk0x429;
|
||||
m_unk0x402 = m_unk0x42a;
|
||||
m_suspended = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1005f130
|
||||
@ -212,22 +283,22 @@ void LegoAnimationManager::Init()
|
||||
|
||||
for (i = 0; i < (MxS32) _countof(m_unk0x3c); i++) {
|
||||
m_unk0x3c[i].m_roi = NULL;
|
||||
m_unk0x3c[i].m_id = -1;
|
||||
m_unk0x3c[i].m_characterId = -1;
|
||||
m_unk0x3c[i].m_unk0x10 = -1.0f;
|
||||
m_unk0x3c[i].m_unk0x14 = 0;
|
||||
m_unk0x3c[i].m_unk0x14 = FALSE;
|
||||
}
|
||||
|
||||
m_unk0x38 = FALSE;
|
||||
m_unk0x39 = FALSE;
|
||||
m_unk0x3a = 1;
|
||||
m_unk0x3a = TRUE;
|
||||
m_unk0x3fc = 0;
|
||||
m_unk0x400 = 0;
|
||||
m_unk0x400 = FALSE;
|
||||
m_unk0x414 = 0;
|
||||
m_unk0x418 = 5;
|
||||
m_unk0x0e = 0;
|
||||
m_unk0x10 = 0;
|
||||
m_unk0x401 = 0;
|
||||
m_unk0x42b = 0;
|
||||
m_suspended = FALSE;
|
||||
m_unk0x430 = 0;
|
||||
m_unk0x42c = 0;
|
||||
m_unk0x408 = m_unk0x40c = m_unk0x404 = Timer()->GetTime();
|
||||
@ -251,16 +322,32 @@ void LegoAnimationManager::Init()
|
||||
m_unk0x424 = new LegoROIList();
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x1005f6d0
|
||||
void LegoAnimationManager::FUN_1005f6d0(MxBool)
|
||||
// FUNCTION: LEGO1 0x1005f6d0
|
||||
// FUNCTION: BETA10 0x100401e7
|
||||
void LegoAnimationManager::FUN_1005f6d0(MxBool p_unk0x400)
|
||||
{
|
||||
// TODO
|
||||
if (m_suspended) {
|
||||
m_unk0x429 = p_unk0x400;
|
||||
}
|
||||
else {
|
||||
m_unk0x400 = p_unk0x400;
|
||||
|
||||
if (!p_unk0x400) {
|
||||
FUN_100627d0(TRUE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x1005f700
|
||||
void LegoAnimationManager::FUN_1005f700(MxBool)
|
||||
// FUNCTION: LEGO1 0x1005f700
|
||||
// FUNCTION: BETA10 0x1004024c
|
||||
void LegoAnimationManager::FUN_1005f700(MxBool p_unk0x3a)
|
||||
{
|
||||
// TODO
|
||||
if (m_suspended) {
|
||||
m_unk0x428 = p_unk0x3a;
|
||||
}
|
||||
else {
|
||||
m_unk0x3a = p_unk0x3a;
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x1005f720
|
||||
@ -364,7 +451,7 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex)
|
||||
}
|
||||
|
||||
m_anims[j].m_unk0x28 = GetCharacterIndex(m_anims[j].m_animName + strlen(m_anims[j].m_animName) - 2);
|
||||
m_anims[j].m_unk0x29 = 0;
|
||||
m_anims[j].m_unk0x29 = FALSE;
|
||||
|
||||
for (k = 0; k < 3; k++) {
|
||||
m_anims[j].m_unk0x2a[k] = -1;
|
||||
@ -402,12 +489,12 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex)
|
||||
result = SUCCESS;
|
||||
m_unk0x402 = 1;
|
||||
|
||||
if (m_unk0x42b) {
|
||||
if (m_suspended) {
|
||||
m_unk0x428 = m_unk0x3a;
|
||||
m_unk0x429 = m_unk0x400;
|
||||
m_unk0x42a = 1;
|
||||
m_unk0x3a = 0;
|
||||
m_unk0x400 = 0;
|
||||
m_unk0x3a = FALSE;
|
||||
m_unk0x400 = FALSE;
|
||||
m_unk0x402 = 0;
|
||||
}
|
||||
|
||||
@ -541,7 +628,7 @@ MxResult LegoAnimationManager::ReadModelInfo(LegoFile* p_file, ModelInfo* p_info
|
||||
// FUNCTION: LEGO1 0x100603c0
|
||||
void LegoAnimationManager::DeleteAnimations()
|
||||
{
|
||||
undefined unk0x42b = m_unk0x42b;
|
||||
MxBool suspended = m_suspended;
|
||||
|
||||
if (m_anims != NULL) {
|
||||
for (MxS32 i = 0; i < m_animCount; i++) {
|
||||
@ -560,7 +647,7 @@ void LegoAnimationManager::DeleteAnimations()
|
||||
}
|
||||
|
||||
Init();
|
||||
m_unk0x42b = unk0x42b;
|
||||
m_suspended = suspended;
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x10060570
|
||||
@ -569,22 +656,100 @@ void LegoAnimationManager::FUN_10060570(MxBool)
|
||||
// TODO
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x100605e0
|
||||
// FUNCTION: LEGO1 0x100605e0
|
||||
// FUNCTION: BETA10 0x1004152b
|
||||
MxResult LegoAnimationManager::FUN_100605e0(
|
||||
MxU32 p_index,
|
||||
MxU8 p_unk0x0a,
|
||||
MxBool p_unk0x0a,
|
||||
MxMatrix* p_matrix,
|
||||
undefined,
|
||||
undefined4,
|
||||
undefined,
|
||||
MxBool,
|
||||
MxBool,
|
||||
undefined
|
||||
MxBool p_bool1,
|
||||
LegoROI* p_roi,
|
||||
MxBool p_bool2,
|
||||
MxBool p_bool3,
|
||||
MxBool p_bool4,
|
||||
MxBool p_bool5
|
||||
)
|
||||
{
|
||||
// TODO
|
||||
return FAILURE;
|
||||
MxResult result = FAILURE;
|
||||
|
||||
if (m_scriptIndex != -1 && p_index < m_animCount && m_tranInfoList != NULL) {
|
||||
FUN_100627d0(FALSE);
|
||||
FUN_10062770();
|
||||
|
||||
MxDSAction action;
|
||||
AnimInfo& animInfo = m_anims[p_index];
|
||||
|
||||
if (!p_bool1) {
|
||||
if (m_unk0x39 || !animInfo.m_unk0x29) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (FUN_100623a0(animInfo)) {
|
||||
return FAILURE;
|
||||
}
|
||||
|
||||
if (FUN_10062710(animInfo)) {
|
||||
return FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
FUN_10062580(animInfo);
|
||||
|
||||
LegoTranInfo* tranInfo = new LegoTranInfo();
|
||||
tranInfo->m_animInfo = &animInfo;
|
||||
tranInfo->m_index = ++m_unk0x1c;
|
||||
tranInfo->m_unk0x10 = 0;
|
||||
tranInfo->m_unk0x08 = p_roi;
|
||||
tranInfo->m_unk0x12 = m_anims[p_index].m_unk0x08;
|
||||
tranInfo->m_unk0x14 = p_unk0x0a;
|
||||
tranInfo->m_objectId = animInfo.m_objectId;
|
||||
tranInfo->m_unk0x15 = p_bool2;
|
||||
|
||||
if (p_matrix != NULL) {
|
||||
tranInfo->m_unk0x0c = new MxMatrix(*p_matrix);
|
||||
}
|
||||
|
||||
tranInfo->m_unk0x1c = m_unk0x28;
|
||||
tranInfo->m_unk0x20 = m_unk0x30;
|
||||
tranInfo->m_unk0x28 = p_bool3;
|
||||
tranInfo->m_unk0x29 = p_bool4;
|
||||
|
||||
if (m_tranInfoList != NULL) {
|
||||
m_tranInfoList->Append(tranInfo);
|
||||
}
|
||||
|
||||
char buf[256];
|
||||
sprintf(buf, "%s:%d", g_strANIMMAN_ID, tranInfo->m_index);
|
||||
|
||||
action.SetAtomId(*Lego()->GetScriptAtom(m_scriptIndex));
|
||||
action.SetObjectId(animInfo.m_objectId);
|
||||
action.SetUnknown24(-1);
|
||||
action.AppendExtra(strlen(buf) + 1, buf);
|
||||
|
||||
if (StartActionIfUnknown0x13c(action) == SUCCESS) {
|
||||
BackgroundAudioManager()->LowerVolume();
|
||||
tranInfo->m_flags |= LegoTranInfo::c_bit2;
|
||||
animInfo.m_unk0x22++;
|
||||
m_unk0x404 = Timer()->GetTime();
|
||||
|
||||
if (p_bool5) {
|
||||
FUN_100648f0(tranInfo, m_unk0x404);
|
||||
}
|
||||
else if (p_unk0x0a) {
|
||||
IslePathActor* actor = CurrentActor();
|
||||
|
||||
if (actor != NULL) {
|
||||
actor->SetState(4);
|
||||
actor->SetWorldSpeed(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
m_unk0x39 = TRUE;
|
||||
result = SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100609f0
|
||||
@ -597,12 +762,12 @@ MxResult LegoAnimationManager::FUN_100609f0(MxU32 p_objectId, MxMatrix* p_matrix
|
||||
FUN_100627d0(FALSE);
|
||||
|
||||
LegoTranInfo* info = new LegoTranInfo();
|
||||
info->m_unk0x00 = 0;
|
||||
info->m_animInfo = NULL;
|
||||
info->m_index = ++m_unk0x1c;
|
||||
info->m_unk0x10 = 0;
|
||||
info->m_unk0x08 = NULL;
|
||||
info->m_unk0x12 = -1;
|
||||
info->m_unk0x14 = 0;
|
||||
info->m_unk0x14 = FALSE;
|
||||
info->m_objectId = p_objectId;
|
||||
|
||||
if (p_matrix != NULL) {
|
||||
@ -657,7 +822,7 @@ MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEnt
|
||||
|
||||
for (MxS32 i = 0; i < (MxS32) _countof(m_unk0x3c); i++) {
|
||||
if (m_unk0x3c[i].m_roi == roi) {
|
||||
MxU32 characterId = m_unk0x3c[i].m_id;
|
||||
MxS32 characterId = m_unk0x3c[i].m_characterId;
|
||||
g_characters[characterId].m_unk0x07 = TRUE;
|
||||
MxS32 vehicleId = g_characters[characterId].m_vehicleId;
|
||||
|
||||
@ -671,7 +836,7 @@ MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEnt
|
||||
}
|
||||
}
|
||||
|
||||
if (StartActionIfUnknown0x13c(p_dsAction) == SUCCESS) {
|
||||
if (LegoOmni::GetInstance()->StartActionIfUnknown0x13c(p_dsAction) == SUCCESS) {
|
||||
result = SUCCESS;
|
||||
}
|
||||
|
||||
@ -683,13 +848,13 @@ MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEnt
|
||||
MxResult LegoAnimationManager::FUN_10060dc0(
|
||||
IsleScript::Script p_objectId,
|
||||
MxMatrix* p_matrix,
|
||||
undefined p_param3,
|
||||
MxBool p_param3,
|
||||
undefined p_param4,
|
||||
undefined4 p_param5,
|
||||
undefined p_param6,
|
||||
LegoROI* p_roi,
|
||||
MxBool p_param6,
|
||||
MxBool p_param7,
|
||||
MxBool p_param8,
|
||||
undefined p_param9
|
||||
MxBool p_param9
|
||||
)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
@ -702,21 +867,21 @@ MxResult LegoAnimationManager::FUN_10060dc0(
|
||||
for (MxS32 i = 0; i < m_animCount; i++) {
|
||||
if (m_anims[i].m_objectId == p_objectId) {
|
||||
found = TRUE;
|
||||
undefined unk0x0a;
|
||||
MxBool unk0x0a;
|
||||
|
||||
switch (p_param4) {
|
||||
case 0:
|
||||
unk0x0a = m_anims[i].m_unk0x0a;
|
||||
break;
|
||||
case 1:
|
||||
unk0x0a = 1;
|
||||
unk0x0a = TRUE;
|
||||
break;
|
||||
default:
|
||||
unk0x0a = 0;
|
||||
unk0x0a = FALSE;
|
||||
break;
|
||||
}
|
||||
|
||||
result = FUN_100605e0(i, unk0x0a, p_matrix, p_param3, p_param5, p_param6, p_param7, p_param8, p_param9);
|
||||
result = FUN_100605e0(i, unk0x0a, p_matrix, p_param3, p_roi, p_param6, p_param7, p_param8, p_param9);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -787,6 +952,29 @@ MxS8 LegoAnimationManager::GetCharacterIndex(const char* p_name)
|
||||
return -1;
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x100623a0
|
||||
// FUNCTION: BETA10 0x10043342
|
||||
MxBool LegoAnimationManager::FUN_100623a0(AnimInfo& p_info)
|
||||
{
|
||||
// TODO
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x10062580
|
||||
// FUNCTION: BETA10 0x10043552
|
||||
void LegoAnimationManager::FUN_10062580(AnimInfo& p_info)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x10062710
|
||||
// FUNCTION: BETA10 0x10043787
|
||||
MxBool LegoAnimationManager::FUN_10062710(AnimInfo& p_info)
|
||||
{
|
||||
// TODO
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10062770
|
||||
// FUNCTION: BETA10 0x1004381a
|
||||
void LegoAnimationManager::FUN_10062770()
|
||||
@ -862,3 +1050,10 @@ void LegoAnimationManager::FUN_10064740(MxBool)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
// STUB: LEGO1 0x100648f0
|
||||
// FUNCTION: BETA10 0x10045daf
|
||||
void LegoAnimationManager::FUN_100648f0(LegoTranInfo*, MxLong)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
@ -35,7 +35,7 @@ MxU32 g_unk0x100fc4ec = 2;
|
||||
MxU32 g_unk0x100fc4f0 = 0;
|
||||
|
||||
// GLOBAL: LEGO1 0x10104f20
|
||||
LegoCharacterData g_characterData[66];
|
||||
LegoCharacterInfo g_chracterInfo[66];
|
||||
|
||||
// FUNCTION: LEGO1 0x10082a20
|
||||
LegoCharacterManager::LegoCharacterManager()
|
||||
@ -50,22 +50,22 @@ LegoCharacterManager::LegoCharacterManager()
|
||||
// FUNCTION: LEGO1 0x10083270
|
||||
void LegoCharacterManager::Init()
|
||||
{
|
||||
for (MxS32 i = 0; i < _countof(g_characterData); i++) {
|
||||
g_characterData[i] = g_characterDataInit[i];
|
||||
for (MxS32 i = 0; i < _countof(g_chracterInfo); i++) {
|
||||
g_chracterInfo[i] = g_characterInfoInit[i];
|
||||
}
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100832a0
|
||||
void LegoCharacterManager::FUN_100832a0()
|
||||
{
|
||||
for (MxS32 i = 0; i < _countof(g_characterData); i++) {
|
||||
LegoCharacterData* data = GetData(g_characterData[i].m_name);
|
||||
for (MxS32 i = 0; i < _countof(g_chracterInfo); i++) {
|
||||
LegoCharacterInfo* info = GetInfo(g_chracterInfo[i].m_name);
|
||||
|
||||
if (data != NULL) {
|
||||
LegoExtraActor* actor = data->m_actor;
|
||||
if (info != NULL) {
|
||||
LegoExtraActor* actor = info->m_actor;
|
||||
|
||||
if (actor != NULL && actor->IsA("LegoExtraActor")) {
|
||||
LegoROI* roi = g_characterData[i].m_roi;
|
||||
LegoROI* roi = g_chracterInfo[i].m_roi;
|
||||
MxU32 refCount = GetRefCount(roi);
|
||||
|
||||
while (refCount != 0) {
|
||||
@ -82,37 +82,46 @@ MxResult LegoCharacterManager::Write(LegoStorage* p_storage)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
|
||||
for (MxS32 i = 0; i < _countof(g_characterData); i++) {
|
||||
LegoCharacterData* data = &g_characterData[i];
|
||||
for (MxS32 i = 0; i < _countof(g_chracterInfo); i++) {
|
||||
LegoCharacterInfo* info = &g_chracterInfo[i];
|
||||
|
||||
if (p_storage->Write(&data->m_unk0x0c, sizeof(data->m_unk0x0c)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_unk0x0c, sizeof(info->m_unk0x0c)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&data->m_unk0x10, sizeof(data->m_unk0x10)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_unk0x10, sizeof(info->m_unk0x10)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&data->m_unk0x14, sizeof(data->m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_unk0x14, sizeof(info->m_unk0x14)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&data->m_parts[1].m_unk0x08, sizeof(data->m_parts[1].m_unk0x08)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_parts[c_infohatPart].m_unk0x08, sizeof(info->m_parts[c_infohatPart].m_unk0x08)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&data->m_parts[1].m_unk0x14, sizeof(data->m_parts[1].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_parts[c_infohatPart].m_unk0x14, sizeof(info->m_parts[c_infohatPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&data->m_parts[2].m_unk0x14, sizeof(data->m_parts[2].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Write(
|
||||
&info->m_parts[c_infogronPart].m_unk0x14,
|
||||
sizeof(info->m_parts[c_infogronPart].m_unk0x14)
|
||||
) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&data->m_parts[4].m_unk0x14, sizeof(data->m_parts[4].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_parts[c_armlftPart].m_unk0x14, sizeof(info->m_parts[c_armlftPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&data->m_parts[5].m_unk0x14, sizeof(data->m_parts[5].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_parts[c_armrtPart].m_unk0x14, sizeof(info->m_parts[c_armrtPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&data->m_parts[8].m_unk0x14, sizeof(data->m_parts[8].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_parts[c_leglftPart].m_unk0x14, sizeof(info->m_parts[c_leglftPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Write(&data->m_parts[9].m_unk0x14, sizeof(data->m_parts[9].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Write(&info->m_parts[c_legrtPart].m_unk0x14, sizeof(info->m_parts[c_legrtPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -128,37 +137,46 @@ MxResult LegoCharacterManager::Read(LegoStorage* p_storage)
|
||||
{
|
||||
MxResult result = FAILURE;
|
||||
|
||||
for (MxS32 i = 0; i < _countof(g_characterData); i++) {
|
||||
LegoCharacterData* data = &g_characterData[i];
|
||||
for (MxS32 i = 0; i < _countof(g_chracterInfo); i++) {
|
||||
LegoCharacterInfo* info = &g_chracterInfo[i];
|
||||
|
||||
if (p_storage->Read(&data->m_unk0x0c, sizeof(data->m_unk0x0c)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_unk0x0c, sizeof(info->m_unk0x0c)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&data->m_unk0x10, sizeof(data->m_unk0x10)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_unk0x10, sizeof(info->m_unk0x10)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&data->m_unk0x14, sizeof(data->m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_unk0x14, sizeof(info->m_unk0x14)) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&data->m_parts[1].m_unk0x08, sizeof(data->m_parts[1].m_unk0x08)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_parts[c_infohatPart].m_unk0x08, sizeof(info->m_parts[c_infohatPart].m_unk0x08)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&data->m_parts[1].m_unk0x14, sizeof(data->m_parts[1].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_parts[c_infohatPart].m_unk0x14, sizeof(info->m_parts[c_infohatPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&data->m_parts[2].m_unk0x14, sizeof(data->m_parts[2].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Read(
|
||||
&info->m_parts[c_infogronPart].m_unk0x14,
|
||||
sizeof(info->m_parts[c_infogronPart].m_unk0x14)
|
||||
) != SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&data->m_parts[4].m_unk0x14, sizeof(data->m_parts[4].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_parts[c_armlftPart].m_unk0x14, sizeof(info->m_parts[c_armlftPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&data->m_parts[5].m_unk0x14, sizeof(data->m_parts[5].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_parts[c_armrtPart].m_unk0x14, sizeof(info->m_parts[c_armrtPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&data->m_parts[8].m_unk0x14, sizeof(data->m_parts[8].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_parts[c_leglftPart].m_unk0x14, sizeof(info->m_parts[c_leglftPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
if (p_storage->Read(&data->m_parts[9].m_unk0x14, sizeof(data->m_parts[9].m_unk0x14)) != SUCCESS) {
|
||||
if (p_storage->Read(&info->m_parts[c_legrtPart].m_unk0x14, sizeof(info->m_parts[c_legrtPart].m_unk0x14)) !=
|
||||
SUCCESS) {
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
@ -213,7 +231,7 @@ LegoROI* LegoCharacterManager::GetROI(const char* p_key, MxBool p_createEntity)
|
||||
actor->SetROI(character->m_roi, FALSE, FALSE);
|
||||
actor->SetType(LegoEntity::e_character);
|
||||
actor->SetFlag(LegoActor::c_bit2);
|
||||
GetData(p_key)->m_actor = actor;
|
||||
GetInfo(p_key)->m_actor = actor;
|
||||
}
|
||||
|
||||
return character->m_roi;
|
||||
@ -250,7 +268,7 @@ void LegoCharacterManager::FUN_10083c30(const char* p_name)
|
||||
character = (*it).second;
|
||||
|
||||
if (character->RemoveRef() == 0) {
|
||||
LegoCharacterData* data = GetData(p_name);
|
||||
LegoCharacterInfo* info = GetInfo(p_name);
|
||||
LegoEntity* entity = character->m_roi->GetEntity();
|
||||
|
||||
if (entity != NULL) {
|
||||
@ -264,18 +282,18 @@ void LegoCharacterManager::FUN_10083c30(const char* p_name)
|
||||
|
||||
m_characters->erase(it);
|
||||
|
||||
if (data != NULL) {
|
||||
if (data->m_actor != NULL) {
|
||||
data->m_actor->ClearFlag(LegoEntity::c_bit2);
|
||||
delete data->m_actor;
|
||||
if (info != NULL) {
|
||||
if (info->m_actor != NULL) {
|
||||
info->m_actor->ClearFlag(LegoEntity::c_bit2);
|
||||
delete info->m_actor;
|
||||
}
|
||||
else if (entity != NULL && entity->GetFlagsIsSet(LegoEntity::c_bit2)) {
|
||||
entity->ClearFlag(LegoEntity::c_bit2);
|
||||
delete entity;
|
||||
}
|
||||
|
||||
data->m_roi = NULL;
|
||||
data->m_actor = NULL;
|
||||
info->m_roi = NULL;
|
||||
info->m_actor = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -292,7 +310,7 @@ void LegoCharacterManager::FUN_10083db0(LegoROI* p_roi)
|
||||
|
||||
if (character->m_roi == p_roi) {
|
||||
if (character->RemoveRef() == 0) {
|
||||
LegoCharacterData* data = GetData(character->m_roi->GetName());
|
||||
LegoCharacterInfo* info = GetInfo(character->m_roi->GetName());
|
||||
LegoEntity* entity = character->m_roi->GetEntity();
|
||||
|
||||
if (entity != NULL) {
|
||||
@ -306,18 +324,18 @@ void LegoCharacterManager::FUN_10083db0(LegoROI* p_roi)
|
||||
|
||||
m_characters->erase(it);
|
||||
|
||||
if (data != NULL) {
|
||||
if (data->m_actor != NULL) {
|
||||
data->m_actor->ClearFlag(LegoEntity::c_bit2);
|
||||
delete data->m_actor;
|
||||
if (info != NULL) {
|
||||
if (info->m_actor != NULL) {
|
||||
info->m_actor->ClearFlag(LegoEntity::c_bit2);
|
||||
delete info->m_actor;
|
||||
}
|
||||
else if (entity != NULL && entity->GetFlagsIsSet(LegoEntity::c_bit2)) {
|
||||
entity->ClearFlag(LegoEntity::c_bit2);
|
||||
delete entity;
|
||||
}
|
||||
|
||||
data->m_roi = NULL;
|
||||
data->m_actor = NULL;
|
||||
info->m_roi = NULL;
|
||||
info->m_actor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -381,39 +399,39 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key)
|
||||
Tgl::Renderer* renderer = VideoManager()->GetRenderer();
|
||||
ViewLODListManager* lodManager = GetViewLODListManager();
|
||||
LegoTextureContainer* textureContainer = TextureContainer();
|
||||
LegoCharacterData* data = GetData(p_key);
|
||||
LegoCharacterInfo* info = GetInfo(p_key);
|
||||
|
||||
if (data == NULL) {
|
||||
if (info == NULL) {
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!strcmpi(p_key, "pep")) {
|
||||
LegoCharacterData* pepper = GetData("pepper");
|
||||
LegoCharacterInfo* pepper = GetInfo("pepper");
|
||||
|
||||
data->m_unk0x0c = pepper->m_unk0x0c;
|
||||
data->m_unk0x10 = pepper->m_unk0x10;
|
||||
data->m_unk0x14 = pepper->m_unk0x14;
|
||||
info->m_unk0x0c = pepper->m_unk0x0c;
|
||||
info->m_unk0x10 = pepper->m_unk0x10;
|
||||
info->m_unk0x14 = pepper->m_unk0x14;
|
||||
|
||||
for (i = 0; i < _countof(data->m_parts); i++) {
|
||||
data->m_parts[i] = pepper->m_parts[i];
|
||||
for (i = 0; i < _countof(info->m_parts); i++) {
|
||||
info->m_parts[i] = pepper->m_parts[i];
|
||||
}
|
||||
}
|
||||
|
||||
roi = new LegoROI(renderer);
|
||||
roi->SetName(p_key);
|
||||
|
||||
boundingSphere.Center()[0] = g_characterLODs[0].m_boundingSphere[0];
|
||||
boundingSphere.Center()[1] = g_characterLODs[0].m_boundingSphere[1];
|
||||
boundingSphere.Center()[2] = g_characterLODs[0].m_boundingSphere[2];
|
||||
boundingSphere.Radius() = g_characterLODs[0].m_boundingSphere[3];
|
||||
boundingSphere.Center()[0] = g_characterLODs[c_topLOD].m_boundingSphere[0];
|
||||
boundingSphere.Center()[1] = g_characterLODs[c_topLOD].m_boundingSphere[1];
|
||||
boundingSphere.Center()[2] = g_characterLODs[c_topLOD].m_boundingSphere[2];
|
||||
boundingSphere.Radius() = g_characterLODs[c_topLOD].m_boundingSphere[3];
|
||||
roi->SetBoundingSphere(boundingSphere);
|
||||
|
||||
boundingBox.Min()[0] = g_characterLODs[0].m_boundingBox[0];
|
||||
boundingBox.Min()[1] = g_characterLODs[0].m_boundingBox[1];
|
||||
boundingBox.Min()[2] = g_characterLODs[0].m_boundingBox[2];
|
||||
boundingBox.Max()[0] = g_characterLODs[0].m_boundingBox[3];
|
||||
boundingBox.Max()[1] = g_characterLODs[0].m_boundingBox[4];
|
||||
boundingBox.Max()[2] = g_characterLODs[0].m_boundingBox[5];
|
||||
boundingBox.Min()[0] = g_characterLODs[c_topLOD].m_boundingBox[0];
|
||||
boundingBox.Min()[1] = g_characterLODs[c_topLOD].m_boundingBox[1];
|
||||
boundingBox.Min()[2] = g_characterLODs[c_topLOD].m_boundingBox[2];
|
||||
boundingBox.Max()[0] = g_characterLODs[c_topLOD].m_boundingBox[3];
|
||||
boundingBox.Max()[1] = g_characterLODs[c_topLOD].m_boundingBox[4];
|
||||
boundingBox.Max()[2] = g_characterLODs[c_topLOD].m_boundingBox[5];
|
||||
roi->SetUnknown0x80(boundingBox);
|
||||
|
||||
comp = new CompoundObject();
|
||||
@ -421,7 +439,7 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key)
|
||||
|
||||
for (i = 0; i < _countof(g_characterLODs) - 1; i++) {
|
||||
char lodName[256];
|
||||
LegoCharacterData::Part& part = data->m_parts[i];
|
||||
LegoCharacterInfo::Part& part = info->m_parts[i];
|
||||
|
||||
const char* parentName;
|
||||
if (i == 0 || i == 1) {
|
||||
@ -495,14 +513,14 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key)
|
||||
}
|
||||
|
||||
CalcLocalTransform(
|
||||
Mx3DPointFloat(g_characterLODs[0].m_position),
|
||||
Mx3DPointFloat(g_characterLODs[0].m_direction),
|
||||
Mx3DPointFloat(g_characterLODs[0].m_up),
|
||||
Mx3DPointFloat(g_characterLODs[c_topLOD].m_position),
|
||||
Mx3DPointFloat(g_characterLODs[c_topLOD].m_direction),
|
||||
Mx3DPointFloat(g_characterLODs[c_topLOD].m_up),
|
||||
mat
|
||||
);
|
||||
roi->WrappedSetLocalTransform(mat);
|
||||
|
||||
data->m_roi = roi;
|
||||
info->m_roi = roi;
|
||||
success = TRUE;
|
||||
|
||||
done:
|
||||
@ -519,12 +537,12 @@ LegoROI* LegoCharacterManager::CreateROI(const char* p_key)
|
||||
MxBool LegoCharacterManager::FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_textureInfo)
|
||||
{
|
||||
LegoResult result = SUCCESS;
|
||||
LegoROI* head = FindChildROI(p_roi, g_characterLODs[4].m_name);
|
||||
LegoROI* head = FindChildROI(p_roi, g_characterLODs[c_headLOD].m_name);
|
||||
|
||||
if (head != NULL) {
|
||||
char lodName[256];
|
||||
|
||||
ViewLODList* lodList = GetViewLODListManager()->Lookup(g_characterLODs[4].m_parentName);
|
||||
ViewLODList* lodList = GetViewLODListManager()->Lookup(g_characterLODs[c_headLOD].m_parentName);
|
||||
MxS32 lodSize = lodList->Size();
|
||||
sprintf(lodName, "%s%s%d", p_roi->GetName(), "head", g_unk0x100fc4e8++);
|
||||
ViewLODList* dupLodList = GetViewLODListManager()->Create(lodName, lodSize);
|
||||
@ -532,8 +550,8 @@ MxBool LegoCharacterManager::FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_tex
|
||||
Tgl::Renderer* renderer = VideoManager()->GetRenderer();
|
||||
|
||||
if (p_textureInfo == NULL) {
|
||||
LegoCharacterData* info = GetData(p_roi->GetName());
|
||||
LegoCharacterData::Part& part = info->m_parts[3];
|
||||
LegoCharacterInfo* info = GetInfo(p_roi->GetName());
|
||||
LegoCharacterInfo::Part& part = info->m_parts[c_headPart];
|
||||
p_textureInfo = TextureContainer()->Get(part.m_unk0x10[part.m_unk0x0c[part.m_unk0x14]]);
|
||||
}
|
||||
|
||||
@ -565,8 +583,8 @@ MxBool LegoCharacterManager::FUN_100849a0(LegoROI* p_roi, LegoTextureInfo* p_tex
|
||||
// FUNCTION: LEGO1 0x10084c00
|
||||
MxBool LegoCharacterManager::Exists(const char* p_key)
|
||||
{
|
||||
for (MxU32 i = 0; i < _countof(g_characterData); i++) {
|
||||
if (!strcmpi(g_characterData[i].m_name, p_key)) {
|
||||
for (MxU32 i = 0; i < _countof(g_chracterInfo); i++) {
|
||||
if (!strcmpi(g_chracterInfo[i].m_name, p_key)) {
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
@ -577,46 +595,46 @@ MxBool LegoCharacterManager::Exists(const char* p_key)
|
||||
// FUNCTION: LEGO1 0x10084c40
|
||||
LegoExtraActor* LegoCharacterManager::GetActor(const char* p_key)
|
||||
{
|
||||
LegoCharacterData* data = GetData(p_key);
|
||||
LegoCharacterInfo* info = GetInfo(p_key);
|
||||
|
||||
if (data != NULL) {
|
||||
return data->m_actor;
|
||||
if (info != NULL) {
|
||||
return info->m_actor;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10084c60
|
||||
LegoCharacterData* LegoCharacterManager::GetData(const char* p_key)
|
||||
LegoCharacterInfo* LegoCharacterManager::GetInfo(const char* p_key)
|
||||
{
|
||||
MxU32 i;
|
||||
|
||||
for (i = 0; i < _countof(g_characterData); i++) {
|
||||
if (!strcmpi(g_characterData[i].m_name, p_key)) {
|
||||
for (i = 0; i < _countof(g_chracterInfo); i++) {
|
||||
if (!strcmpi(g_chracterInfo[i].m_name, p_key)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < _countof(g_characterData)) {
|
||||
return &g_characterData[i];
|
||||
if (i < _countof(g_chracterInfo)) {
|
||||
return &g_chracterInfo[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10084cb0
|
||||
LegoCharacterData* LegoCharacterManager::GetData(LegoROI* p_roi)
|
||||
LegoCharacterInfo* LegoCharacterManager::GetInfo(LegoROI* p_roi)
|
||||
{
|
||||
MxU32 i;
|
||||
|
||||
for (i = 0; i < _countof(g_characterData); i++) {
|
||||
if (g_characterData[i].m_roi == p_roi) {
|
||||
for (i = 0; i < _countof(g_chracterInfo); i++) {
|
||||
if (g_chracterInfo[i].m_roi == p_roi) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i < _countof(g_characterData)) {
|
||||
return &g_characterData[i];
|
||||
if (i < _countof(g_chracterInfo)) {
|
||||
return &g_chracterInfo[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
@ -646,13 +664,13 @@ LegoROI* LegoCharacterManager::FindChildROI(LegoROI* p_roi, const char* p_name)
|
||||
// FUNCTION: LEGO1 0x10084ec0
|
||||
MxBool LegoCharacterManager::SwitchHat(LegoROI* p_roi)
|
||||
{
|
||||
LegoCharacterData* data = GetData(p_roi->GetName());
|
||||
LegoCharacterInfo* info = GetInfo(p_roi->GetName());
|
||||
|
||||
if (data == NULL) {
|
||||
if (info == NULL) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LegoCharacterData::Part& part = data->m_parts[1];
|
||||
LegoCharacterInfo::Part& part = info->m_parts[c_infohatPart];
|
||||
|
||||
part.m_unk0x08++;
|
||||
MxU8 unk0x00 = part.m_unk0x00[part.m_unk0x08];
|
||||
@ -662,7 +680,7 @@ MxBool LegoCharacterManager::SwitchHat(LegoROI* p_roi)
|
||||
unk0x00 = part.m_unk0x00[part.m_unk0x08];
|
||||
}
|
||||
|
||||
LegoROI* childROI = FindChildROI(p_roi, g_characterLODs[2].m_name);
|
||||
LegoROI* childROI = FindChildROI(p_roi, g_characterLODs[c_infohatLOD].m_name);
|
||||
|
||||
if (childROI != NULL) {
|
||||
char lodName[256];
|
||||
@ -700,14 +718,14 @@ MxBool LegoCharacterManager::SwitchHat(LegoROI* p_roi)
|
||||
// FUNCTION: LEGO1 0x10085140
|
||||
MxU32 LegoCharacterManager::FUN_10085140(LegoROI* p_roi, MxBool p_und)
|
||||
{
|
||||
LegoCharacterData* data = GetData(p_roi);
|
||||
LegoCharacterInfo* info = GetInfo(p_roi);
|
||||
|
||||
if (p_und) {
|
||||
return data->m_unk0x14 + g_unk0x100fc4dc;
|
||||
return info->m_unk0x14 + g_unk0x100fc4dc;
|
||||
}
|
||||
|
||||
if (data != NULL) {
|
||||
return data->m_unk0x0c + g_unk0x100fc4d8;
|
||||
if (info != NULL) {
|
||||
return info->m_unk0x0c + g_unk0x100fc4d8;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
#include "legocharacters.h"
|
||||
|
||||
DECOMP_SIZE_ASSERT(LegoCharacterData, 0x108)
|
||||
DECOMP_SIZE_ASSERT(LegoCharacterData::Part, 0x18)
|
||||
DECOMP_SIZE_ASSERT(LegoCharacterInfo, 0x108)
|
||||
DECOMP_SIZE_ASSERT(LegoCharacterInfo::Part, 0x18)
|
||||
DECOMP_SIZE_ASSERT(LegoCharacterLOD, 0x58)
|
||||
|
||||
// Unclear whether g_characterLODs[0] (top) is its own global, see: LegoCharacterManager::CreateROI
|
||||
@ -172,7 +172,7 @@ const char* g_unk0x100f80a0[] =
|
||||
{"lego white", "lego black", "lego yellow", "lego red", "lego blue", "lego brown", "lego lt grey", "lego green"};
|
||||
|
||||
// GLOBAL: LEGO1 0x100f80c0
|
||||
LegoCharacterData g_characterDataInit[] = {
|
||||
LegoCharacterInfo g_characterInfoInit[] = {
|
||||
{"pepper",
|
||||
NULL,
|
||||
NULL,
|
||||
|
||||
@ -791,7 +791,7 @@ void LegoGameState::SwitchArea(Area p_area)
|
||||
|
||||
FUN_10015820(TRUE, LegoOmni::c_disableInput | LegoOmni::c_disable3d);
|
||||
BackgroundAudioManager()->Stop();
|
||||
AnimationManager()->FUN_1005ef10();
|
||||
AnimationManager()->Suspend();
|
||||
VideoManager()->SetUnk0x554(FALSE);
|
||||
|
||||
switch (p_area) {
|
||||
@ -896,7 +896,7 @@ void LegoGameState::SwitchArea(Area p_area)
|
||||
else {
|
||||
SetCameraControllerFromIsle();
|
||||
CurrentActor()->ResetWorldTransform(TRUE);
|
||||
AnimationManager()->FUN_1005f0b0();
|
||||
AnimationManager()->Resume();
|
||||
}
|
||||
|
||||
CurrentActor()->VTable0xe8(p_area, TRUE, 7);
|
||||
@ -910,7 +910,7 @@ void LegoGameState::SwitchArea(Area p_area)
|
||||
LoadIsle();
|
||||
SetCameraControllerFromIsle();
|
||||
CurrentActor()->ResetWorldTransform(TRUE);
|
||||
AnimationManager()->FUN_1005f0b0();
|
||||
AnimationManager()->Resume();
|
||||
CurrentActor()->VTable0xe8(p_area, TRUE, 7);
|
||||
break;
|
||||
case e_police:
|
||||
@ -1083,28 +1083,28 @@ void LegoGameState::Init()
|
||||
if (m_loadedAct == e_act1) {
|
||||
Isle* isle = (Isle*) FindWorld(*g_isleScript, 0);
|
||||
|
||||
Helicopter* copter = (Helicopter*) isle->Find(*g_copterScript, 1);
|
||||
Helicopter* copter = (Helicopter*) isle->Find(*g_copterScript, CopterScript::c_Helicopter_Actor);
|
||||
if (copter) {
|
||||
isle->FUN_1001fc80(copter);
|
||||
isle->VTable0x6c(copter);
|
||||
delete copter;
|
||||
}
|
||||
|
||||
DuneBuggy* dunebuggy = (DuneBuggy*) isle->Find(*g_dunecarScript, 2);
|
||||
DuneBuggy* dunebuggy = (DuneBuggy*) isle->Find(*g_dunecarScript, DunecarScript::c_DuneBugy_Actor);
|
||||
if (dunebuggy) {
|
||||
isle->FUN_1001fc80(dunebuggy);
|
||||
isle->VTable0x6c(dunebuggy);
|
||||
delete dunebuggy;
|
||||
}
|
||||
|
||||
Jetski* jetski = (Jetski*) isle->Find(*g_jetskiScript, 3);
|
||||
Jetski* jetski = (Jetski*) isle->Find(*g_jetskiScript, JetskiScript::c_Jetski_Actor);
|
||||
if (jetski) {
|
||||
isle->FUN_1001fc80(jetski);
|
||||
isle->VTable0x6c(jetski);
|
||||
delete jetski;
|
||||
}
|
||||
|
||||
RaceCar* racecar = (RaceCar*) isle->Find(*g_racecarScript, 4);
|
||||
RaceCar* racecar = (RaceCar*) isle->Find(*g_racecarScript, RacecarScript::c_RaceCar_Actor);
|
||||
if (racecar) {
|
||||
isle->FUN_1001fc80(racecar);
|
||||
isle->VTable0x6c(racecar);
|
||||
|
||||
@ -136,6 +136,13 @@ void SetCurrentActor(IslePathActor* p_currentActor)
|
||||
LegoOmni::GetInstance()->SetCurrentActor(p_currentActor);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x10015890
|
||||
// FUNCTION: BETA10 0x100e4d80
|
||||
MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction)
|
||||
{
|
||||
return LegoOmni::GetInstance()->StartActionIfUnknown0x13c(p_dsAction);
|
||||
}
|
||||
|
||||
// FUNCTION: LEGO1 0x100158b0
|
||||
void DeleteAction()
|
||||
{
|
||||
|
||||
@ -630,7 +630,7 @@ void LegoWorld::Enable(MxBool p_enable)
|
||||
PlantManager()->FUN_10026360(m_scriptIndex);
|
||||
AnimationManager()->LoadScriptInfo(m_scriptIndex);
|
||||
BuildingManager()->FUN_1002fa00();
|
||||
AnimationManager()->FUN_1005f0b0();
|
||||
AnimationManager()->Resume();
|
||||
}
|
||||
|
||||
GameState()->ResetROI();
|
||||
|
||||
@ -666,7 +666,7 @@ void Isle::Enable(MxBool p_enable)
|
||||
break;
|
||||
}
|
||||
|
||||
AnimationManager()->FUN_10060dc0(script, NULL, 1, 1, 0, 0, FALSE, TRUE, 0);
|
||||
AnimationManager()->FUN_10060dc0(script, NULL, TRUE, 1, NULL, FALSE, FALSE, TRUE, 0);
|
||||
}
|
||||
|
||||
m_act1state->m_unk0x018 = 0;
|
||||
@ -694,7 +694,7 @@ void Isle::Enable(MxBool p_enable)
|
||||
break;
|
||||
}
|
||||
|
||||
AnimationManager()->FUN_10060dc0(script, NULL, 1, 1, 0, 0, FALSE, TRUE, 0);
|
||||
AnimationManager()->FUN_10060dc0(script, NULL, TRUE, 1, NULL, FALSE, FALSE, TRUE, 0);
|
||||
}
|
||||
|
||||
m_act1state->m_unk0x018 = 0;
|
||||
@ -857,7 +857,7 @@ MxLong Isle::HandleTransitionEnd()
|
||||
GameState()->StopArea(LegoGameState::e_previousArea);
|
||||
m_destLocation = LegoGameState::e_undefined;
|
||||
VariableTable()->SetVariable("VISIBILITY", "Show Gas");
|
||||
AnimationManager()->FUN_1005f0b0();
|
||||
AnimationManager()->Resume();
|
||||
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
|
||||
SetAppCursor(0);
|
||||
SetIsWorldActive(TRUE);
|
||||
@ -867,7 +867,7 @@ MxLong Isle::HandleTransitionEnd()
|
||||
GameState()->StopArea(LegoGameState::e_previousArea);
|
||||
m_destLocation = LegoGameState::e_undefined;
|
||||
VariableTable()->SetVariable("VISIBILITY", "Show Policsta");
|
||||
AnimationManager()->FUN_1005f0b0();
|
||||
AnimationManager()->Resume();
|
||||
FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen);
|
||||
SetAppCursor(0);
|
||||
SetIsWorldActive(TRUE);
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
import struct
|
||||
import bisect
|
||||
from functools import cached_property
|
||||
from typing import List, Optional, Tuple
|
||||
from typing import Iterator, List, Optional, Tuple
|
||||
from dataclasses import dataclass
|
||||
from collections import namedtuple
|
||||
|
||||
@ -77,6 +77,18 @@ def match_name(self, name: str) -> bool:
|
||||
def contains_vaddr(self, vaddr: int) -> bool:
|
||||
return self.virtual_address <= vaddr < self.virtual_address + self.extent
|
||||
|
||||
def read_virtual(self, vaddr: int, size: int) -> memoryview:
|
||||
ofs = vaddr - self.virtual_address
|
||||
|
||||
# Negative index will read from the end, which we don't want
|
||||
if ofs < 0:
|
||||
raise InvalidVirtualAddressError
|
||||
|
||||
try:
|
||||
return self.view[ofs : ofs + size]
|
||||
except IndexError as ex:
|
||||
raise InvalidVirtualAddressError from ex
|
||||
|
||||
def addr_is_uninitialized(self, vaddr: int) -> bool:
|
||||
"""We cannot rely on the IMAGE_SCN_CNT_UNINITIALIZED_DATA flag (0x80) in
|
||||
the characteristics field so instead we determine it this way."""
|
||||
@ -109,6 +121,7 @@ def __init__(self, filename: str, find_str: bool = False) -> None:
|
||||
self._section_vaddr: List[int] = []
|
||||
self.find_str = find_str
|
||||
self._potential_strings = {}
|
||||
self._relocations = set()
|
||||
self._relocated_addrs = set()
|
||||
self.imports = []
|
||||
self.thunks = []
|
||||
@ -279,11 +292,49 @@ def _populate_relocations(self):
|
||||
# We are now interested in the relocated addresses themselves. Seek to the
|
||||
# address where there is a relocation, then read the four bytes into our set.
|
||||
reloc_addrs.sort()
|
||||
self._relocations = set(reloc_addrs)
|
||||
|
||||
for section_id, offset in map(self.get_relative_addr, reloc_addrs):
|
||||
section = self.get_section_by_index(section_id)
|
||||
(relocated_addr,) = struct.unpack("<I", section.view[offset : offset + 4])
|
||||
self._relocated_addrs.add(relocated_addr)
|
||||
|
||||
def find_float_consts(self) -> Iterator[Tuple[int, int, float]]:
|
||||
"""Floating point instructions that refer to a memory address can
|
||||
point to constant values. Search the code sections to find FP
|
||||
instructions and check whether the pointer address refers to
|
||||
read-only data."""
|
||||
|
||||
# TODO: Should check any section that has code, not just .text
|
||||
text = self.get_section_by_name(".text")
|
||||
rdata = self.get_section_by_name(".rdata")
|
||||
|
||||
# These are the addresses where a relocation occurs.
|
||||
# Meaning: it points to an absolute address of something
|
||||
for addr in self._relocations:
|
||||
if not text.contains_vaddr(addr):
|
||||
continue
|
||||
|
||||
# Read the two bytes before the relocated address.
|
||||
# We will check against possible float opcodes
|
||||
raw = text.read_virtual(addr - 2, 6)
|
||||
(opcode, opcode_ext, const_addr) = struct.unpack("<BBL", raw)
|
||||
|
||||
# Skip right away if this is not const data
|
||||
if not rdata.contains_vaddr(const_addr):
|
||||
continue
|
||||
|
||||
if opcode_ext in (0x5, 0xD, 0x15, 0x1D, 0x25, 0x2D, 0x35, 0x3D):
|
||||
if opcode in (0xD8, 0xD9):
|
||||
# dword ptr -- single precision
|
||||
(float_value,) = struct.unpack("<f", self.read(const_addr, 4))
|
||||
yield (const_addr, 4, float_value)
|
||||
|
||||
elif opcode in (0xDC, 0xDD):
|
||||
# qword ptr -- double precision
|
||||
(float_value,) = struct.unpack("<d", self.read(const_addr, 8))
|
||||
yield (const_addr, 8, float_value)
|
||||
|
||||
def _populate_imports(self):
|
||||
"""Parse .idata to find imported DLLs and their functions."""
|
||||
idata_ofs = self.get_section_offset_by_name(".idata")
|
||||
|
||||
@ -35,16 +35,6 @@ def from_hex(string: str) -> Optional[int]:
|
||||
return None
|
||||
|
||||
|
||||
def bytes_to_float(b: bytes) -> Optional[float]:
|
||||
if len(b) == 4:
|
||||
return struct.unpack("<f", b)[0]
|
||||
|
||||
if len(b) == 8:
|
||||
return struct.unpack("<d", b)[0]
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def bytes_to_dword(b: bytes) -> Optional[int]:
|
||||
if len(b) == 4:
|
||||
return struct.unpack("<L", b)[0]
|
||||
@ -74,18 +64,6 @@ def is_relocated(self, addr: int) -> bool:
|
||||
|
||||
return False
|
||||
|
||||
def float_replace(self, addr: int, data_size: int) -> Optional[str]:
|
||||
if callable(self.bin_lookup):
|
||||
float_bytes = self.bin_lookup(addr, data_size)
|
||||
if float_bytes is None:
|
||||
return None
|
||||
|
||||
float_value = bytes_to_float(float_bytes)
|
||||
if float_value is not None:
|
||||
return f"{float_value} (FLOAT)"
|
||||
|
||||
return None
|
||||
|
||||
def lookup(
|
||||
self, addr: int, use_cache: bool = True, exact: bool = False
|
||||
) -> Optional[str]:
|
||||
@ -165,25 +143,6 @@ def hex_replace_indirect(self, match: re.Match) -> str:
|
||||
|
||||
return match.group(0).replace(match.group(1), self.replace(value))
|
||||
|
||||
def hex_replace_float(self, match: re.Match) -> str:
|
||||
"""Special case for replacements on float instructions.
|
||||
If the pointer is a float constant, read it from the binary."""
|
||||
value = int(match.group(1), 16)
|
||||
|
||||
# If we can find a variable name for this pointer, use it.
|
||||
placeholder = self.lookup(value)
|
||||
|
||||
# Read what's under the pointer and show the decimal value.
|
||||
if placeholder is None:
|
||||
float_size = 8 if "qword" in match.string else 4
|
||||
placeholder = self.float_replace(value, float_size)
|
||||
|
||||
# If we can't read the float, use a regular placeholder.
|
||||
if placeholder is None:
|
||||
placeholder = self.replace(value)
|
||||
|
||||
return match.group(0).replace(match.group(1), placeholder)
|
||||
|
||||
def sanitize(self, inst: DisasmLiteInst) -> Tuple[str, str]:
|
||||
# For jumps or calls, if the entire op_str is a hex number, the value
|
||||
# is a relative offset.
|
||||
@ -224,9 +183,6 @@ def sanitize(self, inst: DisasmLiteInst) -> Tuple[str, str]:
|
||||
if inst.mnemonic == "call":
|
||||
# Special handling for absolute indirect CALL.
|
||||
op_str = ptr_replace_regex.sub(self.hex_replace_indirect, inst.op_str)
|
||||
elif inst.mnemonic.startswith("f"):
|
||||
# If floating point instruction
|
||||
op_str = ptr_replace_regex.sub(self.hex_replace_float, inst.op_str)
|
||||
else:
|
||||
op_str = ptr_replace_regex.sub(self.hex_replace_always, inst.op_str)
|
||||
|
||||
|
||||
@ -82,6 +82,7 @@ def __init__(
|
||||
self._load_cvdump()
|
||||
self._load_markers()
|
||||
self._find_original_strings()
|
||||
self._find_float_const()
|
||||
self._match_imports()
|
||||
self._match_exports()
|
||||
self._match_thunks()
|
||||
@ -249,6 +250,18 @@ def _find_original_strings(self):
|
||||
|
||||
self._db.match_string(addr, string)
|
||||
|
||||
def _find_float_const(self):
|
||||
"""Add floating point constants in each binary to the database.
|
||||
We are not matching anything right now because these values are not
|
||||
deduped like strings."""
|
||||
for addr, size, float_value in self.orig_bin.find_float_consts():
|
||||
self._db.set_orig_symbol(addr, SymbolType.FLOAT, str(float_value), size)
|
||||
|
||||
for addr, size, float_value in self.recomp_bin.find_float_consts():
|
||||
self._db.set_recomp_symbol(
|
||||
addr, SymbolType.FLOAT, str(float_value), None, size
|
||||
)
|
||||
|
||||
def _match_imports(self):
|
||||
"""We can match imported functions based on the DLL name and
|
||||
function symbol name."""
|
||||
|
||||
@ -84,6 +84,23 @@ def __init__(self):
|
||||
self._db = sqlite3.connect(":memory:")
|
||||
self._db.executescript(_SETUP_SQL)
|
||||
|
||||
def set_orig_symbol(
|
||||
self,
|
||||
addr: int,
|
||||
compare_type: Optional[SymbolType],
|
||||
name: Optional[str],
|
||||
size: Optional[int],
|
||||
):
|
||||
# Ignore collisions here.
|
||||
if self._orig_used(addr):
|
||||
return
|
||||
|
||||
compare_value = compare_type.value if compare_type is not None else None
|
||||
self._db.execute(
|
||||
"INSERT INTO `symbols` (orig_addr, compare_type, name, size) VALUES (?,?,?,?)",
|
||||
(addr, compare_value, name, size),
|
||||
)
|
||||
|
||||
def set_recomp_symbol(
|
||||
self,
|
||||
addr: int,
|
||||
|
||||
@ -10,3 +10,4 @@ class SymbolType(Enum):
|
||||
POINTER = 3
|
||||
STRING = 4
|
||||
VTABLE = 5
|
||||
FLOAT = 6
|
||||
|
||||
@ -189,6 +189,7 @@ def substitute_1234(addr: int, _: bool) -> Optional[str]:
|
||||
assert op_str == "0x5555"
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="changed implementation")
|
||||
def test_float_replacement():
|
||||
"""Floating point constants often appear as pointers to data.
|
||||
A good example is ViewROI::IntrinsicImportance and the subclass override
|
||||
@ -208,6 +209,7 @@ def bin_lookup(addr: int, _: int) -> Optional[bytes]:
|
||||
assert op_str == "dword ptr [3.1415927410125732 (FLOAT)]"
|
||||
|
||||
|
||||
@pytest.mark.skip(reason="changed implementation")
|
||||
def test_float_variable():
|
||||
"""If there is a variable at the address referenced by a float instruction,
|
||||
use the name instead of calling into the float replacement handler."""
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
from typing import Iterator, List, Optional, Tuple
|
||||
from collections import namedtuple
|
||||
from isledecomp import Bin as IsleBin
|
||||
from isledecomp.bin import InvalidVirtualAddressError
|
||||
from isledecomp.cvdump import Cvdump
|
||||
from isledecomp.compare import Compare as IsleCompare
|
||||
from isledecomp.types import SymbolType
|
||||
@ -87,7 +88,7 @@ def print_sections(sections):
|
||||
print()
|
||||
|
||||
|
||||
ALLOWED_TYPE_ABBREVIATIONS = ["fun", "dat", "poi", "str", "vta"]
|
||||
ALLOWED_TYPE_ABBREVIATIONS = ["fun", "dat", "poi", "str", "vta", "flo"]
|
||||
|
||||
|
||||
def match_type_abbreviation(mtype: Optional[SymbolType]) -> str:
|
||||
@ -456,7 +457,16 @@ def to_roadmap_row(match):
|
||||
module_name,
|
||||
)
|
||||
|
||||
results = list(map(to_roadmap_row, engine.get_all()))
|
||||
def roadmap_row_generator(matches):
|
||||
for match in matches:
|
||||
try:
|
||||
yield to_roadmap_row(match)
|
||||
except InvalidVirtualAddressError:
|
||||
# This is here to work around the fact that we have RVA
|
||||
# values (i.e. not real virtual addrs) in our compare db.
|
||||
pass
|
||||
|
||||
results = list(roadmap_row_generator(engine.get_all()))
|
||||
|
||||
if args.order is not None:
|
||||
suggest_order(results, module_map, args.order)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user