From d145f914c464a3b1892e6c4a70ceb12dadd3c91a Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 19 Sep 2023 23:00:34 -0400 Subject: [PATCH 01/11] Implement/match MxVideoManager::Tickle (#128) * Implement/match MxPresenter::StartAction * Update mxpoint32.h * Implement/match MxVideoManager::Tickle * Update mxlist.h * Update mxpresenter.cpp --- LEGO1/mxlist.h | 12 +++++- LEGO1/mxmediamanager.cpp | 4 +- LEGO1/mxmediamanager.h | 6 +-- LEGO1/mxpresenter.cpp | 10 ++--- LEGO1/mxpresenter.h | 8 ++-- LEGO1/mxpresenterlist.h | 2 + LEGO1/mxregion.h | 26 +++++++++++ LEGO1/mxvideomanager.cpp | 93 ++++++++++++++++++++++++++++++++-------- LEGO1/mxvideomanager.h | 9 ++-- 9 files changed, 133 insertions(+), 37 deletions(-) create mode 100644 LEGO1/mxregion.h diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index da2c3e4e..013ef852 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -59,6 +59,7 @@ class MxList : protected MxListParent virtual ~MxList(); void Append(T*); + MxU32 GetCount() { return m_count; } friend class MxListCursor; @@ -83,6 +84,8 @@ class MxListCursor : public MxCore MxBool Find(T *p_obj); void Detach(); MxBool Next(T*& p_obj); + void SetValue(T *p_obj); + void Head() { m_match = m_list->m_first; } void Reset() { m_match = NULL; } private: @@ -193,4 +196,11 @@ inline MxBool MxListCursor::Next(T*& p_obj) return m_match != NULL; } -#endif // MXLIST_H \ No newline at end of file +template +inline void MxListCursor::SetValue(T *p_obj) +{ + if (m_match) + m_match->m_obj = p_obj; +} + +#endif // MXLIST_H diff --git a/LEGO1/mxmediamanager.cpp b/LEGO1/mxmediamanager.cpp index b890eec4..3fb28d37 100644 --- a/LEGO1/mxmediamanager.cpp +++ b/LEGO1/mxmediamanager.cpp @@ -5,8 +5,6 @@ DECOMP_SIZE_ASSERT(MxMediaManager, 0x2c); -typedef MxListCursorChildChild MxPresenterListCursor; - // OFFSET: LEGO1 0x100b84c0 MxMediaManager::MxMediaManager() { @@ -40,7 +38,7 @@ MxResult MxMediaManager::Tickle() cursor.Reset(); while (cursor.Next(presenter)) - presenter->VTable0x4c(); + presenter->PutData(); return SUCCESS; } diff --git a/LEGO1/mxmediamanager.h b/LEGO1/mxmediamanager.h index 9df073bc..ccc3ec42 100644 --- a/LEGO1/mxmediamanager.h +++ b/LEGO1/mxmediamanager.h @@ -23,12 +23,10 @@ class MxMediaManager : public MxCore virtual void StopPresenters(); // vtable+24 MxResult Init(); - -private: - MxPresenterList *m_presenters; - MxThread *m_thread; // 0xc protected: + MxPresenterList *m_presenters; + MxThread *m_thread; // 0xc MxCriticalSection m_criticalSection; // 0x10 }; diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index cf934fe7..e82aa3a4 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -20,7 +20,7 @@ void MxPresenter::Init() m_currentTickleState = TickleState_Idle; m_action = NULL; m_location = MxPoint32(0, 0); - m_locationZ = 0; + m_displayZ = 0; m_unkPresenter = NULL; m_previousTickleStates = 0; } @@ -129,7 +129,7 @@ MxLong MxPresenter::StartAction(MxStreamController *, MxDSAction *p_action) MxS32 previousTickleState = this->m_currentTickleState; this->m_location = MxPoint32(location[0], location[1]); - this->m_locationZ = location[2]; + this->m_displayZ = location[2]; this->m_previousTickleStates |= 1 << (unsigned char)previousTickleState; this->m_currentTickleState = TickleState_Ready; @@ -236,13 +236,13 @@ MxBool MxPresenter::HasTickleStatePassed(TickleState p_tickleState) } // OFFSET: LEGO1 0x1000bfc0 -undefined4 MxPresenter::VTable0x4c() +undefined4 MxPresenter::PutData() { return 0; } // OFFSET: LEGO1 0x1000bfd0 -undefined MxPresenter::VTable0x50(undefined4, undefined4) +MxBool MxPresenter::IsHit(MxS32 p_x, MxS32 p_y) { - return 0; + return FALSE; } diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index f20ac647..b7e99edf 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -62,12 +62,14 @@ class MxPresenter : public MxCore __declspec(dllexport) virtual void EndAction(); // vtable+0x40 virtual void SetTickleState(TickleState p_tickleState); // vtable+0x44 virtual MxBool HasTickleStatePassed(TickleState p_tickleState); // vtable+0x48 - virtual undefined4 VTable0x4c(); // vtable+0x4c - virtual undefined VTable0x50(undefined4, undefined4); // vtable+0x50 + virtual undefined4 PutData(); // vtable+0x4c + virtual MxBool IsHit(MxS32 p_x, MxS32 p_y); // vtable+0x50 __declspec(dllexport) virtual void Enable(MxBool p_enable); // vtable+0x54 MxBool IsEnabled(); + inline MxS32 GetDisplayZ() { return this->m_displayZ; } + protected: __declspec(dllexport) void Init(); void SendTo_unkPresenter(MxOmni *); @@ -76,7 +78,7 @@ class MxPresenter : public MxCore MxS32 m_currentTickleState; // 0x8 MxU32 m_previousTickleStates; MxPoint32 m_location; - MxS32 m_locationZ; + MxS32 m_displayZ; MxDSAction *m_action; // 0 MxCriticalSection m_criticalSection; MxPresenter *m_unkPresenter; // 0x3c diff --git a/LEGO1/mxpresenterlist.h b/LEGO1/mxpresenterlist.h index 9373040d..5b36e2d8 100644 --- a/LEGO1/mxpresenterlist.h +++ b/LEGO1/mxpresenterlist.h @@ -24,4 +24,6 @@ class MxPresenterList : public MxPresenterListParent virtual MxS8 Compare(MxPresenter *, MxPresenter *); // +0x14 }; +typedef MxListCursorChildChild MxPresenterListCursor; + #endif // MXPRESENTERLIST_H diff --git a/LEGO1/mxregion.h b/LEGO1/mxregion.h new file mode 100644 index 00000000..717be924 --- /dev/null +++ b/LEGO1/mxregion.h @@ -0,0 +1,26 @@ +#ifndef MXREGION_H +#define MXREGION_H + +#include "mxcore.h" + +// VTABLE 0x100dcae8 +// SIZE 0x1c +class MxRegion : public MxCore +{ +public: + MxRegion(); + virtual ~MxRegion() override; + + virtual void Reset(); + virtual void vtable18(); + virtual void vtable1c(); + virtual void vtable20(); + +private: + // A container (probably MxList) holding MxRect32 + // MxList *m_rects; + // 4 coordinates (could be MxRect32) + // MxS32 left, top, right, bottom; +}; + +#endif // MXREGION_H diff --git a/LEGO1/mxvideomanager.cpp b/LEGO1/mxvideomanager.cpp index 7663743d..81d431a9 100644 --- a/LEGO1/mxvideomanager.cpp +++ b/LEGO1/mxvideomanager.cpp @@ -1,18 +1,6 @@ #include "mxvideomanager.h" - -// OFFSET: LEGO1 0x100be2a0 STUB -MxVideoManager::~MxVideoManager() -{ - // TODO -} - -// OFFSET: LEGO1 0x100bea90 STUB -MxLong MxVideoManager::Tickle() -{ - // TODO - - return 0; -} +#include "mxautolocker.h" +#include "mxpresenter.h" // OFFSET: LEGO1 0x100be1f0 MxVideoManager::MxVideoManager() @@ -20,16 +8,85 @@ MxVideoManager::MxVideoManager() Init(); } +// OFFSET: LEGO1 0x100be2a0 STUB +MxVideoManager::~MxVideoManager() +{ + // TODO +} + +// OFFSET: LEGO1 0x100bea90 +MxLong MxVideoManager::Tickle() +{ + MxAutoLocker lock(&this->m_criticalSection); + + SortPresenterList(); + + MxPresenter *presenter; + MxPresenterListCursor cursor(this->m_presenters); + + while (cursor.Next(presenter)) + presenter->Tickle(); + + cursor.Reset(); + + while (cursor.Next(presenter)) + presenter->PutData(); + + UpdateRegion(); + m_region->Reset(); + + return SUCCESS; +} + // OFFSET: LEGO1 0x100be320 -int MxVideoManager::Init() +MxResult MxVideoManager::Init() { this->m_pDirectDraw = NULL; - this->m_unk54 = NULL; + this->m_pDDSurface = NULL; this->m_displaySurface = NULL; - this->m_unk5c = 0; + this->m_region = NULL; this->m_videoParam.SetPalette(NULL); this->m_unk60 = FALSE; - return 0; + return SUCCESS; +} + +// OFFSET: LEGO1 0x100be440 +void MxVideoManager::SortPresenterList() +{ + if (this->m_presenters->GetCount() <= 1) + return; + + MxPresenterListCursor a(this->m_presenters); + MxPresenterListCursor b(this->m_presenters); + MxU32 count = this->m_presenters->GetCount() - 1; + MxBool finished; + + if (count != 0) { + do { + a.Reset(); + b.Head(); + + finished = TRUE; + for (MxU32 i = count; i != 0; i--) { + MxPresenter *p_a, *p_b; + + a.Next(p_a); + b.Next(p_b); + + if (p_a->GetDisplayZ() < p_b->GetDisplayZ()) { + a.SetValue(p_b); + b.SetValue(p_a); + finished = FALSE; + } + } + } while (!finished && --count != 0); + } +} + +// OFFSET: LEGO1 0x100be3e0 STUB +void MxVideoManager::UpdateRegion() +{ + // TODO } // OFFSET: LEGO1 0x100bea60 STUB diff --git a/LEGO1/mxvideomanager.h b/LEGO1/mxvideomanager.h index 03eac8aa..a7cde92f 100644 --- a/LEGO1/mxvideomanager.h +++ b/LEGO1/mxvideomanager.h @@ -2,6 +2,7 @@ #define MXVIDEOMANAGER_H #include "mxdisplaysurface.h" +#include "mxregion.h" #include "mxmediamanager.h" #include "mxvideoparam.h" @@ -19,16 +20,18 @@ class MxVideoManager : public MxMediaManager MxVideoManager(); - int Init(); + MxResult Init(); + void SortPresenterList(); + void UpdateRegion(); inline MxVideoParam& GetVideoParam() { return this->m_videoParam; } inline LPDIRECTDRAW GetDirectDraw() { return this->m_pDirectDraw; } private: MxVideoParam m_videoParam; LPDIRECTDRAW m_pDirectDraw; - LPDIRECTDRAWSURFACE m_unk54; + LPDIRECTDRAWSURFACE m_pDDSurface; MxDisplaySurface *m_displaySurface; - int m_unk5c; + MxRegion *m_region; MxBool m_unk60; }; From 1d3c1bdbd147ef1ec68ed1e096645c98f90745fe Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Wed, 20 Sep 2023 07:48:46 -0400 Subject: [PATCH 02/11] MxFlcPresenter ctor/dtor (#132) * MxFlcPresenter ctor/dtor * Match constructor --------- Co-authored-by: Christian Semmler --- LEGO1/mxflcpresenter.cpp | 12 ++++++++---- LEGO1/mxflcpresenter.h | 2 +- LEGO1/mxvideopresenter.h | 2 +- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/LEGO1/mxflcpresenter.cpp b/LEGO1/mxflcpresenter.cpp index 8bd23d22..79c1ae49 100644 --- a/LEGO1/mxflcpresenter.cpp +++ b/LEGO1/mxflcpresenter.cpp @@ -4,14 +4,18 @@ DECOMP_SIZE_ASSERT(MxFlcPresenter, 0x68); -// OFFSET: LEGO1 0x100b3310 STUB +// OFFSET: LEGO1 0x100b3310 MxFlcPresenter::MxFlcPresenter() { - // TODO + this->m_unk64 = 0; + this->m_flags &= 0xfd; + this->m_flags &= 0xfb; } -// OFFSET: LEGO1 0x100b3420 STUB +// OFFSET: LEGO1 0x100b3420 MxFlcPresenter::~MxFlcPresenter() { - // TODO + if (this->m_unk64) { + delete this->m_unk64; + } } diff --git a/LEGO1/mxflcpresenter.h b/LEGO1/mxflcpresenter.h index bc34ff12..19535bcd 100644 --- a/LEGO1/mxflcpresenter.h +++ b/LEGO1/mxflcpresenter.h @@ -26,7 +26,7 @@ class MxFlcPresenter : public MxVideoPresenter return !strcmp(name, MxFlcPresenter::ClassName()) || MxVideoPresenter::IsA(name); } - undefined4 m_unk64; + undefined4 *m_unk64; }; #endif // MXFLCPRESENTER_H diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h index 19c211c3..bc5fac5c 100644 --- a/LEGO1/mxvideopresenter.h +++ b/LEGO1/mxvideopresenter.h @@ -32,7 +32,7 @@ class MxVideoPresenter : public MxMediaPresenter undefined4 m_unk54; undefined4 m_unk58; undefined2 m_unk5c; - unsigned char m_flags; + unsigned char m_flags; // 0x5e undefined4 m_unk60; }; From b743f99d2080792468c35f8854e294269cc9b050 Mon Sep 17 00:00:00 2001 From: MS Date: Wed, 20 Sep 2023 16:22:57 -0400 Subject: [PATCH 03/11] LegoOmni::CreateStreamObject and related (#129) * LegoOmni::CreateStreamObject and related * Revert change to MxDSSource/MxDSFile Read export --- LEGO1/legoomni.cpp | 36 +++++++++++++++++-- LEGO1/mxdsfile.cpp | 16 ++++----- LEGO1/mxdsfile.h | 3 +- LEGO1/mxdsmultiaction.cpp | 2 ++ LEGO1/mxdsmultiaction.h | 4 +++ LEGO1/mxdsobject.cpp | 70 ++++++++++++++++++++++++++++++++++++ LEGO1/mxdsobject.h | 2 ++ LEGO1/mxdsparallelaction.cpp | 2 ++ LEGO1/mxdsselectaction.cpp | 2 ++ LEGO1/mxdsselectaction.h | 7 ++++ LEGO1/mxdsserialaction.cpp | 2 ++ LEGO1/mxdsserialaction.h | 5 +++ LEGO1/mxdssource.cpp | 6 ++++ LEGO1/mxdssource.h | 3 +- 14 files changed, 147 insertions(+), 13 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index e5574058..cda6d9ff 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -1,5 +1,7 @@ #include "legoomni.h" +#include "mxdsobject.h" + // 0x100f4588 char *g_nocdSourceName = NULL; @@ -147,10 +149,38 @@ MxBackgroundAudioManager *BackgroundAudioManager() return LegoOmni::GetInstance()->GetBackgroundAudioManager(); } -// OFFSET: LEGO1 0x100c0280 STUB -MxDSObject *CreateStreamObject(MxDSFile *,MxS16) +// OFFSET: LEGO1 0x100c0280 +MxDSObject *CreateStreamObject(MxDSFile *p_file, MxS16 p_ofs) { - // TODO + char *buf; + _MMCKINFO tmp_chunk; + + if (p_file->Seek(((MxLong*)p_file->GetBuffer())[p_ofs], 0)) { + return NULL; + } + + if (p_file->Read((MxU8*)&tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'S', 't')) { + if (p_file->Read((MxU8*)&tmp_chunk.ckid, 8) == 0 && tmp_chunk.ckid == FOURCC('M', 'x', 'O', 'b')) { + + buf = new char[tmp_chunk.cksize]; + if (!buf) { + return NULL; + } + + if (p_file->Read((MxU8*)buf, tmp_chunk.cksize) != 0) { + return NULL; + } + + // Save a copy so we can clean up properly, because + // this function will alter the pointer value. + char *copy = buf; + MxDSObject *obj = DeserializeDSObjectDispatch(&buf, -1); + delete[] copy; + return obj; + } + return NULL; + } + return NULL; } diff --git a/LEGO1/mxdsfile.cpp b/LEGO1/mxdsfile.cpp index 8bccf914..ca6e96fb 100644 --- a/LEGO1/mxdsfile.cpp +++ b/LEGO1/mxdsfile.cpp @@ -47,13 +47,13 @@ MxLong MxDSFile::Open(MxULong uStyle) } // OFFSET: LEGO1 0x100cc780 -MxLong MxDSFile::Read(unsigned char *pch, MxULong cch) +MxResult MxDSFile::Read(unsigned char *p_buf, MxULong p_nbytes) { - if (m_io.Read((char*)pch, cch) != cch) - return -1; + if (m_io.Read(p_buf, p_nbytes) != p_nbytes) + return FAILURE; - m_position += cch; - return 0; + m_position += p_nbytes; + return SUCCESS; } // OFFSET: LEGO1 0x100cc620 @@ -72,7 +72,7 @@ MxLong MxDSFile::ReadChunks() return -1; } - m_io.Read((char*)&m_header, 0xc); + m_io.Read(&m_header, 0xc); if ((m_header.majorVersion == SI_MAJOR_VERSION) && (m_header.minorVersion == SI_MINOR_VERSION)) { childChunk.ckid = FOURCC('M', 'x', 'O', 'f'); @@ -80,9 +80,9 @@ MxLong MxDSFile::ReadChunks() return -1; } MxULong* pLengthInDWords = &m_lengthInDWords; - m_io.Read((char *)pLengthInDWords, 4); + m_io.Read(pLengthInDWords, 4); m_pBuffer = malloc(*pLengthInDWords * 4); - m_io.Read((char*)m_pBuffer, *pLengthInDWords * 4); + m_io.Read(m_pBuffer, *pLengthInDWords * 4); return 0; } else diff --git a/LEGO1/mxdsfile.h b/LEGO1/mxdsfile.h index ac812df7..d46a6153 100644 --- a/LEGO1/mxdsfile.h +++ b/LEGO1/mxdsfile.h @@ -4,6 +4,7 @@ #include "mxdssource.h" #include "mxioinfo.h" #include "mxstring.h" +#include "mxtypes.h" // VTABLE 0x100dc890 class MxDSFile : public MxDSSource @@ -27,7 +28,7 @@ class MxDSFile : public MxDSSource __declspec(dllexport) virtual MxLong Open(MxULong); // vtable+0x14 __declspec(dllexport) virtual MxLong Close(); // vtable+0x18 - __declspec(dllexport) virtual MxLong Read(unsigned char *,MxULong); // vtable+0x20 + __declspec(dllexport) virtual MxResult Read(unsigned char *,MxULong); // vtable+0x20 __declspec(dllexport) virtual MxLong Seek(MxLong,int); // vtable+0x24 __declspec(dllexport) virtual MxULong GetBufferSize(); // vtable+0x28 __declspec(dllexport) virtual MxULong GetStreamBuffersNum(); // vtable+0x2c diff --git a/LEGO1/mxdsmultiaction.cpp b/LEGO1/mxdsmultiaction.cpp index 4188fb66..0328a5fd 100644 --- a/LEGO1/mxdsmultiaction.cpp +++ b/LEGO1/mxdsmultiaction.cpp @@ -1,5 +1,7 @@ #include "mxdsmultiaction.h" +DECOMP_SIZE_ASSERT(MxDSMultiAction, 0x9c) + // OFFSET: LEGO1 0x100c9b90 MxDSMultiAction::MxDSMultiAction() { diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index af3d69df..6e049965 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -2,6 +2,7 @@ #define MXDSMULTIACTION_H #include "mxdsaction.h" +#include "decomp.h" // VTABLE 0x100dcef0 // SIZE 0x9c @@ -23,6 +24,9 @@ class MxDSMultiAction : public MxDSAction { return !strcmp(name, MxDSMultiAction::ClassName()) || MxDSAction::IsA(name); } + + undefined4 m_unk0x94; + undefined4 m_unk0x98; }; #endif // MXDSMULTIACTION_H diff --git a/LEGO1/mxdsobject.cpp b/LEGO1/mxdsobject.cpp index 57663cee..2b7d8437 100644 --- a/LEGO1/mxdsobject.cpp +++ b/LEGO1/mxdsobject.cpp @@ -3,6 +3,19 @@ #include #include +#include "mxdstypes.h" +#include "mxdsaction.h" +#include "mxdsmediaaction.h" +#include "mxdsanim.h" +#include "mxdssound.h" +#include "mxdsmultiaction.h" +#include "mxdsserialaction.h" +#include "mxdsparallelaction.h" +#include "mxdsevent.h" +#include "mxdsselectaction.h" +#include "mxdsstill.h" +#include "mxdsobjectaction.h" + DECOMP_SIZE_ASSERT(MxDSObject, 0x2c); // OFFSET: LEGO1 0x100bf6a0 @@ -127,3 +140,60 @@ void MxDSObject::Deserialize(char **p_source, MxS16 p_unk24) this->m_unk24 = p_unk24; } + + +// OFFSET: LEGO1 0x100bfb30 +MxDSObject *DeserializeDSObjectDispatch(char **p_source, MxS16 p_flags) +{ + MxU16 type = *(MxU16*) *p_source; + *p_source += 2; + + MxDSObject *obj = NULL; + + switch (type) { + default: + return NULL; + case MxDSType_Object: + obj = new MxDSObject(); + break; + case MxDSType_Action: + obj = new MxDSAction(); + break; + case MxDSType_MediaAction: + obj = new MxDSMediaAction(); + break; + case MxDSType_Anim: + obj = new MxDSAnim(); + break; + case MxDSType_Sound: + obj = new MxDSSound(); + break; + case MxDSType_MultiAction: + obj = new MxDSMultiAction(); + break; + case MxDSType_SerialAction: + obj = new MxDSSerialAction(); + break; + case MxDSType_ParallelAction: + obj = new MxDSParallelAction(); + break; + case MxDSType_Event: + obj = new MxDSEvent(); + break; + case MxDSType_SelectAction: + obj = new MxDSSelectAction(); + break; + case MxDSType_Still: + obj = new MxDSStill(); + break; + case MxDSType_ObjectAction: + obj = new MxDSObjectAction(); + break; + } + + if (obj) { + obj->Deserialize(p_source, p_flags); + } + + return obj; +} \ No newline at end of file diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index c46ee609..0b247a6a 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -56,4 +56,6 @@ class MxDSObject : public MxCore undefined4 m_unk28; }; +MxDSObject *DeserializeDSObjectDispatch(char **, MxS16); + #endif // MXDSOBJECT_H diff --git a/LEGO1/mxdsparallelaction.cpp b/LEGO1/mxdsparallelaction.cpp index 97a8a9d3..2e0d66da 100644 --- a/LEGO1/mxdsparallelaction.cpp +++ b/LEGO1/mxdsparallelaction.cpp @@ -1,5 +1,7 @@ #include "mxdsparallelaction.h" +DECOMP_SIZE_ASSERT(MxDSParallelAction, 0x9c) + // OFFSET: LEGO1 0x100cae80 MxDSParallelAction::MxDSParallelAction() { diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 5cae82fb..1c21b466 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -1,5 +1,7 @@ #include "mxdsselectaction.h" +DECOMP_SIZE_ASSERT(MxDSSelectAction, 0xb0) + // OFFSET: LEGO1 0x100cb2b0 MxDSSelectAction::MxDSSelectAction() { diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index cb5374e1..df956fbc 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -2,6 +2,7 @@ #define MXDSSELECTACTION_H #include "mxdsparallelaction.h" +#include "decomp.h" // VTABLE 0x100dcfc8 // SIZE 0xb0 @@ -24,6 +25,12 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } + undefined4 m_unk0x9c; + undefined4 m_unk0xa0; + undefined4 m_unk0xa4; + undefined4 m_unk0xa8; + undefined4 m_unk0xac; + }; #endif // MXDSSELECTACTION_H diff --git a/LEGO1/mxdsserialaction.cpp b/LEGO1/mxdsserialaction.cpp index 46964208..c6aa541f 100644 --- a/LEGO1/mxdsserialaction.cpp +++ b/LEGO1/mxdsserialaction.cpp @@ -1,5 +1,7 @@ #include "mxdsserialaction.h" +DECOMP_SIZE_ASSERT(MxDSSerialAction, 0xa8) + // OFFSET: LEGO1 0x100ca9d0 MxDSSerialAction::MxDSSerialAction() { diff --git a/LEGO1/mxdsserialaction.h b/LEGO1/mxdsserialaction.h index 2b260556..6bf30c0f 100644 --- a/LEGO1/mxdsserialaction.h +++ b/LEGO1/mxdsserialaction.h @@ -2,6 +2,7 @@ #define MXDSSERIALACTION_H #include "mxdsmultiaction.h" +#include "decomp.h" // VTABLE 0x100dcf38 // SIZE 0xa8 @@ -23,6 +24,10 @@ class MxDSSerialAction : public MxDSMultiAction { return !strcmp(name, MxDSSerialAction::ClassName()) || MxDSMultiAction::IsA(name); } + + undefined4 m_unk0x9c; + undefined4 m_unk0xa0; + undefined4 m_unk0xa4; }; #endif // MXDSSERIALACTION_H diff --git a/LEGO1/mxdssource.cpp b/LEGO1/mxdssource.cpp index 9a94f110..4dfb5386 100644 --- a/LEGO1/mxdssource.cpp +++ b/LEGO1/mxdssource.cpp @@ -11,4 +11,10 @@ void MxDSSource::SomethingWhichCallsRead(void* pUnknownObject) MxLong MxDSSource::GetLengthInDWords() { return m_lengthInDWords; +} + +// OFFSET: LEGO1 0x100c0000 +void *MxDSSource::GetBuffer() +{ + return m_pBuffer; } \ No newline at end of file diff --git a/LEGO1/mxdssource.h b/LEGO1/mxdssource.h index 5ff4c33c..67cbc6c7 100644 --- a/LEGO1/mxdssource.h +++ b/LEGO1/mxdssource.h @@ -29,11 +29,12 @@ class MxDSSource : public MxCore virtual MxLong Open(MxULong) = 0; virtual MxLong Close() = 0; virtual void SomethingWhichCallsRead(void* pUnknownObject); - virtual MxLong Read(unsigned char *, MxULong) = 0; + virtual MxResult Read(unsigned char *, MxULong) = 0; virtual MxLong Seek(MxLong, int) = 0; virtual MxULong GetBufferSize() = 0; virtual MxULong GetStreamBuffersNum() = 0; virtual MxLong GetLengthInDWords(); + virtual void* GetBuffer(); // 0x34 protected: MxULong m_lengthInDWords; From 99c27a6a50fa62773d8249ca51a79afeadfcbd39 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 20 Sep 2023 16:36:15 -0400 Subject: [PATCH 04/11] Bootstrap MxDSMultiAction (#133) * Bootstrap MxDSMultiAction * Move destroy function to list class * Fix unk14 call --- CMakeLists.txt | 1 + LEGO1/mxdsactionlist.cpp | 21 +++++++++++++++++++++ LEGO1/mxdsactionlist.h | 28 ++++++++++++++++++++++++++++ LEGO1/mxdsmultiaction.cpp | 36 +++++++++++++++++++++++++++++++++--- LEGO1/mxdsmultiaction.h | 10 +++++++--- LEGO1/mxlist.h | 1 + 6 files changed, 91 insertions(+), 6 deletions(-) create mode 100644 LEGO1/mxdsactionlist.cpp create mode 100644 LEGO1/mxdsactionlist.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 3a47fc78..d96b0c61 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -109,6 +109,7 @@ add_library(lego1 SHARED LEGO1/mxdiskstreamprovider.cpp LEGO1/mxdisplaysurface.cpp LEGO1/mxdsaction.cpp + LEGO1/mxdsactionlist.cpp LEGO1/mxdsanim.cpp LEGO1/mxdschunk.cpp LEGO1/mxdsevent.cpp diff --git a/LEGO1/mxdsactionlist.cpp b/LEGO1/mxdsactionlist.cpp new file mode 100644 index 00000000..86c75365 --- /dev/null +++ b/LEGO1/mxdsactionlist.cpp @@ -0,0 +1,21 @@ +#include "mxdsactionlist.h" +#include "mxdsaction.h" + +DECOMP_SIZE_ASSERT(MxDSActionList, 0x1c); + +// OFFSET: LEGO1 0x100c9c90 +MxS8 MxDSActionList::Compare(MxDSAction *p_var0, MxDSAction *p_var1) +{ + if (p_var1 == p_var0) + return 0; + if (p_var1 <= p_var0) + return 1; + return -1; +} + +// OFFSET: LEGO1 0x100c9cb0 +void MxDSActionList::Destroy(MxDSAction *p_action) +{ + if (p_action) + delete p_action; +} \ No newline at end of file diff --git a/LEGO1/mxdsactionlist.h b/LEGO1/mxdsactionlist.h new file mode 100644 index 00000000..4ae6e2a6 --- /dev/null +++ b/LEGO1/mxdsactionlist.h @@ -0,0 +1,28 @@ +#ifndef MXDSACTIONLIST_H +#define MXDSACTIONLIST_H + +#include "decomp.h" +#include "mxlist.h" + +class MxDSAction; + +// VTABLE 0x100dced8 +// SIZE 0x1c +class MxDSActionList : public MxList +{ +public: + MxDSActionList() { + this->m_unk18 = 0; + } + + virtual MxS8 Compare(MxDSAction *, MxDSAction *); // +0x14 + + static void Destroy(MxDSAction *p_action); + +private: + undefined m_unk18; +}; + +typedef MxListCursorChild MxDSActionListCursor; + +#endif // MXDSACTIONLIST_H diff --git a/LEGO1/mxdsmultiaction.cpp b/LEGO1/mxdsmultiaction.cpp index 0328a5fd..6cbccc39 100644 --- a/LEGO1/mxdsmultiaction.cpp +++ b/LEGO1/mxdsmultiaction.cpp @@ -5,12 +5,42 @@ DECOMP_SIZE_ASSERT(MxDSMultiAction, 0x9c) // OFFSET: LEGO1 0x100c9b90 MxDSMultiAction::MxDSMultiAction() { - // TODO this->SetType(MxDSType_MultiAction); + this->m_actions = new MxDSActionList; + this->m_actions->SetDestroy(MxDSActionList::Destroy); } -// OFFSET: LEGO1 0x100ca060 STUB +// OFFSET: LEGO1 0x100ca060 MxDSMultiAction::~MxDSMultiAction() { - // TODO + if (this->m_actions) + delete this->m_actions; } + +// OFFSET: LEGO1 0x100ca5e0 +undefined4 MxDSMultiAction::unk14() +{ + undefined4 result = MxDSAction::unk14(); + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + result += action->unk14(); + + return result; +} + +// OFFSET: LEGO1 0x100ca6c0 +MxU32 MxDSMultiAction::GetSizeOnDisk() +{ + MxU32 totalSizeOnDisk = MxDSAction::GetSizeOnDisk() + 16; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + while (cursor.Next(action)) + totalSizeOnDisk += action->GetSizeOnDisk(); + + this->m_sizeOnDisk = totalSizeOnDisk - MxDSAction::GetSizeOnDisk(); + + return totalSizeOnDisk; +} \ No newline at end of file diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 6e049965..7d4312f4 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -2,7 +2,7 @@ #define MXDSMULTIACTION_H #include "mxdsaction.h" -#include "decomp.h" +#include "mxdsactionlist.h" // VTABLE 0x100dcef0 // SIZE 0x9c @@ -25,8 +25,12 @@ class MxDSMultiAction : public MxDSAction return !strcmp(name, MxDSMultiAction::ClassName()) || MxDSAction::IsA(name); } - undefined4 m_unk0x94; - undefined4 m_unk0x98; + virtual undefined4 unk14(); // vtable+14; + virtual MxU32 GetSizeOnDisk(); // vtable+18; + +private: + MxU32 m_sizeOnDisk; + MxDSActionList *m_actions; }; #endif // MXDSMULTIACTION_H diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 013ef852..a4231c92 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -60,6 +60,7 @@ class MxList : protected MxListParent void Append(T*); MxU32 GetCount() { return m_count; } + void SetDestroy(void (*p_customDestructor)(T *)) { this->m_customDestructor = p_customDestructor; } friend class MxListCursor; From 611afb779984306116788b04cdb061e2af0f9b70 Mon Sep 17 00:00:00 2001 From: MS Date: Thu, 21 Sep 2023 05:27:27 -0400 Subject: [PATCH 05/11] Quick patch for EqualsDataProduct (#134) --- LEGO1/mxmatrix.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/LEGO1/mxmatrix.cpp b/LEGO1/mxmatrix.cpp index 534db6a9..1cc3c550 100644 --- a/LEGO1/mxmatrix.cpp +++ b/LEGO1/mxmatrix.cpp @@ -111,21 +111,20 @@ void MxMatrix::EqualsMxProduct(const MxMatrix *p_a, const MxMatrix *p_b) EqualsDataProduct(p_a->m_data, p_b->m_data); } -// Just a placeholder matrix multiply implementation. I think the decomp will -// look roughly like this but it's not close to matching and won't be until -// an exact match is found given it's all loop and float crunching. -// OFFSET: LEGO1 0x100024d0 STUB +// OFFSET: LEGO1 0x100024d0 void MxMatrix::EqualsDataProduct(const float *p_a, const float *p_b) { + float *cur = m_data; for (int row = 0; row < 4; ++row) { for (int col = 0; col < 4; ++col) { - m_data[row * 4 + col] = 0.0f; + *cur = 0.0f; for (int k = 0; k < 4; ++k) { - m_data[row * 4 + col] += p_a[row * 4 + k] * p_b[k * 4 + col]; + *cur += p_a[row * 4 + k] * p_b[k * 4 + col]; } + cur++; } } } From b4258da0f5ff9a08ff9211b1169e431d94471f74 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Thu, 21 Sep 2023 14:51:24 -0400 Subject: [PATCH 06/11] MxLong Tickle() -> MxResult Tickle() (#135) * MxLong Tickle() -> MxResult Tickle() * Remove garbage * Fix implementations --- LEGO1/act2brick.cpp | 2 +- LEGO1/act2brick.h | 2 +- LEGO1/gasstation.cpp | 2 +- LEGO1/gasstation.h | 2 +- LEGO1/infocenter.cpp | 2 +- LEGO1/infocenter.h | 2 +- LEGO1/legoanimationmanager.cpp | 2 +- LEGO1/legoanimationmanager.h | 2 +- LEGO1/legocarbuild.cpp | 2 +- LEGO1/legocarbuild.h | 2 +- LEGO1/legocontrolmanager.cpp | 2 +- LEGO1/legocontrolmanager.h | 2 +- LEGO1/legoinputmanager.cpp | 2 +- LEGO1/legoinputmanager.h | 2 +- LEGO1/legopathcontroller.cpp | 2 +- LEGO1/legopathcontroller.h | 2 +- LEGO1/legoplantmanager.cpp | 2 +- LEGO1/legoplantmanager.h | 2 +- LEGO1/legosoundmanager.cpp | 2 +- LEGO1/legosoundmanager.h | 2 +- LEGO1/mxcore.cpp | 2 +- LEGO1/mxdiskstreamcontroller.cpp | 2 +- LEGO1/mxdiskstreamcontroller.h | 2 +- LEGO1/mxmediapresenter.cpp | 2 +- LEGO1/mxmediapresenter.h | 2 +- LEGO1/mxpresenter.cpp | 2 +- LEGO1/mxpresenter.h | 2 +- LEGO1/mxtransitionmanager.cpp | 2 +- LEGO1/mxtransitionmanager.h | 2 +- LEGO1/mxvideomanager.cpp | 2 +- LEGO1/mxvideomanager.h | 2 +- 31 files changed, 31 insertions(+), 31 deletions(-) diff --git a/LEGO1/act2brick.cpp b/LEGO1/act2brick.cpp index 84c8bbb3..dde79d0b 100644 --- a/LEGO1/act2brick.cpp +++ b/LEGO1/act2brick.cpp @@ -21,7 +21,7 @@ MxLong Act2Brick::Notify(MxParam &p) } // OFFSET: LEGO1 0x1007a7f0 STUB -MxLong Act2Brick::Tickle() +MxResult Act2Brick::Tickle() { // TODO diff --git a/LEGO1/act2brick.h b/LEGO1/act2brick.h index bf909198..65aba252 100644 --- a/LEGO1/act2brick.h +++ b/LEGO1/act2brick.h @@ -12,7 +12,7 @@ class Act2Brick : public LegoPathActor virtual ~Act2Brick() override; // vtable+0x0 virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x08 + virtual MxResult Tickle() override; // vtable+0x08 // OFFSET: LEGO1 0x1007a360 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/gasstation.cpp b/LEGO1/gasstation.cpp index 33590dc9..eb178ef0 100644 --- a/LEGO1/gasstation.cpp +++ b/LEGO1/gasstation.cpp @@ -21,7 +21,7 @@ MxLong GasStation::Notify(MxParam &p) } // OFFSET: LEGO1 0x10005c90 STUB -MxLong GasStation::Tickle() +MxResult GasStation::Tickle() { // TODO diff --git a/LEGO1/gasstation.h b/LEGO1/gasstation.h index 7f2263d0..e88c028a 100644 --- a/LEGO1/gasstation.h +++ b/LEGO1/gasstation.h @@ -13,7 +13,7 @@ class GasStation : public LegoWorld virtual ~GasStation() override; // vtable+0x0 virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x10004780 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/infocenter.cpp b/LEGO1/infocenter.cpp index b9ea67c6..eb7e65fc 100644 --- a/LEGO1/infocenter.cpp +++ b/LEGO1/infocenter.cpp @@ -21,7 +21,7 @@ MxLong Infocenter::Notify(MxParam &p) } // OFFSET: LEGO1 0x10070af0 STUB -MxLong Infocenter::Tickle() +MxResult Infocenter::Tickle() { // TODO diff --git a/LEGO1/infocenter.h b/LEGO1/infocenter.h index a6e06f0f..1d385993 100644 --- a/LEGO1/infocenter.h +++ b/LEGO1/infocenter.h @@ -12,7 +12,7 @@ class Infocenter : public LegoWorld virtual ~Infocenter() override; virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x1006eb40 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/legoanimationmanager.cpp b/LEGO1/legoanimationmanager.cpp index d396d431..20e0a0e3 100644 --- a/LEGO1/legoanimationmanager.cpp +++ b/LEGO1/legoanimationmanager.cpp @@ -23,7 +23,7 @@ MxLong LegoAnimationManager::Notify(MxParam &p) } // OFFSET: LEGO1 0x10061cc0 STUB -MxLong LegoAnimationManager::Tickle() +MxResult LegoAnimationManager::Tickle() { // TODO diff --git a/LEGO1/legoanimationmanager.h b/LEGO1/legoanimationmanager.h index 49b95f94..ec07603d 100644 --- a/LEGO1/legoanimationmanager.h +++ b/LEGO1/legoanimationmanager.h @@ -12,7 +12,7 @@ class LegoAnimationManager : public MxCore virtual ~LegoAnimationManager() override; // vtable+0x0 virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x1005ec80 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/legocarbuild.cpp b/LEGO1/legocarbuild.cpp index c9254c37..e204529b 100644 --- a/LEGO1/legocarbuild.cpp +++ b/LEGO1/legocarbuild.cpp @@ -21,7 +21,7 @@ MxLong LegoCarBuild::Notify(MxParam &p) } // OFFSET: LEGO1 0x100238b0 STUB -MxLong LegoCarBuild::Tickle() +MxResult LegoCarBuild::Tickle() { // TODO diff --git a/LEGO1/legocarbuild.h b/LEGO1/legocarbuild.h index d320cd6e..1d68b0c1 100644 --- a/LEGO1/legocarbuild.h +++ b/LEGO1/legocarbuild.h @@ -12,7 +12,7 @@ class LegoCarBuild : public LegoWorld virtual ~LegoCarBuild() override; virtual MxLong Notify(MxParam &p) override; // vtable+0x4 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x10022940 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/legocontrolmanager.cpp b/LEGO1/legocontrolmanager.cpp index 16733e13..91ff8c39 100644 --- a/LEGO1/legocontrolmanager.cpp +++ b/LEGO1/legocontrolmanager.cpp @@ -13,7 +13,7 @@ LegoControlManager::~LegoControlManager() } // OFFSET: LEGO1 0x10029600 STUB -MxLong LegoControlManager::Tickle() +MxResult LegoControlManager::Tickle() { // TODO diff --git a/LEGO1/legocontrolmanager.h b/LEGO1/legocontrolmanager.h index c4563776..0088ac0f 100644 --- a/LEGO1/legocontrolmanager.h +++ b/LEGO1/legocontrolmanager.h @@ -10,7 +10,7 @@ class LegoControlManager : public MxCore LegoControlManager(); virtual ~LegoControlManager() override; // vtable+0x0 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x10028cb0 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 90be0c2c..7c6489ee 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -35,7 +35,7 @@ void LegoInputManager::UnRegister(MxCore *) } // OFFSET: LEGO1 0x1005b8b0 STUB -MxLong LegoInputManager::Tickle() +MxResult LegoInputManager::Tickle() { // TODO diff --git a/LEGO1/legoinputmanager.h b/LEGO1/legoinputmanager.h index 7ae2dd62..3a35d4b1 100644 --- a/LEGO1/legoinputmanager.h +++ b/LEGO1/legoinputmanager.h @@ -26,7 +26,7 @@ class LegoInputManager : public MxPresenter __declspec(dllexport) void Register(MxCore *); __declspec(dllexport) void UnRegister(MxCore *); - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 undefined m_pad40[0x15c]; int m_joystickIndex; diff --git a/LEGO1/legopathcontroller.cpp b/LEGO1/legopathcontroller.cpp index 0cebbc0f..f8b64109 100644 --- a/LEGO1/legopathcontroller.cpp +++ b/LEGO1/legopathcontroller.cpp @@ -13,7 +13,7 @@ LegoPathController::~LegoPathController() } // OFFSET: LEGO1 0x10045c10 STUB -MxLong LegoPathController::Tickle() +MxResult LegoPathController::Tickle() { // TODO return 0; diff --git a/LEGO1/legopathcontroller.h b/LEGO1/legopathcontroller.h index ba415076..61dbdcfe 100644 --- a/LEGO1/legopathcontroller.h +++ b/LEGO1/legopathcontroller.h @@ -11,7 +11,7 @@ class LegoPathController : public MxCore LegoPathController(); virtual ~LegoPathController() override; - virtual MxLong Tickle() override; // vtable+08 + virtual MxResult Tickle() override; // vtable+08 // OFFSET: LEGO1 0x10045110 inline const char *ClassName() const override // vtable+0xc diff --git a/LEGO1/legoplantmanager.cpp b/LEGO1/legoplantmanager.cpp index eee83726..515d330d 100644 --- a/LEGO1/legoplantmanager.cpp +++ b/LEGO1/legoplantmanager.cpp @@ -13,7 +13,7 @@ LegoPlantManager::~LegoPlantManager() } // OFFSET: LEGO1 0x10026e00 STUB -MxLong LegoPlantManager::Tickle() +MxResult LegoPlantManager::Tickle() { // TODO diff --git a/LEGO1/legoplantmanager.h b/LEGO1/legoplantmanager.h index 3e8bfefe..b8e8dd9d 100644 --- a/LEGO1/legoplantmanager.h +++ b/LEGO1/legoplantmanager.h @@ -11,7 +11,7 @@ class LegoPlantManager : public MxCore LegoPlantManager(); virtual ~LegoPlantManager() override; // vtable+0x0 - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x10026290 inline const char *ClassName() const override // vtable+0xc diff --git a/LEGO1/legosoundmanager.cpp b/LEGO1/legosoundmanager.cpp index e56747f6..01f8fee5 100644 --- a/LEGO1/legosoundmanager.cpp +++ b/LEGO1/legosoundmanager.cpp @@ -13,7 +13,7 @@ LegoSoundManager::~LegoSoundManager() } // OFFSET: LEGO1 0x1002a3a0 STUB -MxLong LegoSoundManager::Tickle() +MxResult LegoSoundManager::Tickle() { // TODO return 0; diff --git a/LEGO1/legosoundmanager.h b/LEGO1/legosoundmanager.h index 1d191e03..90e23fba 100644 --- a/LEGO1/legosoundmanager.h +++ b/LEGO1/legosoundmanager.h @@ -10,7 +10,7 @@ class LegoSoundManager : public MxSoundManager public: LegoSoundManager(); virtual ~LegoSoundManager() override; - virtual MxLong Tickle() override; // vtable+08 + virtual MxResult Tickle() override; // vtable+08 private: void Init(); diff --git a/LEGO1/mxcore.cpp b/LEGO1/mxcore.cpp index 78441d8d..ab73e242 100644 --- a/LEGO1/mxcore.cpp +++ b/LEGO1/mxcore.cpp @@ -22,7 +22,7 @@ MxLong MxCore::Notify(MxParam &p) } // OFFSET: LEGO1 0x10001f70 -MxLong MxCore::Tickle() +MxResult MxCore::Tickle() { return 0; } \ No newline at end of file diff --git a/LEGO1/mxdiskstreamcontroller.cpp b/LEGO1/mxdiskstreamcontroller.cpp index 61243410..9e37edc4 100644 --- a/LEGO1/mxdiskstreamcontroller.cpp +++ b/LEGO1/mxdiskstreamcontroller.cpp @@ -13,7 +13,7 @@ MxDiskStreamController::~MxDiskStreamController() } // OFFSET: LEGO1 0x100c8640 STUB -MxLong MxDiskStreamController::Tickle() +MxResult MxDiskStreamController::Tickle() { // TODO diff --git a/LEGO1/mxdiskstreamcontroller.h b/LEGO1/mxdiskstreamcontroller.h index c0142663..1f66984c 100644 --- a/LEGO1/mxdiskstreamcontroller.h +++ b/LEGO1/mxdiskstreamcontroller.h @@ -14,7 +14,7 @@ class MxDiskStreamController : public MxStreamController MxDiskStreamController(); virtual ~MxDiskStreamController() override; - virtual MxLong Tickle() override; // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x100c7360 inline virtual const char *ClassName() const override // vtable+0x0c diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index 31e68abc..6a59a0ec 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -3,7 +3,7 @@ DECOMP_SIZE_ASSERT(MxMediaPresenter, 0x50); // OFFSET: LEGO1 0x100b5d10 STUB -MxLong MxMediaPresenter::Tickle() +MxResult MxMediaPresenter::Tickle() { // TODO return 0; diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index 64de0614..741ab49f 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -14,7 +14,7 @@ class MxMediaPresenter : public MxPresenter Init(); } - virtual MxLong Tickle() override; // vtable+0x8, override MxCore + virtual MxResult Tickle() override; // vtable+0x8, override MxCore // OFFSET: LEGO1 0x1000c5c0 inline virtual const char *ClassName() const override // vtable+0xc diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index e82aa3a4..838b0af3 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -79,7 +79,7 @@ MxPresenter::~MxPresenter() } // OFFSET: LEGO1 0x100b5200 -MxLong MxPresenter::Tickle() +MxResult MxPresenter::Tickle() { MxAutoLocker lock(&this->m_criticalSection); diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index b7e99edf..86b078a6 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -29,7 +29,7 @@ class MxPresenter : public MxCore MxPresenter() { Init(); } __declspec(dllexport) virtual ~MxPresenter(); // vtable+0x0 - __declspec(dllexport) virtual MxLong Tickle() override; // vtable+0x8 + __declspec(dllexport) virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x1000bfe0 inline virtual const char *ClassName() const override// vtable+0xc diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 8af3f497..fdae06ea 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -13,7 +13,7 @@ MxTransitionManager::~MxTransitionManager() } // OFFSET: LEGO1 0x1004bac0 STUB -MxLong MxTransitionManager::Tickle() +MxResult MxTransitionManager::Tickle() { // TODO diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index c6cc28aa..215cd2d7 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -14,7 +14,7 @@ class MxTransitionManager : public MxCore __declspec(dllexport) void SetWaitIndicator(MxVideoPresenter *videoPresenter); - virtual MxLong Tickle(); // vtable+0x8 + virtual MxResult Tickle(); // vtable+0x8 }; #endif // MXTRANSITIONMANAGER_H diff --git a/LEGO1/mxvideomanager.cpp b/LEGO1/mxvideomanager.cpp index 81d431a9..8f64dbd4 100644 --- a/LEGO1/mxvideomanager.cpp +++ b/LEGO1/mxvideomanager.cpp @@ -15,7 +15,7 @@ MxVideoManager::~MxVideoManager() } // OFFSET: LEGO1 0x100bea90 -MxLong MxVideoManager::Tickle() +MxResult MxVideoManager::Tickle() { MxAutoLocker lock(&this->m_criticalSection); diff --git a/LEGO1/mxvideomanager.h b/LEGO1/mxvideomanager.h index a7cde92f..4068b793 100644 --- a/LEGO1/mxvideomanager.h +++ b/LEGO1/mxvideomanager.h @@ -13,7 +13,7 @@ class MxVideoManager : public MxMediaManager public: virtual ~MxVideoManager(); - virtual MxLong Tickle(); // vtable+0x8 + virtual MxResult Tickle(); // vtable+0x8 __declspec(dllexport) void InvalidateRect(MxRect32 &); __declspec(dllexport) virtual MxLong RealizePalette(MxPalette *); // vtable+0x30 From 6dd94d36263c1aed0e56e6be4ad5612e1a92f935 Mon Sep 17 00:00:00 2001 From: MS Date: Fri, 22 Sep 2023 17:42:23 -0400 Subject: [PATCH 07/11] PresenterNameDispatch (#137) * PresenterNameDispatch * Use reference for PresenterNameDispatch param - fix or add const markers so we can use a const reference --- LEGO1/mxdsaction.h | 3 +++ LEGO1/mxdsmediaaction.h | 2 ++ LEGO1/mxdsobject.h | 5 ++-- LEGO1/mxpresenter.cpp | 59 +++++++++++++++++++++++++++++++++++++++++ LEGO1/mxpresenter.h | 2 ++ 5 files changed, 69 insertions(+), 2 deletions(-) diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 3028a43d..265f0a6f 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -12,6 +12,7 @@ class MxDSAction : public MxDSObject public: enum { + Flag_Looping = 0x01, Flag_Enabled = 0x20, Flag_Parsed = 0x80, }; @@ -55,6 +56,8 @@ class MxDSAction : public MxDSObject inline const MxVector3Data &GetLocation() const { return m_location; } inline void SetOmni(MxOmni *p_omni) { m_omni = p_omni; } + inline MxBool IsLooping() const { return this->m_flags & Flag_Looping; } + private: MxU32 m_sizeOnDisk; MxU32 m_flags; diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index 1ebbfdd2..f3c03839 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -32,6 +32,8 @@ class MxDSMediaAction : public MxDSAction virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; void CopyMediaSrcPath(const char *p_mediaSrcPath); + + inline MxS32 GetMediaFormat() const { return this->m_mediaFormat; } private: MxU32 m_sizeOnDisk; char *m_mediaSrcPath; diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index 0b247a6a..1ca3d98a 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -40,9 +40,10 @@ class MxDSObject : public MxCore inline void SetObjectId(MxU32 p_objectId) { this->m_objectId = p_objectId; } inline void SetUnknown24(MxS16 p_unk24) { this->m_unk24 = p_unk24; } -protected: + inline char *GetSourceName() const { return this->m_sourceName; } + inline void SetType(MxDSType p_type) { this->m_type = p_type; } - inline MxDSType GetType() { return (MxDSType) this->m_type; } + inline MxDSType GetType() const { return (MxDSType) this->m_type; } private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 838b0af3..940248a0 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -2,6 +2,8 @@ #include "mxautolocker.h" #include "mxparam.h" #include "legoomni.h" +#include "mxdsanim.h" +#include "mxdssound.h" #include #include "decomp.h" @@ -155,6 +157,63 @@ void MxPresenter::Enable(MxBool p_enable) } } +// OFFSET: LEGO1 0x100b5310 +char *PresenterNameDispatch(const MxDSAction &p_action) +{ + char *name = p_action.GetSourceName(); + MxS32 format; + + if (!name || strlen(name) == 0) { + switch (p_action.GetType()) { + case MxDSType_Anim: + format = ((MxDSAnim&)p_action).GetMediaFormat(); + switch (format) { + case FOURCC(' ', 'F', 'L', 'C'): + name = !p_action.IsLooping() ? + "MxFlcPresenter" : + "MxLoopingFlcPresenter"; + break; + case FOURCC(' ', 'S', 'M', 'K'): + name = !p_action.IsLooping() ? + "MxSmkPresenter" : + "MxLoopingSmkPresenter"; + break; + } + break; + + case MxDSType_Sound: + format = ((MxDSSound&)p_action).GetMediaFormat(); + switch(format) { + case FOURCC(' ', 'M', 'I', 'D'): + name = !p_action.IsLooping() ? + "MxMIDIPresenter" : + "MxLoopingMIDIPresenter"; + break; + case FOURCC(' ', 'W', 'A', 'V'): + name = "MxWavePresenter"; + break; + } + break; + + case MxDSType_SerialAction: + case MxDSType_ParallelAction: + case MxDSType_SelectAction: + name = "MxCompositePresenter"; + break; + + case MxDSType_Event: + name = "MxEventPresenter"; + break; + + case MxDSType_Still: + name = "MxStillPresenter"; + break; + } + } + + return name; +} + // OFFSET: LEGO1 0x100b54c0 MxBool MxPresenter::IsEnabled() { diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 86b078a6..1537d2d3 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -84,4 +84,6 @@ class MxPresenter : public MxCore MxPresenter *m_unkPresenter; // 0x3c }; +char *PresenterNameDispatch(const MxDSAction &); + #endif // MXPRESENTER_H From 548f337cad9bd99636430eb8dc8e5272aeb387a9 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 25 Sep 2023 13:08:19 -0400 Subject: [PATCH 08/11] 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) From b2ec18f943fc91fdc2869026f394e8e94c627678 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 25 Sep 2023 14:58:15 -0400 Subject: [PATCH 09/11] Implement/match MxDSParallelAction (#138) * Implement/match MxDSParallelAction * Fix type * Remove space * Add neccessary MxDSMultiAction functions --- LEGO1/mxdsaction.cpp | 4 +- LEGO1/mxdsaction.h | 5 ++- LEGO1/mxdsmediaaction.h | 1 + LEGO1/mxdsmultiaction.h | 2 + LEGO1/mxdsparallelaction.cpp | 72 ++++++++++++++++++++++++++++++++++++ LEGO1/mxdsparallelaction.h | 5 +++ 6 files changed, 86 insertions(+), 3 deletions(-) diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index cccea39c..536fbd8a 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -96,8 +96,8 @@ void MxDSAction::Deserialize(char **p_source, MxS16 p_unk24) this->m_flags = *(MxU32*) *p_source; *p_source += sizeof(MxU32); - this->m_startTime = *(DWORD*) *p_source; - *p_source += sizeof(DWORD); + this->m_startTime = *(MxLong*) *p_source; + *p_source += sizeof(MxLong); this->m_duration = *(MxLong*) *p_source; *p_source += sizeof(MxLong); this->m_loopCount = *(MxS32*) *p_source; diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index ce54cfc4..7d9d2f0c 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -13,6 +13,7 @@ class MxDSAction : public MxDSObject enum { Flag_Looping = 0x01, + Flag_Bit3 = 0x04, Flag_Enabled = 0x20, Flag_Parsed = 0x80, }; @@ -53,15 +54,17 @@ class MxDSAction : public MxDSObject inline void SetFlags(MxU32 m_flags) { this->m_flags = m_flags; } inline char *GetExtraData() { return m_extraData; } inline MxU16 GetExtraLength() const { return m_extraLength; } + inline MxLong GetStartTime() const { return m_startTime; } inline const MxVector3Data &GetLocation() const { return m_location; } inline void SetOmni(MxOmni *p_omni) { m_omni = p_omni; } inline MxBool IsLooping() const { return this->m_flags & Flag_Looping; } + inline MxBool IsBit3() const { return this->m_flags & Flag_Bit3; } private: MxU32 m_sizeOnDisk; MxU32 m_flags; - DWORD m_startTime; + MxLong m_startTime; protected: MxLong m_duration; diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index f3c03839..cc710425 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -34,6 +34,7 @@ class MxDSMediaAction : public MxDSAction void CopyMediaSrcPath(const char *p_mediaSrcPath); inline MxS32 GetMediaFormat() const { return this->m_mediaFormat; } + inline MxLong GetSustainTime() const { return this->m_sustainTime; } private: MxU32 m_sizeOnDisk; char *m_mediaSrcPath; diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 21b1dc03..4063343c 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -39,6 +39,8 @@ class MxDSMultiAction : public MxDSAction private: MxU32 m_sizeOnDisk; + +protected: MxDSActionList *m_actions; }; diff --git a/LEGO1/mxdsparallelaction.cpp b/LEGO1/mxdsparallelaction.cpp index 2e0d66da..564e39c6 100644 --- a/LEGO1/mxdsparallelaction.cpp +++ b/LEGO1/mxdsparallelaction.cpp @@ -1,4 +1,5 @@ #include "mxdsparallelaction.h" +#include "mxdsmediaaction.h" DECOMP_SIZE_ASSERT(MxDSParallelAction, 0x9c) @@ -12,3 +13,74 @@ MxDSParallelAction::MxDSParallelAction() MxDSParallelAction::~MxDSParallelAction() { } + +// OFFSET: LEGO1 0x100cb090 +void MxDSParallelAction::CopyFrom(MxDSParallelAction &p_dsParallelAction) +{ +} + +// OFFSET: LEGO1 0x100cb0a0 +MxDSParallelAction &MxDSParallelAction::operator=(MxDSParallelAction &p_dsParallelAction) +{ + if (this == &p_dsParallelAction) + return *this; + + MxDSMultiAction::operator=(p_dsParallelAction); + this->CopyFrom(p_dsParallelAction); + return *this; +} + +// OFFSET: LEGO1 0x100cb0d0 +MxDSAction *MxDSParallelAction::Clone() +{ + MxDSParallelAction *clone = new MxDSParallelAction(); + + if (clone) + *clone = *this; + + return clone; +} + +// OFFSET: LEGO1 0x100cb160 +MxLong MxDSParallelAction::GetDuration() +{ + if (this->m_duration) + return this->m_duration; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + + while (cursor.Next(action)) { + if (!action) + continue; + + MxLong duration = action->GetDuration(); + if (duration == -1) { + this->m_duration = -1; + break; + } + + duration += action->GetStartTime(); + if (action->IsA("MxDSMediaAction")) { + MxLong sustainTime = ((MxDSMediaAction*) action)->GetSustainTime(); + + if (sustainTime == -1) + duration = -1; + else if (sustainTime) + duration += sustainTime; + } + + if (duration == -1) { + this->m_duration = -1; + break; + } + + if (this->m_duration < duration) + this->m_duration = duration; + } + + if (this->IsBit3()) + this->m_duration *= this->m_loopCount; + + return this->m_duration; +} \ No newline at end of file diff --git a/LEGO1/mxdsparallelaction.h b/LEGO1/mxdsparallelaction.h index 067dc82c..962ba34b 100644 --- a/LEGO1/mxdsparallelaction.h +++ b/LEGO1/mxdsparallelaction.h @@ -11,6 +11,9 @@ class MxDSParallelAction : public MxDSMultiAction MxDSParallelAction(); virtual ~MxDSParallelAction() override; + void CopyFrom(MxDSParallelAction &p_dsParallelAction); + MxDSParallelAction &operator=(MxDSParallelAction &p_dsParallelAction); + // OFFSET: LEGO1 0x100caf00 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -24,6 +27,8 @@ class MxDSParallelAction : public MxDSMultiAction return !strcmp(name, MxDSParallelAction::ClassName()) || MxDSMultiAction::IsA(name); } + virtual MxLong GetDuration(); // vtable+24; + virtual MxDSAction *Clone(); // vtable+2c; }; #endif // MXDSPARALLELACTION_H From e1e2abc5107c1754d7b6a52dba9a2a84b3b3de08 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 25 Sep 2023 15:53:57 -0400 Subject: [PATCH 10/11] Implement/match MxDSSerialAction (#139) * Implement/match MxDSSerialAction * Add neccessary MxDSMultiAction functions --- LEGO1/mxdsactionlist.cpp | 1 + LEGO1/mxdsserialaction.cpp | 70 ++++++++++++++++++++++++++++++++++++-- LEGO1/mxdsserialaction.h | 10 +++++- LEGO1/mxpresenterlist.cpp | 1 + 4 files changed, 78 insertions(+), 4 deletions(-) diff --git a/LEGO1/mxdsactionlist.cpp b/LEGO1/mxdsactionlist.cpp index 86c75365..46eb4e36 100644 --- a/LEGO1/mxdsactionlist.cpp +++ b/LEGO1/mxdsactionlist.cpp @@ -2,6 +2,7 @@ #include "mxdsaction.h" DECOMP_SIZE_ASSERT(MxDSActionList, 0x1c); +DECOMP_SIZE_ASSERT(MxDSActionListCursor, 0x10); // OFFSET: LEGO1 0x100c9c90 MxS8 MxDSActionList::Compare(MxDSAction *p_var0, MxDSAction *p_var1) diff --git a/LEGO1/mxdsserialaction.cpp b/LEGO1/mxdsserialaction.cpp index c6aa541f..7196b1b7 100644 --- a/LEGO1/mxdsserialaction.cpp +++ b/LEGO1/mxdsserialaction.cpp @@ -1,16 +1,80 @@ #include "mxdsserialaction.h" +#include "mxdsmediaaction.h" DECOMP_SIZE_ASSERT(MxDSSerialAction, 0xa8) // OFFSET: LEGO1 0x100ca9d0 MxDSSerialAction::MxDSSerialAction() { - // TODO this->SetType(MxDSType_SerialAction); + this->m_cursor = new MxDSActionListCursor(this->m_actions); + this->m_unk0xa0 = 0; } -// OFFSET: LEGO1 0x100cac10 STUB +// OFFSET: LEGO1 0x100caac0 +void MxDSSerialAction::SetDuration(MxLong p_duration) +{ + this->m_duration = p_duration; +} + +// OFFSET: LEGO1 0x100cac10 MxDSSerialAction::~MxDSSerialAction() { - // TODO + if (this->m_cursor) + delete this->m_cursor; + + this->m_cursor = NULL; } + +// OFFSET: LEGO1 0x100cac90 +void MxDSSerialAction::CopyFrom(MxDSSerialAction &p_dsSerialAction) +{ +} + +// OFFSET: LEGO1 0x100caca0 +MxDSSerialAction &MxDSSerialAction::operator=(MxDSSerialAction &p_dsSerialAction) +{ + if (this == &p_dsSerialAction) + return *this; + + MxDSMultiAction::operator=(p_dsSerialAction); + this->CopyFrom(p_dsSerialAction); + return *this; +} + +// OFFSET: LEGO1 0x100cacd0 +MxDSAction *MxDSSerialAction::Clone() +{ + MxDSSerialAction *clone = new MxDSSerialAction(); + + if (clone) + *clone = *this; + + return clone; +} + +// OFFSET: LEGO1 0x100cad60 +MxLong MxDSSerialAction::GetDuration() +{ + if (this->m_duration) + return this->m_duration; + + MxDSActionListCursor cursor(this->m_actions); + MxDSAction *action; + + while (cursor.Next(action)) { + if (!action) + continue; + + this->m_duration += action->GetDuration() + action->GetStartTime(); + + if (action->IsA("MxDSMediaAction")) { + MxLong sustainTime = ((MxDSMediaAction*) action)->GetSustainTime(); + + if (sustainTime && sustainTime != -1) + this->m_duration += sustainTime; + } + } + + return this->m_duration; +} \ No newline at end of file diff --git a/LEGO1/mxdsserialaction.h b/LEGO1/mxdsserialaction.h index 6bf30c0f..e2f6cd72 100644 --- a/LEGO1/mxdsserialaction.h +++ b/LEGO1/mxdsserialaction.h @@ -12,6 +12,9 @@ class MxDSSerialAction : public MxDSMultiAction MxDSSerialAction(); virtual ~MxDSSerialAction() override; + void CopyFrom(MxDSSerialAction &p_dsSerialAction); + MxDSSerialAction &operator=(MxDSSerialAction &p_dsSerialAction); + // OFFSET: LEGO1 0x100caad0 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -25,7 +28,12 @@ class MxDSSerialAction : public MxDSMultiAction return !strcmp(name, MxDSSerialAction::ClassName()) || MxDSMultiAction::IsA(name); } - undefined4 m_unk0x9c; + virtual MxLong GetDuration(); // vtable+24; + virtual void SetDuration(MxLong p_duration); // vtable+28; + virtual MxDSAction *Clone(); // vtable+2c; + +private: + MxDSActionListCursor *m_cursor; undefined4 m_unk0xa0; undefined4 m_unk0xa4; }; diff --git a/LEGO1/mxpresenterlist.cpp b/LEGO1/mxpresenterlist.cpp index ca3f15a8..1edb6e12 100644 --- a/LEGO1/mxpresenterlist.cpp +++ b/LEGO1/mxpresenterlist.cpp @@ -2,6 +2,7 @@ #include "mxpresenter.h" DECOMP_SIZE_ASSERT(MxPresenterList, 0x18); +DECOMP_SIZE_ASSERT(MxPresenterListCursor, 0x10); // OFFSET: LEGO1 0x1001cd00 MxS8 MxPresenterList::Compare(MxPresenter *p_var0, MxPresenter *p_var1) From 3f6e3af8cad2d6880db7ec2814f44e3648727d5d Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Mon, 25 Sep 2023 13:28:25 -0700 Subject: [PATCH 11/11] Fix LegoOmni vtable (#140) --- ISLE/isleapp.cpp | 10 +++--- LEGO1/legoomni.cpp | 51 +++++++++++++++--------------- LEGO1/legoomni.h | 30 +++++++++--------- LEGO1/mxbackgroundaudiomanager.cpp | 2 ++ LEGO1/mxdsaction.cpp | 5 +++ LEGO1/mxdsaction.h | 6 ++-- LEGO1/mxomni.cpp | 5 +-- LEGO1/mxomni.h | 9 +++--- 8 files changed, 65 insertions(+), 53 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 198389a3..c20f1652 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -91,9 +91,9 @@ void IsleApp::Close() VideoManager()->Get3DManager()->GetLego3DView()->GetViewManager()->RemoveAll(NULL); Lego()->RemoveWorld(ds.GetAtomId(), ds.GetObjectId()); - Lego()->vtable24(ds); + Lego()->DeleteObject(ds); TransitionManager()->SetWaitIndicator(NULL); - Lego()->vtable3c(); + Lego()->vtable0x3c(); MxLong lVar8; do { @@ -101,7 +101,7 @@ void IsleApp::Close() } while (lVar8 == 0); while (Lego()) { - if (Lego()->vtable28(ds) != FALSE) { + if (Lego()->DoesEntityExist(ds)) { break; } @@ -232,7 +232,7 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine g_reqEnableRMDevice = 0; VideoManager()->EnableRMDevice(); g_rmDisabled = 0; - Lego()->vtable3c(); + Lego()->vtable0x3c(); } if (g_closed) { @@ -379,7 +379,7 @@ LRESULT WINAPI WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } else if (!valid) { g_rmDisabled = 1; - Lego()->vtable38(); + Lego()->StartTimer(); VideoManager()->DisableRMDevice(); } } diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index cda6d9ff..1dd7a561 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -253,48 +253,49 @@ void LegoOmni::Destroy() // FIXME: Stub } -void LegoOmni::vtable20() +void LegoOmni::vtable0x20() { // FIXME: Stub } -void LegoOmni::vtable24(MxDSAction &ds) +void LegoOmni::DeleteObject(MxDSAction &ds) { // FIXME: Stub } -MxBool LegoOmni::vtable28(MxDSAction &ds) +MxBool LegoOmni::DoesEntityExist(MxDSAction &ds) { // FIXME: Stub return TRUE; } -void LegoOmni::vtable2c() +void LegoOmni::vtable0x2c() { // FIXME: Stub } -void LegoOmni::vtable30() -{ - // FIXME: Stub -} - -void LegoOmni::vtable34() -{ - // FIXME: Stub -} - -void LegoOmni::vtable38() -{ - // FIXME: Stub -} - -void LegoOmni::vtable3c() -{ - // FIXME: Stub -} - -unsigned char LegoOmni::vtable40() +int LegoOmni::vtable0x30(char*, int, MxCore*) +{ + // FIXME: Stub + return 0; +} + +void LegoOmni::NotifyCurrentEntity() +{ + // FIXME: Stub +} + +void LegoOmni::StartTimer() +{ + // FIXME: Stub +} + +void LegoOmni::vtable0x3c() +{ + // FIXME: Stub +} + +MxBool LegoOmni::vtable40() { // FIXME: Stub return 0; diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 485da46c..be289769 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -36,33 +36,33 @@ class LegoOmni : public MxOmni LegoOmni(); virtual ~LegoOmni(); // vtable+00 - virtual MxLong Notify(MxParam &p); // vtable+04 + virtual MxLong Notify(MxParam &p) override; // vtable+04 // OFFSET: LEGO1 0x10058aa0 - inline virtual const char *ClassName() const // vtable+0c + inline virtual const char *ClassName() const override // vtable+0c { // 0x100f671c return "LegoOmni"; } // OFFSET: LEGO1 0x10058ab0 - inline virtual MxBool IsA(const char *name) const // vtable+10 + inline virtual MxBool IsA(const char *name) const override // vtable+10 { return !strcmp(name, LegoOmni::ClassName()) || MxOmni::IsA(name); } - virtual void Init(); // vtable+14 - virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p); // vtable+18 - virtual void Destroy(); // vtable+1c - virtual void vtable20(); - virtual void vtable24(MxDSAction &ds); - virtual MxBool vtable28(MxDSAction &ds); - virtual void vtable2c(); - virtual void vtable30(); - virtual void vtable34(); - virtual void vtable38(); - virtual void vtable3c(); - virtual unsigned char vtable40(); + virtual void Init() override; // vtable+14 + virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p) override; // vtable+18 + virtual void Destroy() override; // vtable+1c + virtual void vtable0x20() override; + virtual void DeleteObject(MxDSAction &ds) override; + virtual MxBool DoesEntityExist(MxDSAction &ds) override; + virtual void vtable0x2c() override; + virtual int vtable0x30(char*, int, MxCore*) override; + virtual void NotifyCurrentEntity() override; + virtual void StartTimer() override; + virtual void vtable0x3c() override; + virtual MxBool vtable40(); LegoVideoManager *GetVideoManager() { return (LegoVideoManager *) m_videoManager; } LegoSoundManager *GetSoundManager() { return (LegoSoundManager *)m_soundManager;} diff --git a/LEGO1/mxbackgroundaudiomanager.cpp b/LEGO1/mxbackgroundaudiomanager.cpp index a24286ad..40891bef 100644 --- a/LEGO1/mxbackgroundaudiomanager.cpp +++ b/LEGO1/mxbackgroundaudiomanager.cpp @@ -1,5 +1,7 @@ #include "mxbackgroundaudiomanager.h" +#include "mxomni.h" + DECOMP_SIZE_ASSERT(MxBackgroundAudioManager, 0x150) // OFFSET: LEGO1 0x1007ea90 diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index 536fbd8a..3411a460 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -3,6 +3,8 @@ #include #include +#include "mxomni.h" + DECOMP_SIZE_ASSERT(MxDSAction, 0x94) // GLOBAL OFFSET: LEGO1 0x10101410 @@ -215,6 +217,9 @@ MxLong MxDSAction::GetSomeTimingField() return this->m_someTimingField; } +// Win32 defines GetCurrentTime to GetTickCount +#undef GetCurrentTime + // OFFSET: LEGO1 0x100adcd0 MxLong MxDSAction::GetCurrentTime() { diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 7d9d2f0c..01dfcf2c 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -2,8 +2,10 @@ #define MXDSACTION_H #include "mxdsobject.h" +#include "mxtypes.h" #include "mxvector.h" -#include "mxomni.h" + +class MxOmni; // VTABLE 0x100dc098 // SIZE 0x94 @@ -40,7 +42,7 @@ class MxDSAction : public MxDSObject virtual MxU32 GetSizeOnDisk(); // vtable+18; virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; virtual MxLong GetDuration(); // vtable+24; - virtual void SetDuration(LONG p_duration); // vtable+28; + virtual void SetDuration(MxLong p_duration); // vtable+28; virtual MxDSAction *Clone(); // vtable+2c; virtual void MergeFrom(MxDSAction &p_dsAction); // vtable+30; virtual MxBool HasId(MxU32 p_objectId); // vtable+34; diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 446ac4f9..22cc2a70 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -49,15 +49,16 @@ void MxOmni::vtable0x20() } // OFFSET: LEGO1 0x100b00c0 STUB -void MxOmni::DeleteObject() +void MxOmni::DeleteObject(MxDSAction &ds) { // TODO } // OFFSET: LEGO1 0x100b09a0 STUB -void MxOmni::DoesEntityExist() +MxBool MxOmni::DoesEntityExist(MxDSAction &ds) { // TODO + return FALSE; } // OFFSET: LEGO1 0x100b00e0 STUB diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 8cacc5fc..a8fa9db8 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -2,6 +2,7 @@ #define MXOMNI_H #include "mxcriticalsection.h" +#include "mxdsaction.h" #include "mxeventmanager.h" #include "mxmusicmanager.h" #include "mxnotificationmanager.h" @@ -33,13 +34,13 @@ class MxOmni : public MxCore MxOmni(); virtual ~MxOmni() override; - virtual MxLong Notify(MxParam &p); // vtable+04 + virtual MxLong Notify(MxParam &p) override; // vtable+04 virtual void Init(); // vtable+14 - virtual MxResult Create(MxOmniCreateParam &p); // vtable+18 + virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p); // vtable+18 virtual void Destroy(); // vtable+1c virtual void vtable0x20(); // vtable+20 - virtual void DeleteObject(); // vtable+24 - virtual void DoesEntityExist(); // vtable+28 + virtual void DeleteObject(MxDSAction &ds); // vtable+24 + virtual MxBool DoesEntityExist(MxDSAction &ds); // vtable+28 virtual void vtable0x2c(); // vtable+2c virtual int vtable0x30(char*, int, MxCore*); // vtable+30 virtual void NotifyCurrentEntity(); // vtable+34