From 2b3f7cbfc1f9ccf8c9f7c4649974aac3d31e87ca Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 4 Sep 2023 18:33:38 -0400 Subject: [PATCH] Add tickle states and implement/match MxPresenter::Tickle (#119) * Implement/match MxPresenter::Tickle * Remove space * Explicit inline for aesthetics --- LEGO1/mxdsaction.cpp | 4 +- LEGO1/mxdsaction.h | 10 +++- LEGO1/mxpresenter.cpp | 116 +++++++++++++++++++++++++++++------------- LEGO1/mxpresenter.h | 51 ++++++++++++------- 4 files changed, 125 insertions(+), 56 deletions(-) diff --git a/LEGO1/mxdsaction.cpp b/LEGO1/mxdsaction.cpp index 32bc4f0d..e9b65037 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -94,8 +94,8 @@ void MxDSAction::Deserialize(char **p_source, MxS16 p_unk24) { MxDSObject::Deserialize(p_source, p_unk24); - this->m_flags = *(DWORD*) *p_source; - *p_source += sizeof(DWORD); + this->m_flags = *(MxU32*) *p_source; + *p_source += sizeof(MxU32); this->m_startTime = *(DWORD*) *p_source; *p_source += sizeof(DWORD); this->m_duration = *(MxLong*) *p_source; diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 843d8275..a85e6494 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -10,6 +10,11 @@ class MxDSAction : public MxDSObject { public: + enum + { + Flag_Enabled = 0x20, + }; + __declspec(dllexport) MxDSAction(); __declspec(dllexport) virtual ~MxDSAction(); @@ -42,9 +47,12 @@ class MxDSAction : public MxDSObject void AppendData(MxU16 p_unkLength, const char *p_unkData); + inline MxU32 GetFlags() { return this->m_flags; } + inline void SetFlags(MxU32 m_flags) { this->m_flags = m_flags; } + private: MxU32 m_sizeOnDisk; - DWORD m_flags; + MxU32 m_flags; DWORD m_startTime; protected: diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 9d8722b6..5fbdb8e4 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -1,24 +1,18 @@ #include "mxpresenter.h" +#include "mxautolocker.h" #include "decomp.h" DECOMP_SIZE_ASSERT(MxPresenter, 0x40); -// OFFSET: LEGO1 0x1000bee0 -void MxPresenter::DoneTickle() -{ - m_previousTickleFlags |= 1 << m_currentTickleFlag; - m_currentTickleFlag = 0; -} - // OFFSET: LEGO1 0x100b4d50 void MxPresenter::Init() { - m_currentTickleFlag = 0; + m_currentTickleState = TickleState_Idle; m_action = NULL; m_unk0x18 = 0; m_unk0x3c = 0; - m_previousTickleFlags = 0; + m_previousTickleStates = 0; m_unk0x10 = 0; m_unk0x14 = 0; } @@ -34,10 +28,42 @@ MxPresenter::~MxPresenter() { } -// OFFSET: LEGO1 0x100b5200 STUB +// OFFSET: LEGO1 0x100b5200 MxLong MxPresenter::Tickle() { - // TODO + MxAutoLocker lock(&this->m_criticalSection); + + switch (this->m_currentTickleState) { + case TickleState_Ready: + this->ReadyTickle(); + + if (m_currentTickleState != TickleState_Starting) + break; + case TickleState_Starting: + this->StartingTickle(); + + if (m_currentTickleState != TickleState_Streaming) + break; + case TickleState_Streaming: + this->StreamingTickle(); + + if (m_currentTickleState != TickleState_Repeating) + break; + case TickleState_Repeating: + this->RepeatingTickle(); + + if (m_currentTickleState != TickleState_unk5) + break; + case TickleState_unk5: + this->Unk5Tickle(); + + if (m_currentTickleState != TickleState_Done) + break; + case TickleState_Done: + this->DoneTickle(); + default: + break; + } return 0; } @@ -56,10 +82,23 @@ void MxPresenter::EndAction() // TODO } -// OFFSET: LEGO1 0x100b52d0 STUB -void MxPresenter::Enable(unsigned char) +// OFFSET: LEGO1 0x100b52d0 +void MxPresenter::Enable(MxBool p_enable) { - // TODO + if (this->m_action && this->IsEnabled() != p_enable) { + MxU32 flags = this->m_action->GetFlags(); + + if (p_enable) + this->m_action->SetFlags(flags | MxDSAction::Flag_Enabled); + else + this->m_action->SetFlags(flags & ~MxDSAction::Flag_Enabled); + } +} + +// OFFSET: LEGO1 0x100b54c0 +MxBool MxPresenter::IsEnabled() +{ + return this->m_action && this->m_action->GetFlags() & MxDSAction::Flag_Enabled; } // OFFSET: LEGO1 0x1000be30 @@ -68,39 +107,47 @@ void MxPresenter::VTable0x14() } // OFFSET: LEGO1 0x1000be40 -void MxPresenter::VTable0x18() +void MxPresenter::ReadyTickle() { ParseExtra(); - m_previousTickleFlags |= 1 << (unsigned char)m_currentTickleFlag; - m_currentTickleFlag = 2; + + m_previousTickleStates |= 1 << (unsigned char)m_currentTickleState; + m_currentTickleState = TickleState_Starting; } // OFFSET: LEGO1 0x1000be60 -void MxPresenter::VTable0x1c() +void MxPresenter::StartingTickle() { - m_previousTickleFlags |= 1 << (unsigned char)m_currentTickleFlag; - m_currentTickleFlag = 3; + m_previousTickleStates |= 1 << (unsigned char)m_currentTickleState; + m_currentTickleState = TickleState_Streaming; } // OFFSET: LEGO1 0x1000be80 -void MxPresenter::VTable0x20() +void MxPresenter::StreamingTickle() { - m_previousTickleFlags |= 1 << (unsigned char)m_currentTickleFlag; - m_currentTickleFlag = 4; + m_previousTickleStates |= 1 << (unsigned char)m_currentTickleState; + m_currentTickleState = TickleState_Repeating; } // OFFSET: LEGO1 0x1000bea0 -void MxPresenter::VTable0x24() +void MxPresenter::RepeatingTickle() { - m_previousTickleFlags |= 1 << (unsigned char)m_currentTickleFlag; - m_currentTickleFlag = 5; + m_previousTickleStates |= 1 << (unsigned char)m_currentTickleState; + m_currentTickleState = TickleState_unk5; } // OFFSET: LEGO1 0x1000bec0 -void MxPresenter::VTable0x28() +void MxPresenter::Unk5Tickle() { - m_previousTickleFlags |= 1 << (unsigned char)m_currentTickleFlag; - m_currentTickleFlag = 6; + m_previousTickleStates |= 1 << (unsigned char)m_currentTickleState; + m_currentTickleState = TickleState_Done; +} + +// OFFSET: LEGO1 0x1000bee0 +void MxPresenter::DoneTickle() +{ + m_previousTickleStates |= 1 << m_currentTickleState; + m_currentTickleState = TickleState_Idle; } // OFFSET: LEGO1 0x1000bf70 @@ -114,17 +161,18 @@ void MxPresenter::InitVirtual() { Init(); } + // OFFSET: LEGO1 0x1000bf90 -void MxPresenter::VTable0x44(undefined4 param) +void MxPresenter::SetTickleState(TickleState p_tickleState) { - m_previousTickleFlags |= 1 << (unsigned char)m_currentTickleFlag; - m_currentTickleFlag = param; + m_previousTickleStates |= 1 << (unsigned char)m_currentTickleState; + m_currentTickleState = p_tickleState; } // OFFSET: LEGO1 0x1000bfb0 -unsigned char MxPresenter::VTable0x48(unsigned char param) +MxBool MxPresenter::HasTickleStatePassed(TickleState p_tickleState) { - return m_previousTickleFlags & (1 << param); + return m_previousTickleStates & (1 << (unsigned char)p_tickleState); } // OFFSET: LEGO1 0x1000bfc0 diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 4bb7be10..6f50984e 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -2,21 +2,32 @@ #define MXPRESENTER_H #include "mxcore.h" - +#include "mxdsaction.h" #include "mxcriticalsection.h" #include "decomp.h" class MxStreamController; -class MxDSAction; +// VTABLE 0x100d4d38 class MxPresenter : public MxCore { public: - MxPresenter() { - Init(); - } + enum TickleState + { + TickleState_Idle = 0, + TickleState_Ready, + TickleState_Starting, + TickleState_Streaming, + TickleState_Repeating, + TickleState_unk5, + TickleState_Done, + }; + + MxPresenter() { Init(); } + __declspec(dllexport) virtual ~MxPresenter(); // vtable+0x0 + __declspec(dllexport) virtual MxLong Tickle() override; // vtable+0x8 // OFFSET: LEGO1 0x1000bfe0 inline virtual const char *ClassName() const override// vtable+0xc @@ -31,40 +42,42 @@ class MxPresenter : public MxCore return !strcmp(name, MxPresenter::ClassName()) || MxCore::IsA(name); } - __declspec(dllexport) virtual MxLong Tickle() override; // vtable+0x8 virtual void VTable0x14(); // vtable+0x14 - virtual void VTable0x18(); // vtable+0x18 - virtual void VTable0x1c(); // vtable+0x1c - virtual void VTable0x20(); // vtable+0x20 - virtual void VTable0x24(); // vtable+0x24 - virtual void VTable0x28(); // vtable+0x28 + virtual void ReadyTickle(); // vtable+0x18 + virtual void StartingTickle(); // vtable+0x1c + virtual void StreamingTickle(); // vtable+0x20 + virtual void RepeatingTickle(); // vtable+0x24 + virtual void Unk5Tickle(); // vtable+0x28 + protected: __declspec(dllexport) virtual void DoneTickle(); // vtable+0x2c __declspec(dllexport) virtual void ParseExtra(); // vtable+0x30 + public: virtual undefined4 VTable0x34(); // vtable+0x34 virtual void InitVirtual(); // vtable+0x38 __declspec(dllexport) virtual MxLong StartAction(MxStreamController *, MxDSAction *); // vtable+0x3c __declspec(dllexport) virtual void EndAction(); // vtable+0x40 - virtual void VTable0x44(undefined4 param); // vtable+0x44 - virtual unsigned char VTable0x48(unsigned char param); // vtable+0x48 + 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 - __declspec(dllexport) virtual void Enable(unsigned char); // vtable+0x54 + __declspec(dllexport) virtual void Enable(MxBool p_enable); // vtable+0x54 + + MxBool IsEnabled(); + protected: __declspec(dllexport) void Init(); -public: - MxS32 m_currentTickleFlag; // 0x8 - MxU32 m_previousTickleFlags; +private: + MxS32 m_currentTickleState; // 0x8 + MxU32 m_previousTickleStates; undefined4 m_unk0x10; undefined4 m_unk0x14; undefined4 m_unk0x18; MxDSAction* m_action; // 0 MxCriticalSection m_criticalSection; undefined4 m_unk0x3c; - - // VTABLE 0x100d4d38 }; #endif // MXPRESENTER_H