From d5dd8db46e0c420fd7c3d992daf68b3a3e20ef4c Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 19 Apr 2024 11:42:28 -0400 Subject: [PATCH] Implement LegoAnimationManager::FUN_100609f0 / LegoTranInfo (#820) * Implement LegoAnimationManager::FUN_100609f0 / LegoTranInfo * use NULL --- LEGO1/define.cpp | 4 + LEGO1/define.h | 1 + .../legoomni/include/legoanimationmanager.h | 15 ++-- LEGO1/lego/legoomni/include/legoomni.h | 18 ++--- LEGO1/lego/legoomni/include/legotraninfo.h | 42 +++++++++- .../src/common/legoanimationmanager.cpp | 79 +++++++++++++++++-- LEGO1/lego/legoomni/src/entity/legoentity.cpp | 2 +- LEGO1/lego/legoomni/src/main/legoomni.cpp | 14 +++- LEGO1/omni/include/mxdsaction.h | 2 +- LEGO1/omni/src/action/mxdsaction.cpp | 8 +- 10 files changed, 156 insertions(+), 29 deletions(-) diff --git a/LEGO1/define.cpp b/LEGO1/define.cpp index df5dde53..1ff1f868 100644 --- a/LEGO1/define.cpp +++ b/LEGO1/define.cpp @@ -36,6 +36,10 @@ const char* g_strVISIBILITY = "VISIBILITY"; // STRING: LEGO1 0x10101edc const char* g_strWORLD = "WORLD"; +// GLOBAL: LEGO1 0x101020d4 +// STRING: LEGO1 0x10101ed0 +const char* g_strANIMMAN_ID = "ANIMMAN_ID"; + // GLOBAL: LEGO1 0x101020e4 // STRING: LEGO1 0x10101eac const char* g_parseExtraTokens = ":;"; diff --git a/LEGO1/define.h b/LEGO1/define.h index 9c176a11..086c4500 100644 --- a/LEGO1/define.h +++ b/LEGO1/define.h @@ -13,5 +13,6 @@ extern const char* g_strVISIBILITY; extern const char* g_strSPEED; extern const char* g_strATTACH_CAMERA; extern const char* g_strMUTE; +extern const char* g_strANIMMAN_ID; #endif // DEFINE_H diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index d0a0eb40..7cb0a479 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -71,8 +71,9 @@ class LegoAnimationManager : public MxCore { MxResult ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info); MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info); void DeleteAnimations(); - MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity); void FUN_10060570(MxBool); + MxResult FUN_100609f0(MxU32 p_objectId, MxMatrix* p_matrix, MxBool p_und1, MxBool p_und2); + MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity); undefined4 FUN_10060dc0( IsleScript::Script, undefined4, @@ -87,6 +88,8 @@ class LegoAnimationManager : public MxCore { void FUN_10061010(undefined4); void FUN_100617c0(MxS32, MxU16&, MxU32&); MxS8 FUN_10062360(char*); + void FUN_10062770(); + void FUN_100627d0(MxBool); void FUN_100629b0(MxU32, MxBool); void FUN_10064670(MxBool); void FUN_10064740(MxBool); @@ -99,25 +102,27 @@ class LegoAnimationManager : public MxCore { private: void Init(); - undefined4 m_unk0x08; // 0x08 + MxU32 m_scriptIndex; // 0x08 MxU16 m_animCount; // 0x0c MxU16 m_unk0x0e; // 0x0e MxU32 m_unk0x10; // 0x10 AnimInfo* m_anims; // 0x14 - undefined m_unk0x018[8]; // 0x18 + undefined m_unk0x18[4]; // 0x18 + MxU32 m_unk0x1c; // 0x1c LegoTranInfoList* m_tranInfoList; // 0x20 LegoTranInfoList* m_tranInfoList2; // 0x24 undefined4 m_unk0x28[2]; // 0x28 undefined4 m_unk0x30[2]; // 0x30 undefined m_unk0x38; // 0x38 - undefined m_unk0x39; // 0x39 + MxBool m_unk0x39; // 0x39 undefined m_unk0x3a; // 0x3a Unknown0x3c m_unk0x3c[40]; // 0x3c undefined4 m_unk0x3fc; // 0x3fc MxU8 m_unk0x400; // 0x400 undefined m_unk0x401; // 0x401 MxU8 m_unk0x402; // 0x402 - undefined m_unk0x403[0x1d]; // 0x403 + MxLong m_unk0x404; // 0x404 + undefined m_unk0x408[0x18]; // 0x408 AnimState* m_animState; // 0x420 undefined4 m_unk0x424; // 0x424 undefined m_unk0x428; // 0x428 diff --git a/LEGO1/lego/legoomni/include/legoomni.h b/LEGO1/lego/legoomni/include/legoomni.h index 53fcb270..27f40108 100644 --- a/LEGO1/lego/legoomni/include/legoomni.h +++ b/LEGO1/lego/legoomni/include/legoomni.h @@ -72,10 +72,10 @@ class LegoOmni : public MxOmni { ScriptContainer() { m_index = -1; - m_script = NULL; + m_atomId = NULL; } - ScriptContainer(MxS32 p_index, const char* p_key, MxAtomId* p_script) + ScriptContainer(MxS32 p_index, const char* p_key, MxAtomId* p_atomId) { m_index = p_index; @@ -83,7 +83,7 @@ class LegoOmni : public MxOmni { strcpy(m_key, p_key); } - m_script = p_script; + m_atomId = p_atomId; } // FUNCTION: LEGO1 0x1005ac50 @@ -91,7 +91,7 @@ class LegoOmni : public MxOmni { { m_index = p_container.m_index; strcpy(m_key, p_container.m_key); - m_script = p_container.m_script; + m_atomId = p_container.m_atomId; return *this; } @@ -100,7 +100,7 @@ class LegoOmni : public MxOmni { MxS32 m_index; // 0x00 char m_key[20]; // 0x04 - MxAtomId* m_script; // 0x18 + MxAtomId* m_atomId; // 0x18 }; // SIZE 0x38 @@ -199,11 +199,12 @@ class LegoOmni : public MxOmni { void CreateBackgroundAudio(); void RemoveWorld(const MxAtomId& p_atom, MxLong p_objectId); MxResult RegisterScripts(); + const char* GetScriptName(MxU32 p_index); + MxAtomId* GetScriptAtom(MxU32 p_index); MxS32 GetScriptIndex(const char* p_key); void DeleteAction(); static MxS32 GetCurrPathInfo(LegoPathBoundary**, MxS32&); - const char* FindScript(MxU32 p_id); static void CreateInstance(); static LegoOmni* GetInstance(); @@ -231,10 +232,7 @@ class LegoOmni : public MxOmni { inline void SetExit(MxBool p_exit) { m_exit = p_exit; } inline MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { - if (m_unk0x13c) { - return Start(&p_dsAction); - } - return SUCCESS; + return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; } inline void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; } diff --git a/LEGO1/lego/legoomni/include/legotraninfo.h b/LEGO1/lego/legoomni/include/legotraninfo.h index ee29fc58..8d880889 100644 --- a/LEGO1/lego/legoomni/include/legotraninfo.h +++ b/LEGO1/lego/legoomni/include/legotraninfo.h @@ -2,10 +2,48 @@ #define LEGOTRANINFO_H #include "decomp.h" +#include "mxgeometry/mxmatrix.h" // SIZE 0x78 -struct LegoTranInfo { // See FUN_100609f0 for construction - undefined m_unk0x00[0x78]; // 0x00 +struct LegoTranInfo { + enum { + c_bit2 = 0x02 + }; + + LegoTranInfo() + { + m_index = 0; + m_unk0x08 = 0; + m_unk0x0c = NULL; + m_unk0x10 = FALSE; + m_unk0x12 = -1; + m_unk0x14 = FALSE; + m_unk0x1c = NULL; + m_unk0x20 = NULL; + m_unk0x24 = 0; + m_unk0x15 = TRUE; + m_unk0x28 = TRUE; + m_unk0x29 = TRUE; + m_flags = 0; + m_unk0x2c.SetIdentity(); + } + + undefined4 m_unk0x00; // 0x00 + MxU32 m_index; // 0x04 + undefined4 m_unk0x08; // 0x08 + MxMatrix* m_unk0x0c; // 0x0c + MxBool m_unk0x10; // 0x10 + MxS16 m_unk0x12; // 0x12 + MxBool m_unk0x14; // 0x14 + MxBool m_unk0x15; // 0x15 + MxU32 m_objectId; // 0x18 + undefined4* m_unk0x1c; // 0x1c + undefined4* m_unk0x20; // 0x20 + undefined4 m_unk0x24; // 0x24 + MxBool m_unk0x28; // 0x28 + MxBool m_unk0x29; // 0x29 + MxMatrix m_unk0x2c; // 0x2c + MxU32 m_flags; // 0x74 }; #endif // LEGOTRANINFO_H diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index c2a5d7a4..2a730c6a 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -1,9 +1,13 @@ #include "legoanimationmanager.h" +#include "define.h" #include "legocharactermanager.h" #include "legogamestate.h" #include "legoomni.h" #include "misc.h" +#include "mxbackgroundaudiomanager.h" +#include "mxmisc.h" +#include "mxtimer.h" #include "mxutilities.h" #include "roi/legoroi.h" @@ -13,6 +17,7 @@ DECOMP_SIZE_ASSERT(LegoAnimationManager, 0x500) DECOMP_SIZE_ASSERT(Character, 0x18) DECOMP_SIZE_ASSERT(Vehicle, 0x8) DECOMP_SIZE_ASSERT(Unknown0x3c, 0x18) +DECOMP_SIZE_ASSERT(LegoTranInfo, 0x78) // GLOBAL: LEGO1 0x100f6d20 Vehicle g_vehicles[] = { @@ -139,7 +144,7 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex) MxResult result = FAILURE; MxS32 i, j, k; - if (m_unk0x08 != p_scriptIndex) { + if (m_scriptIndex != p_scriptIndex) { if (m_tranInfoList != NULL) { delete m_tranInfoList; m_tranInfoList = NULL; @@ -156,7 +161,7 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex) } m_unk0x38 = 0; - m_unk0x39 = 0; + m_unk0x39 = FALSE; m_unk0x430 = 0; m_unk0x42c = 0; @@ -169,7 +174,7 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex) m_animState = (AnimState*) GameState()->CreateState("AnimState"); } - if (m_unk0x08 == 0) { + if (m_scriptIndex == 0) { m_animState->FUN_10065240(m_animCount, m_anims, m_unk0x3fc); } @@ -184,7 +189,7 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex) char filename[128]; char path[1024]; - sprintf(filename, "lego\\data\\%sinf.dta", Lego()->FindScript(p_scriptIndex)); + sprintf(filename, "lego\\data\\%sinf.dta", Lego()->GetScriptName(p_scriptIndex)); sprintf(path, "%s", MxOmni::GetHD()); if (path[strlen(path) - 1] != '\\') { @@ -263,7 +268,7 @@ MxResult LegoAnimationManager::LoadScriptInfo(MxS32 p_scriptIndex) } } - m_unk0x08 = p_scriptIndex; + m_scriptIndex = p_scriptIndex; m_tranInfoList = new LegoTranInfoList(); m_tranInfoList2 = new LegoTranInfoList(); @@ -439,6 +444,58 @@ void LegoAnimationManager::FUN_10060570(MxBool) // TODO } +// FUNCTION: LEGO1 0x100609f0 +// FUNCTION: BETA10 0x10041a38 +MxResult LegoAnimationManager::FUN_100609f0(MxU32 p_objectId, MxMatrix* p_matrix, MxBool p_und1, MxBool p_und2) +{ + MxResult result = FAILURE; + MxDSAction action; + + FUN_100627d0(FALSE); + + LegoTranInfo* info = new LegoTranInfo(); + info->m_unk0x00 = 0; + info->m_index = ++m_unk0x1c; + info->m_unk0x10 = FALSE; + info->m_unk0x08 = 0; + info->m_unk0x12 = -1; + info->m_unk0x14 = 0; + info->m_objectId = p_objectId; + + if (p_matrix != NULL) { + info->m_unk0x0c = new MxMatrix(*p_matrix); + } + + FUN_10062770(); + + info->m_unk0x1c = m_unk0x28; + info->m_unk0x20 = m_unk0x30; + info->m_unk0x28 = p_und1; + info->m_unk0x29 = p_und2; + + if (m_tranInfoList != NULL) { + m_tranInfoList->Append(info); + } + + char buf[256]; + sprintf(buf, "%s:%d", g_strANIMMAN_ID, info->m_index); + + action.SetAtomId(*Lego()->GetScriptAtom(m_scriptIndex)); + action.SetObjectId(p_objectId); + action.SetUnknown24(-1); + action.AppendExtra(strlen(buf) + 1, buf); + + if (StartActionIfUnknown0x13c(action) == SUCCESS) { + BackgroundAudioManager()->LowerVolume(); + info->m_flags |= LegoTranInfo::c_bit2; + m_unk0x39 = TRUE; + m_unk0x404 = Timer()->GetTime(); + result = SUCCESS; + } + + return result; +} + // FUNCTION: LEGO1 0x10060d00 MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity) { @@ -528,6 +585,18 @@ MxS8 LegoAnimationManager::FUN_10062360(char*) return 0; } +// STUB: LEGO1 0x10062770 +void LegoAnimationManager::FUN_10062770() +{ + // TODO +} + +// STUB: LEGO1 0x100627d0 +void LegoAnimationManager::FUN_100627d0(MxBool) +{ + // TODO +} + // STUB: LEGO1 0x100629b0 void LegoAnimationManager::FUN_100629b0(MxU32, MxBool) { diff --git a/LEGO1/lego/legoomni/src/entity/legoentity.cpp b/LEGO1/lego/legoomni/src/entity/legoentity.cpp index 5b121c3a..151f7cf6 100644 --- a/LEGO1/lego/legoomni/src/entity/legoentity.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoentity.cpp @@ -265,7 +265,7 @@ void LegoEntity::VTable0x34(MxBool p_und) MxDSAction action; action.SetAtomId(MxAtomId(CharacterManager()->GetCustomizeAnimFile(), e_lowerCase2)); action.SetObjectId(objectId); - action.AppendData(strlen(roiName) + 1, roiName); + action.AppendExtra(strlen(roiName) + 1, roiName); Start(&action); } } diff --git a/LEGO1/lego/legoomni/src/main/legoomni.cpp b/LEGO1/lego/legoomni/src/main/legoomni.cpp index 2ee2d23f..31aa4aec 100644 --- a/LEGO1/lego/legoomni/src/main/legoomni.cpp +++ b/LEGO1/lego/legoomni/src/main/legoomni.cpp @@ -707,7 +707,7 @@ MxS32 LegoOmni::GetCurrPathInfo(LegoPathBoundary** p_path, MxS32& p_value) } // FUNCTION: LEGO1 0x1005b430 -const char* LegoOmni::FindScript(MxU32 p_index) +const char* LegoOmni::GetScriptName(MxU32 p_index) { for (MxS32 i = 0; i < 19; i++) { if (m_scripts[i].m_index == p_index) { @@ -718,6 +718,18 @@ const char* LegoOmni::FindScript(MxU32 p_index) return NULL; } +// FUNCTION: LEGO1 0x1005b460 +MxAtomId* LegoOmni::GetScriptAtom(MxU32 p_index) +{ + for (MxS32 i = 0; i < 19; i++) { + if (m_scripts[i].m_index == p_index) { + return m_scripts[i].m_atomId; + } + } + + return NULL; +} + // FUNCTION: LEGO1 0x1005b490 MxS32 LegoOmni::GetScriptIndex(const char* p_key) { diff --git a/LEGO1/omni/include/mxdsaction.h b/LEGO1/omni/include/mxdsaction.h index c7aa5008..19ea4390 100644 --- a/LEGO1/omni/include/mxdsaction.h +++ b/LEGO1/omni/include/mxdsaction.h @@ -55,7 +55,7 @@ class MxDSAction : public MxDSObject { virtual MxLong GetUnknown90(); // vtable+3c; virtual MxLong GetElapsedTime(); // vtable+40; - void AppendData(MxU16 p_extraLength, const char* p_extraData); + void AppendExtra(MxU16 p_extraLength, const char* p_extraData); inline void GetExtra(MxU16& p_extraLength, char*& p_extraData) { diff --git a/LEGO1/omni/src/action/mxdsaction.cpp b/LEGO1/omni/src/action/mxdsaction.cpp index b72481e2..c5222fcb 100644 --- a/LEGO1/omni/src/action/mxdsaction.cpp +++ b/LEGO1/omni/src/action/mxdsaction.cpp @@ -79,7 +79,7 @@ void MxDSAction::CopyFrom(MxDSAction& p_dsAction) this->m_location = p_dsAction.m_location; this->m_direction = p_dsAction.m_direction; this->m_up = p_dsAction.m_up; - AppendData(p_dsAction.m_extraLength, p_dsAction.m_extraData); + AppendExtra(p_dsAction.m_extraLength, p_dsAction.m_extraData); this->m_unk0x84 = p_dsAction.m_unk0x84; this->m_unk0x88 = p_dsAction.m_unk0x88; this->m_origin = p_dsAction.m_origin; @@ -186,13 +186,13 @@ void MxDSAction::MergeFrom(MxDSAction& p_dsAction) if (!this->m_extraData || !strncmp("XXX", this->m_extraData, 3)) { delete[] this->m_extraData; this->m_extraLength = 0; - AppendData(extraLength, extraData); + AppendExtra(extraLength, extraData); } } } // FUNCTION: LEGO1 0x100ade60 -void MxDSAction::AppendData(MxU16 p_extraLength, const char* p_extraData) +void MxDSAction::AppendExtra(MxU16 p_extraLength, const char* p_extraData) { if (this->m_extraData == p_extraData || !p_extraData) { return; @@ -243,7 +243,7 @@ void MxDSAction::Deserialize(MxU8*& p_source, MxS16 p_unk0x24) p_source += 2; if (extraLength) { - AppendData(extraLength, (char*) p_source); + AppendExtra(extraLength, (char*) p_source); p_source += extraLength; } }