From 974cd7ce7c727d21652c8383f0c58910fce87602 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Fri, 11 Oct 2024 20:21:33 +0200 Subject: [PATCH] Implement `LegoCarBuildAnimPresenter::FUN_10079160()` and others (#1111) * Implement `LegoCarBuildAnimPresenter::FUN_10079160()` and others * Address review comments --------- Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/legocarbuild.h | 4 + .../legoomni/include/legocarbuildpresenter.h | 64 ++-- .../lego/legoomni/src/build/legocarbuild.cpp | 11 + .../src/build/legocarbuildpresenter.cpp | 283 ++++++++++++++++-- .../legoomni/src/video/legoanimpresenter.cpp | 1 + LEGO1/lego/sources/anim/legoanim.cpp | 9 + LEGO1/lego/sources/anim/legoanim.h | 24 +- LEGO1/lego/sources/misc/legotree.cpp | 1 + LEGO1/lego/sources/misc/legotree.h | 5 + LEGO1/library_msvc.h | 9 + LEGO1/omni/src/common/mxpresenter.cpp | 1 + 11 files changed, 360 insertions(+), 52 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocarbuild.h b/LEGO1/lego/legoomni/include/legocarbuild.h index c06d4e9e..8e9e3922 100644 --- a/LEGO1/lego/legoomni/include/legocarbuild.h +++ b/LEGO1/lego/legoomni/include/legocarbuild.h @@ -103,6 +103,7 @@ class LegoCarBuild : public LegoWorld { MxFloat p_param4[2] ); // vtable+0x80 + MxS16 GetPlacedPartCount(); void InitPresenters(); void FUN_10022f30(); void FUN_10023130(MxLong p_x, MxLong p_y); @@ -127,6 +128,9 @@ class LegoCarBuild : public LegoWorld { void FUN_10025e40(); MxS32 FUN_10025ee0(undefined4 p_param1); + // FUNCTION: BETA10 0x100735b0 + void SetUnknown0x258(LegoCarBuildAnimPresenter* p_unk0x258) { m_unk0x258 = p_unk0x258; } + // SYNTHETIC: LEGO1 0x10022a60 // LegoCarBuild::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h index b7b02d52..dffaa43b 100644 --- a/LEGO1/lego/legoomni/include/legocarbuildpresenter.h +++ b/LEGO1/lego/legoomni/include/legocarbuildpresenter.h @@ -11,9 +11,22 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { public: // SIZE 0x0c struct UnknownListEntry { - LegoChar* m_unk0x00; // 0x00 - LegoChar* m_unk0x04; // 0x04 - undefined m_unk0x08[4]; // 0x08 + // FUNCTION: LEGO1 0x100795c0 + // FUNCTION: BETA10 0x10073850 + UnknownListEntry() + { + m_name = NULL; + m_wiredName = NULL; + m_unk0x08 = 0; + } + + // variable name verified by BETA10 0x10071b56 + LegoChar* m_name; // 0x00 + + // variable name verified by BETA10 0x100719f0 + LegoChar* m_wiredName; // 0x04 + + undefined2 m_unk0x08; // 0x08 }; LegoCarBuildAnimPresenter(); @@ -46,18 +59,23 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { void PutFrame() override; // vtable+0x6c void FUN_10079050(MxS16 p_index); - void FUN_10079090(LegoChar* p_param1, LegoChar* p_param2); + void SwapNodesByName(LegoChar* p_param1, LegoChar* p_param2); void FUN_10079160(); void FUN_100795d0(LegoChar* p_param); void FUN_10079680(LegoChar* p_param); + LegoAnimNodeData* FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name); + LegoTreeNode* FindNodeByName(LegoTreeNode* p_treeNode, const LegoChar* p_name); void RotateAroundYAxis(MxFloat p_angle); MxBool FUN_10079c30(const LegoChar* p_name); MxBool FUN_10079ca0(const LegoChar* p_name); + MxBool StringEqualsPlatform(const LegoChar* p_string); + MxBool StringEqualsShelf(const LegoChar* p_string); MxBool FUN_10079cf0(const LegoChar* p_string); // FUNCTION: BETA10 0x10070180 void SetUnknown0xbc(undefined2 p_unk0xbc) { m_unk0xbc = p_unk0xbc; } + MxBool StringEndsOnW(LegoChar* p_param); MxBool StringEndsOnYOrN(const LegoChar* p_string); const BoundingSphere& FUN_10079e20(); @@ -66,21 +84,29 @@ class LegoCarBuildAnimPresenter : public LegoAnimPresenter { // LegoCarBuildAnimPresenter::`scalar deleting destructor' private: - undefined2 m_unk0xbc; // 0xbc - MxS16 m_unk0xbe; // 0xbe - MxS16 m_unk0xc0; // 0xc0 - LegoAnimNodeData* m_unk0xc4; // 0xc4 - LegoAnim m_unk0xc8; // 0xc8 - MxMatrix m_unk0xe0; // 0xe0 - UnknownListEntry* m_unk0x128; // 0x128 - MxFloat m_unk0x12c; // 0x12c - undefined4 m_unk0x130; // 0x130 - undefined4 m_unk0x134; // 0x134 - undefined4 m_unk0x138; // 0x138 - undefined4 m_unk0x13c; // 0x13c - LegoEntity* m_unk0x140; // 0x140 - MxS32 m_unk0x144; // 0x144 - MxS32 m_unk0x148; // 0x148 + undefined2 m_unk0xbc; // 0xbc + + // variable name verified by BETA10 0x1007184f + MxS16 m_numberOfParts; // 0xbe + + // name derived from LegoVehicleBuildState, field 0x4f + MxS16 m_placedPartCount; // 0xc0 + + LegoAnimNodeData* m_unk0xc4; // 0xc4 + LegoAnim m_unk0xc8; // 0xc8 + MxMatrix m_unk0xe0; // 0xe0 + + // variable name verified by BETA10 0x100719f0 + UnknownListEntry* m_parts; // 0x128 + + MxFloat m_unk0x12c; // 0x12c + undefined4 m_unk0x130; // 0x130 + MxFloat m_unk0x134; // 0x134 + MxFloat m_unk0x138; // 0x138 + undefined4 m_unk0x13c; // 0x13c + LegoEntity* m_unk0x140; // 0x140 + MxS32 m_unk0x144; // 0x144 + MxS32 m_unk0x148; // 0x148 // name verified by BETA10 0x10070d63 LegoChar* m_mainSourceId; // 0x14c diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index b9865c1b..b8e7f93a 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -153,6 +153,17 @@ MxResult LegoCarBuild::Create(MxDSAction& p_dsAction) return result; } +// FUNCTION: LEGO1 0x10022cd0 +MxS16 LegoCarBuild::GetPlacedPartCount() +{ + if (m_buildState) { + return m_buildState->m_placedPartCount; + } + else { + return 0; + } +} + // FUNCTION: LEGO1 0x10022d10 // FUNCTION: BETA10 0x1006b27a void LegoCarBuild::InitPresenters() diff --git a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp index 5bd69f58..1c41a335 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp @@ -1,12 +1,16 @@ #include "legocarbuildpresenter.h" #include "3dmanager/lego3dmanager.h" +#include "legocarbuild.h" #include "legoentity.h" #include "legogamestate.h" +#include "legomain.h" #include "legoutils.h" #include "legovideomanager.h" +#include "legoworld.h" #include "misc.h" #include "mxautolock.h" +#include "mxcompositepresenter.h" #include "realtime/realtime.h" DECOMP_SIZE_ASSERT(LegoCarBuildAnimPresenter::UnknownListEntry, 0x0c) @@ -17,9 +21,9 @@ DECOMP_SIZE_ASSERT(LegoCarBuildAnimPresenter, 0x150) LegoCarBuildAnimPresenter::LegoCarBuildAnimPresenter() { m_unk0xbc = 0; - m_unk0xbe = 0; - m_unk0xc0 = 0; - m_unk0x128 = NULL; + m_numberOfParts = 0; + m_placedPartCount = 0; + m_parts = NULL; m_unk0xc4 = NULL; m_unk0x130 = 0; m_unk0x12c = 0; @@ -42,12 +46,12 @@ void LegoCarBuildAnimPresenter::RepeatingTickle() // FUNCTION: BETA10 0x1007091e LegoCarBuildAnimPresenter::~LegoCarBuildAnimPresenter() { - if (m_unk0x128) { - for (MxS16 i = 0; i < m_unk0xbe; i++) { - delete m_unk0x128[i].m_unk0x00; - delete m_unk0x128[i].m_unk0x04; + if (m_parts) { + for (MxS16 i = 0; i < m_numberOfParts; i++) { + delete m_parts[i].m_name; + delete m_parts[i].m_wiredName; } - delete[] m_unk0x128; + delete[] m_parts; } m_unk0xc8.GetRoot()->SetNumChildren(0); @@ -64,11 +68,52 @@ void LegoCarBuildAnimPresenter::PutFrame() // TODO } -// STUB: LEGO1 0x100788c0 -// STUB: BETA10 0x10070b56 +// FUNCTION: LEGO1 0x100788c0 +// FUNCTION: BETA10 0x10070b56 void LegoCarBuildAnimPresenter::ReadyTickle() { - // TODO + if (!m_anim) { + LegoAnimPresenter::ReadyTickle(); + + if (!m_currentWorld) { + return; + } + +#ifdef NDEBUG + if (!m_anim) { + return; + } +#else + assert(m_anim); +#endif + } + + m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "Dunebld"); + + if (!m_unk0x140) { + m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "Chptrbld"); + } + + if (!m_unk0x140) { + m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "Jetbld"); + } + + if (!m_unk0x140) { + m_unk0x140 = (LegoEntity*) m_currentWorld->Find("MxEntity", "bldrace"); + } + + if (m_unk0x140) { + ((LegoCarBuild*) m_currentWorld)->SetUnknown0x258(this); + m_placedPartCount = ((LegoCarBuild*) m_currentWorld)->GetPlacedPartCount(); + SetUnknown0xbc(1); + m_previousTickleStates |= 1 << m_currentTickleState; + m_currentTickleState = e_starting; + m_compositePresenter->SendToCompositePresenter(Lego()); + } + else { + m_previousTickleStates |= 1 << m_currentTickleState; + m_currentTickleState = e_ready; + } } // FUNCTION: LEGO1 0x100789e0 @@ -88,25 +133,25 @@ void LegoCarBuildAnimPresenter::StreamingTickle() FUN_10079160(); if (GameState()->GetCurrentAct() == LegoGameState::e_act2) { - m_unk0xc0 = 10; + m_placedPartCount = 10; } MxS16 i; - for (i = 0; i < m_unk0xbe; i++) { - if (m_unk0xc0 == i) { - FUN_10079680(m_unk0x128[i].m_unk0x04); + for (i = 0; i < m_numberOfParts; i++) { + if (m_placedPartCount == i) { + FUN_10079680(m_parts[i].m_wiredName); } else { - FUN_100795d0(m_unk0x128[i].m_unk0x04); + FUN_100795d0(m_parts[i].m_wiredName); } - if (i < m_unk0xc0) { + if (i < m_placedPartCount) { FUN_10079050(i); - FUN_10079680(m_unk0x128[i].m_unk0x00); + FUN_10079680(m_parts[i].m_name); } - LegoChar* name = m_unk0x128[i].m_unk0x04; + LegoChar* name = m_parts[i].m_wiredName; if (name) { for (MxS32 j = 0; j <= m_roiMapSize; j++) { @@ -185,23 +230,125 @@ void LegoCarBuildAnimPresenter::EndAction() // FUNCTION: BETA10 0x1007151e void LegoCarBuildAnimPresenter::FUN_10079050(MxS16 p_index) { - FUN_10079090(m_unk0x128[p_index].m_unk0x04, m_unk0x128[p_index].m_unk0x00); - FUN_100795d0(m_unk0x128[p_index].m_unk0x04); + SwapNodesByName(m_parts[p_index].m_wiredName, m_parts[p_index].m_name); + FUN_100795d0(m_parts[p_index].m_wiredName); } -// STUB: LEGO1 0x10079090 -// STUB: BETA10 0x10071584 -void LegoCarBuildAnimPresenter::FUN_10079090(LegoChar* p_param1, LegoChar* p_param2) +// FUNCTION: LEGO1 0x10079090 +// FUNCTION: BETA10 0x10071584 +void LegoCarBuildAnimPresenter::SwapNodesByName(LegoChar* p_name1, LegoChar* p_name2) { - // TODO + char buffer[40]; + + if (stricmp(p_name1, p_name2) != 0) { + LegoAnimNodeData* node1 = FindNodeDataByName(m_anim->GetRoot(), p_name1); + LegoAnimNodeData* node2 = FindNodeDataByName(m_anim->GetRoot(), p_name2); + + strcpy(buffer, node1->GetName()); + strcpy(node1->GetName(), node2->GetName()); + strcpy(node2->GetName(), buffer); + + LegoU16 val1 = node1->GetUnknown0x20(); + node1->SetUnknown0x20(node2->GetUnknown0x20()); + node2->SetUnknown0x20(val1); + } } -// STUB: LEGO1 0x10079160 -// STUB: BETA10 0x1007165d +// FUNCTION: LEGO1 0x10079160 +// FUNCTION: BETA10 0x1007165d void LegoCarBuildAnimPresenter::FUN_10079160() { - // called from LegoCarBuildAnimPresenter::StreamingTickle() - // TODO + LegoTreeNode* root; + LegoAnimNodeData* data2; + MxS16 i; + MxS16 totalNodes = CountTotalTreeNodes(m_anim->GetRoot()); + LegoChar* name; + LegoTreeNode* destNode; + LegoAnimNodeData* destData; + LegoTreeNode** children; + + for (i = 0; i < totalNodes; i++) { + LegoAnimNodeData* data = (LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData(); + name = data->GetName(); + + if (StringEqualsPlatform(name)) { + m_unk0xc4 = data; + if (m_unk0xc4->GetNumRotationKeys() == 0) { + LegoRotationKey* key = new LegoRotationKey(); + m_unk0xc4->SetNumRotationKeys(1); + m_unk0xc4->SetRotationKeys(key); + } + } + else { + if (StringEndsOnYOrN(name)) { + m_numberOfParts++; + } + else { + if (m_unk0x134 == 0.0f && StringEqualsShelf(name)) { + m_unk0x134 = m_anim->GetDuration(); + m_unk0x138 = m_unk0x134 / (data->GetNumTranslationKeys() - 1); + } + } + } + } + + assert(m_numberOfParts); + m_parts = new UnknownListEntry[m_numberOfParts]; + assert(m_parts); + + for (i = 0; i < totalNodes; i++) { + name = ((LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData())->GetName(); + + strupr(name); + + if (StringEndsOnW(name)) { + m_parts[name[strlen(name) - 1] - 'A'].m_wiredName = new LegoChar[strlen(name) + 1]; + + // clang-format off + assert(m_parts[name[strlen(name)-1] - 'A'].m_wiredName); + // clang-format on + + strcpy(m_parts[name[strlen(name) - 1] - 'A'].m_wiredName, name); + } + } + + MxS16 counter = 0; + + for (i = 0; i < totalNodes; i++) { + name = ((LegoAnimNodeData*) GetTreeNode(m_anim->GetRoot(), i)->GetData())->GetName(); + if (StringEndsOnYOrN(name)) { + for (MxS16 ii = 0; ii < m_numberOfParts; ii++) { + if (strnicmp(m_parts[ii].m_wiredName, name, strlen(name) - 2) == 0) { + m_parts[ii].m_name = new LegoChar[strlen(name) + 1]; + assert(m_parts[ii].m_name); + strcpy(m_parts[ii].m_name, name); + + counter++; + if (m_numberOfParts == counter) { + break; + } + } + } + } + } + + destNode = new LegoTreeNode(); + assert(destNode); + destData = new LegoAnimNodeData(); + assert(destData); + destNode->SetData(destData); + + root = m_anim->GetRoot(); + data2 = (LegoAnimNodeData*) root->GetData(); + destData->FUN_100a0360(data2->GetName()); + + destNode->SetNumChildren(1); + children = new LegoTreeNode*; + assert(children); + *children = FindNodeByName(m_anim->GetRoot(), "PLATFORM"); + + destNode->SetChildren(children); + m_unk0xc8.SetRoot(destNode); } // STUB: LEGO1 0x100795d0 @@ -218,6 +365,57 @@ void LegoCarBuildAnimPresenter::FUN_10079680(LegoChar* p_param) // TODO } +// FUNCTION: LEGO1 0x100796b0 +// FUNCTION: BETA10 0x10071f3c +LegoAnimNodeData* LegoCarBuildAnimPresenter::FindNodeDataByName(LegoTreeNode* p_treeNode, const LegoChar* p_name) +{ + LegoAnimNodeData* data = NULL; + + if (p_treeNode) { + data = (LegoAnimNodeData*) p_treeNode->GetData(); + + if (stricmp(data->GetName(), p_name) == 0) { + return data; + } + + for (MxS32 i = 0; i < p_treeNode->GetNumChildren(); i++) { + data = FindNodeDataByName(p_treeNode->GetChildren()[i], p_name); + + if (data) { + return data; + } + } + } + + return NULL; +} + +// FUNCTION: LEGO1 0x10079720 +// FUNCTION: BETA10 0x10071fec +LegoTreeNode* LegoCarBuildAnimPresenter::FindNodeByName(LegoTreeNode* p_treeNode, const LegoChar* p_name) +{ + LegoAnimNodeData* data = NULL; + LegoTreeNode* node = NULL; + + if (p_treeNode) { + data = (LegoAnimNodeData*) p_treeNode->GetData(); + + if (stricmp(data->GetName(), p_name) == 0) { + return p_treeNode; + } + + for (MxS32 i = 0; i < p_treeNode->GetNumChildren(); i++) { + node = FindNodeByName(p_treeNode->GetChildren()[i], p_name); + + if (node) { + return node; + } + } + } + + return NULL; +} + // FUNCTION: LEGO1 0x10079920 // FUNCTION: BETA10 0x1007225d void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle) @@ -251,6 +449,20 @@ void LegoCarBuildAnimPresenter::RotateAroundYAxis(MxFloat p_angle) } } +// FUNCTION: LEGO1 0x10079b20 +// FUNCTION: BETA10 0x100724fa +MxBool LegoCarBuildAnimPresenter::StringEqualsPlatform(const LegoChar* p_string) +{ + return stricmp(p_string, "PLATFORM") == 0; +} + +// FUNCTION: LEGO1 0x10079b40 +// FUNCTION: BETA10 0x10072534 +MxBool LegoCarBuildAnimPresenter::StringEndsOnW(LegoChar* p_param) +{ + return (p_param[strlen(p_param) - 2] == 'W') || (p_param[strlen(p_param) - 2] == 'w'); +} + // FUNCTION: LEGO1 0x10079b80 // FUNCTION: BETA10 0x1007258f MxBool LegoCarBuildAnimPresenter::StringEndsOnYOrN(const LegoChar* p_string) @@ -259,6 +471,13 @@ MxBool LegoCarBuildAnimPresenter::StringEndsOnYOrN(const LegoChar* p_string) (p_string[strlen(p_string) - 2] == 'Y') || (p_string[strlen(p_string) - 2] == 'y'); } +// FUNCTION: LEGO1 0x10079bf0 +// FUNCTION: BETA10 0x10072624 +MxBool LegoCarBuildAnimPresenter::StringEqualsShelf(const LegoChar* p_string) +{ + return strnicmp(p_string, "SHELF", strlen("SHELF")) == 0; +} + // STUB: LEGO1 0x10079c30 // STUB: BETA10 0x100726a6 MxBool LegoCarBuildAnimPresenter::FUN_10079c30(const LegoChar* p_name) @@ -271,8 +490,8 @@ MxBool LegoCarBuildAnimPresenter::FUN_10079c30(const LegoChar* p_name) // FUNCTION: BETA10 0x10072740 MxBool LegoCarBuildAnimPresenter::FUN_10079ca0(const LegoChar* p_name) { - for (MxS16 i = 0; i < m_unk0xc0; i++) { - if (strcmpi(p_name, m_unk0x128[i].m_unk0x00) == 0) { + for (MxS16 i = 0; i < m_placedPartCount; i++) { + if (strcmpi(p_name, m_parts[i].m_name) == 0) { return TRUE; } } @@ -292,5 +511,5 @@ MxBool LegoCarBuildAnimPresenter::FUN_10079cf0(const LegoChar* p_string) const BoundingSphere& LegoCarBuildAnimPresenter::FUN_10079e20() { LegoROI* roi = m_unk0x140->GetROI(); - return roi->FindChildROI(m_unk0x128[m_unk0xc0].m_unk0x04, roi)->GetWorldBoundingSphere(); + return roi->FindChildROI(m_parts[m_placedPartCount].m_wiredName, roi)->GetWorldBoundingSphere(); } diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 28b2b2e1..fcffcba6 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -750,6 +750,7 @@ MxResult LegoAnimPresenter::FUN_1006b140(LegoROI* p_roi) } // FUNCTION: LEGO1 0x1006b550 +// FUNCTION: BETA10 0x10050a9c void LegoAnimPresenter::ReadyTickle() { m_currentWorld = CurrentWorld(); diff --git a/LEGO1/lego/sources/anim/legoanim.cpp b/LEGO1/lego/sources/anim/legoanim.cpp index 77801f61..0683fa7b 100644 --- a/LEGO1/lego/sources/anim/legoanim.cpp +++ b/LEGO1/lego/sources/anim/legoanim.cpp @@ -279,6 +279,7 @@ LegoResult LegoTranslationKey::Read(LegoStorage* p_storage) } // FUNCTION: LEGO1 0x1009faa0 +// FUNCTION: BETA10 0x1017e2b3 LegoRotationKey::LegoRotationKey() { m_angle = 1.0F; @@ -356,6 +357,7 @@ LegoResult LegoScaleKey::Read(LegoStorage* p_storage) } // FUNCTION: LEGO1 0x1009fcf0 +// FUNCTION: BETA10 0x1017e71a LegoAnimNodeData::LegoAnimNodeData() { m_numTranslationKeys = 0; @@ -494,6 +496,13 @@ LegoResult LegoAnimNodeData::Write(LegoStorage* p_storage) return SUCCESS; } +// STUB: LEGO1 0x100a0360 +// STUB: BETA10 0x1017f1e5 +void LegoAnimNodeData::FUN_100a0360(LegoChar* p_param) +{ + // TODO +} + // FUNCTION: LEGO1 0x100a03c0 LegoResult LegoAnimNodeData::CreateLocalTransform(LegoFloat p_time, Matrix4& p_matrix) { diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index 62816ba9..1782034c 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -145,17 +145,37 @@ class LegoAnimNodeData : public LegoTreeNodeData { LegoResult Read(LegoStorage* p_storage) override; // vtable+0x04 LegoResult Write(LegoStorage* p_storage) override; // vtable+0x08 + void FUN_100a0360(LegoChar* p_param); LegoResult CreateLocalTransform(LegoFloat p_time, Matrix4& p_matrix); LegoBool FUN_100a0990(LegoFloat p_time); // FUNCTION: BETA10 0x100595d0 - const LegoChar* GetName() { return m_name; } + LegoChar* GetName() { return m_name; } + + // FUNCTION: BETA10 0x10073780 + LegoU16 GetNumTranslationKeys() { return m_numTranslationKeys; } + + // FUNCTION: BETA10 0x100737b0 + LegoU16 GetNumRotationKeys() { return m_numRotationKeys; } + + // FUNCTION: BETA10 0x100737e0 + void SetNumRotationKeys(LegoU16 p_numRotationKeys) { m_numRotationKeys = p_numRotationKeys; } + + // FUNCTION: BETA10 0x10073810 + void SetRotationKeys(LegoRotationKey* p_keys) + { + m_rotationKeys = p_keys; + m_rotationIndex = 0; + } LegoU32 GetTranslationIndex() { return m_translationIndex; } LegoU32 GetRotationIndex() { return m_rotationIndex; } LegoU32 GetScaleIndex() { return m_scaleIndex; } LegoU32 GetMorphIndex() { return m_morphIndex; } + + // FUNCTION: BETA10 0x1005abc0 LegoU16 GetUnknown0x20() { return m_unk0x20; } + LegoU16 GetUnknown0x22() { return m_unk0x22; } // FUNCTION: BETA10 0x10073b80 @@ -165,6 +185,8 @@ class LegoAnimNodeData : public LegoTreeNodeData { void SetRotationIndex(LegoU32 p_rotationIndex) { m_rotationIndex = p_rotationIndex; } void SetScaleIndex(LegoU32 p_scaleIndex) { m_scaleIndex = p_scaleIndex; } void SetMorphIndex(LegoU32 p_morphIndex) { m_morphIndex = p_morphIndex; } + + // FUNCTION: BETA10 0x10059600 void SetUnknown0x20(LegoU16 p_unk0x20) { m_unk0x20 = p_unk0x20; } // FUNCTION: BETA10 0x1005f2e0 diff --git a/LEGO1/lego/sources/misc/legotree.cpp b/LEGO1/lego/sources/misc/legotree.cpp index e7f24513..e77e8222 100644 --- a/LEGO1/lego/sources/misc/legotree.cpp +++ b/LEGO1/lego/sources/misc/legotree.cpp @@ -8,6 +8,7 @@ DECOMP_SIZE_ASSERT(LegoTreeNode, 0x010) DECOMP_SIZE_ASSERT(LegoTree, 0x08) // FUNCTION: LEGO1 0x10099d60 +// FUNCTION: BETA10 0x10187dd0 LegoTreeNode::LegoTreeNode() { m_data = NULL; diff --git a/LEGO1/lego/sources/misc/legotree.h b/LEGO1/lego/sources/misc/legotree.h index fea8d5ec..c444a31e 100644 --- a/LEGO1/lego/sources/misc/legotree.h +++ b/LEGO1/lego/sources/misc/legotree.h @@ -9,6 +9,7 @@ class LegoStorage; // VTABLE: LEGO1 0x100db778 +// VTABLE: BETA10 0x101c37f4 // SIZE 0x04 class LegoTreeNodeData { public: @@ -36,6 +37,7 @@ class LegoTreeNode { // FUNCTION: BETA10 0x100595a0 LegoTreeNodeData* GetData() { return m_data; } + // FUNCTION: BETA10 0x100736f0 void SetData(LegoTreeNodeData* p_data) { m_data = p_data; } // FUNCTION: BETA10 0x10012150 @@ -52,6 +54,7 @@ class LegoTreeNode { // FUNCTION: BETA10 0x100733a0 LegoTreeNode** GetChildren() { return m_children; } + // FUNCTION: BETA10 0x10073720 void SetChildren(LegoTreeNode** p_children) { m_children = p_children; } // SYNTHETIC: LEGO1 0x10099d80 @@ -73,7 +76,9 @@ class LegoTree { // FUNCTION: BETA10 0x100121b0 LegoTreeNode* GetRoot() { return m_root; } + // FUNCTION: BETA10 0x10073750 void SetRoot(LegoTreeNode* p_root) { m_root = p_root; } + virtual LegoResult Read(LegoStorage* p_storage); // vtable+0x04 virtual LegoResult Write(LegoStorage* p_storage); // vtable+0x08 diff --git a/LEGO1/library_msvc.h b/LEGO1/library_msvc.h index b1e8afa6..49e2efbd 100644 --- a/LEGO1/library_msvc.h +++ b/LEGO1/library_msvc.h @@ -725,4 +725,13 @@ // LIBRARY: BETA10 0x100ff82b // __ctrandisp1 +// LIBRARY: BETA10 0x100f8a92 +// operator delete + +// LIBRARY: BETA10 0x1018ed70 +// _strupr + +// LIBRARY: BETA10 0x1001d1a0 +// `vector constructor iterator' + #endif diff --git a/LEGO1/omni/src/common/mxpresenter.cpp b/LEGO1/omni/src/common/mxpresenter.cpp index 214f35c6..8731baa3 100644 --- a/LEGO1/omni/src/common/mxpresenter.cpp +++ b/LEGO1/omni/src/common/mxpresenter.cpp @@ -112,6 +112,7 @@ void MxPresenter::ParseExtra() } // FUNCTION: LEGO1 0x100b5120 +// FUNCTION: BETA10 0x1012e5d8 void MxPresenter::SendToCompositePresenter(MxOmni* p_omni) { if (m_compositePresenter) {