diff --git a/CMakeLists.txt b/CMakeLists.txt index f63e39e9..a297f7f4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -170,6 +170,7 @@ add_library(lego1 SHARED LEGO1/mxsoundmanager.cpp LEGO1/mxsoundpresenter.cpp LEGO1/mxstillpresenter.cpp + LEGO1/mxstreamchunklist.cpp LEGO1/mxstreamcontroller.cpp LEGO1/mxstreamer.cpp LEGO1/mxstreamprovider.cpp diff --git a/LEGO1/mxdsactionlist.cpp b/LEGO1/mxdsactionlist.cpp index 394512e5..2959ffcd 100644 --- a/LEGO1/mxdsactionlist.cpp +++ b/LEGO1/mxdsactionlist.cpp @@ -6,13 +6,9 @@ DECOMP_SIZE_ASSERT(MxDSActionList, 0x1c); DECOMP_SIZE_ASSERT(MxDSActionListCursor, 0x10); // OFFSET: LEGO1 0x100c9c90 -MxS8 MxDSActionList::Compare(MxDSAction* p_var0, MxDSAction* p_var1) +MxS8 MxDSActionList::Compare(MxDSAction* p_a, MxDSAction* p_b) { - if (p_var1 == p_var0) - return 0; - if (p_var1 <= p_var0) - return 1; - return -1; + return p_a == p_b ? 0 : p_a < p_b ? -1 : 1; } // OFFSET: LEGO1 0x100c9cb0 diff --git a/LEGO1/mxdschunk.h b/LEGO1/mxdschunk.h index ba716de6..c061a50e 100644 --- a/LEGO1/mxdschunk.h +++ b/LEGO1/mxdschunk.h @@ -23,7 +23,7 @@ class MxDSChunk : public MxCore { return !strcmp(name, MxDSChunk::ClassName()) || MxCore::IsA(name); } -private: + // private: MxS16 m_length; // 0x8 MxLong m_buffer; // 0xc MxLong m_unk10; // 0x10 diff --git a/LEGO1/mxdssubscriber.cpp b/LEGO1/mxdssubscriber.cpp index d97b6946..530a3a09 100644 --- a/LEGO1/mxdssubscriber.cpp +++ b/LEGO1/mxdssubscriber.cpp @@ -1,13 +1,28 @@ #include "mxdssubscriber.h" -// OFFSET: LEGO1 0x100b7bb0 +DECOMP_SIZE_ASSERT(MxDSSubscriber, 0x4c); + +// OFFSET: LEGO1 0x100b7bb0 STUB MxDSSubscriber::MxDSSubscriber() { // TODO } -// OFFSET: LEGO1 0x100b7e00 +// OFFSET: LEGO1 0x100b7e00 STUB MxDSSubscriber::~MxDSSubscriber() { // TODO } + +// OFFSET: LEGO1 0x100b7ed0 STUB +MxResult MxDSSubscriber::FUN_100b7ed0(MxStreamController*, MxU32, MxS16) +{ + // TODO + return SUCCESS; +} + +// OFFSET: LEGO1 0x100b8390 STUB +void MxDSSubscriber::FUN_100b8390(MxDSChunk*) +{ + // TODO +} diff --git a/LEGO1/mxdssubscriber.h b/LEGO1/mxdssubscriber.h index c56835db..c8efc64d 100644 --- a/LEGO1/mxdssubscriber.h +++ b/LEGO1/mxdssubscriber.h @@ -1,7 +1,10 @@ #ifndef MXDSSUBSCRIBER_H #define MXDSSUBSCRIBER_H +#include "decomp.h" #include "mxcore.h" +#include "mxdschunk.h" +#include "mxstreamcontroller.h" // VTABLE 0x100dc698 // SIZE 0x4c @@ -22,6 +25,12 @@ class MxDSSubscriber : public MxCore { { return !strcmp(name, MxDSSubscriber::ClassName()) || MxCore::IsA(name); } + + MxResult FUN_100b7ed0(MxStreamController*, MxU32, MxS16); + void FUN_100b8390(MxDSChunk*); + +private: + undefined m_pad[0x44]; // 0x8 }; #endif // MXDSSUBSCRIBER_H diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index 4350c62c..d2ebd702 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -1,5 +1,8 @@ #include "mxmediapresenter.h" +#include "mxautolocker.h" +#include "mxstreamchunk.h" + DECOMP_SIZE_ASSERT(MxMediaPresenter, 0x50); // OFFSET: LEGO1 0x1000c550 @@ -8,26 +11,59 @@ MxMediaPresenter::~MxMediaPresenter() Destroy(TRUE); } -// OFFSET: LEGO1 0x100b5d10 STUB -MxResult MxMediaPresenter::Tickle() +// OFFSET: LEGO1 0x1000c5b0 +void MxMediaPresenter::Destroy() { - // TODO - return SUCCESS; + Destroy(FALSE); } // OFFSET: LEGO1 0x100b54e0 void MxMediaPresenter::Init() { - this->m_unk40 = NULL; - this->m_unk44 = NULL; - this->m_unk48 = NULL; - this->m_unk4c = NULL; + this->m_subscriber = NULL; + this->m_chunks = NULL; + this->m_cursor = NULL; + this->m_currentChunk = NULL; } -// OFFSET: LEGO1 0x100b54f0 STUB +// OFFSET: LEGO1 0x100b54f0 void MxMediaPresenter::Destroy(MxBool p_fromDestructor) +{ + { + MxAutoLocker lock(&m_criticalSection); + + if (m_currentChunk && m_subscriber) + m_subscriber->FUN_100b8390(m_currentChunk); + + if (m_subscriber) + delete m_subscriber; + + if (m_cursor) + delete m_cursor; + + if (m_chunks) { + MxStreamChunkListCursor cursor(m_chunks); + MxStreamChunk* chunk; + + while (cursor.Next(chunk)) + if (chunk->m_unk18) + delete[] chunk->m_unk18; + + delete m_chunks; + } + + Init(); + } + + if (!p_fromDestructor) + MxPresenter::Destroy(); +} + +// OFFSET: LEGO1 0x100b5d10 STUB +MxResult MxMediaPresenter::Tickle() { // TODO + return SUCCESS; } // OFFSET: LEGO1 0x100b5d90 STUB @@ -56,16 +92,34 @@ void MxMediaPresenter::Enable(MxBool p_enable) // TODO } -// OFFSET: LEGO1 0x1000c5b0 -void MxMediaPresenter::Destroy() +// OFFSET: LEGO1 0x100b5700 +MxResult MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) { - Destroy(FALSE); -} + MxResult result = FAILURE; + MxAutoLocker lock(&m_criticalSection); -// OFFSET: LEGO1 0x100b5700 STUB -MxLong MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) -{ - return 0; + if (MxPresenter::StartAction(p_controller, p_action) == SUCCESS) { + if (m_action->GetFlags() & MxDSAction::Flag_Looping) { + m_chunks = new MxStreamChunkList; + m_cursor = new MxStreamChunkListCursor(m_chunks); + + if (!m_chunks && !m_cursor) + goto done; + } + + if (p_controller) { + m_subscriber = new MxDSSubscriber; + + if (!m_subscriber || + m_subscriber->FUN_100b7ed0(p_controller, p_action->GetObjectId(), p_action->GetUnknown24()) != SUCCESS) + goto done; + } + + result = SUCCESS; + } + +done: + return result; } // OFFSET: LEGO1 0x100b5bc0 STUB diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index 59ca015b..6c40f93b 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -2,15 +2,18 @@ #define MXMEDIAPRESENTER_H #include "decomp.h" +#include "mxdssubscriber.h" #include "mxpresenter.h" +#include "mxstreamchunklist.h" // VTABLE 0x100d4cd8 +// SIZE 0x50 class MxMediaPresenter : public MxPresenter { public: inline MxMediaPresenter() { Init(); } virtual ~MxMediaPresenter() override; - virtual MxResult Tickle() override; + virtual MxResult Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x1000c5c0 inline virtual const char* ClassName() const override // vtable+0xc @@ -29,17 +32,17 @@ class MxMediaPresenter : public MxPresenter { virtual void RepeatingTickle() override; virtual void DoneTickle() override; virtual void Destroy() override; - virtual MxLong StartAction(MxStreamController*, MxDSAction*) override; + virtual MxResult StartAction(MxStreamController*, MxDSAction*) override; virtual void EndAction() override; virtual void Enable(MxBool p_enable) override; virtual void VTable0x58(); - undefined4 m_unk40; - undefined4 m_unk44; - undefined4 m_unk48; - undefined4 m_unk4c; - protected: + MxDSSubscriber* m_subscriber; // 0x40 + MxStreamChunkList* m_chunks; // 0x44 + MxStreamChunkListCursor* m_cursor; // 0x48 + MxStreamChunk* m_currentChunk; // 0x4c + void Init(); void Destroy(MxBool p_fromDestructor); }; diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index e4121602..1ff02c7a 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -116,7 +116,7 @@ MxResult MxPresenter::Tickle() } // OFFSET: LEGO1 0x100b4d80 -MxLong MxPresenter::StartAction(MxStreamController*, MxDSAction* p_action) +MxResult MxPresenter::StartAction(MxStreamController*, MxDSAction* p_action) { MxAutoLocker lock(&this->m_criticalSection); diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 9427e79d..a126a370 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -54,15 +54,15 @@ class MxPresenter : public MxCore { __declspec(dllexport) virtual void ParseExtra(); // vtable+0x30 public: - virtual MxResult AddToManager(); // vtable+0x34 - virtual void Destroy(); // vtable+0x38 - __declspec(dllexport) virtual MxLong StartAction(MxStreamController*, MxDSAction*); // vtable+0x3c - __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 PutData(); // vtable+0x4c - virtual MxBool IsHit(MxS32 p_x, MxS32 p_y); // vtable+0x50 - __declspec(dllexport) virtual void Enable(MxBool p_enable); // vtable+0x54 + virtual MxResult AddToManager(); // vtable+0x34 + virtual void Destroy(); // vtable+0x38 + __declspec(dllexport) virtual MxResult StartAction(MxStreamController*, MxDSAction*); // vtable+0x3c + __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 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(); diff --git a/LEGO1/mxpresenterlist.cpp b/LEGO1/mxpresenterlist.cpp index fb95aa99..f6ed6594 100644 --- a/LEGO1/mxpresenterlist.cpp +++ b/LEGO1/mxpresenterlist.cpp @@ -6,11 +6,7 @@ DECOMP_SIZE_ASSERT(MxPresenterList, 0x18); DECOMP_SIZE_ASSERT(MxPresenterListCursor, 0x10); // OFFSET: LEGO1 0x1001cd00 -MxS8 MxPresenterList::Compare(MxPresenter* p_var0, MxPresenter* p_var1) +MxS8 MxPresenterList::Compare(MxPresenter* p_a, MxPresenter* p_b) { - if (p_var1 == p_var0) - return 0; - if (p_var1 <= p_var0) - return 1; - return -1; + return p_a == p_b ? 0 : p_a < p_b ? -1 : 1; } diff --git a/LEGO1/mxstreamchunklist.cpp b/LEGO1/mxstreamchunklist.cpp new file mode 100644 index 00000000..8c76452e --- /dev/null +++ b/LEGO1/mxstreamchunklist.cpp @@ -0,0 +1,19 @@ +#include "mxstreamchunklist.h" + +#include "mxstreamchunk.h" + +DECOMP_SIZE_ASSERT(MxStreamChunkList, 0x18); +DECOMP_SIZE_ASSERT(MxStreamChunkListCursor, 0x10); + +// OFFSET: LEGO1 0x100b5900 +MxS8 MxStreamChunkList::Compare(MxStreamChunk* p_a, MxStreamChunk* p_b) +{ + return p_a == p_b ? 0 : p_a < p_b ? -1 : 1; +} + +// OFFSET: LEGO1 0x100b5920 +void MxStreamChunkList::Destroy(MxStreamChunk* p_chunk) +{ + if (p_chunk) + delete p_chunk; +} diff --git a/LEGO1/mxstreamchunklist.h b/LEGO1/mxstreamchunklist.h new file mode 100644 index 00000000..3a19950b --- /dev/null +++ b/LEGO1/mxstreamchunklist.h @@ -0,0 +1,34 @@ +#ifndef MXSTREAMCHUNKLIST_H +#define MXSTREAMCHUNKLIST_H + +#include "decomp.h" +#include "mxlist.h" + +class MxStreamChunk; + +// VTABLE 0x100dc600 +// SIZE 0x18 +class MxStreamChunkList : public MxList { +public: + MxStreamChunkList() { m_customDestructor = Destroy; } + + virtual MxS8 Compare(MxStreamChunk*, MxStreamChunk*) override; // +0x14 + + static void Destroy(MxStreamChunk* p_chunk); +}; + +typedef MxListCursorChild MxStreamChunkListCursor; + +// OFFSET: LEGO1 0x100b5930 TEMPLATE +// MxListParent::Compare + +// OFFSET: LEGO1 0x100b5990 TEMPLATE +// MxListParent::Destroy + +// OFFSET: LEGO1 0x100b59a0 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x100b5b10 TEMPLATE +// MxList::`scalar deleting destructor' + +#endif // MXSTREAMCHUNKLIST_H