From 23b9d47e8a2099b7d19865ca30b20c5e57ea1ed9 Mon Sep 17 00:00:00 2001 From: vMidz <147055059+vMidz@users.noreply.github.com> Date: Tue, 10 Oct 2023 20:05:04 +0300 Subject: [PATCH] implement EndAction (#196) * implement EndAction implement EndAction +offsets commenets * Refactor MxParam/MxNotificationParam * Add correct address for destructor * Make MxNoticiationParam more concise --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 3 +- LEGO1/mxactionnotificationparam.cpp | 16 ++++++++ LEGO1/mxactionnotificationparam.h | 59 +++++++++++++++++++++++++++++ LEGO1/mxdsobject.h | 18 ++++----- LEGO1/mxnotificationmanager.cpp | 4 +- LEGO1/mxnotificationmanager.h | 18 +++------ LEGO1/mxnotificationparam.cpp | 11 ++++++ LEGO1/mxnotificationparam.h | 35 +++++++++++++++++ LEGO1/mxomni.cpp | 7 ++-- LEGO1/mxomni.h | 2 +- LEGO1/mxomnicreateparam.h | 4 +- LEGO1/mxomnicreateparambase.cpp | 1 - LEGO1/mxomnicreateparambase.h | 12 ------ LEGO1/mxparam.cpp | 10 ----- LEGO1/mxparam.h | 36 +----------------- LEGO1/mxpresenter.cpp | 20 ++++++++-- LEGO1/mxpresenter.h | 10 ++--- LEGO1/mxstreamer.cpp | 7 ++-- LEGO1/mxstreamer.h | 9 ++--- LEGO1/mxtransitionmanager.cpp | 2 +- 20 files changed, 177 insertions(+), 107 deletions(-) create mode 100644 LEGO1/mxactionnotificationparam.cpp create mode 100644 LEGO1/mxactionnotificationparam.h create mode 100644 LEGO1/mxnotificationparam.cpp create mode 100644 LEGO1/mxnotificationparam.h delete mode 100644 LEGO1/mxomnicreateparambase.cpp delete mode 100644 LEGO1/mxomnicreateparambase.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2e0fed5a..2cedd429 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -93,6 +93,7 @@ add_library(lego1 SHARED LEGO1/legoworld.cpp LEGO1/legoworldpresenter.cpp LEGO1/motorcycle.cpp + LEGO1/mxactionnotificationparam.cpp LEGO1/mxatomid.cpp LEGO1/mxatomidcounter.cpp LEGO1/mxaudiomanager.cpp @@ -144,11 +145,11 @@ add_library(lego1 SHARED LEGO1/mxmusicmanager.cpp LEGO1/mxmusicpresenter.cpp LEGO1/mxnotificationmanager.cpp + LEGO1/mxnotificationparam.cpp LEGO1/mxobjectfactory.cpp LEGO1/mxomni.cpp LEGO1/mxomnicreateflags.cpp LEGO1/mxomnicreateparam.cpp - LEGO1/mxomnicreateparambase.cpp LEGO1/mxpalette.cpp LEGO1/mxparam.cpp LEGO1/mxpresenter.cpp diff --git a/LEGO1/mxactionnotificationparam.cpp b/LEGO1/mxactionnotificationparam.cpp new file mode 100644 index 00000000..33395c4d --- /dev/null +++ b/LEGO1/mxactionnotificationparam.cpp @@ -0,0 +1,16 @@ +#include "mxactionnotificationparam.h" + +DECOMP_SIZE_ASSERT(MxActionNotificationParam, 0x14) +DECOMP_SIZE_ASSERT(MxEndActionNotificationParam, 0x14) + +// OFFSET: LEGO1 0x100510c0 +MxNotificationParam *MxActionNotificationParam::Clone() +{ + return new MxActionNotificationParam(this->m_type, this->m_sender, this->m_action, this->m_realloc); +} + +// OFFSET: LEGO1 0x10051270 +MxNotificationParam *MxEndActionNotificationParam::Clone() +{ + return new MxEndActionNotificationParam(MXSTREAMER_UNKNOWN, this->m_sender, this->m_action, this->m_realloc); +} diff --git a/LEGO1/mxactionnotificationparam.h b/LEGO1/mxactionnotificationparam.h new file mode 100644 index 00000000..4229e252 --- /dev/null +++ b/LEGO1/mxactionnotificationparam.h @@ -0,0 +1,59 @@ +#ifndef MXACTIONNOTIFICATIONPARAM_H +#define MXACTIONNOTIFICATIONPARAM_H + +#include "mxnotificationparam.h" +#include "mxdsaction.h" + +// VTABLE 0x100d8350 +// SIZE 0x14 +class MxActionNotificationParam : public MxNotificationParam +{ +public: + inline MxActionNotificationParam(MxParamType p_type, MxCore *p_sender, MxDSAction *p_action, MxBool p_reallocAction) : MxNotificationParam(p_type, p_sender) + { + MxDSAction *oldAction = p_action; + this->m_realloc = p_reallocAction; + + if (p_reallocAction) + this->m_action = new MxDSAction(); + else { + this->m_action = oldAction; + return; + } + + this->m_action->SetAtomId(oldAction->GetAtomId()); + this->m_action->SetObjectId(oldAction->GetObjectId()); + this->m_action->SetUnknown24(oldAction->GetUnknown24()); + } + + // OFFSET: LEGO1 0x10051050 + inline virtual MxActionNotificationParam::~MxActionNotificationParam() override + { + if (!this->m_realloc) + return; + + if (this->m_action) + delete this->m_action; + } + + virtual MxNotificationParam *Clone() override; // vtable+0x4 + +protected: + MxDSAction *m_action; // 0xc + MxBool m_realloc; // 0x10 +}; + +// VTABLE 0x100d8358 +// SIZE 0x14 +class MxEndActionNotificationParam : public MxActionNotificationParam +{ +public: + inline MxEndActionNotificationParam(MxParamType p_type, MxCore *p_sender, MxDSAction *p_action, MxBool p_reallocAction) + : MxActionNotificationParam(p_type, p_sender, p_action, p_reallocAction) {} + + inline virtual ~MxEndActionNotificationParam() override {}; // 0x100513a0 + + virtual MxNotificationParam *Clone() override; // vtable+0x4 +}; + +#endif \ No newline at end of file diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index e340789a..cfb5d6a1 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -47,15 +47,15 @@ class MxDSObject : public MxCore inline MxDSType GetType() const { return (MxDSType) this->m_type; } private: - MxU32 m_sizeOnDisk; - MxU16 m_type; - char* m_sourceName; - undefined4 m_unk14; - char *m_objectName; - MxU32 m_objectId; - MxAtomId m_atomId; - MxS16 m_unk24; - undefined4 m_unk28; + MxU32 m_sizeOnDisk; // 0x8 + MxU16 m_type; // 0xc + char* m_sourceName; // 0x10 + undefined4 m_unk14; // 0x14 + char *m_objectName; // 0x18 + MxU32 m_objectId; // 0x1c + MxAtomId m_atomId; // 0x20 + MxS16 m_unk24; // 0x24 + undefined4 m_unk28; // 0x28 }; MxDSObject *DeserializeDSObjectDispatch(char **, MxS16); diff --git a/LEGO1/mxnotificationmanager.cpp b/LEGO1/mxnotificationmanager.cpp index cb653ba4..017df73d 100644 --- a/LEGO1/mxnotificationmanager.cpp +++ b/LEGO1/mxnotificationmanager.cpp @@ -13,7 +13,7 @@ DECOMP_SIZE_ASSERT(MxNotification, 0x8); DECOMP_SIZE_ASSERT(MxNotificationManager, 0x40); // OFFSET: LEGO1 0x100ac220 -MxNotification::MxNotification(MxCore *p_target, MxParam *p_param) +MxNotification::MxNotification(MxCore *p_target, MxNotificationParam *p_param) { m_target = p_target; m_param = p_param->Clone(); @@ -161,7 +161,7 @@ void MxNotificationManager::FlushPending(MxCore *p_listener) } // OFFSET: LEGO1 0x100ac6c0 -MxResult MxNotificationManager::Send(MxCore *p_listener, MxParam *p_param) +MxResult MxNotificationManager::Send(MxCore *p_listener, MxNotificationParam *p_param) { MxAutoLocker lock(&m_lock); diff --git a/LEGO1/mxnotificationmanager.h b/LEGO1/mxnotificationmanager.h index 1c2aee7c..89908871 100644 --- a/LEGO1/mxnotificationmanager.h +++ b/LEGO1/mxnotificationmanager.h @@ -3,6 +3,7 @@ #include "mxcore.h" #include "mxcriticalsection.h" +#include "mxnotificationparam.h" #include "mxtypes.h" #include "compat.h" @@ -10,22 +11,15 @@ class MxNotification { public: - MxNotification(MxCore *p_target, MxParam *p_param); + MxNotification(MxCore *p_target, MxNotificationParam *p_param); ~MxNotification(); - inline MxCore *GetTarget() - { - return m_target; - } - - inline MxParam *GetParam() - { - return m_param; - } + inline MxCore *GetTarget() { return m_target; } + inline MxNotificationParam *GetParam() { return m_param; } private: MxCore *m_target; // 0x0 - MxParam *m_param; // 0x4 + MxNotificationParam *m_param; // 0x4 }; class MxIdList : public list @@ -54,7 +48,7 @@ class MxNotificationManager : public MxCore virtual MxResult Create(MxS32 p_unk1, MxS32 p_unk2); // vtable+0x14 void Register(MxCore *p_listener); void Unregister(MxCore *p_listener); - MxResult Send(MxCore *p_listener, MxParam *p_param); + MxResult Send(MxCore *p_listener, MxNotificationParam *p_param); private: void FlushPending(MxCore *p_listener); diff --git a/LEGO1/mxnotificationparam.cpp b/LEGO1/mxnotificationparam.cpp new file mode 100644 index 00000000..16a0b41f --- /dev/null +++ b/LEGO1/mxnotificationparam.cpp @@ -0,0 +1,11 @@ +#include "mxnotificationparam.h" + +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxNotificationParam, 0xc); + +// OFFSET: LEGO1 0x10010390 +MxNotificationParam* MxNotificationParam::Clone() +{ + return new MxNotificationParam(m_type, m_sender); +} diff --git a/LEGO1/mxnotificationparam.h b/LEGO1/mxnotificationparam.h new file mode 100644 index 00000000..a02f33d8 --- /dev/null +++ b/LEGO1/mxnotificationparam.h @@ -0,0 +1,35 @@ +#ifndef MXNOTIFICATIONPARAM_H +#define MXNOTIFICATIONPARAM_H + +#include "compat.h" +#include "mxparam.h" +#include "mxtypes.h" + +class MxCore; + +enum MxParamType +{ + MXSTREAMER_UNKNOWN = 2, + MXPRESENTER_NOTIFICATION = 5, + MXSTREAMER_DELETE_NOTIFY = 6, + MXTRANSITIONMANAGER_TRANSITIONENDED = 24 +}; + +// VTABLE 0x100d56e0 +class MxNotificationParam : public MxParam +{ +public: + inline MxNotificationParam(MxParamType p_type, MxCore *p_sender) : MxParam(), m_type(p_type), m_sender(p_sender){} + + virtual ~MxNotificationParam() override {} // vtable+0x0 (scalar deleting destructor) + virtual MxNotificationParam *Clone(); // vtable+0x4 + + inline MxParamType GetType() const { return m_type; } + inline MxCore *GetSender() const { return m_sender; } + +protected: + MxParamType m_type; // 0x4 + MxCore *m_sender; // 0x8 +}; + +#endif // MXNOTIFICATIONPARAM_H diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 69473b0d..43b9578a 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -93,10 +93,9 @@ int MxOmni::vtable0x30(char*, int, MxCore*) return 0; } -// OFFSET: LEGO1 0x100aefc0 STUB -void MxOmni::NotifyCurrentEntity() +// OFFSET: LEGO1 0x100aefc0 +void MxOmni::NotifyCurrentEntity(MxParam *p_param) { - // TODO } // OFFSET: LEGO1 0x100b09d0 @@ -352,7 +351,7 @@ MxLong MxOmni::Notify(MxParam &p) { MxAutoLocker lock(&this->m_criticalsection); - if (p.GetType() != MXSTREAMER_UNKNOWN) + if (((MxNotificationParam&) p).GetType() != MXSTREAMER_UNKNOWN) return 0; return HandleNotificationType2(p); diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 9b2c6581..265db29b 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -45,7 +45,7 @@ class MxOmni : public MxCore virtual MxBool DoesEntityExist(MxDSAction &ds); // vtable+28 virtual void vtable0x2c(); // vtable+2c virtual int vtable0x30(char*, int, MxCore*); // vtable+30 - virtual void NotifyCurrentEntity(); // vtable+34 + virtual void NotifyCurrentEntity(MxParam *p_param); // vtable+34 virtual void StartTimer(); // vtable+38 virtual void StopTimer(); // vtable+3c virtual MxBool IsTimerRunning(); //vtable+40 diff --git a/LEGO1/mxomnicreateparam.h b/LEGO1/mxomnicreateparam.h index 3c1059dd..d4984b24 100644 --- a/LEGO1/mxomnicreateparam.h +++ b/LEGO1/mxomnicreateparam.h @@ -4,11 +4,11 @@ #include #include "mxomnicreateflags.h" -#include "mxomnicreateparambase.h" +#include "mxparam.h" #include "mxstring.h" #include "mxvideoparam.h" -class MxOmniCreateParam : public MxOmniCreateParamBase +class MxOmniCreateParam : public MxParam { public: __declspec(dllexport) MxOmniCreateParam(const char *mediaPath, struct HWND__ *windowHandle, MxVideoParam &vparam, MxOmniCreateFlags flags); diff --git a/LEGO1/mxomnicreateparambase.cpp b/LEGO1/mxomnicreateparambase.cpp deleted file mode 100644 index 0091785d..00000000 --- a/LEGO1/mxomnicreateparambase.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "mxomnicreateparam.h" diff --git a/LEGO1/mxomnicreateparambase.h b/LEGO1/mxomnicreateparambase.h deleted file mode 100644 index 605f4d30..00000000 --- a/LEGO1/mxomnicreateparambase.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef MXOMNICREATEPARAMBASE_H -#define MXOMNICREATEPARAMBASE_H - -// FIXME: Clearly not its real name -class MxOmniCreateParamBase -{ -public: - virtual ~MxOmniCreateParamBase(){} - -}; - -#endif // MXOMNICREATEPARAMBASE_H diff --git a/LEGO1/mxparam.cpp b/LEGO1/mxparam.cpp index d7bb36b2..4faa1625 100644 --- a/LEGO1/mxparam.cpp +++ b/LEGO1/mxparam.cpp @@ -1,11 +1 @@ #include "mxparam.h" - -#include "decomp.h" - -DECOMP_SIZE_ASSERT(MxParam, 0xc); - -// OFFSET: LEGO1 0x10010390 -MxParam* MxParam::Clone() -{ - return new MxParam(m_type, m_sender); -} diff --git a/LEGO1/mxparam.h b/LEGO1/mxparam.h index d76ecdb0..8f89e2d0 100644 --- a/LEGO1/mxparam.h +++ b/LEGO1/mxparam.h @@ -1,42 +1,10 @@ #ifndef MXPARAM_H #define MXPARAM_H -#include "compat.h" -#include "mxomnicreateparambase.h" -#include "mxtypes.h" - -class MxCore; - -enum MxParamType -{ - MXSTREAMER_UNKNOWN = 2, - MXPRESENTER_NOTIFICATION = 5, - MXSTREAMER_DELETE_NOTIFY = 6, - MXTRANSITIONMANAGER_TRANSITIONENDED = 24 -}; - -// VTABLE 0x100d56e0 -class MxParam : public MxOmniCreateParamBase +class MxParam { public: - inline MxParam(MxParamType p_type, MxCore *p_sender) : MxOmniCreateParamBase(), m_type(p_type), m_sender(p_sender){} - - virtual ~MxParam() override {} // vtable+0x0 (scalar deleting destructor) - virtual MxParam *Clone(); // vtable+0x4 - - inline MxParamType GetType() const - { - return m_type; - } - - inline MxCore *GetSender() const - { - return m_sender; - } - -protected: - MxParamType m_type; // 0x4 - MxCore *m_sender; // 0x8 + virtual ~MxParam() {} }; #endif // MXPARAM_H diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index f8f60386..86e4ae26 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -6,7 +6,8 @@ #include "mxdsanim.h" #include "mxdssound.h" #include "mxnotificationmanager.h" - +#include "mxactionnotificationparam.h" +#include "mxstreamer.h" #include "decomp.h" #include "define.h" @@ -65,7 +66,7 @@ void MxPresenter::SendTo_unkPresenter(MxOmni *p_omni) if (m_unkPresenter) { MxAutoLocker lock(&m_criticalSection); - NotificationManager()->Send(m_unkPresenter, &MxParam(MXPRESENTER_NOTIFICATION, this)); + NotificationManager()->Send(m_unkPresenter, &MxNotificationParam(MXPRESENTER_NOTIFICATION, this)); m_action->SetOmni(p_omni ? p_omni : MxOmni::GetInstance()); m_unkPresenter = NULL; @@ -135,10 +136,21 @@ MxLong MxPresenter::StartAction(MxStreamController *, MxDSAction *p_action) return SUCCESS; } -// OFFSET: LEGO1 0x100b4e40 STUB +// OFFSET: LEGO1 0x100b4e40 void MxPresenter::EndAction() { - // TODO + if (this->m_action == FALSE) + return; + MxAutoLocker lock(&this->m_criticalSection); + if (!this->m_unkPresenter) + { + MxOmni::GetInstance()->NotifyCurrentEntity(&MxEndActionNotificationParam(MXSTREAMER_UNKNOWN, NULL, this->m_action, TRUE)); + } + + this->m_action = FALSE; + MxS32 previousTickleState = 1 << m_currentTickleState; + this->m_previousTickleStates |= previousTickleState; + this->m_currentTickleState = TickleState_Idle; } // OFFSET: LEGO1 0x100b52d0 diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 959533c5..bcdc5aac 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -79,11 +79,11 @@ class MxPresenter : public MxCore __declspec(dllexport) void Init(); void SendTo_unkPresenter(MxOmni *); TickleState m_currentTickleState; // 0x8 - MxU32 m_previousTickleStates; - MxPoint32 m_location; - MxS32 m_displayZ; - MxDSAction *m_action; // 0 - MxCriticalSection m_criticalSection; + MxU32 m_previousTickleStates; // 0x0c + MxPoint32 m_location; // 0x10 + MxS32 m_displayZ; // 0x18 + MxDSAction *m_action; // 0x1c + MxCriticalSection m_criticalSection; // 0x20 MxPresenter *m_unkPresenter; // 0x3c }; diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index 8e7cc231..e95e4558 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -99,7 +99,7 @@ MxLong MxStreamer::Close(const char *p) } // OFFSET: LEGO1 0x100b9700 -MxParam *MxStreamerNotification::Clone() +MxNotificationParam *MxStreamerNotification::Clone() { return new MxStreamerNotification(m_type, m_sender, m_controller); } @@ -120,7 +120,6 @@ MxStreamController *MxStreamer::GetOpenStream(const char *p_name) return NULL; } - // OFFSET: LEGO1 0x100b9930 MxResult MxStreamer::AddStreamControllerToOpenList(MxStreamController *stream) { @@ -151,7 +150,7 @@ MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action) // OFFSET: LEGO1 0x100b9b60 MxLong MxStreamer::Notify(MxParam &p) { - if (p.GetType() == MXSTREAMER_DELETE_NOTIFY) { + if (((MxNotificationParam&) p).GetType() == MXSTREAMER_DELETE_NOTIFY) { MxDSAction ds; ds.SetUnknown24(-2); @@ -178,4 +177,4 @@ MxStreamerSubClass1::MxStreamerSubClass1(undefined4 size) for (int i = 0; i >= 0; i--) { ptr[i] = 0; } -} +} \ No newline at end of file diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index 515be51b..529a564a 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -5,7 +5,7 @@ #include "decomp.h" #include "mxcore.h" -#include "mxparam.h" +#include "mxnotificationparam.h" #include "mxstreamcontroller.h" #include "mxtypes.h" @@ -40,17 +40,17 @@ class MxStreamerSubClass3 : public MxStreamerSubClass1 inline MxStreamerSubClass3() : MxStreamerSubClass1(0x80) {} }; -class MxStreamerNotification : public MxParam +class MxStreamerNotification : public MxNotificationParam { public: - inline MxStreamerNotification(MxParamType p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxParam(p_type, p_sender) + inline MxStreamerNotification(MxParamType p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxNotificationParam(p_type, p_sender) { m_controller = p_ctrlr; } virtual ~MxStreamerNotification() override {} - virtual MxParam *Clone() override; + virtual MxNotificationParam *Clone() override; MxStreamController *GetController() { return m_controller; } @@ -102,7 +102,6 @@ class MxStreamer : public MxCore list m_openStreams; // 0x8 MxStreamerSubClass2 m_subclass1; // 0x14 MxStreamerSubClass3 m_subclass2; // 0x20 - }; #endif // MXSTREAMER_H diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 66c99532..12d989c8 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -85,7 +85,7 @@ void MxTransitionManager::EndTransition(MxBool p_notifyWorld) LegoWorld *world = GetCurrentWorld(); if (world) { - world->Notify(MxParam(MXTRANSITIONMANAGER_TRANSITIONENDED, this)); + world->Notify(MxNotificationParam(MXTRANSITIONMANAGER_TRANSITIONENDED, this)); } } }