From 743e042564bc6a9f44a0367b796e1ab169446161 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Mon, 29 Jan 2024 17:46:22 -0500 Subject: [PATCH] Finish MxControlPresenter (#505) * Push changes * fix order * use MxBitmap::Start * Fixes/changes --------- Co-authored-by: Christian Semmler --- .../legoomni/include/mxcontrolpresenter.h | 5 +- .../src/control/mxcontrolpresenter.cpp | 116 ++++++++++++++++-- LEGO1/omni/include/mxcompositepresenter.h | 2 + LEGO1/omni/include/mxutil.h | 3 + LEGO1/omni/include/mxvideopresenter.h | 3 +- LEGO1/omni/src/common/mxutil.cpp | 15 +++ 6 files changed, 133 insertions(+), 11 deletions(-) diff --git a/LEGO1/lego/legoomni/include/mxcontrolpresenter.h b/LEGO1/lego/legoomni/include/mxcontrolpresenter.h index 34b3082d..0903f557 100644 --- a/LEGO1/lego/legoomni/include/mxcontrolpresenter.h +++ b/LEGO1/lego/legoomni/include/mxcontrolpresenter.h @@ -5,6 +5,7 @@ #include "mxcompositepresenter.h" class LegoControlManagerEvent; +class MxVideoPresenter; // VTABLE: LEGO1 0x100d7b88 // SIZE 0x5c @@ -36,12 +37,12 @@ class MxControlPresenter : public MxCompositePresenter { virtual void Enable(MxBool p_enable) override; // vtable+0x54 virtual MxBool VTable0x64(undefined4 p_undefined) override; // vtable+0x64 virtual void VTable0x68(MxBool p_unk0x50); // vtable+0x68 - virtual void VTable0x6c(undefined2); // vtable+0x6c + virtual void VTable0x6c(MxS16); // vtable+0x6c MxBool FUN_10044480(LegoControlManagerEvent* p_event, MxPresenter* p_presenter); private: - MxBool FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter); + MxBool FUN_10044270(MxS32 p_x, MxS32 p_y, MxVideoPresenter* p_presenter); void FUN_10044540(undefined2); undefined2 m_unk0x4c; // 0x4c diff --git a/LEGO1/lego/legoomni/src/control/mxcontrolpresenter.cpp b/LEGO1/lego/legoomni/src/control/mxcontrolpresenter.cpp index ad19bb94..ae0288f7 100644 --- a/LEGO1/lego/legoomni/src/control/mxcontrolpresenter.cpp +++ b/LEGO1/lego/legoomni/src/control/mxcontrolpresenter.cpp @@ -2,8 +2,11 @@ #include "define.h" #include "legocontrolmanager.h" +#include "mxdsmultiaction.h" #include "mxticklemanager.h" +#include "mxtimer.h" #include "mxutil.h" +#include "mxvideopresenter.h" DECOMP_SIZE_ASSERT(MxControlPresenter, 0x5c) @@ -99,11 +102,90 @@ void MxControlPresenter::EndAction() } } -// STUB: LEGO1 0x10044270 -MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxPresenter* p_presenter) +// FUNCTION: LEGO1 0x10044270 +MxBool MxControlPresenter::FUN_10044270(MxS32 p_x, MxS32 p_y, MxVideoPresenter* p_presenter) { - // TODO - return TRUE; + if (m_unk0x4c == 3) { + MxVideoPresenter* frontPresenter = (MxVideoPresenter*) m_list.front(); + + if (p_presenter == frontPresenter || frontPresenter->GetDisplayZ() < frontPresenter->GetDisplayZ()) { + if (p_presenter->VTable0x7c()) { + MxS32 height = frontPresenter->GetHeight(); + MxS32 width = frontPresenter->GetWidth(); + + if (frontPresenter->GetLocation().GetX() <= p_x && + p_x < width - 1 + frontPresenter->GetLocation().GetY() && + frontPresenter->GetLocation().GetY() <= p_y && + p_y < height - 1 + frontPresenter->GetLocation().GetY()) { + MxU8* start; + + if (frontPresenter->GetAlphaMask() == NULL) { + start = frontPresenter->GetBitmap()->GetStart( + p_x - frontPresenter->GetLocation().GetX(), + p_y - frontPresenter->GetLocation().GetY() + ); + } + else { + start = NULL; + } + + m_unk0x56 = 0; + if (m_unk0x58 == NULL) { + if (*start != 0) { + m_unk0x56 = 1; + } + } + else { + for (MxS16 i = 1; i <= *m_unk0x58; i++) { + if (m_unk0x58[i] == *start) { + m_unk0x56 = i; + break; + } + } + } + + if (m_unk0x56) { + return TRUE; + } + } + } + } + } + else { + if (ContainsPresenter(m_list, p_presenter)) { + if (m_unk0x4c == 2) { + MxS32 width = p_presenter->GetWidth(); + MxS32 height = p_presenter->GetHeight(); + + if (m_unk0x52 == 2 && m_unk0x54 == 2) { + MxS16 val; + if (p_x < p_presenter->GetLocation().GetX() + width / 2) { + val = 3; + if (p_y < p_presenter->GetLocation().GetY() + height / 2) { + val = 1; + } + m_unk0x56 = val; + return TRUE; + } + + val = 4; + if (p_y < p_presenter->GetLocation().GetY() + height / 2) { + val = 2; + } + + m_unk0x56 = val; + return TRUE; + } + } + else { + m_unk0x56 = -1; + } + + return TRUE; + } + } + + return FALSE; } // FUNCTION: LEGO1 0x10044480 @@ -122,7 +204,7 @@ MxBool MxControlPresenter::FUN_10044480(LegoControlManagerEvent* p_event, MxPres } break; case c_notificationButtonDown: - if (FUN_10044270(p_event->GetX(), p_event->GetY(), p_presenter)) { + if (FUN_10044270(p_event->GetX(), p_event->GetY(), (MxVideoPresenter*) p_presenter)) { p_event->SetClickedObjectId(m_action->GetObjectId()); p_event->SetClickedAtom(m_action->GetAtomId().GetInternal()); VTable0x6c(m_unk0x56); @@ -137,10 +219,28 @@ MxBool MxControlPresenter::FUN_10044480(LegoControlManagerEvent* p_event, MxPres return FALSE; } -// STUB: LEGO1 0x10044540 -void MxControlPresenter::VTable0x6c(undefined2) +// FUNCTION: LEGO1 0x10044540 +void MxControlPresenter::VTable0x6c(MxS16 p_val) { - // TODO + if (p_val == -1) { + if ((MxS16) ((MxDSMultiAction*) m_action)->GetActionList()->GetCount() - m_unk0x4e == 1) { + m_unk0x4e = 0; + } + else { + m_unk0x4e++; + } + } + else { + m_unk0x4e = p_val; + } + + m_action->SetUnknown90(Timer()->GetTime()); + + MxS16 i = 0; + for (MxCompositePresenterList::iterator it = m_list.begin(); it != m_list.end(); it++) { + (*it)->Enable((m_unk0x4c == 3 && m_unk0x4e == 0 || !IsEnabled()) ? FALSE : m_unk0x4e == i); + i++; + } } // FUNCTION: LEGO1 0x10044610 diff --git a/LEGO1/omni/include/mxcompositepresenter.h b/LEGO1/omni/include/mxcompositepresenter.h index 066a9ae2..122778d6 100644 --- a/LEGO1/omni/include/mxcompositepresenter.h +++ b/LEGO1/omni/include/mxcompositepresenter.h @@ -46,6 +46,8 @@ class MxCompositePresenter : public MxPresenter { return TRUE; } // vtable+0x64 + inline MxCompositePresenterList& GetList() { return m_list; } + protected: MxCompositePresenterList m_list; // 0x40 }; diff --git a/LEGO1/omni/include/mxutil.h b/LEGO1/omni/include/mxutil.h index e043ebd4..c85259bb 100644 --- a/LEGO1/omni/include/mxutil.h +++ b/LEGO1/omni/include/mxutil.h @@ -8,6 +8,8 @@ class MxDSFile; class MxDSObject; class MxDSAction; +class MxCompositePresenterList; +class MxPresenter; template inline T Abs(T p_t) @@ -71,6 +73,7 @@ MxBool GetRectIntersection( void MakeSourceName(char*, const char*); void SetOmniUserMessage(void (*)(const char*, int)); +MxBool ContainsPresenter(MxCompositePresenterList& p_presenterList, MxPresenter* p_presenter); void FUN_100b7220(MxDSAction* p_action, MxU32 p_newFlags, MxBool p_setFlags); MxDSObject* CreateStreamObject(MxDSFile*, MxS16); diff --git a/LEGO1/omni/include/mxvideopresenter.h b/LEGO1/omni/include/mxvideopresenter.h index d6ed46fa..2fc3b1f4 100644 --- a/LEGO1/omni/include/mxvideopresenter.h +++ b/LEGO1/omni/include/mxvideopresenter.h @@ -64,7 +64,7 @@ class MxVideoPresenter : public MxMediaPresenter { virtual LPDIRECTDRAWSURFACE VTable0x78() { return m_unk0x58; } // vtable+0x78 // FUNCTION: LEGO1 0x1000c7c0 - virtual MxBool VTable0x7c() { return (m_bitmap != NULL) || (m_alpha != NULL); } // vtable+0x7c + virtual MxBool VTable0x7c() { return m_bitmap != NULL || m_alpha != NULL; } // vtable+0x7c // FUNCTION: LEGO1 0x1000c7e0 virtual MxS32 GetWidth() { return m_alpha ? m_alpha->m_width : m_bitmap->GetBmiWidth(); } // vtable+0x80 @@ -91,6 +91,7 @@ class MxVideoPresenter : public MxMediaPresenter { inline MxS32 PrepareRects(MxRect32& p_rectDest, MxRect32& p_rectSrc); inline MxBitmap* GetBitmap() { return m_bitmap; } + inline AlphaMask* GetAlphaMask() { return m_alpha; } inline void SetBit0(BOOL p_e) { m_flags.m_bit0 = p_e; } inline void SetBit1(BOOL p_e) { m_flags.m_bit1 = p_e; } diff --git a/LEGO1/omni/src/common/mxutil.cpp b/LEGO1/omni/src/common/mxutil.cpp index 29b71863..d06b2653 100644 --- a/LEGO1/omni/src/common/mxutil.cpp +++ b/LEGO1/omni/src/common/mxutil.cpp @@ -1,10 +1,12 @@ #include "mxutil.h" +#include "mxcompositepresenter.h" #include "mxdsaction.h" #include "mxdsactionlist.h" #include "mxdsfile.h" #include "mxdsmultiaction.h" #include "mxdsobject.h" +#include "mxpresenterlist.h" #include "mxrect32.h" // GLOBAL: LEGO1 0x101020e8 @@ -109,6 +111,19 @@ MxBool KeyValueStringParse(char* p_outputValue, const char* p_key, const char* p return didMatch; } +// FUNCTION: LEGO1 0x100b7170 +MxBool ContainsPresenter(MxCompositePresenterList& p_presenterList, MxPresenter* p_presenter) +{ + for (MxCompositePresenterList::iterator it = p_presenterList.begin(); it != p_presenterList.end(); it++) { + if (p_presenter == *it || (*it)->IsA("MxCompositePresenter") && + ContainsPresenter(((MxCompositePresenter*) *it)->GetList(), p_presenter)) { + return TRUE; + } + } + + return FALSE; +} + // FUNCTION: LEGO1 0x100b7210 void SetOmniUserMessage(void (*p_userMsg)(const char*, int)) {