diff --git a/LEGO1/mxhashtable.h b/LEGO1/mxhashtable.h index f9505bb5..3d91717b 100644 --- a/LEGO1/mxhashtable.h +++ b/LEGO1/mxhashtable.h @@ -67,7 +67,7 @@ public: virtual ~MxHashTable(); void Resize(); - void MxHashTable::Add(T* ); + void Add(T* ); virtual MxS8 Compare(T*, T*) = 0; diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 9ace7bf7..6f26cad8 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -5,13 +5,14 @@ #include "mxcore.h" template +// SIZE 0xc class MxListEntry { public: - MxListEntry() {} - MxListEntry(T *p_obj) { + MxListEntry() {} + MxListEntry(T *p_obj, MxListEntry *p_prev) { m_obj = p_obj; - m_prev = NULL; + m_prev = p_prev; m_next = NULL; } @@ -56,9 +57,54 @@ public: } virtual ~MxList(); + + void Append(T*); + + friend class MxListCursor; + protected: MxListEntry *m_first; // +0x10 MxListEntry *m_last; // +0x14 + +private: + void _DeleteEntry(MxListEntry *match); +}; + +// VTABLE 0x100d6488 +template +class MxListCursor : public MxCore +{ +public: + MxListCursor(MxList *p_list) { + m_list = p_list; + m_match = NULL; + } + + MxBool Find(T *p_obj); + void Detach(); + MxBool Next(T*& p_obj); + +private: + MxList *m_list; + MxListEntry *m_match; +}; + +// Unclear purpose +// VTABLE 0x100d6530 +template +class MxListCursorChild : public MxListCursor +{ +public: + MxListCursorChild(MxList *p_list) : MxListCursor(p_list) {} +}; + +// Unclear purpose +// VTABLE 0x100d6470 +template +class MxListCursorChildChild : public MxListCursorChild +{ +public: + MxListCursorChildChild(MxList *p_list) : MxListCursorChild(p_list) {} }; template @@ -80,4 +126,70 @@ MxList::~MxList() m_first = NULL; } +template +inline void MxList::Append(T *p_newobj) +{ + MxListEntry *currentLast = this->m_last; + MxListEntry *newEntry = new MxListEntry(p_newobj, currentLast); + + if (currentLast) + currentLast->m_next = newEntry; + else + this->m_first = newEntry; + + this->m_last = newEntry; + this->m_count++; +} + +template +inline void MxList::_DeleteEntry(MxListEntry *match) +{ + MxListEntry **pPrev = &match->m_prev; + MxListEntry **pNext = &match->m_next; + + if (match->m_prev) + match->m_prev->m_next = *pNext; + else + m_first = *pNext; + + if (*pNext) + (*pNext)->m_prev = *pPrev; + else + m_last = *pPrev; + + delete match; + m_count--; +} + +template +inline MxBool MxListCursor::Find(T *p_obj) +{ + for (m_match = m_list->m_first; + m_match && m_list->Compare(m_match->m_obj, p_obj); + m_match = m_match->m_next); + + return m_match != NULL; +} + +template +inline void MxListCursor::Detach() +{ + m_list->_DeleteEntry(m_match); + m_match = NULL; +} + +template +inline MxBool MxListCursor::Next(T*& p_obj) +{ + if (!m_match) + m_match = m_list->m_first; + else + m_match = m_match->m_next; + + if (m_match) + p_obj = m_match->m_obj; + + return m_match != NULL; +} + #endif // MXLIST_H \ No newline at end of file diff --git a/LEGO1/mxmediamanager.cpp b/LEGO1/mxmediamanager.cpp index 95012e19..d1823c03 100644 --- a/LEGO1/mxmediamanager.cpp +++ b/LEGO1/mxmediamanager.cpp @@ -1,9 +1,12 @@ #include "mxmediamanager.h" #include "mxautolocker.h" +#include "mxpresenter.h" #include "decomp.h" DECOMP_SIZE_ASSERT(MxMediaManager, 0x2c); +typedef MxListCursorChildChild MxPresenterListCursor; + // OFFSET: LEGO1 0x100b84c0 MxMediaManager::MxMediaManager() { @@ -24,17 +27,6 @@ MxResult MxMediaManager::Init() return SUCCESS; } -// OFFSET: LEGO1 0x100b8710 -void MxMediaManager::Destroy() -{ - MxAutoLocker lock(&this->m_criticalSection); - - if (this->m_presenters) - delete this->m_presenters; - - Init(); -} - // OFFSET: LEGO1 0x100b8790 STUB MxResult MxMediaManager::Tickle() { @@ -55,3 +47,43 @@ MxResult MxMediaManager::InitPresenters() return SUCCESS; } + +// OFFSET: LEGO1 0x100b8710 +void MxMediaManager::Destroy() +{ + MxAutoLocker lock(&this->m_criticalSection); + + if (this->m_presenters) + delete this->m_presenters; + + Init(); +} + +// OFFSET: LEGO1 0x100b88c0 +void MxMediaManager::AddPresenter(MxPresenter &p_presenter) +{ + MxAutoLocker lock(&this->m_criticalSection); + + this->m_presenters->Append(&p_presenter); +} + +// OFFSET: LEGO1 0x100b8980 +void MxMediaManager::RemovePresenter(MxPresenter &p_presenter) +{ + MxAutoLocker lock(&this->m_criticalSection); + MxPresenterListCursor cursor(this->m_presenters); + + if (cursor.Find(&p_presenter)) + cursor.Detach(); +} + +// OFFSET: LEGO1 0x100b8ac0 +void MxMediaManager::StopPresenters() +{ + MxAutoLocker lock(&this->m_criticalSection); + MxPresenter *presenter; + MxPresenterListCursor cursor(this->m_presenters); + + while (cursor.Next(presenter)) + presenter->EndAction(); +} diff --git a/LEGO1/mxmediamanager.h b/LEGO1/mxmediamanager.h index b5435957..9df073bc 100644 --- a/LEGO1/mxmediamanager.h +++ b/LEGO1/mxmediamanager.h @@ -18,14 +18,15 @@ public: virtual MxResult Tickle(); // vtable+08 virtual MxResult InitPresenters(); // vtable+14 virtual void Destroy(); // vtable+18 - // vtable+1c - // vtable+20 - // vtable+24 + virtual void AddPresenter(MxPresenter &p_presenter); // vtable+1c + virtual void RemovePresenter(MxPresenter &p_presenter); // vtable+20 + virtual void StopPresenters(); // vtable+24 MxResult Init(); + private: MxPresenterList *m_presenters; - MxThread* m_thread; // 0xc + MxThread *m_thread; // 0xc protected: MxCriticalSection m_criticalSection; // 0x10 diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 4b8659ec..87ef9645 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -77,7 +77,7 @@ private: undefined4 m_unk0x10; undefined4 m_unk0x14; undefined4 m_unk0x18; - MxDSAction* m_action; // 0 + MxDSAction *m_action; // 0 MxCriticalSection m_criticalSection; MxPresenter *m_unkPresenter; // 0x3c };