From 29a0e32739399ee2bc942f630cf388e04b12713c Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 14 May 2024 14:50:37 -0400 Subject: [PATCH] Implement/match remaining LegoHideAnimPresenter functions (#923) * Implement/match remaining LegoHideAnimPresenter functions * Fix type * Fix marker * Fix type --- .../lego/legoomni/include/legoanimpresenter.h | 6 +- .../legoomni/include/legohideanimpresenter.h | 55 +++++++- .../legoomni/src/video/legoanimpresenter.cpp | 10 +- .../src/video/legohideanimpresenter.cpp | 119 ++++++++++++++++-- LEGO1/lego/sources/anim/legoanim.h | 10 +- LEGO1/lego/sources/geom/legowegedge.h | 10 ++ 6 files changed, 188 insertions(+), 22 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 4e51ebb4..a4909b5d 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -26,7 +26,7 @@ struct LegoAnimStruct { MxU32 m_index; // 0x04 }; -typedef map LegoAnimPresenterMap; +typedef map LegoAnimStructMap; typedef map LegoAnimSubstMap; // VTABLE: LEGO1 0x100d90c8 @@ -95,8 +95,8 @@ class LegoAnimPresenter : public MxVideoPresenter { LegoBool FUN_100698b0(const CompoundObject& p_rois, const LegoChar* p_und2); LegoROI* FUN_100699e0(const LegoChar* p_und); void FUN_10069b10(); - void FUN_1006a3c0(LegoAnimPresenterMap& p_map, LegoTreeNode* p_node, LegoROI* p_roi); - void FUN_1006a4f0(LegoAnimPresenterMap& p_map, LegoAnimNodeData* p_data, const LegoChar* p_und, LegoROI* p_roi); + void FUN_1006a3c0(LegoAnimStructMap& p_map, LegoTreeNode* p_node, LegoROI* p_roi); + void FUN_1006a4f0(LegoAnimStructMap& p_map, LegoAnimNodeData* p_data, const LegoChar* p_und, LegoROI* p_roi); void FUN_1006aa60(); void FUN_1006ab70(); LegoBool FUN_1006aba0(); diff --git a/LEGO1/lego/legoomni/include/legohideanimpresenter.h b/LEGO1/lego/legoomni/include/legohideanimpresenter.h index 7dfab184..0bb652d7 100644 --- a/LEGO1/lego/legoomni/include/legohideanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legohideanimpresenter.h @@ -4,6 +4,20 @@ #include "decomp.h" #include "legoloopinganimpresenter.h" +class LegoPathBoundary; + +struct LegoHideAnimStructComparator { + MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; } +}; + +// SIZE 0x08 +struct LegoHideAnimStruct { + LegoPathBoundary* m_boundary; // 0x00 + MxU32 m_index; // 0x04 +}; + +typedef map LegoHideAnimStructMap; + // VTABLE: LEGO1 0x100d9278 // SIZE 0xc4 class LegoHideAnimPresenter : public LegoLoopingAnimPresenter { @@ -36,13 +50,50 @@ class LegoHideAnimPresenter : public LegoLoopingAnimPresenter { private: void Init(); void Destroy(MxBool p_fromDestructor); - void FUN_1006db40(undefined4); + void FUN_1006db40(LegoTime p_time); + void FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time); void FUN_1006dc10(); + void FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node); + void FUN_1006e470( + LegoHideAnimStructMap& p_map, + LegoAnimNodeData* p_data, + const char* p_name, + LegoPathBoundary* p_boundary + ); - undefined4* m_unk0xc0; // 0xc0 + LegoPathBoundary** m_boundaryMap; // 0xc0 }; +// clang-format off // SYNTHETIC: LEGO1 0x1006d9d0 // LegoHideAnimPresenter::`scalar deleting destructor' +// TEMPLATE: LEGO1 0x1006ddb0 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::~_Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Inc + +// TEMPLATE: LEGO1 0x1006dec0 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::erase + +// TEMPLATE: LEGO1 0x1006e310 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Erase + +// TEMPLATE: LEGO1 0x1006e350 +// Map::~Map + +// TEMPLATE: LEGO1 0x1006e3a0 +// map >::~map > + +// TEMPLATE: LEGO1 0x1006e6d0 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Dec + +// TEMPLATE: LEGO1 0x1006e720 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Insert + +// GLOBAL: LEGO1 0x100f768c +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Nil +// clang-format on + #endif // LEGOHIDEANIMPRESENTER_H diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 32a8d26f..99aa243d 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -402,7 +402,7 @@ LegoROI* LegoAnimPresenter::FUN_100699e0(const LegoChar* p_und) // FUNCTION: LEGO1 0x10069b10 void LegoAnimPresenter::FUN_10069b10() { - LegoAnimPresenterMap map; + LegoAnimStructMap map; if (m_unk0x8c != NULL) { memset(m_unk0x8c, 0, m_unk0x94 * sizeof(*m_unk0x8c)); @@ -419,7 +419,7 @@ void LegoAnimPresenter::FUN_10069b10() m_roiMap = new LegoROI*[map.size() + 1]; memset(m_roiMap, 0, (map.size() + 1) * sizeof(*m_roiMap)); - for (LegoAnimPresenterMap::iterator it = map.begin(); it != map.end();) { + for (LegoAnimStructMap::iterator it = map.begin(); it != map.end();) { MxU32 index = (*it).second.m_index; m_roiMap[index] = (*it).second.m_roi; @@ -441,7 +441,7 @@ void LegoAnimPresenter::FUN_10069b10() } // FUNCTION: LEGO1 0x1006a3c0 -void LegoAnimPresenter::FUN_1006a3c0(LegoAnimPresenterMap& p_map, LegoTreeNode* p_node, LegoROI* p_roi) +void LegoAnimPresenter::FUN_1006a3c0(LegoAnimStructMap& p_map, LegoTreeNode* p_node, LegoROI* p_roi) { LegoROI* roi = p_roi; LegoChar* und = NULL; @@ -494,13 +494,13 @@ void LegoAnimPresenter::FUN_1006a3c0(LegoAnimPresenterMap& p_map, LegoTreeNode* // FUNCTION: LEGO1 0x1006a4f0 void LegoAnimPresenter::FUN_1006a4f0( - LegoAnimPresenterMap& p_map, + LegoAnimStructMap& p_map, LegoAnimNodeData* p_data, const LegoChar* p_und, LegoROI* p_roi ) { - LegoAnimPresenterMap::iterator it; + LegoAnimStructMap::iterator it; it = p_map.find(p_und); if (it == p_map.end()) { diff --git a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp index b5d06b82..51e62448 100644 --- a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp @@ -1,10 +1,12 @@ #include "legohideanimpresenter.h" +#include "anim/legoanim.h" #include "legomain.h" #include "legoworld.h" #include "misc.h" DECOMP_SIZE_ASSERT(LegoHideAnimPresenter, 0xc4) +DECOMP_SIZE_ASSERT(LegoHideAnimStruct, 0x08) // FUNCTION: LEGO1 0x1006d7e0 LegoHideAnimPresenter::LegoHideAnimPresenter() @@ -31,7 +33,7 @@ LegoHideAnimPresenter::~LegoHideAnimPresenter() // FUNCTION: LEGO1 0x1006da50 void LegoHideAnimPresenter::Init() { - m_unk0xc0 = NULL; + m_boundaryMap = NULL; } // FUNCTION: LEGO1 0x1006da60 @@ -39,8 +41,8 @@ void LegoHideAnimPresenter::Destroy(MxBool p_fromDestructor) { m_criticalSection.Enter(); - if (m_unk0xc0) { - delete m_unk0xc0; + if (m_boundaryMap) { + delete[] m_boundaryMap; } Init(); @@ -96,18 +98,119 @@ void LegoHideAnimPresenter::StartingTickle() } } -// STUB: LEGO1 0x1006db40 +// FUNCTION: LEGO1 0x1006db40 // FUNCTION: BETA10 0x100531ab -void LegoHideAnimPresenter::FUN_1006db40(undefined4) +void LegoHideAnimPresenter::FUN_1006db40(LegoTime p_time) { - // TODO + FUN_1006db60(m_anim->GetRoot(), p_time); } -// STUB: LEGO1 0x1006dc10 +// FUNCTION: LEGO1 0x1006db60 +// FUNCTION: BETA10 0x100531de +void LegoHideAnimPresenter::FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time) +{ + LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData(); + MxBool newB = FALSE; + MxBool previousB = FALSE; + + if (m_roiMap != NULL) { + LegoROI* roi = m_roiMap[data->GetUnknown0x20()]; + + if (roi != NULL) { + newB = data->FUN_100a0990(p_time); + previousB = roi->GetVisibility(); + roi->SetVisibility(newB); + } + } + + if (m_boundaryMap != NULL) { + LegoPathBoundary* boundary = m_boundaryMap[data->GetUnknown0x22()]; + + if (boundary != NULL) { + newB = data->FUN_100a0990(p_time); + boundary->GetFlag0x10(); + // TODO: Match + boundary->SetFlag0x10(newB); + } + } + + for (MxS32 i = 0; i < p_node->GetNumChildren(); i++) { + FUN_1006db60(p_node->GetChild(i), p_time); + } +} + +// FUNCTION: LEGO1 0x1006dc10 // FUNCTION: BETA10 0x100532fd void LegoHideAnimPresenter::FUN_1006dc10() { - // TODO + LegoHideAnimStructMap map; + + FUN_1006e3f0(map, m_anim->GetRoot()); + + if (m_boundaryMap != NULL) { + delete[] m_boundaryMap; + } + + m_boundaryMap = new LegoPathBoundary*[map.size() + 1]; + m_boundaryMap[0] = NULL; + + for (LegoHideAnimStructMap::iterator it = map.begin(); !(it == map.end()); it++) { + m_boundaryMap[(*it).second.m_index] = (*it).second.m_boundary; + delete[] const_cast((*it).first); + } +} + +// FUNCTION: LEGO1 0x1006e3f0 +// FUNCTION: BETA10 0x1005345e +void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node) +{ + LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData(); + const char* name = data->GetName(); + + if (name != NULL) { + LegoPathBoundary* boundary = m_currentWorld->FindPathBoundary(name); + + if (boundary != NULL) { + FUN_1006e470(p_map, data, name, boundary); + } + else { + data->SetUnknown0x22(0); + } + } + + MxS32 count = p_node->GetNumChildren(); + for (MxS32 i = 0; i < count; i++) { + FUN_1006e3f0(p_map, p_node->GetChild(i)); + } +} + +// FUNCTION: LEGO1 0x1006e470 +// FUNCTION: BETA10 0x10053520 +void LegoHideAnimPresenter::FUN_1006e470( + LegoHideAnimStructMap& p_map, + LegoAnimNodeData* p_data, + const char* p_name, + LegoPathBoundary* p_boundary +) +{ + LegoHideAnimStructMap::iterator it; + + it = p_map.find(p_name); + if (it == p_map.end()) { + LegoHideAnimStruct animStruct; + animStruct.m_index = p_map.size() + 1; + animStruct.m_boundary = p_boundary; + + p_data->SetUnknown0x22(animStruct.m_index); + + char* name = new char[strlen(p_name) + 1]; + strcpy(name, p_name); + + p_map[name] = animStruct; + } + else { + p_data->SetUnknown0x22((*it).second.m_index); + } } // FUNCTION: LEGO1 0x1006e9e0 diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index 9dd23a55..ae6f3bb6 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -124,13 +124,15 @@ class LegoAnimNodeData : public LegoTreeNodeData { LegoU32 GetRotationIndex() { return m_rotationIndex; } LegoU32 GetScaleIndex() { return m_scaleIndex; } LegoU32 GetMorphIndex() { return m_morphIndex; } - undefined2 GetUnknown0x20() { return m_unk0x20; } + LegoU16 GetUnknown0x20() { return m_unk0x20; } + LegoU16 GetUnknown0x22() { return m_unk0x22; } void SetTranslationIndex(LegoU32 p_translationIndex) { m_translationIndex = p_translationIndex; } 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; } + void SetUnknown0x20(LegoU16 p_unk0x20) { m_unk0x20 = p_unk0x20; } + void SetUnknown0x22(LegoU16 p_unk0x22) { m_unk0x22 = p_unk0x22; } LegoResult CreateLocalTransform(LegoTime p_time, Matrix4& p_matrix) { @@ -190,8 +192,8 @@ class LegoAnimNodeData : public LegoTreeNodeData { LegoRotationKey* m_rotationKeys; // 0x14 LegoScaleKey* m_scaleKeys; // 0x18 LegoMorphKey* m_morphKeys; // 0x1c - undefined2 m_unk0x20; // 0x20 - undefined2 m_unk0x22; // 0x22 + LegoU16 m_unk0x20; // 0x20 + LegoU16 m_unk0x22; // 0x22 LegoU32 m_translationIndex; // 0x24 LegoU32 m_rotationIndex; // 0x28 LegoU32 m_scaleIndex; // 0x2c diff --git a/LEGO1/lego/sources/geom/legowegedge.h b/LEGO1/lego/sources/geom/legowegedge.h index e34dfcdf..e8a0c396 100644 --- a/LEGO1/lego/sources/geom/legowegedge.h +++ b/LEGO1/lego/sources/geom/legowegedge.h @@ -43,6 +43,16 @@ class LegoWEGEdge : public LegoWEEdge { inline Mx4DPointFloat* GetEdgeNormal(int index) { return &m_edgeNormals[index]; } inline LegoChar* GetName() { return m_name; } + inline void SetFlag0x10(LegoU32 p_disable) + { + if (p_disable) { + m_flags &= ~c_bit5; + } + else { + m_flags |= c_bit5; + } + } + // SYNTHETIC: LEGO1 0x1009a7e0 // LegoWEGEdge::`scalar deleting destructor'