From 548f337cad9bd99636430eb8dc8e5272aeb387a9 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 25 Sep 2023 13:08:19 -0400 Subject: [PATCH] Implement/match remaining MxDSMultiAction functions (#136) * Implement/match MxDSMultiAction::Deserialize * Implement remaining functions of MxDSMultiAction * Remove space --- LEGO1/mxdsaction.h | 2 + LEGO1/mxdsmultiaction.cpp | 108 ++++++++++++++++++++++++++++++++++++++ LEGO1/mxdsmultiaction.h | 9 ++++ LEGO1/mxlist.h | 7 +++ 4 files changed, 126 insertions(+) diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 265f0a6f..ce54cfc4 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -76,6 +76,8 @@ class MxDSAction : public MxDSObject undefined4 m_unk84; undefined4 m_unk88; MxOmni *m_omni; // 0x8c + +protected: MxLong m_someTimingField; // 0x90 }; diff --git a/LEGO1/mxdsmultiaction.cpp b/LEGO1/mxdsmultiaction.cpp index 6cbccc39..2580b813 100644 --- a/LEGO1/mxdsmultiaction.cpp +++ b/LEGO1/mxdsmultiaction.cpp @@ -17,6 +17,77 @@ MxDSMultiAction::~MxDSMultiAction() delete this->m_actions; } +// OFFSET: LEGO1 0x100ca0d0 +void MxDSMultiAction::CopyFrom(MxDSMultiAction &p_dsMultiAction) +{ + this->m_actions->DeleteAll(); + + MxDSActionListCursor cursor(p_dsMultiAction.m_actions); + MxDSAction *action; + while (cursor.Next(action)) + this->m_actions->Append(action->Clone()); +} + +// OFFSET: LEGO1 0x100ca260 +MxDSMultiAction &MxDSMultiAction::operator=(MxDSMultiAction &p_dsMultiAction) +{ + if (this == &p_dsMultiAction) + return *this; + + MxDSAction::operator=(p_dsMultiAction); + this->CopyFrom(p_dsMultiAction); + return *this; +} + +// OFFSET: LEGO1 0x100ca290 +void MxDSMultiAction::SetSomeTimingField(MxLong p_someTimingField) +{ + this->m_someTimingField = p_someTimingField; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + action->SetSomeTimingField(p_someTimingField); +} + +// OFFSET: LEGO1 0x100ca370 +void MxDSMultiAction::MergeFrom(MxDSAction &p_dsMultiAction) +{ + MxDSAction::MergeFrom(p_dsMultiAction); + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + action->MergeFrom(p_dsMultiAction); +} + +// OFFSET: LEGO1 0x100ca450 +MxBool MxDSMultiAction::HasId(MxU32 p_objectId) +{ + if (this->GetObjectId() == p_objectId) + return TRUE; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) { + if (action->HasId(p_objectId)) + return TRUE; + } + + return FALSE; +} + +// OFFSET: LEGO1 0x100ca550 +MxDSAction *MxDSMultiAction::Clone() +{ + MxDSMultiAction *clone = new MxDSMultiAction(); + + if (clone) + *clone = *this; + + return clone; +} + // OFFSET: LEGO1 0x100ca5e0 undefined4 MxDSMultiAction::unk14() { @@ -43,4 +114,41 @@ MxU32 MxDSMultiAction::GetSizeOnDisk() this->m_sizeOnDisk = totalSizeOnDisk - MxDSAction::GetSizeOnDisk(); return totalSizeOnDisk; +} + +// OFFSET: LEGO1 0x100ca7b0 +void MxDSMultiAction::Deserialize(char **p_source, MxS16 p_unk24) +{ + MxDSAction::Deserialize(p_source, p_unk24); + + MxU32 extraFlag = *(MxU32*)(*p_source + 4) & 1; + *p_source += 12; + + MxU32 count = *(MxU32*) *p_source; + *p_source += sizeof(count); + + if (count) { + while (count--) { + MxU32 extraFlag = *(MxU32*)(*p_source + 4) & 1; + *p_source += 8; + + MxDSAction *action = (MxDSAction*) DeserializeDSObjectDispatch(p_source, p_unk24); + *p_source += extraFlag; + + this->m_actions->Append(action); + } + } + + *p_source += extraFlag; +} + +// OFFSET: LEGO1 0x100ca8c0 +void MxDSMultiAction::SetAtomId(MxAtomId p_atomId) +{ + MxDSAction::SetAtomId(p_atomId); + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + action->SetAtomId(p_atomId); } \ No newline at end of file diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 7d4312f4..21b1dc03 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -12,6 +12,9 @@ class MxDSMultiAction : public MxDSAction MxDSMultiAction(); virtual ~MxDSMultiAction() override; + void CopyFrom(MxDSMultiAction &p_dsMultiAction); + MxDSMultiAction &operator=(MxDSMultiAction &p_dsMultiAction); + // OFFSET: LEGO1 0x100c9f50 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -27,6 +30,12 @@ class MxDSMultiAction : public MxDSAction virtual undefined4 unk14(); // vtable+14; virtual MxU32 GetSizeOnDisk(); // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; + virtual void SetAtomId(MxAtomId p_atomId); // vtable+20; + virtual MxDSAction *Clone(); // vtable+2c; + virtual void MergeFrom(MxDSAction &p_dsAction); // vtable+30; + virtual MxBool HasId(MxU32 p_objectId); // vtable+34; + virtual void SetSomeTimingField(MxLong p_someTimingField); // vtable+38; private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index a4231c92..0de71903 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -59,6 +59,7 @@ class MxList : protected MxListParent virtual ~MxList(); void Append(T*); + void DeleteAll(); MxU32 GetCount() { return m_count; } void SetDestroy(void (*p_customDestructor)(T *)) { this->m_customDestructor = p_customDestructor; } @@ -115,6 +116,12 @@ class MxListCursorChildChild : public MxListCursorChild template // OFFSET: LEGO1 0x1001ce20 MxList::~MxList() +{ + DeleteAll(); +} + +template +inline void MxList::DeleteAll() { for (MxListEntry *t = m_first;;) { if (!t)