From 4a674d823b18817dd35182fcaefef27209429266 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Sat, 7 Oct 2023 14:03:15 -0400 Subject: [PATCH] Implement MxDSSelectAction Clone/operator=/CopyFrom (#154) --- CMakeLists.txt | 1 + LEGO1/mxdsaction.h | 4 ++-- LEGO1/mxdsanim.h | 2 +- LEGO1/mxdschunk.h | 1 - LEGO1/mxdsevent.h | 2 +- LEGO1/mxdsmediaaction.h | 4 ++-- LEGO1/mxdsmultiaction.h | 16 ++++++++-------- LEGO1/mxdsobjectaction.h | 2 +- LEGO1/mxdsparallelaction.h | 4 ++-- LEGO1/mxdsselectaction.cpp | 34 ++++++++++++++++++++++++++++++++++ LEGO1/mxdsselectaction.h | 8 ++++++++ LEGO1/mxdsserialaction.h | 6 +++--- LEGO1/mxdssound.h | 6 +++--- LEGO1/mxdsstill.h | 2 +- LEGO1/mxdsstreamingaction.h | 2 +- LEGO1/mxlist.h | 33 ++++++++++++++++++++++++++------- LEGO1/mxstring.cpp | 8 ++++---- LEGO1/mxstring.h | 2 +- LEGO1/mxstringlist.cpp | 5 +++++ LEGO1/mxstringlist.h | 12 ++++++++++++ 20 files changed, 116 insertions(+), 38 deletions(-) create mode 100644 LEGO1/mxstringlist.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 0e2135c9..a3573874 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -163,6 +163,7 @@ add_library(lego1 SHARED LEGO1/mxstreamcontroller.cpp LEGO1/mxstreamer.cpp LEGO1/mxstring.cpp + LEGO1/mxstringlist.cpp LEGO1/mxthread.cpp LEGO1/mxticklemanager.cpp LEGO1/mxtimer.cpp diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 9881f3e2..57d1f200 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -41,8 +41,8 @@ class MxDSAction : public MxDSObject return !strcmp(name, MxDSAction::ClassName()) || MxDSObject::IsA(name); } - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; virtual MxLong GetDuration(); // vtable+24; virtual void SetDuration(MxLong p_duration); // vtable+28; virtual MxDSAction *Clone(); // vtable+2c; diff --git a/LEGO1/mxdsanim.h b/LEGO1/mxdsanim.h index 92890e8e..1bc77558 100644 --- a/LEGO1/mxdsanim.h +++ b/LEGO1/mxdsanim.h @@ -27,7 +27,7 @@ class MxDSAnim : public MxDSMediaAction return !strcmp(name, MxDSAnim::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSANIM_H diff --git a/LEGO1/mxdschunk.h b/LEGO1/mxdschunk.h index f9b1d9d0..367dcb4d 100644 --- a/LEGO1/mxdschunk.h +++ b/LEGO1/mxdschunk.h @@ -1,7 +1,6 @@ #ifndef MXDSCHUNK_H #define MXDSCHUNK_H - #include "mxcore.h" #include "mxtypes.h" diff --git a/LEGO1/mxdsevent.h b/LEGO1/mxdsevent.h index b8fedace..576c8b14 100644 --- a/LEGO1/mxdsevent.h +++ b/LEGO1/mxdsevent.h @@ -25,7 +25,7 @@ class MxDSEvent : public MxDSMediaAction return !strcmp(name, MxDSEvent::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSEVENT_H diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index cc710425..34b6695e 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -28,8 +28,8 @@ class MxDSMediaAction : public MxDSAction return !strcmp(name, MxDSMediaAction::ClassName()) || MxDSAction::IsA(name); } - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; void CopyMediaSrcPath(const char *p_mediaSrcPath); diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 4063343c..1689cc2d 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -28,14 +28,14 @@ class MxDSMultiAction : public MxDSAction return !strcmp(name, MxDSMultiAction::ClassName()) || MxDSAction::IsA(name); } - 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; + virtual undefined4 unk14() override; // vtable+14; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; + virtual void SetAtomId(MxAtomId p_atomId) override; // vtable+20; + virtual MxDSAction *Clone() override; // vtable+2c; + virtual void MergeFrom(MxDSAction &p_dsAction) override; // vtable+30; + virtual MxBool HasId(MxU32 p_objectId) override; // vtable+34; + virtual void SetSomeTimingField(MxLong p_someTimingField) override; // vtable+38; private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxdsobjectaction.h b/LEGO1/mxdsobjectaction.h index 4a1b68bb..07f35758 100644 --- a/LEGO1/mxdsobjectaction.h +++ b/LEGO1/mxdsobjectaction.h @@ -26,7 +26,7 @@ class MxDSObjectAction : public MxDSMediaAction return !strcmp(name, MxDSObjectAction::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; virtual void CopyFrom(MxDSObjectAction &p_dsObjectAction); // vtable+44; }; diff --git a/LEGO1/mxdsparallelaction.h b/LEGO1/mxdsparallelaction.h index 962ba34b..e28bfe58 100644 --- a/LEGO1/mxdsparallelaction.h +++ b/LEGO1/mxdsparallelaction.h @@ -27,8 +27,8 @@ class MxDSParallelAction : public MxDSMultiAction return !strcmp(name, MxDSParallelAction::ClassName()) || MxDSMultiAction::IsA(name); } - virtual MxLong GetDuration(); // vtable+24; - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxLong GetDuration() override; // vtable+24; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSPARALLELACTION_H diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 29f69022..58af9543 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -15,3 +15,37 @@ MxDSSelectAction::~MxDSSelectAction() if (this->m_unk0xac) delete this->m_unk0xac; } + +// OFFSET: LEGO1 0x100cb950 +void MxDSSelectAction::CopyFrom(MxDSSelectAction &p_dsSelectAction) +{ + this->m_unk0x9c = p_dsSelectAction.m_unk0x9c; + + this->m_unk0xac->DeleteAll(); + + MxStringListCursor cursor(p_dsSelectAction.m_unk0xac); + MxString string; + while (cursor.Next(string)) + this->m_unk0xac->OtherAppend(string); +} + +// OFFSET: LEGO1 0x100cbd50 +MxDSSelectAction &MxDSSelectAction::operator=(MxDSSelectAction &p_dsSelectAction) +{ + if (this != &p_dsSelectAction) { + MxDSParallelAction::operator=(p_dsSelectAction); + this->CopyFrom(p_dsSelectAction); + } + return *this; +} + +// OFFSET: LEGO1 0x100cbd80 +MxDSAction *MxDSSelectAction::Clone() +{ + MxDSSelectAction *clone = new MxDSSelectAction(); + + if (clone) + *clone = *this; + + return clone; +} \ No newline at end of file diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index d513efd0..746afc87 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -13,6 +13,9 @@ class MxDSSelectAction : public MxDSParallelAction MxDSSelectAction(); virtual ~MxDSSelectAction() override; + void CopyFrom(MxDSSelectAction &p_dsSelectAction); + MxDSSelectAction &operator=(MxDSSelectAction &p_dsSelectAction); + // OFFSET: LEGO1 0x100cb6f0 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -26,6 +29,11 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } + //virtual MxU32 GetSizeOnDisk() override; // vtable+18; + //virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; + //virtual MxLong GetDuration() override; // vtable+24; + virtual MxDSAction *Clone() override; // vtable+2c; + private: MxString m_unk0x9c; MxStringList *m_unk0xac; diff --git a/LEGO1/mxdsserialaction.h b/LEGO1/mxdsserialaction.h index e2f6cd72..4e383681 100644 --- a/LEGO1/mxdsserialaction.h +++ b/LEGO1/mxdsserialaction.h @@ -28,9 +28,9 @@ class MxDSSerialAction : public MxDSMultiAction return !strcmp(name, MxDSSerialAction::ClassName()) || MxDSMultiAction::IsA(name); } - virtual MxLong GetDuration(); // vtable+24; - virtual void SetDuration(MxLong p_duration); // vtable+28; - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxLong GetDuration() override; // vtable+24; + virtual void SetDuration(MxLong p_duration) override; // vtable+28; + virtual MxDSAction *Clone() override; // vtable+2c; private: MxDSActionListCursor *m_cursor; diff --git a/LEGO1/mxdssound.h b/LEGO1/mxdssound.h index de345e51..514ef1ec 100644 --- a/LEGO1/mxdssound.h +++ b/LEGO1/mxdssound.h @@ -27,9 +27,9 @@ class MxDSSound : public MxDSMediaAction return !strcmp(name, MxDSSound::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; + virtual MxDSAction *Clone() override; // vtable+2c; private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxdsstill.h b/LEGO1/mxdsstill.h index 084fe931..3b29c287 100644 --- a/LEGO1/mxdsstill.h +++ b/LEGO1/mxdsstill.h @@ -27,7 +27,7 @@ class MxDSStill : public MxDSMediaAction return !strcmp(name, MxDSStill::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSSTILL_H diff --git a/LEGO1/mxdsstreamingaction.h b/LEGO1/mxdsstreamingaction.h index d50dbed8..f95621eb 100644 --- a/LEGO1/mxdsstreamingaction.h +++ b/LEGO1/mxdsstreamingaction.h @@ -24,7 +24,7 @@ class MxDSStreamingAction : public MxDSAction return *this; } - virtual MxBool HasId(MxU32 p_objectId); // vtable+34; + virtual MxBool HasId(MxU32 p_objectId) override; // vtable+34; MxResult Init(); void SetInternalAction(MxDSAction *p_dsAction); diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 12695f82..94798b33 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -4,7 +4,6 @@ #include "mxtypes.h" #include "mxcore.h" -// SIZE 0xc template class MxListEntry { @@ -15,6 +14,11 @@ class MxListEntry m_prev = p_prev; m_next = NULL; } + MxListEntry(T p_obj, MxListEntry *p_prev, MxListEntry *p_next) { + m_obj = p_obj; + m_prev = p_prev; + m_next = p_next; + } T GetValue() { return this->m_obj; } @@ -26,7 +30,6 @@ class MxListEntry MxListEntry *m_next; }; -// VTABLE 0x100d6350 // SIZE 0x10 template class MxListParent : public MxCore @@ -46,7 +49,6 @@ class MxListParent : public MxCore void (*m_customDestructor)(T); // +0xc }; -// VTABLE 0x100d6368 // SIZE 0x18 template class MxList : protected MxListParent @@ -60,6 +62,7 @@ class MxList : protected MxListParent virtual ~MxList(); void Append(T); + void OtherAppend(T p_obj) { _InsertEntry(p_obj, this->m_last, NULL); }; void DeleteAll(); MxU32 GetCount() { return m_count; } void SetDestroy(void (*p_customDestructor)(T)) { this->m_customDestructor = p_customDestructor; } @@ -71,9 +74,9 @@ class MxList : protected MxListParent private: void _DeleteEntry(MxListEntry *match); + void _InsertEntry(T, MxListEntry *, MxListEntry *); }; -// VTABLE 0x100d6488 template class MxListCursor : public MxCore { @@ -96,7 +99,6 @@ class MxListCursor : public MxCore }; // Unclear purpose -// VTABLE 0x100d6530 template class MxListCursorChild : public MxListCursor { @@ -105,7 +107,6 @@ class MxListCursorChild : public MxListCursor }; // Unclear purpose -// VTABLE 0x100d6470 template class MxListCursorChildChild : public MxListCursorChild { @@ -152,6 +153,24 @@ inline void MxList::Append(T p_newobj) this->m_count++; } +template +inline void MxList::_InsertEntry(T p_newobj, MxListEntry *p_prev, MxListEntry *p_next) +{ + MxListEntry *newEntry = new MxListEntry(p_newobj, p_prev, p_next); + + if (p_prev) + p_prev->m_next = newEntry; + else + this->m_first = newEntry; + + if (p_next) + p_next->m_prev = newEntry; + else + this->m_last = newEntry; + + this->m_count++; +} + template inline void MxList::_DeleteEntry(MxListEntry *match) { @@ -198,7 +217,7 @@ inline MxBool MxListCursor::Next(T& p_obj) m_match = m_match->m_next; if (m_match) - p_obj = m_match->m_obj; + p_obj = m_match->GetValue(); return m_match != NULL; } diff --git a/LEGO1/mxstring.cpp b/LEGO1/mxstring.cpp index e82d431a..fe221f94 100644 --- a/LEGO1/mxstring.cpp +++ b/LEGO1/mxstring.cpp @@ -56,14 +56,14 @@ void MxString::ToLowerCase() } // OFFSET: LEGO1 0x100ae4b0 -MxString &MxString::operator=(MxString *param) +MxString &MxString::operator=(MxString ¶m) { - if (this->m_data != param->m_data) + if (this->m_data != param.m_data) { delete[] this->m_data; - this->m_length = param->m_length; + this->m_length = param.m_length; this->m_data = new char[this->m_length + 1]; - strcpy(this->m_data, param->m_data); + strcpy(this->m_data, param.m_data); } return *this; diff --git a/LEGO1/mxstring.h b/LEGO1/mxstring.h index a24a0df1..ec20f879 100644 --- a/LEGO1/mxstring.h +++ b/LEGO1/mxstring.h @@ -15,7 +15,7 @@ class MxString : public MxCore MxString(const char *); void ToUpperCase(); void ToLowerCase(); - MxString& operator=(MxString *); + MxString& operator=(MxString &); MxString operator+(const char *); MxString& operator+=(const char *); diff --git a/LEGO1/mxstringlist.cpp b/LEGO1/mxstringlist.cpp new file mode 100644 index 00000000..8a0a2ddc --- /dev/null +++ b/LEGO1/mxstringlist.cpp @@ -0,0 +1,5 @@ +#include "mxstringlist.h" + +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxListEntry, 0x18) diff --git a/LEGO1/mxstringlist.h b/LEGO1/mxstringlist.h index dbf063f6..f92d2b7d 100644 --- a/LEGO1/mxstringlist.h +++ b/LEGO1/mxstringlist.h @@ -8,6 +8,9 @@ // SIZE 0x18 class MxStringList : public MxList {}; +// VTABLE 0x100dd058 +typedef MxListCursorChild MxStringListCursor; + // OFFSET: LEGO1 0x100cb3c0 TEMPLATE // MxListParent::Compare @@ -17,6 +20,15 @@ class MxStringList : public MxList {}; // OFFSET: LEGO1 0x100cb4c0 TEMPLATE // MxList::~MxList +// OFFSET: LEGO1 0x100cbb40 TEMPLATE +// MxList::OtherAppend + +// OFFSET: LEGO1 0x100cc2d0 TEMPLATE +// MxList::_InsertEntry + +// OFFSET: LEGO1 0x100cc3c0 TEMPLATE +// MxListEntry::MxListEntry + // OFFSET: LEGO1 0x100cc450 TEMPLATE // MxListEntry::GetValue