From dc3259bb17ab57bc46b7bcb932b39114b0321bbf Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 12 Apr 2024 11:53:22 -0400 Subject: [PATCH] Implement/match LegoAnimPresenter::FUN_1006a4f0 (#789) --- .../lego/legoomni/include/legoanimpresenter.h | 25 ++++ .../legoomni/include/legocharactermanager.h | 10 +- .../legoomni/src/video/legoanimpresenter.cpp | 113 ++++++++++++------ LEGO1/lego/sources/anim/legoanim.h | 1 + 4 files changed, 110 insertions(+), 39 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 0eff701b..5b6c62fc 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -10,6 +10,18 @@ class LegoWorld; class LegoAnimClass; class LegoAnimActor; +struct LegoAnimStructComparator { + MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; } +}; + +// SIZE 0x08 +struct LegoAnimStruct { + LegoROI* m_roi; // 0x00 + undefined4 m_unk0x04; // 0x04 +}; + +typedef map LegoAnimPresenterMap; + // VTABLE: LEGO1 0x100d90c8 // SIZE 0xbc class LegoAnimPresenter : public MxVideoPresenter { @@ -74,6 +86,8 @@ class LegoAnimPresenter : public MxVideoPresenter { LegoChar* FUN_100697c0(const LegoChar* p_und1, const LegoChar* p_und2); LegoBool FUN_100698b0(const CompoundObject& p_rois, const LegoChar* p_und2); void FUN_10069b10(); + void FUN_1006a3c0(LegoAnimPresenterMap& p_map, LegoTreeNode* p_root, LegoROI* p_roi); + void FUN_1006a4f0(LegoAnimPresenterMap& p_map, LegoAnimNodeData* p_data, const LegoChar* p_und, LegoROI* p_roi); LegoBool FUN_1006aba0(); LegoBool FUN_1006abb0(LegoTreeNode*, undefined4); void FUN_1006ac90(); @@ -102,7 +116,18 @@ class LegoAnimPresenter : public MxVideoPresenter { Mx3DPointFloat m_unk0xa8; // 0xa8 }; +// clang-format off // SYNTHETIC: LEGO1 0x10068650 // LegoAnimPresenter::`scalar deleting destructor' +// TEMPLATE: LEGO1 0x1006a750 +// _Tree,map >::_Kfn,LegoAnimStructComparator,allocator >::iterator::_Dec + +// TEMPLATE: LEGO1 0x1006a7a0 +// _Tree,map >::_Kfn,LegoAnimStructComparator,allocator >::_Insert + +// GLOBAL: LEGO1 0x100f7688 +// _Tree,map >::_Kfn,LegoAnimStructComparator,allocator >::_Nil +// clang-format on + #endif // LEGOANIMPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index b86a1dab..ece8b915 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -13,7 +13,6 @@ class LegoROI; #pragma warning(disable : 4237) -// TODO: generic string comparator? struct LegoCharacterComparator { MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmpi(p_a, p_b) < 0; } }; @@ -115,6 +114,15 @@ class LegoCharacterManager { // TEMPLATE: LEGO1 0x10085500 // _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::insert +// TEMPLATE: LEGO1 0x10085790 +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::_Buynode + +// TEMPLATE: LEGO1 0x100857b0 +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::_Lrotate + +// TEMPLATE: LEGO1 0x10085810 +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::_Rrotate + // GLOBAL: LEGO1 0x100fc508 // _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::_Nil // clang-format on diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 95bd4c8c..c124409b 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -312,6 +312,40 @@ void LegoAnimPresenter::FUN_10069b10() // TODO } +// STUB: LEGO1 0x1006a3c0 +void LegoAnimPresenter::FUN_1006a3c0(LegoAnimPresenterMap& p_map, LegoTreeNode* p_root, LegoROI* p_roi) +{ + // TODO +} + +// FUNCTION: LEGO1 0x1006a4f0 +void LegoAnimPresenter::FUN_1006a4f0( + LegoAnimPresenterMap& p_map, + LegoAnimNodeData* p_data, + const LegoChar* p_und, + LegoROI* p_roi +) +{ + LegoAnimPresenterMap::iterator it; + + it = p_map.find(p_und); + if (it == p_map.end()) { + LegoAnimStruct animStruct; + animStruct.m_unk0x04 = p_map.size() + 1; + animStruct.m_roi = p_roi; + + p_data->SetUnknown0x20(animStruct.m_unk0x04); + + LegoChar* und = new LegoChar[strlen(p_und) + 1]; + strcpy(und, p_und); + + p_map[und] = animStruct; + } + else { + p_data->SetUnknown0x20((*it).second.m_unk0x04); + } +} + // FUNCTION: LEGO1 0x1006aba0 LegoBool LegoAnimPresenter::FUN_1006aba0() { @@ -368,46 +402,49 @@ void LegoAnimPresenter::StartingTickle() FUN_100692b0(); FUN_100695c0(); - if ((m_unk0x7c & c_bit2) == 0 || FUN_1006aba0()) { - FUN_10069b10(); - FUN_1006c8a0(TRUE); - - if (m_unk0x78 == NULL) { - if (fabs(m_action->GetDirection().GetX()) >= 0.00000047683716F || - fabs(m_action->GetDirection().GetY()) >= 0.00000047683716F || - fabs(m_action->GetDirection().GetZ()) >= 0.00000047683716F) { - m_unk0x78 = new MxMatrix(); - CalcLocalTransform(m_action->GetLocation(), m_action->GetDirection(), m_action->GetUp(), *m_unk0x78); - } - else if (m_unk0x68) { - MxU8* und = (MxU8*) m_unk0x68[1]; - - if (und) { - MxMatrix mat; - mat = *(Matrix4*) (und + 0x10); - m_unk0x78 = new MxMatrix(mat); - } - } - } - - if ((m_action->GetDuration() == -1 || ((MxDSMediaAction*) m_action)->GetSustainTime() == -1) && - m_compositePresenter) { - m_compositePresenter->VTable0x60(this); - } - else { - m_action->SetUnknown90(Timer()->GetTime()); - } - - ProgressTickleState(e_streaming); - - if (m_compositePresenter && m_compositePresenter->IsA("LegoAnimMMPresenter")) { - m_unk0x96 = ((LegoAnimMMPresenter*) m_compositePresenter)->FUN_1004b8b0(); - m_compositePresenter->VTable0x60(this); - } - - VTable0x8c(); + if (m_unk0x7c & c_bit2 && !FUN_1006aba0()) { + goto done; } + FUN_10069b10(); + FUN_1006c8a0(TRUE); + + if (m_unk0x78 == NULL) { + if (fabs(m_action->GetDirection().GetX()) >= 0.00000047683716F || + fabs(m_action->GetDirection().GetY()) >= 0.00000047683716F || + fabs(m_action->GetDirection().GetZ()) >= 0.00000047683716F) { + m_unk0x78 = new MxMatrix(); + CalcLocalTransform(m_action->GetLocation(), m_action->GetDirection(), m_action->GetUp(), *m_unk0x78); + } + else if (m_unk0x68) { + MxU8* und = (MxU8*) m_unk0x68[1]; + + if (und) { + MxMatrix mat; + mat = *(Matrix4*) (und + 0x10); + m_unk0x78 = new MxMatrix(mat); + } + } + } + + if ((m_action->GetDuration() == -1 || ((MxDSMediaAction*) m_action)->GetSustainTime() == -1) && + m_compositePresenter) { + m_compositePresenter->VTable0x60(this); + } + else { + m_action->SetUnknown90(Timer()->GetTime()); + } + + ProgressTickleState(e_streaming); + + if (m_compositePresenter && m_compositePresenter->IsA("LegoAnimMMPresenter")) { + m_unk0x96 = ((LegoAnimMMPresenter*) m_compositePresenter)->FUN_1004b8b0(); + m_compositePresenter->VTable0x60(this); + } + + VTable0x8c(); + +done: if (m_unk0x70 != NULL) { delete m_unk0x70; m_unk0x70 = NULL; diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index 960d7c90..c1ccc016 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -128,6 +128,7 @@ 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; } + void SetUnknown0x20(undefined2 p_unk0x20) { m_unk0x20 = p_unk0x20; } LegoResult CreateLocalTransform(LegoTime p_time, Matrix4& p_matrix) {