From 56f3d120964c6dea5e994132e0db4c1743575bb1 Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Sun, 1 Oct 2023 17:18:16 -0700 Subject: [PATCH 01/15] Implement MxTransitionManager ctor/dtor/rest of StartTransition (#153) --- LEGO1/mxtransitionmanager.cpp | 65 +++++++++++++++++++++++------------ LEGO1/mxtransitionmanager.h | 60 ++++++++++++++++++++++++++++++-- LEGO1/mxtypes.h | 15 ++++++++ LEGO1/mxvideoparamflags.h | 15 +------- 4 files changed, 116 insertions(+), 39 deletions(-) diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 12bd0931..c5a0cb27 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -4,16 +4,30 @@ DECOMP_SIZE_ASSERT(MxTransitionManager, 0x900); -// OFFSET: LEGO1 0x1004b8d0 STUB +// OFFSET: LEGO1 0x1004b8d0 MxTransitionManager::MxTransitionManager() { - // TODO + m_animationTimer = 0; + m_transitionType = NOT_TRANSITIONING; + m_ddSurface = NULL; + m_unk08 = 0; + m_unk1c = 0; + m_unk20.bit0 = FALSE; + m_unk28.bit0 = FALSE; + m_unk24 = 0; } -// OFFSET: LEGO1 0x1004ba00 STUB +// OFFSET: LEGO1 0x1004ba00 MxTransitionManager::~MxTransitionManager() { - // TODO + free(m_unk1c); + + if (m_unk08 != NULL) { + delete m_unk08->m_unk1c; + delete m_unk08; + } + + TickleManager()->UnregisterClient(this); } // OFFSET: LEGO1 0x1004bac0 STUB @@ -40,36 +54,43 @@ MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 // OFFSET: LEGO1 0x1004bb70 MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, MxS32 p_speed, - undefined p_unk, MxBool p_playMusicInAnim) + MxBool p_unk, MxBool p_playMusicInAnim) { - // TODO: Incomplete and far from matching - if (this->m_transitionType == NOT_TRANSITIONING) { if (!p_playMusicInAnim) { MxBackgroundAudioManager *backgroundAudioManager = BackgroundAudioManager(); backgroundAudioManager->Stop(); } - this->m_transitionType = p_animationType; - // TODO: This part of the function is mangled and I can't make out what it's doing right now + this->m_transitionType = p_animationType; - MxU32 time = timeGetTime(); - this->m_systemTime = time; + m_unk20.bit0 = p_unk; - this->m_animationSpeed = p_speed; + if (m_unk20.bit0 && m_unk08 != NULL) { + m_unk08->vtable54(1); - MxTickleManager *tickleManager = TickleManager(); - tickleManager->RegisterClient(this, p_speed); + MxTransitionManagerUnknownSubclass2 *iVar2 = m_unk08->m_unk1c; + iVar2->m_unk3c = 10000; + iVar2->m_unk30 |= 0x200; + } - LegoInputManager *inputManager = InputManager(); - inputManager->m_unk88 = TRUE; - inputManager->m_unk336 = FALSE; + MxU32 time = timeGetTime(); + this->m_systemTime = time; - LegoVideoManager *videoManager = VideoManager(); - videoManager->SetUnkE4(FALSE); + this->m_animationSpeed = p_speed; - SetAppCursor(1); - return SUCCESS; + MxTickleManager *tickleManager = TickleManager(); + tickleManager->RegisterClient(this, p_speed); + + LegoInputManager *inputManager = InputManager(); + inputManager->m_unk88 = TRUE; + inputManager->m_unk336 = FALSE; + + LegoVideoManager *videoManager = VideoManager(); + videoManager->SetUnkE4(FALSE); + + SetAppCursor(1); + return SUCCESS; } return FAILURE; -} \ No newline at end of file +} diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 1b662e98..723366c1 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -5,6 +5,52 @@ #include "mxvideopresenter.h" #include "legoomni.h" +class MxTransitionManagerUnknownSubclass2 +{ +public: + virtual ~MxTransitionManagerUnknownSubclass2(){} + + undefined m_unk04[0x2c]; + undefined4 m_unk30; + undefined4 m_unk34; + undefined4 m_unk38; + undefined4 m_unk3c; + +}; + +// TODO: Don't know what this is yet +class MxTransitionManagerUnknownSubclass1 +{ +public: + virtual ~MxTransitionManagerUnknownSubclass1(){} + + virtual void vtable04(); + virtual void vtable08(); + virtual void vtable0c(); + virtual void vtable10(); + virtual void vtable14(); + virtual void vtable18(); + virtual void vtable1c(); + virtual void vtable20(); + virtual void vtable24(); + virtual void vtable28(); + virtual void vtable2c(); + virtual void vtable30(); + virtual void vtable34(); + virtual void vtable38(); + virtual void vtable3c(); + virtual void vtable40(); + virtual void vtable44(); + virtual void vtable48(); + virtual void vtable4c(); + virtual void vtable50(); + virtual void vtable54(undefined4 p_unk1); + + undefined m_unk04[0x18]; + MxTransitionManagerUnknownSubclass2 *m_unk1c; + +}; + // VTABLE 0x100d7ea0 class MxTransitionManager : public MxCore { @@ -40,11 +86,19 @@ class MxTransitionManager : public MxCore BROKEN // Unknown what this is supposed to be, it locks the game up }; - MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, undefined p_unk, MxBool p_playMusicInAnim); + MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_unk, MxBool p_playMusicInAnim); private: - undefined m_pad00[0x20]; - undefined m_pad20[0x04]; + MxTransitionManagerUnknownSubclass1 *m_unk08; + undefined4 m_unk0c; + undefined4 m_unk10; + undefined4 m_unk14; + undefined4 m_unk18; + void *m_unk1c; + flag_bitfield m_unk20; + undefined4 m_unk24; + flag_bitfield m_unk28; + TransitionType m_transitionType; LPDIRECTDRAWSURFACE m_ddSurface; MxU16 m_animationTimer; diff --git a/LEGO1/mxtypes.h b/LEGO1/mxtypes.h index fc8d47b5..75f19d4a 100644 --- a/LEGO1/mxtypes.h +++ b/LEGO1/mxtypes.h @@ -44,4 +44,19 @@ typedef MxU8 MxBool; #define TWOCC(a, b) (((a) << 0) | ((b) << 8)) #define FOURCC(a, b, c, d) (((a) << 0) | ((b) << 8) | ((c) << 16) | ((d) << 24)) +// Must be union with struct for match. +typedef union { + struct { + MxU8 bit0: 1; + MxU8 bit1: 1; + MxU8 bit2: 1; + MxU8 bit3: 1; + MxU8 bit4: 1; + MxU8 bit5: 1; + MxU8 bit6: 1; + MxU8 bit7: 1; + }; + // BYTE all; // ? +} flag_bitfield; + #endif // MXTYPE_H diff --git a/LEGO1/mxvideoparamflags.h b/LEGO1/mxvideoparamflags.h index f25ab4bd..8d1714ed 100644 --- a/LEGO1/mxvideoparamflags.h +++ b/LEGO1/mxvideoparamflags.h @@ -3,20 +3,7 @@ #include -// Must be union with struct for match. -typedef union { - struct { - BYTE bit0: 1; - BYTE bit1: 1; - BYTE bit2: 1; - BYTE bit3: 1; - BYTE bit4: 1; - BYTE bit5: 1; - BYTE bit6: 1; - BYTE bit7: 1; - }; - // BYTE all; // ? -} flag_bitfield; +#include "mxtypes.h" class MxVideoParamFlags { From b7efd64ac1ce93f2d15f646c68d5c5917be0a17b Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 2 Oct 2023 09:51:43 -0400 Subject: [PATCH 02/15] Bootstrap MxDSSelectAction, generalize MxList (#142) * reccmp: Add ability to compare template instantiations * Add example of template instantiation comparison. * merge * Add template compare annotations for MxList instances * Bootstrap MxDSSelectAction, generalize MxList * Fix template annotations * Fix merge error * Fix merge error --------- Co-authored-by: Brendan Dougherty --- LEGO1/mxdsactionlist.h | 14 +++++++------- LEGO1/mxdsselectaction.cpp | 7 ++++--- LEGO1/mxdsselectaction.h | 10 ++++------ LEGO1/mxlist.h | 38 +++++++++++++++++++++----------------- LEGO1/mxpresenterlist.h | 14 +++++++------- LEGO1/mxstringlist.h | 23 +++++++++++++++++++++++ 6 files changed, 66 insertions(+), 40 deletions(-) create mode 100644 LEGO1/mxstringlist.h diff --git a/LEGO1/mxdsactionlist.h b/LEGO1/mxdsactionlist.h index 127dd142..fe0e162c 100644 --- a/LEGO1/mxdsactionlist.h +++ b/LEGO1/mxdsactionlist.h @@ -8,7 +8,7 @@ class MxDSAction; // VTABLE 0x100dced8 // SIZE 0x1c -class MxDSActionList : public MxList +class MxDSActionList : public MxList { public: MxDSActionList() { @@ -23,15 +23,15 @@ class MxDSActionList : public MxList undefined m_unk18; }; -typedef MxListCursorChild MxDSActionListCursor; +typedef MxListCursorChild MxDSActionListCursor; + +// OFFSET: LEGO1 0x100c9cc0 TEMPLATE +// MxListParent::Compare // OFFSET: LEGO1 0x100c9d20 TEMPLATE -// MxListParent::Destroy - -// OFFSET: LEGO1 0x100c9cd0 TEMPLATE -// MxListParent::~MxListParent +// MxListParent::Destroy // OFFSET: LEGO1 0x100c9d30 TEMPLATE -// MxList::~MxList +// MxList::~MxList #endif // MXDSACTIONLIST_H diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 1c21b466..29f69022 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -5,12 +5,13 @@ DECOMP_SIZE_ASSERT(MxDSSelectAction, 0xb0) // OFFSET: LEGO1 0x100cb2b0 MxDSSelectAction::MxDSSelectAction() { - // TODO this->SetType(MxDSType_SelectAction); + this->m_unk0xac = new MxStringList; } -// OFFSET: LEGO1 0x100cb8d0 STUB +// OFFSET: LEGO1 0x100cb8d0 MxDSSelectAction::~MxDSSelectAction() { - // TODO + if (this->m_unk0xac) + delete this->m_unk0xac; } diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index df956fbc..d513efd0 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -2,6 +2,7 @@ #define MXDSSELECTACTION_H #include "mxdsparallelaction.h" +#include "mxstringlist.h" #include "decomp.h" // VTABLE 0x100dcfc8 @@ -25,12 +26,9 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } - undefined4 m_unk0x9c; - undefined4 m_unk0xa0; - undefined4 m_unk0xa4; - undefined4 m_unk0xa8; - undefined4 m_unk0xac; - +private: + MxString m_unk0x9c; + MxStringList *m_unk0xac; }; #endif // MXDSSELECTACTION_H diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index ed4c2802..12695f82 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -4,19 +4,24 @@ #include "mxtypes.h" #include "mxcore.h" -template // SIZE 0xc +template class MxListEntry { public: MxListEntry() {} - MxListEntry(T *p_obj, MxListEntry *p_prev) { + MxListEntry(T p_obj, MxListEntry *p_prev) { m_obj = p_obj; m_prev = p_prev; m_next = NULL; } - T *m_obj; + T GetValue() { return this->m_obj; } + + friend class MxList; + friend class MxListCursor; +private: + T m_obj; MxListEntry *m_prev; MxListEntry *m_next; }; @@ -33,12 +38,12 @@ class MxListParent : public MxCore } virtual ~MxListParent() {} - virtual MxS8 Compare(T *, T *) = 0; + virtual MxS8 Compare(T, T) { return 0; }; - static void Destroy(T *) {}; + static void Destroy(T) {}; protected: MxU32 m_count; // +0x8 - void (*m_customDestructor)(T *); // +0xc + void (*m_customDestructor)(T); // +0xc }; // VTABLE 0x100d6368 @@ -54,13 +59,12 @@ class MxList : protected MxListParent virtual ~MxList(); - void Append(T*); + void Append(T); void DeleteAll(); MxU32 GetCount() { return m_count; } - void SetDestroy(void (*p_customDestructor)(T *)) { this->m_customDestructor = p_customDestructor; } + void SetDestroy(void (*p_customDestructor)(T)) { this->m_customDestructor = p_customDestructor; } friend class MxListCursor; - protected: MxListEntry *m_first; // +0x10 MxListEntry *m_last; // +0x14 @@ -79,10 +83,10 @@ class MxListCursor : public MxCore m_match = NULL; } - MxBool Find(T *p_obj); + MxBool Find(T p_obj); void Detach(); - MxBool Next(T*& p_obj); - void SetValue(T *p_obj); + MxBool Next(T& p_obj); + void SetValue(T p_obj); void Head() { m_match = m_list->m_first; } void Reset() { m_match = NULL; } @@ -123,7 +127,7 @@ inline void MxList::DeleteAll() break; MxListEntry *next = t->m_next; - m_customDestructor(t->m_obj); + m_customDestructor(t->GetValue()); delete t; t = next; } @@ -134,7 +138,7 @@ inline void MxList::DeleteAll() } template -inline void MxList::Append(T *p_newobj) +inline void MxList::Append(T p_newobj) { MxListEntry *currentLast = this->m_last; MxListEntry *newEntry = new MxListEntry(p_newobj, currentLast); @@ -169,7 +173,7 @@ inline void MxList::_DeleteEntry(MxListEntry *match) } template -inline MxBool MxListCursor::Find(T *p_obj) +inline MxBool MxListCursor::Find(T p_obj) { for (m_match = m_list->m_first; m_match && m_list->Compare(m_match->m_obj, p_obj); @@ -186,7 +190,7 @@ inline void MxListCursor::Detach() } template -inline MxBool MxListCursor::Next(T*& p_obj) +inline MxBool MxListCursor::Next(T& p_obj) { if (!m_match) m_match = m_list->m_first; @@ -200,7 +204,7 @@ inline MxBool MxListCursor::Next(T*& p_obj) } template -inline void MxListCursor::SetValue(T *p_obj) +inline void MxListCursor::SetValue(T p_obj) { if (m_match) m_match->m_obj = p_obj; diff --git a/LEGO1/mxpresenterlist.h b/LEGO1/mxpresenterlist.h index 71a7f9aa..0ee54a85 100644 --- a/LEGO1/mxpresenterlist.h +++ b/LEGO1/mxpresenterlist.h @@ -8,7 +8,7 @@ class MxPresenter; // Unclear what the purpose of this class is // VTABLE 0x100d62f0 // SIZE 0x18 -class MxPresenterListParent : public MxList +class MxPresenterListParent : public MxList { public: MxPresenterListParent() { @@ -24,15 +24,15 @@ class MxPresenterList : public MxPresenterListParent virtual MxS8 Compare(MxPresenter *, MxPresenter *); // +0x14 }; -typedef MxListCursorChildChild MxPresenterListCursor; +typedef MxListCursorChildChild MxPresenterListCursor; + +// OFFSET: LEGO1 0x1001cd20 TEMPLATE +// MxListParent::Compare // OFFSET: LEGO1 0x1001cd30 TEMPLATE -// MxListParent::Destroy - -// OFFSET: LEGO1 0x1001cdd0 TEMPLATE -// MxListParent::~MxListParent +// MxListParent::Destroy // OFFSET: LEGO1 0x1001ce20 TEMPLATE -// MxList::~MxList +// MxList::~MxList #endif // MXPRESENTERLIST_H diff --git a/LEGO1/mxstringlist.h b/LEGO1/mxstringlist.h new file mode 100644 index 00000000..dbf063f6 --- /dev/null +++ b/LEGO1/mxstringlist.h @@ -0,0 +1,23 @@ +#ifndef MXSTRINGLIST_H +#define MXSTRINGLIST_H + +#include "mxlist.h" +#include "mxstring.h" + +// VTABLE 0x100dd040 +// SIZE 0x18 +class MxStringList : public MxList {}; + +// OFFSET: LEGO1 0x100cb3c0 TEMPLATE +// MxListParent::Compare + +// OFFSET: LEGO1 0x100cb470 TEMPLATE +// MxListParent::Destroy + +// OFFSET: LEGO1 0x100cb4c0 TEMPLATE +// MxList::~MxList + +// OFFSET: LEGO1 0x100cc450 TEMPLATE +// MxListEntry::GetValue + +#endif // MXSTRINGLIST_H From 6480fd90e73aceac0ca47b415f873c71d087acff Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Tue, 3 Oct 2023 04:02:08 -0400 Subject: [PATCH 03/15] Motorcycle initial class structure and ctor (#156) --- LEGO1/motorcycle.cpp | 9 +++++++-- LEGO1/motorcycle.h | 6 +++++- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/LEGO1/motorcycle.cpp b/LEGO1/motorcycle.cpp index 9b0e0e40..59188fc4 100644 --- a/LEGO1/motorcycle.cpp +++ b/LEGO1/motorcycle.cpp @@ -1,7 +1,12 @@ #include "motorcycle.h" -// OFFSET: LEGO1 0x100357b0 STUB +DECOMP_SIZE_ASSERT(Motorcycle, 0x16c); + +// OFFSET: LEGO1 0x100357b0 Motorcycle::Motorcycle() { - // TODO + this->m_unk13c = 40.0; + this->m_unk150 = 1.75; + this->m_unk148 = 1; + this->m_unk164 = 1.0; } diff --git a/LEGO1/motorcycle.h b/LEGO1/motorcycle.h index 5ba746a8..ee39fe24 100644 --- a/LEGO1/motorcycle.h +++ b/LEGO1/motorcycle.h @@ -1,6 +1,7 @@ #ifndef MOTORCYCLE_H #define MOTORCYCLE_H +#include "decomp.h" #include "islepathactor.h" // VTABLE 0x100d7090 @@ -22,7 +23,10 @@ class Motorcycle : public IslePathActor { return !strcmp(name, Motorcycle::ClassName()) || IslePathActor::IsA(name); } - +private: + undefined m_unk160[4]; + MxFloat m_unk164; + undefined m_unk168[4]; }; #endif // MOTORCYCLE_H From a6f3acf5b7bd34468cdeb6906e6c27cae12c5f9e Mon Sep 17 00:00:00 2001 From: ecumber Date: Tue, 3 Oct 2023 10:53:22 -0700 Subject: [PATCH 04/15] LegoInputManager: some members and functions (#81) * Squashed commit of the following: commit 1fe03a4a787693616c56f59622bcaae8fd53b30b Author: ecumber Date: Thu Jul 6 21:04:15 2023 -0700 data types commit 7c8432f88236c42c17998d51e820b5e219f3c326 Author: ecumber Date: Thu Jul 6 12:39:13 2023 -0700 Destroy commit f60eb3923b24bc87bb31ba783676c6a50d48e9b8 Author: ecumber Date: Thu Jul 6 12:15:33 2023 -0700 compile fix commit e2f78d557f223c2552a046470578d154c29e473b Author: ecumber Date: Tue Jul 4 13:37:33 2023 -0700 Timer functions commit 447e234e6324a5b0958e9e94c5cda53703abada2 Author: ecumber Date: Thu Jul 6 02:40:10 2023 -0700 fix commit 4670fd790b16a15b5797d50bc3cd1f6e2c9e890d Author: ecumber Date: Thu Jul 6 02:39:04 2023 -0700 improvements commit 7f70bce1eefe550fe6bef193e7ee54948af354b6 Author: ecumber Date: Tue Jul 4 03:42:47 2023 -0700 Update legoinputmanager.cpp commit 0d3433a75d2b20a3fff1da8147ce502b279b1e9c Author: ecumber Date: Tue Jul 4 03:38:32 2023 -0700 Add ReleaseDX commit 72d27fd402efb37da1ce8c41a3350df66c99db1d Author: ecumber Date: Tue Jul 4 02:27:12 2023 -0700 Update CMakeLists.txt commit 09626a62f9d2c56a523ca582be95a4dfb29ee188 Author: ecumber Date: Mon Jul 3 13:48:46 2023 -0700 Move to new branch * Squashed commit of the following: commit d9148242a322ec54750c89357a0db2154310907d Author: ecumber Date: Sun Jul 16 23:56:54 2023 -0700 Update legoinputmanager.cpp commit 983d08650eb3df0b9103761b4023a6d3395686b2 Author: ecumber Date: Thu Jul 6 21:04:15 2023 -0700 data types commit 4e8aac36ece6f3d7cfff39432ebc4e731876fb75 Author: ecumber Date: Thu Jul 6 12:39:13 2023 -0700 Destroy commit 907801567a8c93ebd242b25b4aa2b00d38eaedc8 Author: ecumber Date: Thu Jul 6 12:15:33 2023 -0700 compile fix commit 91a5f75e938d796f153cc872e46acef2c342818c Author: ecumber Date: Tue Jul 4 13:37:33 2023 -0700 Timer functions commit e77f08f5358b6cc4ee41583f70281c40b95bea29 Author: ecumber Date: Thu Jul 6 02:40:10 2023 -0700 fix commit 30d204b7734a56b4140a3bf53c9825126a1f80c7 Author: ecumber Date: Thu Jul 6 02:39:04 2023 -0700 improvements commit dd4ff493355796c41a6fb328fda1892c0f1fec0a Author: ecumber Date: Tue Jul 4 03:42:47 2023 -0700 Update legoinputmanager.cpp commit 852658cdbc0e6f792a6a79dfc77df3539ea4a15a Author: ecumber Date: Tue Jul 4 03:38:32 2023 -0700 Add ReleaseDX commit 430d4e100811bc00dc983a9fe78aa1482fb92f7f Author: ecumber Date: Tue Jul 4 02:27:12 2023 -0700 Update CMakeLists.txt commit 6fb94f007613e920b1d64775b7b76cb721482884 Author: ecumber Date: Mon Jul 3 13:48:46 2023 -0700 Move to new branch * Fixes * Remove obsolete stuff * Fixes --------- Co-authored-by: Christian Semmler --- CMakeLists.txt | 4 +- LEGO1/legoinputmanager.cpp | 190 +++++++++++++++++++++++++++++++--- LEGO1/legoinputmanager.h | 53 +++++++--- LEGO1/mxtransitionmanager.cpp | 4 +- 4 files changed, 220 insertions(+), 31 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bcdadc2e..0da82a25 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -213,7 +213,7 @@ if (ISLE_USE_DX5) endif() # Link libraries -target_link_libraries(lego1 PRIVATE ddraw dsound dxguid winmm) +target_link_libraries(lego1 PRIVATE ddraw dsound dxguid dinput winmm) # Make sure filenames are ALL CAPS set_property(TARGET lego1 PROPERTY OUTPUT_NAME LEGO1) @@ -272,4 +272,4 @@ if (MSVC) set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/incremental:no") set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "/incremental:no /debug") set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "/incremental:no") -endif() +endif() \ No newline at end of file diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 7c6489ee..149af67b 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -1,25 +1,175 @@ #include "legoinputmanager.h" +#include "legocontrolmanager.h" +#include "legoomni.h" -#include "decomp.h" +#include "mxautolocker.h" -DECOMP_SIZE_ASSERT(LegoInputManager, 0x338); // 0x10059085 +DECOMP_SIZE_ASSERT(LegoInputManager, 0x338); -// OFFSET: LEGO1 0x1005b790 STUB +// OFFSET: LEGO1 0x1005b790 LegoInputManager::LegoInputManager() { - // TODO + m_unk0x5c = NULL; + m_unk0x64 = 0; + m_unk0x60 = 0; + m_unk0x68 = NULL; + m_unk0x80 = 0; + m_timer = 0; + m_unk0x6c = 0; + m_unk0x70 = 0; + m_controlManager = NULL; + m_unk0x81 = 0; + m_unk0x88 = FALSE; + m_directInput = NULL; + m_directInputDevice = NULL; + m_unk0x94 = 0; + m_unk0x195 = 0; + m_joyid = (UINT) -1; + m_joystickIndex = -1; + m_useJoystick = FALSE; + m_unk0x335 = 0; + m_unk0x336 = 0; + m_unk0x74 = 0x19; + m_timeout = 1000; } -// OFFSET: LEGO1 0x1005b8f0 STUB +// OFFSET: LEGO1 0x1005b8b0 STUB +MxResult LegoInputManager::Tickle() +{ + // TODO + return SUCCESS; +} + +// OFFSET: LEGO1 0x1005b8f0 LegoInputManager::~LegoInputManager() { - // TODO + Destroy(); } -// OFFSET: LEGO1 0x1005c740 STUB -void LegoInputManager::QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5) +// OFFSET: LEGO1 0x1005bfe0 +void LegoInputManager::Destroy() { - // TODO + ReleaseDX(); + + if (m_unk0x5c) + delete m_unk0x5c; + m_unk0x5c = NULL; + + if (m_unk0x68) + delete m_unk0x68; + m_unk0x68 = NULL; + + if (m_controlManager) + delete m_controlManager; +} + +// OFFSET: LEGO1 0x1005c030 +void LegoInputManager::CreateAndAcquireKeyboard(HWND hwnd) +{ + HINSTANCE hinstance = (HINSTANCE) GetWindowLong(hwnd, GWL_HINSTANCE); + HRESULT hresult = DirectInputCreate(hinstance, 0x500, &m_directInput, NULL); // 0x500 for DX5 + + if (hresult == DI_OK) { + HRESULT createdeviceresult = m_directInput->CreateDevice(GUID_SysKeyboard, &m_directInputDevice, NULL); + if (createdeviceresult == DI_OK) { + m_directInputDevice->SetCooperativeLevel(hwnd, DISCL_NONEXCLUSIVE | DISCL_FOREGROUND); + m_directInputDevice->SetDataFormat(&c_dfDIKeyboard); + m_directInputDevice->Acquire(); + } + } +} + +// OFFSET: LEGO1 0x1005c0a0 +void LegoInputManager::ReleaseDX() +{ + if (m_directInputDevice != NULL) { + m_directInputDevice->Unacquire(); + m_directInputDevice->Release(); + m_directInputDevice = NULL; + } + + if (m_directInput != NULL) { + m_directInput->Release(); + m_directInput = NULL; + } +} + +// OFFSET: LEGO1 0x1005c240 +MxResult LegoInputManager::GetJoystickId() +{ + JOYINFOEX joyinfoex; + + if (m_useJoystick != FALSE) { + MxS32 joyid = m_joystickIndex; + if (joyid >= 0) { + joyinfoex.dwSize = 0x34; + joyinfoex.dwFlags = 0xFF; + + if (joyGetPosEx(joyid, &joyinfoex) == JOYERR_NOERROR && joyGetDevCaps(joyid, &m_joyCaps, 0x194) == JOYERR_NOERROR) { + m_joyid = joyid; + return SUCCESS; + } + } + + for (joyid = JOYSTICKID1; joyid < 16; joyid++) { + joyinfoex.dwSize = 0x34; + joyinfoex.dwFlags = 0xFF; + if (joyGetPosEx(joyid, &joyinfoex) == JOYERR_NOERROR && joyGetDevCaps(joyid, &m_joyCaps, 0x194) == JOYERR_NOERROR) { + m_joyid = joyid; + return SUCCESS; + } + } + } + + return FAILURE; +} + +// OFFSET: LEGO1 0x1005c320 +MxResult LegoInputManager::GetJoystickState(MxU32 *joystick_x, MxU32 *joystick_y, DWORD *buttons_state, MxU32 *pov_position) +{ + if (m_useJoystick != FALSE) { + if (m_joyid < 0 && GetJoystickId() == -1) { + m_useJoystick = FALSE; + return FAILURE; + } + + JOYINFOEX joyinfoex; + joyinfoex.dwSize = 0x34; + joyinfoex.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNBUTTONS; + MxU32 capabilities = m_joyCaps.wCaps; + + if ((capabilities & JOYCAPS_HASPOV) != 0) { + joyinfoex.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNPOV | JOY_RETURNBUTTONS; + + if ((capabilities & JOYCAPS_POVCTS) != 0) + joyinfoex.dwFlags = JOY_RETURNX | JOY_RETURNY | JOY_RETURNPOV | JOY_RETURNBUTTONS | JOY_RETURNPOVCTS; + } + + MMRESULT mmresult = joyGetPosEx(m_joyid, &joyinfoex); + + if (mmresult == MMSYSERR_NOERROR) { + *buttons_state = joyinfoex.dwButtons; + MxU32 xmin = m_joyCaps.wXmin; + MxU32 ymax = m_joyCaps.wYmax; + MxU32 ymin = m_joyCaps.wYmin; + MxS32 ydiff = ymax - ymin; + *joystick_x = ((joyinfoex.dwXpos - xmin) * 100) / (m_joyCaps.wXmax - xmin); + *joystick_y = ((joyinfoex.dwYpos - m_joyCaps.wYmin) * 100) / ydiff; + if ((m_joyCaps.wCaps & (JOYCAPS_POV4DIR | JOYCAPS_POVCTS)) != 0) { + if (joyinfoex.dwPOV == JOY_POVCENTERED) { + *pov_position = (MxU32) -1; + return SUCCESS; + } + *pov_position = joyinfoex.dwPOV / 100; + return SUCCESS; + } + else { + *pov_position = (MxU32) -1; + return SUCCESS; + } + } + } + return FAILURE; } // OFFSET: LEGO1 0x1005c470 STUB @@ -34,11 +184,25 @@ void LegoInputManager::UnRegister(MxCore *) // TODO } -// OFFSET: LEGO1 0x1005b8b0 STUB -MxResult LegoInputManager::Tickle() +// OFFSET: LEGO1 0x1005c740 STUB +void LegoInputManager::QueueEvent(NotificationId id, unsigned char p2, MxLong p3, MxLong p4, unsigned char p5) { // TODO - - return 0; } +// OFFSET: LEGO1 0x1005cfb0 +void LegoInputManager::SetTimer() +{ + LegoOmni* omni = LegoOmni::GetInstance(); + UINT timer = ::SetTimer(omni->GetWindowHandle(), 1, m_timeout, NULL); + m_timer = timer; +} + +// OFFSET: LEGO1 0x1005cfd0 +void LegoInputManager::KillTimer() +{ + if (m_timer != 0) { + LegoOmni* omni = LegoOmni::GetInstance(); + ::KillTimer(omni->GetWindowHandle(), m_timer); + } +} diff --git a/LEGO1/legoinputmanager.h b/LEGO1/legoinputmanager.h index 56b77445..a44aef32 100644 --- a/LEGO1/legoinputmanager.h +++ b/LEGO1/legoinputmanager.h @@ -3,6 +3,9 @@ #include "decomp.h" #include "mxpresenter.h" +#include "mxlist.h" + +#include enum NotificationId { @@ -14,6 +17,8 @@ enum NotificationId TIMER = 15 }; +class LegoControlManager; + // VTABLE 0x100d8760 // SIZE 0x338 class LegoInputManager : public MxPresenter @@ -28,22 +33,42 @@ class LegoInputManager : public MxPresenter virtual MxResult Tickle() override; // vtable+0x8 - undefined m_pad40[0x48]; + void Destroy(); + void CreateAndAcquireKeyboard(HWND hwnd); + void ReleaseDX(); + MxResult GetJoystickId(); + MxResult GetJoystickState(MxU32 *joystick_x, MxU32 *joystick_y, DWORD *buttons_state, MxU32 *pov_position); + void SetTimer(); + void KillTimer(); - MxBool m_unk88; - undefined m_unk89[0x113]; - - // 0x19C - int m_joystickIndex; - - undefined m_pad1a0[0x194]; - - // 0x334 +//private: + MxCriticalSection m_criticalSection; + MxList *m_unk0x5c; // list or hash table + undefined4 m_unk0x60; + undefined4 m_unk0x64; + MxList *m_unk0x68; // list or hash table + undefined4 m_unk0x6c; + undefined4 m_unk0x70; + undefined4 m_unk0x74; + UINT m_timer; + UINT m_timeout; + undefined m_unk0x80; + undefined m_unk0x81; + LegoControlManager* m_controlManager; + MxBool m_unk0x88; + IDirectInput *m_directInput; + IDirectInputDevice *m_directInputDevice; + undefined m_unk0x94; + undefined4 m_unk0x98; + undefined m_unk0x9c[0xF8]; + undefined m_unk0x194; + MxBool m_unk0x195; + MxS32 m_joyid; + MxS32 m_joystickIndex; + JOYCAPS m_joyCaps; MxBool m_useJoystick; - - undefined m_unk335; - MxBool m_unk336; - undefined m_unk337; + MxBool m_unk0x335; + MxBool m_unk0x336; }; #endif // LEGOINPUTMANAGER_H diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index c5a0cb27..c3dfb035 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -83,8 +83,8 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx tickleManager->RegisterClient(this, p_speed); LegoInputManager *inputManager = InputManager(); - inputManager->m_unk88 = TRUE; - inputManager->m_unk336 = FALSE; + inputManager->m_unk0x88 = TRUE; + inputManager->m_unk0x336 = FALSE; LegoVideoManager *videoManager = VideoManager(); videoManager->SetUnkE4(FALSE); From 6c86503d3596c4f591415ba7eddcd75228af2797 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 3 Oct 2023 14:02:50 -0400 Subject: [PATCH 05/15] Remove UINT cast --- LEGO1/legoinputmanager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 149af67b..750c4700 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -24,7 +24,7 @@ LegoInputManager::LegoInputManager() m_directInputDevice = NULL; m_unk0x94 = 0; m_unk0x195 = 0; - m_joyid = (UINT) -1; + m_joyid = -1; m_joystickIndex = -1; m_useJoystick = FALSE; m_unk0x335 = 0; From f9cd17e3dc5bc901b51f3172c19f97ac330fba96 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 3 Oct 2023 14:50:14 -0400 Subject: [PATCH 06/15] Initialize bool members with FALSE --- LEGO1/legoinputmanager.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 750c4700..3aaaec76 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -27,8 +27,8 @@ LegoInputManager::LegoInputManager() m_joyid = -1; m_joystickIndex = -1; m_useJoystick = FALSE; - m_unk0x335 = 0; - m_unk0x336 = 0; + m_unk0x335 = FALSE; + m_unk0x336 = FALSE; m_unk0x74 = 0x19; m_timeout = 1000; } From 62d953c6c3b03fd233732e8fe4cbf664757a4220 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Tue, 3 Oct 2023 17:38:03 -0400 Subject: [PATCH 07/15] MxLoopingFlcPresenter ctor/half of Init (#158) * MxLoopingFlcPresenter ctor/half of Init * MxLoopingFlcPresenter - finish Init, stub Destroy function, match dtor * Update mxloopingflcpresenter.cpp --------- Co-authored-by: Christian Semmler --- LEGO1/mxloopingflcpresenter.cpp | 18 +++++++++++++----- LEGO1/mxloopingflcpresenter.h | 2 ++ 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/LEGO1/mxloopingflcpresenter.cpp b/LEGO1/mxloopingflcpresenter.cpp index 041ae6a5..54002246 100644 --- a/LEGO1/mxloopingflcpresenter.cpp +++ b/LEGO1/mxloopingflcpresenter.cpp @@ -4,20 +4,28 @@ DECOMP_SIZE_ASSERT(MxLoopingFlcPresenter, 0x6c); -// OFFSET: LEGO1 0x100b4310 STUB +// OFFSET: LEGO1 0x100b4310 MxLoopingFlcPresenter::MxLoopingFlcPresenter() { - // TODO + Init(); } // OFFSET: LEGO1 0x100b43b0 STUB MxLoopingFlcPresenter::~MxLoopingFlcPresenter() { - // TODO + Destroy(TRUE); } -// OFFSET: LEGO1 0x100b4410 STUB +// OFFSET: LEGO1 0x100b4410 void MxLoopingFlcPresenter::Init() { - // TODO + this->m_unk68 = 0; + this->m_flags &= 0xfd; + this->m_flags &= 0xfb; +} + +// OFFSET: LEGO1 0x100b4432 STUB +void MxLoopingFlcPresenter::Destroy(MxBool p_param) +{ + // TODO } diff --git a/LEGO1/mxloopingflcpresenter.h b/LEGO1/mxloopingflcpresenter.h index 1973c28e..209e2a53 100644 --- a/LEGO1/mxloopingflcpresenter.h +++ b/LEGO1/mxloopingflcpresenter.h @@ -22,6 +22,8 @@ class MxLoopingFlcPresenter : public MxFlcPresenter private: void Init(); + void Destroy(MxBool); + undefined4 m_unk68; }; From 129e8d6373ff8167b4549a855132e1411dc449c1 Mon Sep 17 00:00:00 2001 From: MS Date: Tue, 3 Oct 2023 18:03:10 -0400 Subject: [PATCH 08/15] MxTransitionManager::Dissolve (#155) * MxTransitionManager::Dissolve * Some comments and better names * use refs instead of pointers * slightly improved name for rect * Use MxS32 instead of int --- LEGO1/mxdisplaysurface.h | 1 + LEGO1/mxtransitionmanager.cpp | 101 ++++++++++++++++++++++++++++++++++ LEGO1/mxtransitionmanager.h | 8 ++- 3 files changed, 109 insertions(+), 1 deletion(-) diff --git a/LEGO1/mxdisplaysurface.h b/LEGO1/mxdisplaysurface.h index 4c2c3866..9bbc44bc 100644 --- a/LEGO1/mxdisplaysurface.h +++ b/LEGO1/mxdisplaysurface.h @@ -33,6 +33,7 @@ class MxDisplaySurface : public MxCore virtual void ReleaseDC(HDC p_hdc); virtual undefined4 vtable44(undefined4, undefined4*, undefined4, undefined4); + inline LPDIRECTDRAWSURFACE GetDirectDrawSurface1() { return this->m_ddSurface1; } inline LPDIRECTDRAWSURFACE GetDirectDrawSurface2() { return this->m_ddSurface2; } private: diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index c3dfb035..61283718 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -4,6 +4,9 @@ DECOMP_SIZE_ASSERT(MxTransitionManager, 0x900); +// 0x100f4378 +RECT g_fullScreenRect = {0, 0, 640, 480}; + // OFFSET: LEGO1 0x1004b8d0 MxTransitionManager::MxTransitionManager() { @@ -38,12 +41,110 @@ MxResult MxTransitionManager::Tickle() return 0; } +// OFFSET: LEGO1 0x1004bc30 STUB +void MxTransitionManager::EndTransition(MxBool) +{ + // TODO +} + +// OFFSET: LEGO1 0x1004bd10 +void MxTransitionManager::Transition_Dissolve() +{ + // If the animation is finished + if (m_animationTimer == 40) { + m_animationTimer = 0; + EndTransition(TRUE); + return; + } + + // If we are starting the animation + if (m_animationTimer == 0) { + // Generate the list of columns in order... + for (MxS32 i = 0; i < 640; i++) { + m_columnOrder[i] = i; + } + + // ...then shuffle the list (to ensure that we hit each column once) + for (i = 0; i < 640; i++) { + MxS32 swap = rand() % 640; + MxU16 t = m_columnOrder[i]; + m_columnOrder[i] = m_columnOrder[swap]; + m_columnOrder[swap] = t; + } + + // For each scanline, pick a random X offset + for (i = 0; i < 480; i++) { + m_randomShift[i] = rand() % 640; + } + } + + // Run one tick of the animation + DDSURFACEDESC ddsd; + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + HRESULT res = m_ddSurface->Lock(NULL, &ddsd, 1, NULL); + if (res == DDERR_SURFACELOST) { + m_ddSurface->Restore(); + res = m_ddSurface->Lock(NULL, &ddsd, 1, NULL); + } + + if (res == DD_OK) { + FUN_1004c4d0(ddsd); + + for (MxS32 i = 0; i < 640; i++) { + // Select 16 columns on each tick + if (m_animationTimer * 16 > m_columnOrder[i]) + continue; + + if (m_animationTimer * 16 + 15 < m_columnOrder[i]) + continue; + + for (MxS32 j = 0; j < 480; j++) { + // Shift the chosen column a different amount at each scanline. + // We use the same shift for that scanline each time. + // By the end, every pixel gets hit. + MxS32 ofs = (m_randomShift[j] + i) % 640; + + // Set the chosen pixel to black + if (ddsd.ddpfPixelFormat.dwRGBBitCount == 8) { + ((MxU8*)ddsd.lpSurface)[j * ddsd.lPitch + ofs] = 0; + } else { + ((MxU16*)ddsd.lpSurface)[j * ddsd.lPitch + ofs] = 0; + } + } + } + + FUN_1004c580(ddsd); + m_ddSurface->Unlock(ddsd.lpSurface); + + if (VideoManager()->GetVideoParam().flags().GetFlipSurfaces()) { + LPDIRECTDRAWSURFACE surf = VideoManager()->GetDisplaySurface()->GetDirectDrawSurface1(); + surf->BltFast(NULL, NULL, m_ddSurface, &g_fullScreenRect, 0x10); + } + + m_animationTimer++; + } +} + // OFFSET: LEGO1 0x1004c470 STUB void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) { // TODO } +// OFFSET: LEGO1 0x1004c4d0 STUB +void MxTransitionManager::FUN_1004c4d0(DDSURFACEDESC &ddsc) +{ + // TODO +} + +// OFFSET: LEGO1 0x1004c580 STUB +void MxTransitionManager::FUN_1004c580(DDSURFACEDESC &ddsc) +{ + // TODO +} + // OFFSET: LEGO1 0x1004baa0 MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 { diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 723366c1..09d3e622 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -89,6 +89,11 @@ class MxTransitionManager : public MxCore MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_unk, MxBool p_playMusicInAnim); private: + void EndTransition(MxBool); + void Transition_Dissolve(); + void FUN_1004c4d0(DDSURFACEDESC &); + void FUN_1004c580(DDSURFACEDESC &); + MxTransitionManagerUnknownSubclass1 *m_unk08; undefined4 m_unk0c; undefined4 m_unk10; @@ -102,7 +107,8 @@ class MxTransitionManager : public MxCore TransitionType m_transitionType; LPDIRECTDRAWSURFACE m_ddSurface; MxU16 m_animationTimer; - undefined m_pad36[0x8c2]; + MxU16 m_columnOrder[640]; // 0x36 + MxU16 m_randomShift[480]; // 0x536 MxULong m_systemTime; MxS32 m_animationSpeed; }; From 6da912e932643b28a0f97d12e7c81692bd60d699 Mon Sep 17 00:00:00 2001 From: MattKC <34096995+itsmattkc@users.noreply.github.com> Date: Tue, 3 Oct 2023 23:56:16 -0700 Subject: [PATCH 09/15] Implement MxTransitionManager::EndTransition and GetCurrentWorld (#159) * Implement MxTransitionManager::EndTransition and GetCurrentWorld * Match EndTransition --------- Co-authored-by: Christian Semmler --- LEGO1/legoomni.cpp | 6 ++++++ LEGO1/legoomni.h | 7 ++++++- LEGO1/mxtransitionmanager.cpp | 20 +++++++++++++++++--- LEGO1/mxtransitionmanager.h | 6 +++--- 4 files changed, 32 insertions(+), 7 deletions(-) diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index bbc8258b..929ba556 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -312,3 +312,9 @@ MxBool LegoOmni::vtable40() // FIXME: Stub return 0; } + +// OFFSET: LEGO1 0x100157a0 +LegoWorld *GetCurrentWorld() +{ + return LegoOmni::GetInstance()->GetCurrentWorld(); +} diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 4e772cae..4a5fe6e4 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -75,12 +75,16 @@ class LegoOmni : public MxOmni LegoGameState *GetGameState() { return m_gameState; } LegoNavController *GetNavController() { return m_navController; } MxTransitionManager *GetTransitionManager() { return m_transitionManager; } + LegoWorld *GetCurrentWorld() { return m_currentWorld; } private: int m_unk68; int m_unk6c; LegoInputManager *m_inputMgr; // 0x70 - char m_unk74[0x10]; + undefined4 m_unk74; + undefined4 m_unk78; + LegoWorld *m_currentWorld; + undefined4 m_unk80; LegoNavController *m_navController; // 0x84 Isle* m_isle; // 0x88 char m_unk8c[0x4]; @@ -115,5 +119,6 @@ LegoBuildingManager* BuildingManager(); Isle* GetIsle(); LegoPlantManager* PlantManager(); MxBool KeyValueStringParse(char *, const char *, const char *); +LegoWorld *GetCurrentWorld(); #endif // LEGOOMNI_H diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 61283718..4581abe9 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -41,10 +41,24 @@ MxResult MxTransitionManager::Tickle() return 0; } -// OFFSET: LEGO1 0x1004bc30 STUB -void MxTransitionManager::EndTransition(MxBool) +// OFFSET: LEGO1 0x1004bc30 +void MxTransitionManager::EndTransition(MxBool p_notifyWorld) { - // TODO + if (m_transitionType != NOT_TRANSITIONING) { + m_transitionType = NOT_TRANSITIONING; + + m_unk20.bit0 = FALSE; + + TickleManager()->UnregisterClient(this); + + if (p_notifyWorld) { + LegoWorld *world = GetCurrentWorld(); + + if (world) { + world->Notify(MxParam(0x18, this)); + } + } + } } // OFFSET: LEGO1 0x1004bd10 diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 09d3e622..c66e7380 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -89,7 +89,7 @@ class MxTransitionManager : public MxCore MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_unk, MxBool p_playMusicInAnim); private: - void EndTransition(MxBool); + void EndTransition(MxBool p_notifyWorld); void Transition_Dissolve(); void FUN_1004c4d0(DDSURFACEDESC &); void FUN_1004c580(DDSURFACEDESC &); @@ -109,8 +109,8 @@ class MxTransitionManager : public MxCore MxU16 m_animationTimer; MxU16 m_columnOrder[640]; // 0x36 MxU16 m_randomShift[480]; // 0x536 - MxULong m_systemTime; - MxS32 m_animationSpeed; + MxULong m_systemTime; // 0x8f8 + MxS32 m_animationSpeed; // 0x8fc }; #endif // MXTRANSITIONMANAGER_H From 7c7311ea5e3ccc2f725f677b0f6646c3cc9e07c3 Mon Sep 17 00:00:00 2001 From: Regan Green Date: Wed, 4 Oct 2023 09:43:34 -0400 Subject: [PATCH 10/15] Implement MxTransitionManager::SubmitCopyRect (#160) * Implement MxTransitionManager::SubmitCopyRect * MxTransitionManager::SubmitCopyRect Amendments * Fix MxTransitionManager::EndTransition * Fix MxDSAction::SetLoopCount --- LEGO1/mxdsaction.h | 11 ++-- LEGO1/mxpresenter.h | 1 + LEGO1/mxtransitionmanager.cpp | 96 ++++++++++++++++++++++------------- LEGO1/mxtransitionmanager.h | 64 +++-------------------- 4 files changed, 77 insertions(+), 95 deletions(-) diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 01dfcf2c..eb7afb99 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -18,6 +18,7 @@ class MxDSAction : public MxDSObject Flag_Bit3 = 0x04, Flag_Enabled = 0x20, Flag_Parsed = 0x80, + Flag_Bit9 = 0x200, }; __declspec(dllexport) MxDSAction(); @@ -52,16 +53,18 @@ class MxDSAction : public MxDSObject void AppendData(MxU16 p_extraLength, const char *p_extraData); - inline MxU32 GetFlags() { return this->m_flags; } - inline void SetFlags(MxU32 m_flags) { this->m_flags = m_flags; } + inline MxU32 GetFlags() { return m_flags; } + inline void SetFlags(MxU32 p_flags) { m_flags = p_flags; } inline char *GetExtraData() { return m_extraData; } inline MxU16 GetExtraLength() const { return m_extraLength; } inline MxLong GetStartTime() const { return m_startTime; } + inline MxS32 GetLoopCount() { return m_loopCount; } + inline void SetLoopCount(MxS32 p_loopCount) { m_loopCount = p_loopCount; } inline const MxVector3Data &GetLocation() const { return m_location; } inline void SetOmni(MxOmni *p_omni) { m_omni = p_omni; } - inline MxBool IsLooping() const { return this->m_flags & Flag_Looping; } - inline MxBool IsBit3() const { return this->m_flags & Flag_Bit3; } + inline MxBool IsLooping() const { return m_flags & Flag_Looping; } + inline MxBool IsBit3() const { return m_flags & Flag_Bit3; } private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 1537d2d3..c0757665 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -69,6 +69,7 @@ class MxPresenter : public MxCore MxBool IsEnabled(); inline MxS32 GetDisplayZ() { return this->m_displayZ; } + inline MxDSAction *GetAction() { return this->m_action; } protected: __declspec(dllexport) void Init(); diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index 4581abe9..c3de0ff8 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -13,9 +13,9 @@ MxTransitionManager::MxTransitionManager() m_animationTimer = 0; m_transitionType = NOT_TRANSITIONING; m_ddSurface = NULL; - m_unk08 = 0; - m_unk1c = 0; - m_unk20.bit0 = FALSE; + m_waitIndicator = NULL; + m_copyBuffer = NULL; + m_copyFlags.bit0 = FALSE; m_unk28.bit0 = FALSE; m_unk24 = 0; } @@ -23,11 +23,11 @@ MxTransitionManager::MxTransitionManager() // OFFSET: LEGO1 0x1004ba00 MxTransitionManager::~MxTransitionManager() { - free(m_unk1c); + free(m_copyBuffer); - if (m_unk08 != NULL) { - delete m_unk08->m_unk1c; - delete m_unk08; + if (m_waitIndicator != NULL) { + delete m_waitIndicator->GetAction(); + delete m_waitIndicator; } TickleManager()->UnregisterClient(this); @@ -47,7 +47,7 @@ void MxTransitionManager::EndTransition(MxBool p_notifyWorld) if (m_transitionType != NOT_TRANSITIONING) { m_transitionType = NOT_TRANSITIONING; - m_unk20.bit0 = FALSE; + m_copyFlags.bit0 = FALSE; TickleManager()->UnregisterClient(this); @@ -104,7 +104,7 @@ void MxTransitionManager::Transition_Dissolve() } if (res == DD_OK) { - FUN_1004c4d0(ddsd); + SubmitCopyRect(ddsd); for (MxS32 i = 0; i < 640; i++) { // Select 16 columns on each tick @@ -129,7 +129,7 @@ void MxTransitionManager::Transition_Dissolve() } } - FUN_1004c580(ddsd); + SetupCopyRect(ddsd); m_ddSurface->Unlock(ddsd.lpSurface); if (VideoManager()->GetVideoParam().flags().GetFlipSurfaces()) { @@ -141,24 +141,6 @@ void MxTransitionManager::Transition_Dissolve() } } -// OFFSET: LEGO1 0x1004c470 STUB -void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) -{ - // TODO -} - -// OFFSET: LEGO1 0x1004c4d0 STUB -void MxTransitionManager::FUN_1004c4d0(DDSURFACEDESC &ddsc) -{ - // TODO -} - -// OFFSET: LEGO1 0x1004c580 STUB -void MxTransitionManager::FUN_1004c580(DDSURFACEDESC &ddsc) -{ - // TODO -} - // OFFSET: LEGO1 0x1004baa0 MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 { @@ -169,7 +151,7 @@ MxResult MxTransitionManager::GetDDrawSurfaceFromVideoManager() // vtable+0x14 // OFFSET: LEGO1 0x1004bb70 MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, MxS32 p_speed, - MxBool p_unk, MxBool p_playMusicInAnim) + MxBool p_doCopy, MxBool p_playMusicInAnim) { if (this->m_transitionType == NOT_TRANSITIONING) { if (!p_playMusicInAnim) { @@ -179,14 +161,14 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx this->m_transitionType = p_animationType; - m_unk20.bit0 = p_unk; + m_copyFlags.bit0 = p_doCopy; - if (m_unk20.bit0 && m_unk08 != NULL) { - m_unk08->vtable54(1); + if (m_copyFlags.bit0 && m_waitIndicator != NULL) { + m_waitIndicator->Enable(TRUE); - MxTransitionManagerUnknownSubclass2 *iVar2 = m_unk08->m_unk1c; - iVar2->m_unk3c = 10000; - iVar2->m_unk30 |= 0x200; + MxDSAction *action = m_waitIndicator->GetAction(); + action->SetLoopCount(10000); + action->SetFlags(action->GetFlags() | MxDSAction::Flag_Bit9); } MxU32 time = timeGetTime(); @@ -209,3 +191,47 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx } return FAILURE; } + +// OFFSET: LEGO1 0x1004c470 STUB +void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) +{ + // TODO +} + +// OFFSET: LEGO1 0x1004c4d0 +void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) +{ + // Check if the copy rect is setup + if (m_copyFlags.bit0 == FALSE || m_waitIndicator == NULL || m_copyBuffer == NULL) { + return; + } + + // Copy the copy rect onto the surface + char *dst; + + DWORD bytesPerPixel = ddsc.ddpfPixelFormat.dwRGBBitCount / 8; + + const char *src = (const char *)m_copyBuffer; + + LONG copyPitch; + copyPitch = ((m_copyRect.right - m_copyRect.left) + 1) * bytesPerPixel; + + LONG y; + dst = (char *)ddsc.lpSurface + (ddsc.lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left); + + for (y = 0; y < m_copyRect.bottom - m_copyRect.top + 1; ++y) { + memcpy(dst, src, copyPitch); + src += copyPitch; + dst += ddsc.lPitch; + } + + // Free the copy buffer + free(m_copyBuffer); + m_copyBuffer = NULL; +} + +// OFFSET: LEGO1 0x1004c580 STUB +void MxTransitionManager::SetupCopyRect(DDSURFACEDESC &ddsc) +{ + // TODO +} diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index c66e7380..6cbc608b 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -5,52 +5,6 @@ #include "mxvideopresenter.h" #include "legoomni.h" -class MxTransitionManagerUnknownSubclass2 -{ -public: - virtual ~MxTransitionManagerUnknownSubclass2(){} - - undefined m_unk04[0x2c]; - undefined4 m_unk30; - undefined4 m_unk34; - undefined4 m_unk38; - undefined4 m_unk3c; - -}; - -// TODO: Don't know what this is yet -class MxTransitionManagerUnknownSubclass1 -{ -public: - virtual ~MxTransitionManagerUnknownSubclass1(){} - - virtual void vtable04(); - virtual void vtable08(); - virtual void vtable0c(); - virtual void vtable10(); - virtual void vtable14(); - virtual void vtable18(); - virtual void vtable1c(); - virtual void vtable20(); - virtual void vtable24(); - virtual void vtable28(); - virtual void vtable2c(); - virtual void vtable30(); - virtual void vtable34(); - virtual void vtable38(); - virtual void vtable3c(); - virtual void vtable40(); - virtual void vtable44(); - virtual void vtable48(); - virtual void vtable4c(); - virtual void vtable50(); - virtual void vtable54(undefined4 p_unk1); - - undefined m_unk04[0x18]; - MxTransitionManagerUnknownSubclass2 *m_unk1c; - -}; - // VTABLE 0x100d7ea0 class MxTransitionManager : public MxCore { @@ -86,21 +40,19 @@ class MxTransitionManager : public MxCore BROKEN // Unknown what this is supposed to be, it locks the game up }; - MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_unk, MxBool p_playMusicInAnim); + MxResult StartTransition(TransitionType p_animationType, MxS32 p_speed, MxBool p_doCopy, MxBool p_playMusicInAnim); private: void EndTransition(MxBool p_notifyWorld); void Transition_Dissolve(); - void FUN_1004c4d0(DDSURFACEDESC &); - void FUN_1004c580(DDSURFACEDESC &); + void SubmitCopyRect(DDSURFACEDESC &); + void SetupCopyRect(DDSURFACEDESC &); - MxTransitionManagerUnknownSubclass1 *m_unk08; - undefined4 m_unk0c; - undefined4 m_unk10; - undefined4 m_unk14; - undefined4 m_unk18; - void *m_unk1c; - flag_bitfield m_unk20; + MxVideoPresenter *m_waitIndicator; + RECT m_copyRect; + void *m_copyBuffer; + + flag_bitfield m_copyFlags; undefined4 m_unk24; flag_bitfield m_unk28; From 5125314755fd4d558a337446228e025869196b9b Mon Sep 17 00:00:00 2001 From: MS Date: Wed, 4 Oct 2023 11:48:25 -0400 Subject: [PATCH 11/15] Wipe transition (#161) --- LEGO1/mxtransitionmanager.cpp | 39 +++++++++++++++++++++++++++++++++++ LEGO1/mxtransitionmanager.h | 1 + 2 files changed, 40 insertions(+) diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index c3de0ff8..f66f4bae 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -192,6 +192,45 @@ MxResult MxTransitionManager::StartTransition(TransitionType p_animationType, Mx return FAILURE; } +// OFFSET: LEGO1 0x1004c170 +void MxTransitionManager::Transition_Wipe() +{ + // If the animation is finished + if (m_animationTimer == 240) { + m_animationTimer = 0; + EndTransition(TRUE); + return; + } + + DDSURFACEDESC ddsd; + memset(&ddsd, 0, sizeof(ddsd)); + ddsd.dwSize = sizeof(ddsd); + + HRESULT res = m_ddSurface->Lock(NULL, &ddsd, 1, NULL); + if (res == DDERR_SURFACELOST) { + m_ddSurface->Restore(); + res = m_ddSurface->Lock(NULL, &ddsd, 1, NULL); + } + + if (res == DD_OK) { + SubmitCopyRect(ddsd); + + // For each of the 240 animation ticks, blank out two scanlines + // starting at the top of the screen. + // (dwRGBBitCount / 8) will tell how many bytes are used per pixel. + MxU8 *line = (MxU8*)ddsd.lpSurface + 2*ddsd.lPitch*m_animationTimer; + memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8); + + line += ddsd.lPitch; + memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8); + + SetupCopyRect(ddsd); + m_ddSurface->Unlock(ddsd.lpSurface); + + m_animationTimer++; + } +} + // OFFSET: LEGO1 0x1004c470 STUB void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) { diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 6cbc608b..cc5bd678 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -45,6 +45,7 @@ class MxTransitionManager : public MxCore private: void EndTransition(MxBool p_notifyWorld); void Transition_Dissolve(); + void Transition_Wipe(); void SubmitCopyRect(DDSURFACEDESC &); void SetupCopyRect(DDSURFACEDESC &); From 6916aa49e3298153d5442851910191bc2c9a7cba Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Wed, 4 Oct 2023 13:30:37 -0400 Subject: [PATCH 12/15] MxLoopingSmkPresenter - dtor, Init, stub Destroy (#162) --- LEGO1/mxloopingsmkpresenter.cpp | 16 ++++++++++++---- LEGO1/mxloopingsmkpresenter.h | 2 ++ 2 files changed, 14 insertions(+), 4 deletions(-) diff --git a/LEGO1/mxloopingsmkpresenter.cpp b/LEGO1/mxloopingsmkpresenter.cpp index da9223df..f51e2750 100644 --- a/LEGO1/mxloopingsmkpresenter.cpp +++ b/LEGO1/mxloopingsmkpresenter.cpp @@ -10,14 +10,22 @@ MxLoopingSmkPresenter::MxLoopingSmkPresenter() Init(); } -// OFFSET: LEGO1 0x100b4950 STUB +// OFFSET: LEGO1 0x100b4950 MxLoopingSmkPresenter::~MxLoopingSmkPresenter() { - // TODO + Destroy(TRUE); } -// OFFSET: LEGO1 0x100b49b0 STUB +// OFFSET: LEGO1 0x100b49b0 void MxLoopingSmkPresenter::Init() { - // TODO + this->m_unk720 = 0; + this->m_flags &= 0xfd; + this->m_flags &= 0xfb; +} + +// OFFSET: LEGO1 0x100b49d0 STUB +void MxLoopingSmkPresenter::Destroy(MxBool p_bool) +{ + // TODO - theres a chain of destroy and free function calls here (FUN_100b4300 -> FUN_100b3900 -> FUN_100c5d40 -> function at 0x100b27b0) } diff --git a/LEGO1/mxloopingsmkpresenter.h b/LEGO1/mxloopingsmkpresenter.h index 8ca18d20..ae9cfa05 100644 --- a/LEGO1/mxloopingsmkpresenter.h +++ b/LEGO1/mxloopingsmkpresenter.h @@ -22,6 +22,8 @@ class MxLoopingSmkPresenter : public MxSmkPresenter private: void Init(); + void Destroy(MxBool); + undefined4 m_unk720; }; From 2d45914ddf43843febc110c37c40f03143f7c569 Mon Sep 17 00:00:00 2001 From: Joshua Peisach Date: Thu, 5 Oct 2023 03:47:37 -0400 Subject: [PATCH 13/15] MxSoundManager: dtor, destroy, update types (#164) * MxSoundManager: dtor, destroy, update types Also make MxThread's destructor public * Minor adjustments --------- Co-authored-by: Christian Semmler --- LEGO1/mxsoundmanager.cpp | 34 +++++++++++++++++++++++++++++++--- LEGO1/mxsoundmanager.h | 11 ++++++++--- LEGO1/mxthread.h | 2 ++ 3 files changed, 41 insertions(+), 6 deletions(-) diff --git a/LEGO1/mxsoundmanager.cpp b/LEGO1/mxsoundmanager.cpp index 275d0514..16d504ce 100644 --- a/LEGO1/mxsoundmanager.cpp +++ b/LEGO1/mxsoundmanager.cpp @@ -1,21 +1,49 @@ #include "mxsoundmanager.h" +#include "mxomni.h" + +DECOMP_SIZE_ASSERT(MxSoundManager, 0x3c); + // OFFSET: LEGO1 0x100ae740 MxSoundManager::MxSoundManager() { Init(); } -// OFFSET: LEGO1 0x100ae7d0 STUB +// OFFSET: LEGO1 0x100ae7d0 MxSoundManager::~MxSoundManager() { - // TODO + Destroy(TRUE); } // OFFSET: LEGO1 0x100ae830 void MxSoundManager::Init() { m_unk30 = 0; - m_unk34 = 0; + m_dsBuffer = NULL; } +// OFFSET: LEGO1 0x100ae840 +void MxSoundManager::Destroy(MxBool p_param) +{ + if (this->m_thread) { + this->m_thread->Terminate(); + delete this->m_thread; + } + else { + TickleManager()->UnregisterClient(this); + } + + this->m_criticalSection.Enter(); + + if (this->m_dsBuffer) { + this->m_dsBuffer->Release(); + } + + Init(); + this->m_criticalSection.Leave(); + + if (!p_param) { + MxAudioManager::Destroy(); + } +} \ No newline at end of file diff --git a/LEGO1/mxsoundmanager.h b/LEGO1/mxsoundmanager.h index 06dc9d5f..d41c6fdb 100644 --- a/LEGO1/mxsoundmanager.h +++ b/LEGO1/mxsoundmanager.h @@ -1,11 +1,13 @@ #ifndef MXSOUNDMANAGER_H #define MXSOUNDMANAGER_H +#include "decomp.h" #include "mxaudiomanager.h" +#include + // VTABLE 0x100dc128 // SIZE 0x3c -// Base vtables are: MxCore -> 0x100dc6b0 -> MxAudioManager -> MxSoundManager class MxSoundManager : public MxAudioManager { public: @@ -14,8 +16,11 @@ class MxSoundManager : public MxAudioManager private: void Init(); - int m_unk30; - int m_unk34; + void Destroy(MxBool); + + undefined4 m_unk30; + LPDIRECTSOUNDBUFFER m_dsBuffer; // 0x34 + undefined m_unk35[4]; }; #endif // MXSOUNDMANAGER_H diff --git a/LEGO1/mxthread.h b/LEGO1/mxthread.h index 4537dc14..758205d7 100644 --- a/LEGO1/mxthread.h +++ b/LEGO1/mxthread.h @@ -24,6 +24,8 @@ class MxThread protected: MxThread(); + +public: virtual ~MxThread(); private: From c46bc985c272ceeff9d6fee2ff88a3f24ef0154b Mon Sep 17 00:00:00 2001 From: Regan Green Date: Thu, 5 Oct 2023 06:31:20 -0400 Subject: [PATCH 14/15] Implement MxTransitionManager SetWaitIndicator and SetupCopyRect (#165) * Implement MxTransitionManager SetWaitIndicator and SetupCopyRect * More accurate SetupCopyRect * Add MxDSAction::Flag_Bit5 * SetupCopyRect PR Amends * Correct braces formatting * Stub MxVideoPresenter::Destroy --- LEGO1/mxdisplaysurface.cpp | 4 +- LEGO1/mxdisplaysurface.h | 4 +- LEGO1/mxdsaction.h | 1 + LEGO1/mxmediapresenter.cpp | 6 ++ LEGO1/mxmediapresenter.h | 2 + LEGO1/mxpresenter.h | 2 + LEGO1/mxtransitionmanager.cpp | 101 +++++++++++++++++++++++++++++----- LEGO1/mxtransitionmanager.h | 6 +- LEGO1/mxvideopresenter.cpp | 86 +++++++++++++++++++++++++++++ LEGO1/mxvideopresenter.h | 17 ++++++ 10 files changed, 208 insertions(+), 21 deletions(-) diff --git a/LEGO1/mxdisplaysurface.cpp b/LEGO1/mxdisplaysurface.cpp index 4f02aeb6..619f5eef 100644 --- a/LEGO1/mxdisplaysurface.cpp +++ b/LEGO1/mxdisplaysurface.cpp @@ -174,7 +174,7 @@ void MxDisplaySurface::SetPalette(MxPalette *p_palette) } // OFFSET: LEGO1 0x100bc200 STUB -void MxDisplaySurface::vtable24(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) +void MxDisplaySurface::vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) { } @@ -186,7 +186,7 @@ MxBool MxDisplaySurface::vtable28(undefined4, undefined4, undefined4, undefined4 } // OFFSET: LEGO1 0x100bc630 STUB -MxBool MxDisplaySurface::vtable2c(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool) +MxBool MxDisplaySurface::vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool) { return 0; } diff --git a/LEGO1/mxdisplaysurface.h b/LEGO1/mxdisplaysurface.h index 9bbc44bc..af484716 100644 --- a/LEGO1/mxdisplaysurface.h +++ b/LEGO1/mxdisplaysurface.h @@ -23,9 +23,9 @@ class MxDisplaySurface : public MxCore virtual MxResult Create(MxVideoParam &p_videoParam); virtual void Clear(); virtual void SetPalette(MxPalette *p_palette); - virtual void vtable24(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); + virtual void vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual MxBool vtable28(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); - virtual MxBool vtable2c(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); + virtual MxBool vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); virtual MxBool vtable30(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); virtual undefined4 vtable34(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual void Display(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index eb7afb99..9881f3e2 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -16,6 +16,7 @@ class MxDSAction : public MxDSObject { Flag_Looping = 0x01, Flag_Bit3 = 0x04, + Flag_Bit5 = 0x10, Flag_Enabled = 0x20, Flag_Parsed = 0x80, Flag_Bit9 = 0x200, diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index 6a59a0ec..f36ecbdc 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -17,3 +17,9 @@ void MxMediaPresenter::Init() this->m_unk48 = NULL; this->m_unk4c = NULL; } + +// OFFSET: LEGO1 0x100b5f10 STUB +void MxMediaPresenter::VTable0x58() +{ + // TODO +} diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index 741ab49f..824dd399 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -29,6 +29,8 @@ class MxMediaPresenter : public MxPresenter return !strcmp(name, MxMediaPresenter::ClassName()) || MxPresenter::IsA(name); } + virtual void VTable0x58(); // vtable+0x58 + undefined4 m_unk40; undefined4 m_unk44; undefined4 m_unk48; diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index c0757665..81ea14ad 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -68,6 +68,8 @@ class MxPresenter : public MxCore MxBool IsEnabled(); + inline MxS32 GetCurrentTickleState() { return this->m_currentTickleState; } + inline MxPoint32 GetLocation() { return this->m_location; } inline MxS32 GetDisplayZ() { return this->m_displayZ; } inline MxDSAction *GetAction() { return this->m_action; } diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index f66f4bae..efb90604 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -104,7 +104,7 @@ void MxTransitionManager::Transition_Dissolve() } if (res == DD_OK) { - SubmitCopyRect(ddsd); + SubmitCopyRect(&ddsd); for (MxS32 i = 0; i < 640; i++) { // Select 16 columns on each tick @@ -129,7 +129,7 @@ void MxTransitionManager::Transition_Dissolve() } } - SetupCopyRect(ddsd); + SetupCopyRect(&ddsd); m_ddSurface->Unlock(ddsd.lpSurface); if (VideoManager()->GetVideoParam().flags().GetFlipSurfaces()) { @@ -213,7 +213,7 @@ void MxTransitionManager::Transition_Wipe() } if (res == DD_OK) { - SubmitCopyRect(ddsd); + SubmitCopyRect(&ddsd); // For each of the 240 animation ticks, blank out two scanlines // starting at the top of the screen. @@ -224,21 +224,42 @@ void MxTransitionManager::Transition_Wipe() line += ddsd.lPitch; memset(line, 0, 640 * ddsd.ddpfPixelFormat.dwRGBBitCount / 8); - SetupCopyRect(ddsd); + SetupCopyRect(&ddsd); m_ddSurface->Unlock(ddsd.lpSurface); m_animationTimer++; } } -// OFFSET: LEGO1 0x1004c470 STUB -void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *videoPresenter) +// OFFSET: LEGO1 0x1004c470 +void MxTransitionManager::SetWaitIndicator(MxVideoPresenter *p_waitIndicator) { - // TODO + // End current wait indicator + if (m_waitIndicator != NULL) { + m_waitIndicator->GetAction()->SetFlags(m_waitIndicator->GetAction()->GetFlags() & ~MxDSAction::Flag_Parsed); + m_waitIndicator->EndAction(); + m_waitIndicator = NULL; + } + + // Check if we were given a new wait indicator + if (p_waitIndicator != NULL) { + // Setup the new wait indicator + m_waitIndicator = p_waitIndicator; + + LegoVideoManager *videoManager = VideoManager(); + videoManager->RemovePresenter(*m_waitIndicator); + + if (m_waitIndicator->GetCurrentTickleState() < MxPresenter::TickleState_Streaming) { + m_waitIndicator->Tickle(); + } + } else { + // Disable copy rect + m_copyFlags.bit0 = FALSE; + } } // OFFSET: LEGO1 0x1004c4d0 -void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) +void MxTransitionManager::SubmitCopyRect(LPDDSURFACEDESC ddsc) { // Check if the copy rect is setup if (m_copyFlags.bit0 == FALSE || m_waitIndicator == NULL || m_copyBuffer == NULL) { @@ -248,7 +269,7 @@ void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) // Copy the copy rect onto the surface char *dst; - DWORD bytesPerPixel = ddsc.ddpfPixelFormat.dwRGBBitCount / 8; + DWORD bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; const char *src = (const char *)m_copyBuffer; @@ -256,12 +277,12 @@ void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) copyPitch = ((m_copyRect.right - m_copyRect.left) + 1) * bytesPerPixel; LONG y; - dst = (char *)ddsc.lpSurface + (ddsc.lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left); + dst = (char *)ddsc->lpSurface + (ddsc->lPitch * m_copyRect.top) + (bytesPerPixel * m_copyRect.left); for (y = 0; y < m_copyRect.bottom - m_copyRect.top + 1; ++y) { memcpy(dst, src, copyPitch); src += copyPitch; - dst += ddsc.lPitch; + dst += ddsc->lPitch; } // Free the copy buffer @@ -269,8 +290,60 @@ void MxTransitionManager::SubmitCopyRect(DDSURFACEDESC &ddsc) m_copyBuffer = NULL; } -// OFFSET: LEGO1 0x1004c580 STUB -void MxTransitionManager::SetupCopyRect(DDSURFACEDESC &ddsc) +// OFFSET: LEGO1 0x1004c580 +void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc) { - // TODO + // Check if the copy rect is setup + if (m_copyFlags.bit0 == FALSE || m_waitIndicator == NULL) { + return; + } + + // Tickle wait indicator + m_waitIndicator->Tickle(); + + // Check if wait indicator has started + if (m_waitIndicator->GetCurrentTickleState() >= MxPresenter::TickleState_Streaming) { + // Setup the copy rect + DWORD copyPitch = (ddsc->ddpfPixelFormat.dwRGBBitCount / 8) * (m_copyRect.right - m_copyRect.left + 1); // This uses m_copyRect, seemingly erroneously + DWORD bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; + + m_copyRect.left = m_waitIndicator->GetLocation().m_x; + m_copyRect.top = m_waitIndicator->GetLocation().m_y; + + MxS32 height = m_waitIndicator->GetHeight(); + MxS32 width = m_waitIndicator->GetWidth(); + + m_copyRect.right = m_copyRect.left + width - 1; + m_copyRect.bottom = m_copyRect.top + height - 1; + + // Allocate the copy buffer + const char *src = (const char*)ddsc->lpSurface + m_copyRect.top * ddsc->lPitch + bytesPerPixel * m_copyRect.left; + + m_copyBuffer = malloc(bytesPerPixel * width * height); + if (!m_copyBuffer) + return; + + // Copy into the copy buffer + char *dst = (char*)m_copyBuffer; + + for (MxS32 i = 0; i < (m_copyRect.bottom - m_copyRect.top + 1); i++) + { + memcpy(dst, src, copyPitch); + src += ddsc->lPitch; + dst += copyPitch; + } + } + + // Setup display surface + if ((m_waitIndicator->GetAction()->GetFlags() & MxDSAction::Flag_Bit5) != 0) + { + MxDisplaySurface *displaySurface = VideoManager()->GetDisplaySurface(); + MxBool unkbool = FALSE; + displaySurface->vtable2c(ddsc, m_waitIndicator->m_unk50, 0, 0, m_waitIndicator->GetLocation().m_x, m_waitIndicator->GetLocation().m_y, m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight(), unkbool); + } + else + { + MxDisplaySurface *displaySurface = VideoManager()->GetDisplaySurface(); + displaySurface->vtable24(ddsc, m_waitIndicator->m_unk50, 0, 0, m_waitIndicator->GetLocation().m_x, m_waitIndicator->GetLocation().m_y, m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight()); + } } diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index cc5bd678..4ed82229 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -12,7 +12,7 @@ class MxTransitionManager : public MxCore MxTransitionManager(); virtual ~MxTransitionManager() override; // vtable+0x0 - __declspec(dllexport) void SetWaitIndicator(MxVideoPresenter *videoPresenter); + __declspec(dllexport) void SetWaitIndicator(MxVideoPresenter *p_waitIndicator); virtual MxResult Tickle(); // vtable+0x8 @@ -46,8 +46,8 @@ class MxTransitionManager : public MxCore void EndTransition(MxBool p_notifyWorld); void Transition_Dissolve(); void Transition_Wipe(); - void SubmitCopyRect(DDSURFACEDESC &); - void SetupCopyRect(DDSURFACEDESC &); + void SubmitCopyRect(LPDDSURFACEDESC ddsc); + void SetupCopyRect(LPDDSURFACEDESC ddsc); MxVideoPresenter *m_waitIndicator; RECT m_copyRect; diff --git a/LEGO1/mxvideopresenter.cpp b/LEGO1/mxvideopresenter.cpp index 4e47e4a4..fe83a2dc 100644 --- a/LEGO1/mxvideopresenter.cpp +++ b/LEGO1/mxvideopresenter.cpp @@ -2,8 +2,94 @@ DECOMP_SIZE_ASSERT(MxVideoPresenter, 0x64); +// OFFSET: LEGO1 0x1000c700 STUB +void MxVideoPresenter::VTable0x5c() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c710 STUB +void MxVideoPresenter::VTable0x60() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c720 STUB +void MxVideoPresenter::VTable0x68() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c730 STUB +void MxVideoPresenter::VTable0x70() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c740 +MxVideoPresenter::~MxVideoPresenter() +{ + Destroy(TRUE); +} + +// OFFSET: LEGO1 0x1000c7a0 STUB +void MxVideoPresenter::InitVirtual() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c7b0 STUB +void MxVideoPresenter::VTable0x78() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c7c0 STUB +void MxVideoPresenter::VTable0x7c() +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c7e0 STUB +MxS32 MxVideoPresenter::GetWidth() +{ + // TODO + return 0; +} + +// OFFSET: LEGO1 0x1000c800 STUB +MxS32 MxVideoPresenter::GetHeight() +{ + // TODO + return 0; +} + // OFFSET: LEGO1 0x100b2760 STUB void MxVideoPresenter::Init() { // TODO } + +// OFFSET: LEGO1 0x100b27b0 STUB +void MxVideoPresenter::Destroy(MxBool) +{ + // TODO +} + +// OFFSET: LEGO1 0x100b28b0 STUB +void MxVideoPresenter::VTable0x64() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b2a70 STUB +void MxVideoPresenter::VTable0x6c() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b3300 STUB +void MxVideoPresenter::VTable0x74() +{ + // TODO +} diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h index bc5fac5c..84822f71 100644 --- a/LEGO1/mxvideopresenter.h +++ b/LEGO1/mxvideopresenter.h @@ -13,6 +13,8 @@ class MxVideoPresenter : public MxMediaPresenter Init(); } + virtual ~MxVideoPresenter() override; // vtable+0x0 + // OFFSET: LEGO1 0x1000c820 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -27,6 +29,21 @@ class MxVideoPresenter : public MxMediaPresenter } void Init(); + void Destroy(MxBool); + + virtual void InitVirtual() override; // vtable+0x38 + + virtual void VTable0x5c(); // vtable+0x5c + virtual void VTable0x60(); // vtable+0x60 + virtual void VTable0x64(); // vtable+0x64 + virtual void VTable0x68(); // vtable+0x68 + virtual void VTable0x6c(); // vtable+0x6c + virtual void VTable0x70(); // vtable+0x70 + virtual void VTable0x74(); // vtable+0x74 + virtual void VTable0x78(); // vtable+0x78 + virtual void VTable0x7c(); // vtable+0x7c + virtual MxS32 GetWidth(); // vtable+0x80 + virtual MxS32 GetHeight(); // vtable+0x84 undefined4 m_unk50; undefined4 m_unk54; From e767d6524e73d5f24863ebf70923b1248c0d51b9 Mon Sep 17 00:00:00 2001 From: vMidz <147055059+vMidz@users.noreply.github.com> Date: Thu, 5 Oct 2023 23:06:11 +0300 Subject: [PATCH 15/15] implement MxMIDIManager (#167) * added MxMIDIManager * implement MxMIDIManager implement MxMIDIManager implement MxAudioManager::GetVolume implement MxAudioManager::SetVolume * added override + small changes --- CMakeLists.txt | 3 +- LEGO1/mxaudiomanager.cpp | 16 +++- LEGO1/mxaudiomanager.h | 10 ++- LEGO1/mxmidimanager.cpp | 161 +++++++++++++++++++++++++++++++++++++++ LEGO1/mxmidimanager.h | 42 ++++++++++ 5 files changed, 226 insertions(+), 6 deletions(-) create mode 100644 LEGO1/mxmidimanager.cpp create mode 100644 LEGO1/mxmidimanager.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 0da82a25..818d3773 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,6 +140,7 @@ add_library(lego1 SHARED LEGO1/mxmatrix.cpp LEGO1/mxmediamanager.cpp LEGO1/mxmediapresenter.cpp + LEGO1/mxmidimanager.cpp LEGO1/mxmidipresenter.cpp LEGO1/mxmusicpresenter.cpp LEGO1/mxnotificationmanager.cpp @@ -272,4 +273,4 @@ if (MSVC) set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "/incremental:no") set(CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO "/incremental:no /debug") set(CMAKE_SHARED_LINKER_FLAGS_MINSIZEREL "/incremental:no") -endif() \ No newline at end of file +endif() diff --git a/LEGO1/mxaudiomanager.cpp b/LEGO1/mxaudiomanager.cpp index c7ecdc12..bb358e47 100644 --- a/LEGO1/mxaudiomanager.cpp +++ b/LEGO1/mxaudiomanager.cpp @@ -20,7 +20,21 @@ MxAudioManager::~MxAudioManager() // OFFSET: LEGO1 0x100b8df0 void MxAudioManager::Init() { - this->m_unk2c = 100; + this->m_volume = 100; +} + +// OFFSET: LEGO1 0x10029910 +MxS32 MxAudioManager::GetVolume() +{ + return this->m_volume; +} + +// OFFSET: LEGO1 0x100b8ea0 +void MxAudioManager::SetVolume(MxS32 p_volume) +{ + this->m_criticalSection.Enter(); + this->m_volume = p_volume; + this->m_criticalSection.Leave(); } // OFFSET: LEGO1 0x100b8e00 diff --git a/LEGO1/mxaudiomanager.h b/LEGO1/mxaudiomanager.h index 1403f36d..1ba5b6fd 100644 --- a/LEGO1/mxaudiomanager.h +++ b/LEGO1/mxaudiomanager.h @@ -11,18 +11,20 @@ class MxAudioManager : public MxMediaManager MxAudioManager(); virtual ~MxAudioManager() override; - virtual MxResult InitPresenters(); // vtable+14 - virtual void Destroy(); // vtable+18 + virtual MxResult InitPresenters() override; // vtable+14 + virtual void Destroy() override; // vtable+18 + virtual MxS32 GetVolume(); // vtable+28 + virtual void SetVolume(MxS32 p_volume); // vtable+2c private: - void LockedReinitialize(MxBool); + void LockedReinitialize(MxBool p_skipDestroy); static MxS32 g_unkCount; protected: void Init(); - undefined4 m_unk2c; + MxS32 m_volume; // 0x2c }; #endif // MXAUDIOMANAGER_H diff --git a/LEGO1/mxmidimanager.cpp b/LEGO1/mxmidimanager.cpp new file mode 100644 index 00000000..62bcb6d2 --- /dev/null +++ b/LEGO1/mxmidimanager.cpp @@ -0,0 +1,161 @@ +#include "mxmidimanager.h" +#include "mxomni.h" +#include + +DECOMP_SIZE_ASSERT(MxMIDIManager, 0x58); + +// OFFSET: LEGO1 0x100c05a0 +MxMIDIManager::MxMIDIManager() +{ + Init(); +} + +// OFFSET: LEGO1 0x100c0630 +MxMIDIManager::~MxMIDIManager() +{ + LockedReinitialize(TRUE); +} + +// OFFSET: LEGO1 0x100c0b20 +void MxMIDIManager::DeinitializeMIDI() +{ + m_criticalSection.Enter(); + + if (this->m_MIDIInitialized) + { + this->m_MIDIInitialized = FALSE; + midiStreamStop(this->m_MIDIStreamH); + midiOutUnprepareHeader(this->m_MIDIStreamH, this->m_MIDIHdrP, sizeof(MIDIHDR)); + midiOutSetVolume(this->m_MIDIStreamH, this->m_MIDIVolume); + midiStreamClose(this->m_MIDIStreamH); + delete this->m_MIDIHdrP; + this->InitData(); + } + + this->m_criticalSection.Leave(); +} + +// OFFSET: LEGO1 0x100c0690 +void MxMIDIManager::Init() +{ + this->m_multiplier = 100; + InitData(); +} + +// OFFSET: LEGO1 0x100c06a0 +void MxMIDIManager::InitData() +{ + this->m_MIDIStreamH = 0; + this->m_MIDIInitialized = FALSE; + this->m_unk38 = 0; + this->m_unk3c = 0; + this->m_unk40 = 0; + this->m_unk44 = 0; + this->m_unk48 = 0; + this->m_MIDIHdrP = NULL; +} + +// OFFSET: LEGO1 0x100c06c0 +void MxMIDIManager::LockedReinitialize(MxBool p_skipDestroy) +{ + if (this->m_thread) + { + this->m_thread->Terminate(); + if (this->m_thread) + { + delete m_thread; + } + } + else + { + TickleManager()->UnregisterClient(this); + } + + this->m_criticalSection.Enter(); + DeinitializeMIDI(); + Init(); + this->m_criticalSection.Leave(); + + if (!p_skipDestroy) + { + MxAudioManager::Destroy(); + } +} + +// OFFSET: LEGO1 0x100c0930 +void MxMIDIManager::Destroy() +{ + LockedReinitialize(FALSE); +} + +// OFFSET: LEGO1 0x100c09a0 +MxS32 MxMIDIManager::CalculateVolume(MxS32 p_volume) +{ + MxS32 result = (p_volume * 0xffff) / 100; + return (result << 0x10) | result; +} + +// OFFSET: LEGO1 0x100c07f0 +void MxMIDIManager::SetMIDIVolume() +{ + MxS32 result = (this->m_volume * this->m_multiplier) / 0x64; + HMIDISTRM streamHandle = this->m_MIDIStreamH; + + if (streamHandle) + { + MxS32 volume = CalculateVolume(result); + midiOutSetVolume(streamHandle, volume); + } +} + +// OFFSET: LEGO1 0x100c0940 +void MxMIDIManager::SetVolume(MxS32 p_volume) +{ + MxAudioManager::SetVolume(p_volume); + this->m_criticalSection.Enter(); + SetMIDIVolume(); + this->m_criticalSection.Leave(); +} + +// OFFSET: LEGO1 0x100c0840 +MxResult MxMIDIManager::StartMIDIThread(MxU32 p_frequencyMS, MxBool p_noRegister) +{ + MxResult status = FAILURE; + MxBool locked = FALSE; + + MxResult result = MxAudioManager::InitPresenters(); + if (result == SUCCESS) + { + if (p_noRegister) + { + this->m_criticalSection.Enter(); + locked = TRUE; + this->m_thread = new MxTickleThread(this, p_frequencyMS); + + if (this->m_thread) + { + if (this->m_thread->Start(0, 0) == SUCCESS) + { + status = SUCCESS; + } + } + } + else + { + TickleManager()->RegisterClient(this, p_frequencyMS); + status = SUCCESS; + } + } + + if (status != SUCCESS) + { + Destroy(); + } + + if (locked) + { + this->m_criticalSection.Leave(); + } + + return status; +} \ No newline at end of file diff --git a/LEGO1/mxmidimanager.h b/LEGO1/mxmidimanager.h new file mode 100644 index 00000000..f944d67d --- /dev/null +++ b/LEGO1/mxmidimanager.h @@ -0,0 +1,42 @@ +#ifndef MXMIDIMANAGER_H +#define MXMIDIMANAGER_H + +#include "decomp.h" +#include "mxaudiomanager.h" + +// VTABLE 0x100dc930 +// SIZE 0x58 +class MxMIDIManager : public MxAudioManager +{ +public: + MxMIDIManager(); + virtual ~MxMIDIManager() override; + + virtual void Destroy() override; // vtable+18 + virtual void SetVolume(MxS32 p_volume) override; // vtable+2c + virtual MxResult StartMIDIThread(MxU32 p_frequencyMS, MxU8 p_noRegister); // vtable+30 + +private: + void LockedReinitialize(MxBool p_skipDestroy); + void DeinitializeMIDI(); + + MxS32 CalculateVolume(MxS32 p_volume); + void SetMIDIVolume(); + + HMIDISTRM m_MIDIStreamH; // 0x30 + MxBool m_MIDIInitialized; // 0x34 + undefined4 m_unk38; // 0x38 + undefined4 m_unk3c; // 0x3c + undefined4 m_unk40; // 0x40 + undefined4 m_unk44; // 0x44 + undefined4 m_unk48; // 0x48 + MIDIHDR *m_MIDIHdrP; // 0x4c + MxS32 m_multiplier; // 0x50 + DWORD m_MIDIVolume; // 0x54 + +protected: + void Init(); + void InitData(); +}; + +#endif // MXMIDIMANAGER_H \ No newline at end of file