From 96c98cec3dbd699b25f2ed2503a4bbce6384d158 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sun, 25 Feb 2024 12:04:30 -0500 Subject: [PATCH] Implement LegoAnimPresenter::FUN_100692b0 (#594) * Implement LegoAnimPresenter::FUN_100692b0 * Match --- .../lego/legoomni/include/legoanimpresenter.h | 6 +- LEGO1/lego/legoomni/include/legoroilist.h | 54 +++++++++++ .../legoomni/include/legounksavedatawriter.h | 2 + .../src/common/legounksavedatawriter.cpp | 12 +++ .../legoomni/src/video/legoanimpresenter.cpp | 96 ++++++++++++++++++- LEGO1/lego/sources/anim/legoanim.cpp | 20 ++++ LEGO1/lego/sources/anim/legoanim.h | 4 + 7 files changed, 190 insertions(+), 4 deletions(-) create mode 100644 LEGO1/lego/legoomni/include/legoroilist.h diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 6492c701..86206fee 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -2,6 +2,7 @@ #define LEGOANIMPRESENTER_H #include "anim/legoanim.h" +#include "legoroilist.h" #include "mxgeometry/mxgeometry3d.h" #include "mxvideopresenter.h" @@ -47,12 +48,15 @@ class LegoAnimPresenter : public MxVideoPresenter { protected: void Init(); void Destroy(MxBool p_fromDestructor); + LegoChar* FUN_10069150(const LegoChar*); + void FUN_100692b0(); + LegoChar* FUN_100697c0(const LegoChar*, LegoChar*); LegoAnim* m_anim; // 0x64 undefined4 m_unk0x68; // 0x68 undefined4 m_unk0x6c; // 0x6c undefined4 m_unk0x70; // 0x70 - undefined4 m_unk0x74; // 0x74 + LegoROIList* m_unk0x74; // 0x74 undefined4 m_unk0x78; // 0x78 undefined4 m_unk0x7c; // 0x7c LegoWorld* m_currentWorld; // 0x80 diff --git a/LEGO1/lego/legoomni/include/legoroilist.h b/LEGO1/lego/legoomni/include/legoroilist.h new file mode 100644 index 00000000..fb2cb3f1 --- /dev/null +++ b/LEGO1/lego/legoomni/include/legoroilist.h @@ -0,0 +1,54 @@ +#ifndef LEGOROILIST_H +#define LEGOROILIST_H + +#include "mxlist.h" +#include "mxtypes.h" +#include "roi/legoroi.h" + +// VTABLE: LEGO1 0x100d8c30 +// class MxCollection + +// VTABLE: LEGO1 0x100d8c48 +// class MxList + +// VTABLE: LEGO1 0x100d8c60 +// class MxPtrList + +// VTABLE: LEGO1 0x100d8c78 +// SIZE 0x18 +class LegoROIList : public MxPtrList { +public: + LegoROIList(MxBool p_ownership = FALSE) : MxPtrList(p_ownership) {} + + // FUNCTION: LEGO1 0x1005f360 + MxS8 Compare(LegoROI* p_a, LegoROI* p_b) override { return p_a == p_b ? 0 : p_a < p_b ? -1 : 1; } // vtable+0x14 + + // SYNTHETIC: LEGO1 0x1005f480 + // LegoROIList::`scalar deleting destructor' +}; + +// TEMPLATE: LEGO1 0x1005f380 +// MxCollection::Compare + +// TEMPLATE: LEGO1 0x1005f390 +// MxCollection::~MxCollection + +// TEMPLATE: LEGO1 0x1005f3e0 +// MxCollection::Destroy + +// TEMPLATE: LEGO1 0x1005f3f0 +// MxList::~MxList + +// TEMPLATE: LEGO1 0x1005f4f0 +// MxPtrList::~MxPtrList + +// SYNTHETIC: LEGO1 0x1005f540 +// MxCollection::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x1005f5b0 +// MxList::`scalar deleting destructor' + +// SYNTHETIC: LEGO1 0x1005f660 +// MxPtrList::`scalar deleting destructor' + +#endif // LEGOROILIST_H diff --git a/LEGO1/lego/legoomni/include/legounksavedatawriter.h b/LEGO1/lego/legoomni/include/legounksavedatawriter.h index 7fa539ca..7c49bfa1 100644 --- a/LEGO1/lego/legoomni/include/legounksavedatawriter.h +++ b/LEGO1/lego/legoomni/include/legounksavedatawriter.h @@ -64,6 +64,8 @@ class LegoUnkSaveDataWriter { void FUN_100832a0(); void FUN_10083db0(LegoROI* p_roi); void FUN_10083f10(LegoROI* p_roi); + LegoROI* FUN_10085210(LegoChar*, LegoChar*, undefined); + LegoROI* FUN_10085a80(LegoChar* p_und1, LegoChar* p_und2, undefined p_und3); private: static char* g_customizeAnimFile; diff --git a/LEGO1/lego/legoomni/src/common/legounksavedatawriter.cpp b/LEGO1/lego/legoomni/src/common/legounksavedatawriter.cpp index 336c5838..a1055e63 100644 --- a/LEGO1/lego/legoomni/src/common/legounksavedatawriter.cpp +++ b/LEGO1/lego/legoomni/src/common/legounksavedatawriter.cpp @@ -127,3 +127,15 @@ void LegoUnkSaveDataWriter::SetCustomizeAnimFile(const char* p_value) g_customizeAnimFile = NULL; } } + +// STUB: LEGO1 0x10085210 +LegoROI* LegoUnkSaveDataWriter::FUN_10085210(LegoChar*, LegoChar*, undefined) +{ + return NULL; +} + +// FUNCTION: LEGO1 0x10085a80 +LegoROI* LegoUnkSaveDataWriter::FUN_10085a80(LegoChar* p_und1, LegoChar* p_und2, undefined p_und3) +{ + return FUN_10085210(p_und1, p_und2, p_und3); +} diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index a841b50d..2eae93ca 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -1,6 +1,7 @@ #include "legoanimpresenter.h" #include "legoomni.h" +#include "legounksavedatawriter.h" #include "legoworld.h" #include "mxcompositepresenter.h" #include "mxdsanim.h" @@ -27,7 +28,7 @@ void LegoAnimPresenter::Init() m_anim = NULL; m_unk0x68 = 0; m_unk0x6c = 0; - m_unk0x74 = 0; + m_unk0x74 = NULL; m_unk0x70 = 0; m_unk0x78 = 0; m_unk0x7c = 0; @@ -104,6 +105,95 @@ MxResult LegoAnimPresenter::CreateAnim(MxStreamChunk* p_chunk) return result; } +// STUB: LEGO1 0x10069150 +LegoChar* LegoAnimPresenter::FUN_10069150(const LegoChar*) +{ + return NULL; +} + +// FUNCTION: LEGO1 0x100692b0 +void LegoAnimPresenter::FUN_100692b0() +{ + m_unk0x74 = new LegoROIList(); + + if (m_unk0x74) { + LegoU32 numActors = m_anim->GetNumActors(); + + for (LegoU32 i = 0; i < numActors; i++) { + LegoChar* str = FUN_100697c0(m_anim->GetActorName(i), NULL); + undefined4 unk0x04 = m_anim->GetActorUnknown0x04(i); + LegoROI* roi = NULL; + + if (unk0x04 == 2) { + LegoChar* src; + if (str[0] == '*') { + src = str + 1; + } + else { + src = str; + } + + roi = UnkSaveDataWriter()->FUN_10083500(src, TRUE); + + if (roi != NULL && str[0] == '*') { + roi->SetUnknown0x0c(0); + } + } + else if (unk0x04 == 4) { + LegoChar* src = new LegoChar[strlen(str)]; + strcpy(src, str + 1); + strlwr(src); + + LegoChar* und = FUN_10069150(str); + roi = UnkSaveDataWriter()->FUN_10085a80(und, src, 1); + + if (roi != NULL) { + roi->SetUnknown0x0c(0); + } + + delete[] src; + delete[] und; + } + else if (unk0x04 == 3) { + LegoChar* src = new LegoChar[strlen(str)]; + strcpy(src, str + 1); + + for (LegoChar* i = &src[strlen(src) - 1]; i > src; i--) { + if ((*i < '0' || *i > '9') && *i != '_') { + break; + } + + *i = '\0'; + } + + strlwr(src); + + LegoChar* und = FUN_10069150(str); + roi = UnkSaveDataWriter()->FUN_10085210(und, src, 1); + + if (roi != NULL) { + roi->SetUnknown0x0c(0); + } + + delete[] src; + delete[] und; + } + + if (roi != NULL) { + m_unk0x74->Append(roi); + } + + delete[] str; + } + } +} + +// STUB: LEGO1 0x100697c0 +LegoChar* LegoAnimPresenter::FUN_100697c0(const LegoChar*, LegoChar*) +{ + return NULL; +} + // STUB: LEGO1 0x1006ad30 void LegoAnimPresenter::PutFrame() { @@ -165,10 +255,10 @@ void LegoAnimPresenter::StreamingTickle() } } -// STUB: LEGO1 0x1006b8c0 +// FUNCTION: LEGO1 0x1006b8c0 void LegoAnimPresenter::DoneTickle() { - // TODO + MxVideoPresenter::DoneTickle(); } // FUNCTION: LEGO1 0x1006b8d0 diff --git a/LEGO1/lego/sources/anim/legoanim.cpp b/LEGO1/lego/sources/anim/legoanim.cpp index d172ceb8..5cae74c3 100644 --- a/LEGO1/lego/sources/anim/legoanim.cpp +++ b/LEGO1/lego/sources/anim/legoanim.cpp @@ -504,6 +504,26 @@ LegoResult LegoAnim::Write(LegoStorage* p_storage) return SUCCESS; } +// FUNCTION: LEGO1 0x100a0f20 +const LegoChar* LegoAnim::GetActorName(LegoU32 p_index) +{ + if (p_index < m_numActors) { + return m_actors[p_index].m_name; + } + + return NULL; +} + +// FUNCTION: LEGO1 0x100a0f40 +undefined4 LegoAnim::GetActorUnknown0x04(LegoU32 p_index) +{ + if (p_index < m_numActors) { + return m_actors[p_index].m_unk0x04; + } + + return NULL; +} + // FUNCTION: LEGO1 0x100a0f60 LegoMorphKey::LegoMorphKey() { diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index a16b2415..ce8326d0 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -139,9 +139,13 @@ class LegoAnim : public LegoTree { LegoAnim(); ~LegoAnim() override; LegoTime GetDuration() { return m_duration; } + LegoU32 GetNumActors() { return m_numActors; } LegoResult Write(LegoStorage* p_storage) override; // vtable+0x08 virtual LegoResult Read(LegoStorage* p_storage, LegoS32 p_parseScene); // vtable+0x10 + const LegoChar* GetActorName(LegoU32 p_index); + undefined4 GetActorUnknown0x04(LegoU32 p_index); + // SYNTHETIC: LEGO1 0x100a0ba0 // LegoAnim::`scalar deleting destructor'