From 8a1422f13e8ef70f18ed4759d519c14955f91b57 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 13 Nov 2023 05:22:58 -0500 Subject: [PATCH] Implement/match MxMediaPresenter::EndAction (#276) * Bootstrap MxMediaPresenter * Implement/match MxMediaPresenter::EndAction * Merge * Remove garbage --- LEGO1/legoomni.cpp | 2 +- LEGO1/legoomni.h | 20 ++++++++++---------- LEGO1/mxcompositepresenter.cpp | 8 +++++--- LEGO1/mxcompositepresenter.h | 2 +- LEGO1/mxdsaction.h | 3 ++- LEGO1/mxmediapresenter.cpp | 34 ++++++++++++++++++++++++++++++++-- LEGO1/mxomni.cpp | 2 +- LEGO1/mxomni.h | 3 ++- LEGO1/mxpresenter.cpp | 19 +++++++++++-------- LEGO1/mxpresenter.h | 18 ++++++++++-------- LEGO1/mxtransitionmanager.cpp | 2 +- 11 files changed, 76 insertions(+), 37 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index fb5e187c..12cc7f9f 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -532,7 +532,7 @@ MxBool LegoOmni::DoesEntityExist(MxDSAction& ds) } // OFFSET: LEGO1 0x1005b2f0 -MxEntity* LegoOmni::FindWorld(const char* p_id, MxS32 p_entityId, MxCore* p_presenter) +MxEntity* LegoOmni::FindWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter) { LegoWorld* foundEntity = NULL; if (strcmpi(p_id, g_current)) { diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 52ea2d85..3406bd6c 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -83,16 +83,16 @@ public: return !strcmp(name, LegoOmni::ClassName()) || MxOmni::IsA(name); } - virtual void Init() override; // vtable+14 - virtual MxResult Create(MxOmniCreateParam& p) override; // vtable+18 - virtual void Destroy() override; // vtable+1c - virtual MxResult Start(MxDSAction* action) override; // vtable+20 - virtual MxResult DeleteObject(MxDSAction& ds) override; // vtable+24 - virtual MxBool DoesEntityExist(MxDSAction& ds) override; // vtable+28 - virtual MxEntity* FindWorld(const char* p_id, MxS32 p_entityId, MxCore* p_presenter) override; // vtable+30 - virtual void NotifyCurrentEntity(MxNotificationParam* p_param) override; // vtable+34 - virtual void StartTimer() override; // vtable+38 - virtual void StopTimer() override; // vtable+3c + virtual void Init() override; // vtable+14 + virtual MxResult Create(MxOmniCreateParam& p) override; // vtable+18 + virtual void Destroy() override; // vtable+1c + virtual MxResult Start(MxDSAction* action) override; // vtable+20 + virtual MxResult DeleteObject(MxDSAction& ds) override; // vtable+24 + virtual MxBool DoesEntityExist(MxDSAction& ds) override; // vtable+28 + virtual MxEntity* FindWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter) override; // vtable+30 + virtual void NotifyCurrentEntity(MxNotificationParam* p_param) override; // vtable+34 + virtual void StartTimer() override; // vtable+38 + virtual void StopTimer() override; // vtable+3c LegoEntity* FindByEntityIdOrAtomId(const MxAtomId& p_atom, MxS32 p_entityid); diff --git a/LEGO1/mxcompositepresenter.cpp b/LEGO1/mxcompositepresenter.cpp index 25a290a4..b702acda 100644 --- a/LEGO1/mxcompositepresenter.cpp +++ b/LEGO1/mxcompositepresenter.cpp @@ -35,8 +35,10 @@ void MxCompositePresenter::VTable0x60(undefined4 p_unknown) // TODO } -// OFFSET: LEGO1 0x1000caf0 STUB -void MxCompositePresenter::VTable0x64() +// OFFSET: LEGO1 0x1000caf0 +MxBool MxCompositePresenter::VTable0x64(undefined4 p_unknown) { - // TODO + if (m_compositePresenter) + return m_compositePresenter->VTable0x64(p_unknown); + return TRUE; } diff --git a/LEGO1/mxcompositepresenter.h b/LEGO1/mxcompositepresenter.h index 7def4ded..c8eedfaf 100644 --- a/LEGO1/mxcompositepresenter.h +++ b/LEGO1/mxcompositepresenter.h @@ -27,7 +27,7 @@ public: virtual void VTable0x58(); virtual void VTable0x5c(); virtual void VTable0x60(undefined4 p_unknown); - virtual void VTable0x64(); + virtual MxBool VTable0x64(undefined4 p_unknown); private: MxUnkList m_list; diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index c56a71e4..7f110ada 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -17,7 +17,7 @@ public: Flag_Bit4 = 0x08, Flag_Bit5 = 0x10, Flag_Enabled = 0x20, - Flag_Parsed = 0x80, + Flag_World = 0x80, Flag_Bit9 = 0x200, Flag_Bit10 = 0x400, }; @@ -63,6 +63,7 @@ public: inline void SetLoopCount(MxS32 p_loopCount) { m_loopCount = p_loopCount; } inline const MxVector3Data& GetLocation() const { return m_location; } inline void SetUnknown84(MxCore* p_unk84) { m_unk84 = p_unk84; } + inline MxCore* GetUnknown8c() { return m_unk8c; } inline void SetUnknown8c(MxCore* p_unk8c) { m_unk8c = p_unk8c; } inline MxBool IsLooping() const { return m_flags & Flag_Looping; } diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index d2ebd702..19021eb2 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -1,6 +1,9 @@ #include "mxmediapresenter.h" +#include "mxactionnotificationparam.h" #include "mxautolocker.h" +#include "mxcompositepresenter.h" +#include "mxnotificationmanager.h" #include "mxstreamchunk.h" DECOMP_SIZE_ASSERT(MxMediaPresenter, 0x50); @@ -122,10 +125,37 @@ done: return result; } -// OFFSET: LEGO1 0x100b5bc0 STUB +// OFFSET: LEGO1 0x100b5bc0 void MxMediaPresenter::EndAction() { - // TODO + MxAutoLocker lock(&m_criticalSection); + + if (!m_action) + return; + + m_currentChunk = NULL; + + if (m_action->GetFlags() & MxDSAction::Flag_World && + (!m_compositePresenter || !m_compositePresenter->VTable0x64(2))) { + MxPresenter::Enable(FALSE); + SetTickleState(TickleState::TickleState_Idle); + } + else { + MxDSAction* action = m_action; + MxPresenter::EndAction(); + + if (m_subscriber) { + delete m_subscriber; + m_subscriber = NULL; + } + + if (action && action->GetUnknown8c()) { + NotificationManager()->Send( + action->GetUnknown8c(), + &MxEndActionNotificationParam(c_notificationEndAction, this, action, FALSE) + ); + } + } } // OFFSET: LEGO1 0x100b5f10 STUB diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index b4b430a3..469e058a 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -92,7 +92,7 @@ void MxOmni::Vtable0x2c() } // OFFSET: LEGO1 0x100aefb0 -MxEntity* MxOmni::FindWorld(const char*, MxS32, MxCore*) +MxEntity* MxOmni::FindWorld(const char*, MxS32, MxPresenter*) { return NULL; } diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 562de18a..bdafe9c1 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -14,6 +14,7 @@ class MxNotificationManager; class MxNotificationParam; class MxObjectFactory; class MxOmniCreateParam; +class MxPresenter; class MxSoundManager; class MxStreamer; class MxTickleManager; @@ -46,7 +47,7 @@ public: virtual MxResult DeleteObject(MxDSAction& p_dsAction); // vtable+24 virtual MxBool DoesEntityExist(MxDSAction& p_dsAction); // vtable+28 virtual void Vtable0x2c(); // vtable+2c - virtual MxEntity* FindWorld(const char*, MxS32, MxCore*); // vtable+30 + virtual MxEntity* FindWorld(const char*, MxS32, MxPresenter*); // vtable+30 virtual void NotifyCurrentEntity(MxNotificationParam* p_param); // vtable+34 virtual void StartTimer(); // vtable+38 virtual void StopTimer(); // vtable+3c diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 1ff02c7a..8843bef5 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -5,6 +5,7 @@ #include "legoomni.h" #include "mxactionnotificationparam.h" #include "mxautolocker.h" +#include "mxcompositepresenter.h" #include "mxdsanim.h" #include "mxdssound.h" #include "mxnotificationmanager.h" @@ -22,7 +23,7 @@ void MxPresenter::Init() m_action = NULL; m_location = MxPoint32(0, 0); m_displayZ = 0; - m_unkPresenter = NULL; + m_compositePresenter = NULL; m_previousTickleStates = 0; } @@ -49,24 +50,24 @@ void MxPresenter::ParseExtra() MxS32 val = token ? atoi(token) : 0; MxEntity* result = MxOmni::GetInstance()->FindWorld(t_token, val, this); - m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_Parsed); + m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_World); if (result) - SendTo_unkPresenter(MxOmni::GetInstance()); + SendToCompositePresenter(MxOmni::GetInstance()); } } } // OFFSET: LEGO1 0x100b5120 -void MxPresenter::SendTo_unkPresenter(MxOmni* p_omni) +void MxPresenter::SendToCompositePresenter(MxOmni* p_omni) { - if (m_unkPresenter) { + if (m_compositePresenter) { MxAutoLocker lock(&m_criticalSection); - NotificationManager()->Send(m_unkPresenter, &MxNotificationParam(MXPRESENTER_NOTIFICATION, this)); + NotificationManager()->Send(m_compositePresenter, &MxNotificationParam(MXPRESENTER_NOTIFICATION, this)); m_action->SetUnknown8c(p_omni ? p_omni : MxOmni::GetInstance()); - m_unkPresenter = NULL; + m_compositePresenter = NULL; } } @@ -138,8 +139,10 @@ void MxPresenter::EndAction() { if (this->m_action == FALSE) return; + MxAutoLocker lock(&this->m_criticalSection); - if (!this->m_unkPresenter) { + + if (!this->m_compositePresenter) { MxOmni::GetInstance()->NotifyCurrentEntity( &MxEndActionNotificationParam(c_notificationEndAction, NULL, this->m_action, TRUE) ); diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index a126a370..ea552845 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -8,6 +8,7 @@ #include "mxomni.h" #include "mxpoint32.h" +class MxCompositePresenter; class MxStreamController; // VTABLE 0x100d4d38 @@ -75,14 +76,15 @@ public: protected: __declspec(dllexport) void Init(); - void SendTo_unkPresenter(MxOmni*); - TickleState m_currentTickleState; // 0x8 - MxU32 m_previousTickleStates; // 0x0c - MxPoint32 m_location; // 0x10 - MxS32 m_displayZ; // 0x18 - MxDSAction* m_action; // 0x1c - MxCriticalSection m_criticalSection; // 0x20 - MxPresenter* m_unkPresenter; // 0x3c + void SendToCompositePresenter(MxOmni*); + + TickleState m_currentTickleState; // 0x8 + MxU32 m_previousTickleStates; // 0x0c + MxPoint32 m_location; // 0x10 + MxS32 m_displayZ; // 0x18 + MxDSAction* m_action; // 0x1c + MxCriticalSection m_criticalSection; // 0x20 + MxCompositePresenter* m_compositePresenter; // 0x3c }; const char* PresenterNameDispatch(const MxDSAction&); diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 0e60855e..0df51929 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -468,7 +468,7 @@ void MxTransitionManager::SetWaitIndicator(MxVideoPresenter* p_waitIndicator) { // End current wait indicator if (m_waitIndicator != NULL) { - m_waitIndicator->GetAction()->SetFlags(m_waitIndicator->GetAction()->GetFlags() & ~MxDSAction::Flag_Parsed); + m_waitIndicator->GetAction()->SetFlags(m_waitIndicator->GetAction()->GetFlags() & ~MxDSAction::Flag_World); m_waitIndicator->EndAction(); m_waitIndicator = NULL; }