diff --git a/LEGO1/mxcompositemediapresenter.cpp b/LEGO1/mxcompositemediapresenter.cpp index 01a6e135..454fb976 100644 --- a/LEGO1/mxcompositemediapresenter.cpp +++ b/LEGO1/mxcompositemediapresenter.cpp @@ -1,7 +1,12 @@ #include "mxcompositemediapresenter.h" #include "legoomni.h" +#include "legosoundmanager.h" #include "legovideomanager.h" +#include "mxautolocker.h" +#include "mxdsmultiaction.h" +#include "mxobjectfactory.h" +#include "mxtimer.h" DECOMP_SIZE_ASSERT(MxCompositeMediaPresenter, 0x50) @@ -19,11 +24,65 @@ MxCompositeMediaPresenter::~MxCompositeMediaPresenter() VideoManager()->RemovePresenter(*this); } -// STUB: LEGO1 0x10074090 +// FUNCTION: LEGO1 0x10074090 MxResult MxCompositeMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) { - // TODO - return SUCCESS; + MxAutoLocker lock(&m_criticalSection); + + MxResult result = FAILURE; + MxDSActionList* actions = ((MxDSMultiAction*) p_action)->GetActionList(); + MxDSActionListCursor cursor(actions); + MxDSAction* action; + + if (MxPresenter::StartAction(p_controller, p_action) == SUCCESS) { + // The usual cursor.Next() loop doesn't match here, even though + // the logic is the same. It does match when "deconstructed" into + // the following Head(), Current() and NextFragment() calls, + // but this seems unlikely to be the original code. + // The alpha debug build also uses Next(). + // cursor.Head(); + // while (cursor.Current(action)) { + // cursor.NextFragment(); + while (cursor.Next(action)) { + MxBool success = FALSE; + + action->CopyFlags(m_action->GetFlags()); + + const char* presenterName = PresenterNameDispatch(*action); + MxPresenter* presenter = (MxPresenter*) ObjectFactory()->Create(presenterName); + + if (presenter && presenter->AddToManager() == SUCCESS) { + presenter->SetCompositePresenter(this); + if (presenter->StartAction(p_controller, action) == SUCCESS) { + presenter->SetTickleState(TickleState_Idle); + + if (presenter->IsA("MxVideoPresenter")) + VideoManager()->RemovePresenter(*presenter); + else if (presenter->IsA("MxAudioPresenter")) + SoundManager()->RemovePresenter(*presenter); + + success = TRUE; + } + } + + if (success) { + action->SetOrigin(this); + m_list.push_back(presenter); + } + else if (presenter) + delete presenter; + } + + if (!m_compositePresenter) { + SetTickleState(TickleState_Ready); + MxLong time = Timer()->GetTime(); + m_action->SetUnknown90(time); + } + + result = SUCCESS; + } + + return result; } // STUB: LEGO1 0x100742e0 diff --git a/LEGO1/mxcompositemediapresenter.h b/LEGO1/mxcompositemediapresenter.h index f28465f2..93a74642 100644 --- a/LEGO1/mxcompositemediapresenter.h +++ b/LEGO1/mxcompositemediapresenter.h @@ -27,7 +27,7 @@ public: virtual void StartingTickle() override; // vtable+0x1c virtual MxResult StartAction(MxStreamController*, MxDSAction* p_action) override; // vtable+0x3c - virtual MxResult PutData(); // vtable+0x4c + virtual MxResult PutData() override; // vtable+0x4c private: undefined2 m_unk0x4c; // 0x4c diff --git a/LEGO1/mxcompositepresenter.h b/LEGO1/mxcompositepresenter.h index 30dc170d..93148065 100644 --- a/LEGO1/mxcompositepresenter.h +++ b/LEGO1/mxcompositepresenter.h @@ -39,7 +39,7 @@ public: virtual void VTable0x60(MxPresenter* p_presenter); // vtable+0x60 virtual MxBool VTable0x64(undefined4 p_undefined); // vtable+0x64 -private: +protected: MxCompositePresenterList m_list; // 0x40 };