diff --git a/CMakeLists.txt b/CMakeLists.txt index 818d3773..2e0fed5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,8 +140,8 @@ add_library(lego1 SHARED LEGO1/mxmatrix.cpp LEGO1/mxmediamanager.cpp LEGO1/mxmediapresenter.cpp - LEGO1/mxmidimanager.cpp LEGO1/mxmidipresenter.cpp + LEGO1/mxmusicmanager.cpp LEGO1/mxmusicpresenter.cpp LEGO1/mxnotificationmanager.cpp LEGO1/mxobjectfactory.cpp @@ -154,6 +154,7 @@ add_library(lego1 SHARED LEGO1/mxpresenter.cpp LEGO1/mxpresenterlist.cpp LEGO1/mxramstreamcontroller.cpp + LEGO1/mxramstreamprovider.cpp LEGO1/mxscheduler.cpp LEGO1/mxsemaphore.cpp LEGO1/mxsmkpresenter.cpp @@ -162,7 +163,9 @@ add_library(lego1 SHARED LEGO1/mxstillpresenter.cpp LEGO1/mxstreamcontroller.cpp LEGO1/mxstreamer.cpp + LEGO1/mxstreamprovider.cpp LEGO1/mxstring.cpp + LEGO1/mxstringlist.cpp LEGO1/mxthread.cpp LEGO1/mxticklemanager.cpp LEGO1/mxtimer.cpp diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index c20f1652..803ef45e 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -3,14 +3,25 @@ #include -#include "legoomni.h" #include "legoanimationmanager.h" #include "legobuildingmanager.h" +#include "legogamestate.h" +#include "legoinputmanager.h" #include "legomodelpresenter.h" +#include "legoomni.h" #include "legopartpresenter.h" +#include "legoroi.h" +#include "legovideomanager.h" #include "legoworldpresenter.h" +#include "mxbackgroundaudiomanager.h" #include "mxdirectdraw.h" #include "mxdsaction.h" +#include "mxomnicreateflags.h" +#include "mxomnicreateparam.h" +#include "mxstreamer.h" +#include "mxticklemanager.h" +#include "mxtimer.h" +#include "mxtransitionmanager.h" #include "res/resource.h" @@ -93,7 +104,7 @@ void IsleApp::Close() Lego()->RemoveWorld(ds.GetAtomId(), ds.GetObjectId()); Lego()->DeleteObject(ds); TransitionManager()->SetWaitIndicator(NULL); - Lego()->vtable0x3c(); + Lego()->StopTimer(); MxLong lVar8; do { @@ -232,23 +243,19 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine g_reqEnableRMDevice = 0; VideoManager()->EnableRMDevice(); g_rmDisabled = 0; - Lego()->vtable0x3c(); + Lego()->StopTimer(); } if (g_closed) { break; } - if (g_mousedown == 0) { -LAB_00401bc7: - if (g_mousemoved) { - g_mousemoved = FALSE; - } - } else if (g_mousemoved) { - if (g_isle) { - g_isle->Tick(0); - } - goto LAB_00401bc7; + if (g_mousedown && g_mousemoved && g_isle) { + g_isle->Tick(0); + } + + if (g_mousemoved) { + g_mousemoved = FALSE; } } } @@ -727,7 +734,7 @@ inline void IsleApp::Tick(BOOL sleepIfNotNextFrame) return; } - ds.SetAtomId(stream->atom); + ds.SetAtomId(stream->GetAtom()); ds.SetUnknown24(-1); ds.SetObjectId(0); VideoManager()->EnableFullScreenMovie(TRUE, TRUE); @@ -736,7 +743,7 @@ inline void IsleApp::Tick(BOOL sleepIfNotNextFrame) return; } } else { - ds.SetAtomId(stream->atom); + ds.SetAtomId(stream->GetAtom()); ds.SetUnknown24(-1); ds.SetObjectId(0); if (Start(&ds) != SUCCESS) { diff --git a/LEGO1/compat.h b/LEGO1/compat.h index 33b97d5a..ba0b9d34 100644 --- a/LEGO1/compat.h +++ b/LEGO1/compat.h @@ -18,6 +18,9 @@ // Impossible to avoid this if using STL map or set. // This removes most (but not all) occurrences of the warning. #pragma warning( disable : 4786 ) +// To really remove *all* of the warnings, we have to employ the following, +// obscure workaround from https://www.earthli.com/news/view_article.php?id=376 +static class msVC6_4786WorkAround { public: msVC6_4786WorkAround() {} } msVC6_4786WorkAround; #define MSVC420_VERSION 1020 diff --git a/LEGO1/legoentity.cpp b/LEGO1/legoentity.cpp index 105b4b5f..e7601cc2 100644 --- a/LEGO1/legoentity.cpp +++ b/LEGO1/legoentity.cpp @@ -23,12 +23,8 @@ MxLong LegoEntity::Notify(MxParam &p) // OFFSET: LEGO1 0x100105f0 void LegoEntity::Reset() { - float value = 0.0f; - m_vec1.EqualsScalar(&value); - - value = 0.0f; - m_vec2.EqualsScalar(&value); - + m_vec1.Fill(0); + m_vec2.Fill(0); m_unk50 = 0; m_unk54 = 0; m_unk58 = 0; diff --git a/LEGO1/legofullscreenmovie.cpp b/LEGO1/legofullscreenmovie.cpp index f2a287f3..cb803133 100644 --- a/LEGO1/legofullscreenmovie.cpp +++ b/LEGO1/legofullscreenmovie.cpp @@ -1,6 +1,8 @@ #include "legofullscreenmovie.h" -#include "mxtypes.h" + #include "legoomni.h" +#include "legovideomanager.h" +#include "mxtypes.h" #include "decomp.h" DECOMP_SIZE_ASSERT(LegoFullScreenMovie, 0x24) diff --git a/LEGO1/legogamestate.cpp b/LEGO1/legogamestate.cpp index 0f444f95..a08ce8e2 100644 --- a/LEGO1/legogamestate.cpp +++ b/LEGO1/legogamestate.cpp @@ -1,5 +1,7 @@ #include "legogamestate.h" + #include "legoomni.h" +#include "mxvariabletable.h" #include "decomp.h" // Based on the highest dword offset (0x42c) referenced in the constructor. diff --git a/LEGO1/legonavcontroller.cpp b/LEGO1/legonavcontroller.cpp index 90c0a485..1f056f59 100644 --- a/LEGO1/legonavcontroller.cpp +++ b/LEGO1/legonavcontroller.cpp @@ -1,6 +1,7 @@ #include "legonavcontroller.h" #include "legoomni.h" +#include "legovideomanager.h" #include "legoutil.h" // 0x100f4c28 diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index 929ba556..f4480bb8 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -1,6 +1,9 @@ #include "legoomni.h" -#include "mxdsobject.h" +#include "mxbackgroundaudiomanager.h" +#include "mxdsfile.h" +#include "legogamestate.h" +#include "legoutil.h" // 0x100f4588 char *g_nocdSourceName = NULL; @@ -99,11 +102,10 @@ void SetOmniUserMessage(void (*p_userMsg)(const char *,int)) g_omniUserMessage = p_userMsg; } -// OFFSET: LEGO1 0x100acf50 STUB -MxLong Start(MxDSAction *) +// OFFSET: LEGO1 0x100acf50 +MxResult Start(MxDSAction* p_dsAction) { - // TODO - return 0; + return MxOmni::GetInstance()->Start(p_dsAction); } // OFFSET: LEGO1 0x1005ad10 @@ -257,6 +259,10 @@ void LegoOmni::Init() MxResult LegoOmni::Create(COMPAT_CONST MxOmniCreateParam &p) { // FIXME: Stub + MxOmni::Create(p); + m_gameState = new LegoGameState(); + m_bkgAudioManager = new MxBackgroundAudioManager(); + return SUCCESS; } @@ -265,9 +271,14 @@ void LegoOmni::Destroy() // FIXME: Stub } -void LegoOmni::vtable0x20() +// OFFSET: LEGO1 0x1005b580 +MxResult LegoOmni::Start(MxDSAction* action) { - // FIXME: Stub + MxResult result = MxOmni::Start(action); + this->m_action.SetAtomId(action->GetAtomId()); + this->m_action.SetObjectId(action->GetObjectId()); + this->m_action.SetUnknown24(action->GetUnknown24()); + return result; } void LegoOmni::DeleteObject(MxDSAction &ds) @@ -297,14 +308,18 @@ void LegoOmni::NotifyCurrentEntity() // FIXME: Stub } +// OFFSET: LEGO1 0x1005b640 void LegoOmni::StartTimer() { - // FIXME: Stub + MxOmni::StartTimer(); + SetAppCursor(2); } -void LegoOmni::vtable0x3c() +// OFFSET: LEGO1 0x1005b650 +void LegoOmni::StopTimer() { - // FIXME: Stub + MxOmni::StopTimer(); + SetAppCursor(0); } MxBool LegoOmni::vtable40() diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index 4a5fe6e4..4de0d1b5 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -2,25 +2,24 @@ #define LEGOOMNI_H #include "compat.h" -#include "legoentity.h" -#include "legoinputmanager.h" -#include "legogamestate.h" -#include "legonavcontroller.h" -#include "legopathboundary.h" -#include "legoroi.h" -#include "legovideomanager.h" -#include "mxatomid.h" -#include "mxbackgroundaudiomanager.h" -#include "mxdsaction.h" -#include "mxdsfile.h" -#include "mxdsobject.h" #include "mxomni.h" -#include "mxtransitionmanager.h" -#include "isle.h" -#include "legobuildingmanager.h" -#include "legoplantmanager.h" +#include "mxdsaction.h" +class Isle; +class LegoBuildingManager; +class LegoEntity; +class LegoGameState; +class LegoInputManager; +class LegoNavController; +class LegoPathBoundary; +class LegoPlantManager; +class LegoROI; class LegoSoundManager; +class LegoVideoManager; +class LegoWorld; +class MxAtomId; +class MxBackgroundAudioManager; +class MxDSFile; class MxTransitionManager; // VTABLE 0x100d8638 @@ -55,14 +54,14 @@ class LegoOmni : public MxOmni virtual void Init() override; // vtable+14 virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p) override; // vtable+18 virtual void Destroy() override; // vtable+1c - virtual void vtable0x20() override; + virtual MxResult Start(MxDSAction* action) override; virtual void DeleteObject(MxDSAction &ds) override; virtual MxBool DoesEntityExist(MxDSAction &ds) override; virtual void vtable0x2c() override; virtual int vtable0x30(char*, int, MxCore*) override; virtual void NotifyCurrentEntity() override; virtual void StartTimer() override; - virtual void vtable0x3c() override; + virtual void StopTimer() override; virtual MxBool vtable40(); LegoVideoManager *GetVideoManager() { return (LegoVideoManager *) m_videoManager; } @@ -110,10 +109,9 @@ __declspec(dllexport) LegoEntity * PickEntity(MxLong,MxLong); __declspec(dllexport) LegoROI * PickROI(MxLong,MxLong); __declspec(dllexport) void SetOmniUserMessage(void (*)(const char *,int)); __declspec(dllexport) LegoSoundManager * SoundManager(); -__declspec(dllexport) MxLong Start(MxDSAction *); +__declspec(dllexport) MxResult Start(MxDSAction*); __declspec(dllexport) MxTransitionManager * TransitionManager(); __declspec(dllexport) LegoVideoManager * VideoManager(); -__declspec(dllexport) MxLong Start(MxDSAction *a); LegoBuildingManager* BuildingManager(); Isle* GetIsle(); diff --git a/LEGO1/legoutil.h b/LEGO1/legoutil.h index e912991d..cc54da74 100644 --- a/LEGO1/legoutil.h +++ b/LEGO1/legoutil.h @@ -23,6 +23,35 @@ inline T Max(T p_t1, T p_t2) return p_t1 > p_t2 ? p_t1 : p_t2; } +template +inline void GetScalar(char **p_source, T& p_dest) +{ + p_dest = *(T*) *p_source; + *p_source += sizeof(T); +} + +template +inline T GetScalar(T **p_source) +{ + T val = **p_source; + *p_source += 1; + return val; +} + +template +inline void GetDouble(char **p_source, T& p_dest) +{ + p_dest = *(double*) *p_source; + *p_source += sizeof(double); +} + +template +inline void GetString(char **p_source, const char *&p_dest, T *p_obj, void (T::*p_setter)(const char*)) +{ + (p_obj->*p_setter)(*p_source); + *p_source += strlen(p_dest) + 1; +} + ExtraActionType MatchActionString(const char *); void ConvertHSVToRGB(float r, float g, float b, float* out_r, float* out_g, float* out_b); void SetAppCursor(WPARAM p_wparam); diff --git a/LEGO1/legovideomanager.cpp b/LEGO1/legovideomanager.cpp index 4105ef2a..ca7926b9 100644 --- a/LEGO1/legovideomanager.cpp +++ b/LEGO1/legovideomanager.cpp @@ -1,5 +1,6 @@ #include "legovideomanager.h" -#include + +DECOMP_SIZE_ASSERT(LegoVideoManager, 0x590); // OFFSET: LEGO1 0x1007aa20 STUB LegoVideoManager::LegoVideoManager() @@ -39,20 +40,32 @@ void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable, MxBool p_scale) // TODO } -// OFFSET: LEGO1 0x1007b6a0 STUB -void LegoVideoManager::MoveCursor(int x, int y) +// OFFSET: LEGO1 0x1007b6a0 +void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY) { - // TODO + m_cursorX = p_cursorX; + m_cursorY = p_cursorY; + m_cursorMoved = TRUE; + + if (623 < p_cursorX) + m_cursorX = 623; + + if (463 < p_cursorY) + m_cursorY = 463; } // OFFSET: LEGO1 0x1007c440 -void LegoVideoManager::SetSkyColor(float red, float green, float blue) +void LegoVideoManager::SetSkyColor(float p_red, float p_green, float p_blue) { - PALETTEENTRY colorStrucure; // [esp+0h] [ebp-4h] BYREF + PALETTEENTRY colorStrucure; - colorStrucure.peRed = (red* 255.0); - colorStrucure.peGreen = (green * 255.0); - colorStrucure.peBlue = (blue * 255.0); + colorStrucure.peRed = (p_red * 255.0f); + colorStrucure.peGreen = (p_green * 255.0f); + colorStrucure.peBlue = (p_blue * 255.0f); colorStrucure.peFlags = -124; - // TODO + m_videoParam.GetPalette()->SetSkyColor(&colorStrucure); + m_videoParam.GetPalette()->SetOverrideSkyColor(TRUE); + + // TODO 3d manager + //m_3dManager->m_pViewport->vtable1c(red, green, blue) } diff --git a/LEGO1/legovideomanager.h b/LEGO1/legovideomanager.h index 4ff8491b..cc051f16 100644 --- a/LEGO1/legovideomanager.h +++ b/LEGO1/legovideomanager.h @@ -6,6 +6,8 @@ #include "lego3dmanager.h" #include "decomp.h" +#include + // VTABLE 0x100d9c88 // SIZE 0x590 class LegoVideoManager : public MxVideoManager @@ -24,7 +26,10 @@ class LegoVideoManager : public MxVideoManager inline MxDirect3D *GetDirect3D() { return this->m_direct3d; } void SetSkyColor(float r, float g, float b); - inline void SetUnkE4(MxBool p_value) { this->m_unke4 = p_value; } + inline void SetUnkE4(MxBool p_unk0xe4) { this->m_unk0xe4 = p_unk0xe4; } + + // OFFSET: LEGO1 0x1007c4c0 + void OverrideSkyColor(MxBool p_shouldOverride) { this->m_videoParam.GetPalette()->SetOverrideSkyColor(p_shouldOverride);} private: undefined4 m_unk64; @@ -32,8 +37,14 @@ class LegoVideoManager : public MxVideoManager undefined4 m_unk6c; undefined4 m_unk70; MxDirect3D *m_direct3d; - undefined m_pad78[0x6c]; - MxBool m_unke4; + undefined m_pad0x78[0x6c]; + MxBool m_unk0xe4; + undefined m_pad0xe8[0x41c]; + MxBool m_cursorMoved; // 0x501 + undefined m_pad0x502[0x8]; + MxS32 m_cursorX; // 0x50c + MxS32 m_cursorY; // 0x510 + undefined m_pad0x514[0x7c]; }; #endif // LEGOVIDEOMANAGER_H diff --git a/LEGO1/mxaudiopresenter.cpp b/LEGO1/mxaudiopresenter.cpp index ac634362..48a02377 100644 --- a/LEGO1/mxaudiopresenter.cpp +++ b/LEGO1/mxaudiopresenter.cpp @@ -3,3 +3,15 @@ #include "decomp.h" DECOMP_SIZE_ASSERT(MxAudioPresenter, 0x54); + +// OFFSET: LEGO1 0x1000d260 +undefined4 MxAudioPresenter::vtable5c() +{ + return this->m_unk50; +} + +// OFFSET: LEGO1 0x1000d270 +void MxAudioPresenter::vtable60(undefined4 p_unk50) +{ + this->m_unk50 = p_unk50; +} diff --git a/LEGO1/mxaudiopresenter.h b/LEGO1/mxaudiopresenter.h index c1001a13..fb2e75a8 100644 --- a/LEGO1/mxaudiopresenter.h +++ b/LEGO1/mxaudiopresenter.h @@ -1,6 +1,7 @@ #ifndef MXAUDIOPRESENTER_H #define MXAUDIOPRESENTER_H +#include "decomp.h" #include "mxmediapresenter.h" // VTABLE 0x100d4c70 @@ -24,7 +25,10 @@ class MxAudioPresenter : public MxMediaPresenter return !strcmp(name, MxAudioPresenter::ClassName()) || MxMediaPresenter::IsA(name); } - int m_unk50; + virtual undefined4 vtable5c(); + virtual void vtable60(undefined4); + + undefined4 m_unk50; }; #endif // MXAUDIOPRESENTER_H diff --git a/LEGO1/mxbitmap.h b/LEGO1/mxbitmap.h index ba90b7da..791581c6 100644 --- a/LEGO1/mxbitmap.h +++ b/LEGO1/mxbitmap.h @@ -25,6 +25,8 @@ struct MxBITMAPINFO { #define LOWCOLOR 0 // 256 color #define HIGHCOLOR 1 // High Color (16-bit) +// SIZE 0x20 +// VTABLE 0x100dc7b0 class MxBitmap : public MxCore { public: @@ -44,6 +46,8 @@ class MxBitmap : public MxCore virtual MxResult SetBitDepth(MxBool); // vtable+3c virtual MxResult StretchBits(HDC p_hdc, int p_xSrc, int p_ySrc, int p_xDest, int p_yDest, int p_destWidth, int p_destHeight); // vtable+40 + inline BITMAPINFOHEADER *GetBmiHeader() const { return m_bmiHeader; } + private: MxResult ImportColorsToPalette(RGBQUAD*, MxPalette*); diff --git a/LEGO1/mxcompositepresenter.cpp b/LEGO1/mxcompositepresenter.cpp index 342f3d96..06477c94 100644 --- a/LEGO1/mxcompositepresenter.cpp +++ b/LEGO1/mxcompositepresenter.cpp @@ -1,17 +1,18 @@ #include "mxcompositepresenter.h" #include "decomp.h" +#include "mxnotificationmanager.h" DECOMP_SIZE_ASSERT(MxCompositePresenter, 0x4c); -// OFFSET: LEGO1 0x100b60b0 STUB +// OFFSET: LEGO1 0x100b60b0 MxCompositePresenter::MxCompositePresenter() { - // TODO + NotificationManager()->Register(this); } -// OFFSET: LEGO1 0x100b6390 STUB +// OFFSET: LEGO1 0x100b6390 MxCompositePresenter::~MxCompositePresenter() { - // TODO + NotificationManager()->Unregister(this); } diff --git a/LEGO1/mxcompositepresenter.h b/LEGO1/mxcompositepresenter.h index 9f517652..0be080f0 100644 --- a/LEGO1/mxcompositepresenter.h +++ b/LEGO1/mxcompositepresenter.h @@ -2,6 +2,7 @@ #define MXCOMPOSITEPRESENTER_H #include "mxpresenter.h" +#include "mxunklist.h" // VTABLE 0x100dc618 // SIZE 0x4c @@ -24,9 +25,7 @@ class MxCompositePresenter : public MxPresenter return !strcmp(name, MxCompositePresenter::ClassName()) || MxPresenter::IsA(name); } - undefined m_unk40; - undefined4 *m_unk44; - undefined4 m_unk48; + MxUnkList m_list; }; #endif // MXCOMPOSITEPRESENTER_H diff --git a/LEGO1/mxdiskstreamprovider.h b/LEGO1/mxdiskstreamprovider.h index b6ff8c18..c797a0de 100644 --- a/LEGO1/mxdiskstreamprovider.h +++ b/LEGO1/mxdiskstreamprovider.h @@ -5,6 +5,7 @@ #include "mxstreamprovider.h" #include "mxthread.h" #include "mxcriticalsection.h" +#include "mxunklist.h" class MxDiskStreamProvider; @@ -23,32 +24,6 @@ class MxDiskStreamProviderThread : public MxThread MxDiskStreamProvider *m_target; }; -// TODO -struct MxDiskStreamListNode { - MxDiskStreamListNode *m_unk00; - MxDiskStreamListNode *m_unk04; - undefined4 m_unk08; -}; - -// TODO -struct MxDiskStreamList { - inline MxDiskStreamList() { - undefined unk; - this->m_unk00 = unk; - - MxDiskStreamListNode *node = new MxDiskStreamListNode(); - node->m_unk00 = node; - node->m_unk04 = node; - - this->m_head = node; - this->m_count = 0; - } - - undefined m_unk00; - MxDiskStreamListNode *m_head; - MxU32 m_count; -}; - // VTABLE 0x100dd138 class MxDiskStreamProvider : public MxStreamProvider { @@ -80,7 +55,7 @@ class MxDiskStreamProvider : public MxStreamProvider undefined m_remainingWork; // 0x34 undefined m_unk35; // 0x35 MxCriticalSection m_criticalSection; // 0x38 - MxDiskStreamList m_list; + MxUnkList m_list; }; #endif // MXDISKSTREAMPROVIDER_H diff --git a/LEGO1/mxdisplaysurface.cpp b/LEGO1/mxdisplaysurface.cpp index e22244c5..af7e57db 100644 --- a/LEGO1/mxdisplaysurface.cpp +++ b/LEGO1/mxdisplaysurface.cpp @@ -1,5 +1,7 @@ #include "mxdisplaysurface.h" + #include "mxomni.h" +#include "mxvideomanager.h" DECOMP_SIZE_ASSERT(MxDisplaySurface, 0xac); @@ -174,7 +176,7 @@ void MxDisplaySurface::SetPalette(MxPalette *p_palette) } // OFFSET: LEGO1 0x100bc200 STUB -void MxDisplaySurface::vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) +void MxDisplaySurface::vtable24(LPDDSURFACEDESC, MxBitmap*, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4) { } @@ -186,7 +188,7 @@ MxBool MxDisplaySurface::vtable28(undefined4, undefined4, undefined4, undefined4 } // OFFSET: LEGO1 0x100bc630 STUB -MxBool MxDisplaySurface::vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool) +MxBool MxDisplaySurface::vtable2c(LPDDSURFACEDESC, MxBitmap*, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool) { return 0; } diff --git a/LEGO1/mxdisplaysurface.h b/LEGO1/mxdisplaysurface.h index 8e79f6e8..8a80a0f4 100644 --- a/LEGO1/mxdisplaysurface.h +++ b/LEGO1/mxdisplaysurface.h @@ -3,6 +3,7 @@ #include +#include "mxbitmap.h" #include "mxcore.h" #include "mxpalette.h" #include "mxvideoparam.h" @@ -25,9 +26,9 @@ class MxDisplaySurface : public MxCore virtual MxResult Create(MxVideoParam &p_videoParam); virtual void Clear(); virtual void SetPalette(MxPalette *p_palette); - virtual void vtable24(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); + virtual void vtable24(LPDDSURFACEDESC, MxBitmap*, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); virtual MxBool vtable28(undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4); - virtual MxBool vtable2c(LPDDSURFACEDESC, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, undefined4, MxBool); + virtual MxBool vtable2c(LPDDSURFACEDESC, MxBitmap*, 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.cpp b/LEGO1/mxdsaction.cpp index 3411a460..153a6498 100644 --- a/LEGO1/mxdsaction.cpp +++ b/LEGO1/mxdsaction.cpp @@ -1,10 +1,12 @@ #include "mxdsaction.h" +#include "mxomni.h" +#include "mxtimer.h" +#include "legoutil.h" + #include #include -#include "mxomni.h" - DECOMP_SIZE_ASSERT(MxDSAction, 0x94) // GLOBAL OFFSET: LEGO1 0x10101410 @@ -21,22 +23,9 @@ MxDSAction::MxDSAction() this->m_loopCount = -1; this->SetType(MxDSType_Action); - - { - float value = FLT_MAX; - this->m_location.EqualsScalar(&value); - } - - { - float value = FLT_MAX; - this->m_direction.EqualsScalar(&value); - } - - { - float value = FLT_MAX; - this->m_up.EqualsScalar(&value); - } - + this->m_location.Fill(FLT_MAX); + this->m_direction.Fill(FLT_MAX); + this->m_up.Fill(FLT_MAX); this->m_unk84 = 0; this->m_unk88 = 0; this->m_omni = NULL; @@ -96,38 +85,24 @@ void MxDSAction::Deserialize(char **p_source, MxS16 p_unk24) { MxDSObject::Deserialize(p_source, p_unk24); - this->m_flags = *(MxU32*) *p_source; - *p_source += sizeof(MxU32); - this->m_startTime = *(MxLong*) *p_source; - *p_source += sizeof(MxLong); - this->m_duration = *(MxLong*) *p_source; - *p_source += sizeof(MxLong); - this->m_loopCount = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); - this->m_location[0] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_location[1] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_location[2] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_direction[0] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_direction[1] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_direction[2] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_up[0] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_up[1] = *(double*) *p_source; - *p_source += sizeof(double); - this->m_up[2] = *(double*) *p_source; - *p_source += sizeof(double); + GetScalar(p_source, this->m_flags); + GetScalar(p_source, this->m_startTime); + GetScalar(p_source, this->m_duration); + GetScalar(p_source, this->m_loopCount); + GetDouble(p_source, this->m_location[0]); + GetDouble(p_source, this->m_location[1]); + GetDouble(p_source, this->m_location[2]); + GetDouble(p_source, this->m_direction[0]); + GetDouble(p_source, this->m_direction[1]); + GetDouble(p_source, this->m_direction[2]); + GetDouble(p_source, this->m_up[0]); + GetDouble(p_source, this->m_up[1]); + GetDouble(p_source, this->m_up[2]); - MxU16 unkLength = *(MxU16*) *p_source; - *p_source += sizeof(MxU16); - if (unkLength) { - AppendData(unkLength, *p_source); - *p_source += unkLength; + MxU16 extraLength = GetScalar((MxU16**) p_source); + if (extraLength) { + AppendData(extraLength, *p_source); + *p_source += extraLength; } } diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index 9881f3e2..57d1f200 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -41,8 +41,8 @@ class MxDSAction : public MxDSObject return !strcmp(name, MxDSAction::ClassName()) || MxDSObject::IsA(name); } - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; virtual MxLong GetDuration(); // vtable+24; virtual void SetDuration(MxLong p_duration); // vtable+28; virtual MxDSAction *Clone(); // vtable+2c; diff --git a/LEGO1/mxdsanim.h b/LEGO1/mxdsanim.h index 92890e8e..1bc77558 100644 --- a/LEGO1/mxdsanim.h +++ b/LEGO1/mxdsanim.h @@ -27,7 +27,7 @@ class MxDSAnim : public MxDSMediaAction return !strcmp(name, MxDSAnim::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSANIM_H diff --git a/LEGO1/mxdschunk.h b/LEGO1/mxdschunk.h index f9b1d9d0..367dcb4d 100644 --- a/LEGO1/mxdschunk.h +++ b/LEGO1/mxdschunk.h @@ -1,7 +1,6 @@ #ifndef MXDSCHUNK_H #define MXDSCHUNK_H - #include "mxcore.h" #include "mxtypes.h" diff --git a/LEGO1/mxdsevent.h b/LEGO1/mxdsevent.h index b8fedace..576c8b14 100644 --- a/LEGO1/mxdsevent.h +++ b/LEGO1/mxdsevent.h @@ -25,7 +25,7 @@ class MxDSEvent : public MxDSMediaAction return !strcmp(name, MxDSEvent::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSEVENT_H diff --git a/LEGO1/mxdsmediaaction.cpp b/LEGO1/mxdsmediaaction.cpp index d368aa3d..19f3bde2 100644 --- a/LEGO1/mxdsmediaaction.cpp +++ b/LEGO1/mxdsmediaaction.cpp @@ -1,5 +1,7 @@ #include "mxdsmediaaction.h" +#include "legoutil.h" + DECOMP_SIZE_ASSERT(MxDSMediaAction, 0xb8) // OFFSET: LEGO1 0x100c8b40 @@ -68,21 +70,13 @@ void MxDSMediaAction::Deserialize(char **p_source, MxS16 p_unk24) { MxDSAction::Deserialize(p_source, p_unk24); - CopyMediaSrcPath(*p_source); - *p_source += strlen(this->m_mediaSrcPath) + 1; - - this->m_unk9c = *(undefined4*) *p_source; - *p_source += sizeof(undefined4); - this->m_unka0 = *(undefined4*) *p_source; - *p_source += sizeof(undefined4); - this->m_framesPerSecond = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); - this->m_mediaFormat = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); - this->m_paletteManagement = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); - this->m_sustainTime = *(MxLong*) *p_source; - *p_source += sizeof(MxLong); + GetString(p_source, this->m_mediaSrcPath, this, &MxDSMediaAction::CopyMediaSrcPath); + GetScalar(p_source, this->m_unk9c); + GetScalar(p_source, this->m_unka0); + GetScalar(p_source, this->m_framesPerSecond); + GetScalar(p_source, this->m_mediaFormat); + GetScalar(p_source, this->m_paletteManagement); + GetScalar(p_source, this->m_sustainTime); } // OFFSET: LEGO1 0x100c8e80 diff --git a/LEGO1/mxdsmediaaction.h b/LEGO1/mxdsmediaaction.h index cc710425..34b6695e 100644 --- a/LEGO1/mxdsmediaaction.h +++ b/LEGO1/mxdsmediaaction.h @@ -28,8 +28,8 @@ class MxDSMediaAction : public MxDSAction return !strcmp(name, MxDSMediaAction::ClassName()) || MxDSAction::IsA(name); } - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; void CopyMediaSrcPath(const char *p_mediaSrcPath); diff --git a/LEGO1/mxdsmultiaction.h b/LEGO1/mxdsmultiaction.h index 4063343c..1689cc2d 100644 --- a/LEGO1/mxdsmultiaction.h +++ b/LEGO1/mxdsmultiaction.h @@ -28,14 +28,14 @@ class MxDSMultiAction : public MxDSAction return !strcmp(name, MxDSMultiAction::ClassName()) || MxDSAction::IsA(name); } - virtual undefined4 unk14(); // vtable+14; - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; - virtual void SetAtomId(MxAtomId p_atomId); // vtable+20; - virtual MxDSAction *Clone(); // vtable+2c; - virtual void MergeFrom(MxDSAction &p_dsAction); // vtable+30; - virtual MxBool HasId(MxU32 p_objectId); // vtable+34; - virtual void SetSomeTimingField(MxLong p_someTimingField); // vtable+38; + virtual undefined4 unk14() override; // vtable+14; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; + virtual void SetAtomId(MxAtomId p_atomId) override; // vtable+20; + virtual MxDSAction *Clone() override; // vtable+2c; + virtual void MergeFrom(MxDSAction &p_dsAction) override; // vtable+30; + virtual MxBool HasId(MxU32 p_objectId) override; // vtable+34; + virtual void SetSomeTimingField(MxLong p_someTimingField) override; // vtable+38; private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxdsobject.cpp b/LEGO1/mxdsobject.cpp index 2b7d8437..f508c53b 100644 --- a/LEGO1/mxdsobject.cpp +++ b/LEGO1/mxdsobject.cpp @@ -15,6 +15,7 @@ #include "mxdsselectaction.h" #include "mxdsstill.h" #include "mxdsobjectaction.h" +#include "legoutil.h" DECOMP_SIZE_ASSERT(MxDSObject, 0x2c); @@ -128,20 +129,14 @@ MxU32 MxDSObject::GetSizeOnDisk() // OFFSET: LEGO1 0x100bfa20 void MxDSObject::Deserialize(char **p_source, MxS16 p_unk24) { - this->SetSourceName(*p_source); - *p_source += strlen(this->m_sourceName) + 1; - this->m_unk14 = *(undefined4*) *p_source; - *p_source += sizeof(undefined4); - - this->SetObjectName(*p_source); - *p_source += strlen(this->m_objectName) + 1; - this->m_objectId = *(MxU32*) *p_source; - *p_source += sizeof(MxU32); + GetString(p_source, this->m_sourceName, this, &MxDSObject::SetSourceName); + GetScalar(p_source, this->m_unk14); + GetString(p_source, this->m_objectName, this, &MxDSObject::SetObjectName); + GetScalar(p_source, this->m_objectId); this->m_unk24 = p_unk24; } - // OFFSET: LEGO1 0x100bfb30 MxDSObject *DeserializeDSObjectDispatch(char **p_source, MxS16 p_flags) { diff --git a/LEGO1/mxdsobject.h b/LEGO1/mxdsobject.h index 1ca3d98a..e340789a 100644 --- a/LEGO1/mxdsobject.h +++ b/LEGO1/mxdsobject.h @@ -36,6 +36,7 @@ class MxDSObject : public MxCore inline const MxAtomId& GetAtomId() { return this->m_atomId; } inline MxU32 GetObjectId() { return this->m_objectId; } + inline MxS16 GetUnknown24() { return this->m_unk24; } inline void SetObjectId(MxU32 p_objectId) { this->m_objectId = p_objectId; } inline void SetUnknown24(MxS16 p_unk24) { this->m_unk24 = p_unk24; } diff --git a/LEGO1/mxdsobjectaction.h b/LEGO1/mxdsobjectaction.h index 4a1b68bb..07f35758 100644 --- a/LEGO1/mxdsobjectaction.h +++ b/LEGO1/mxdsobjectaction.h @@ -26,7 +26,7 @@ class MxDSObjectAction : public MxDSMediaAction return !strcmp(name, MxDSObjectAction::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; virtual void CopyFrom(MxDSObjectAction &p_dsObjectAction); // vtable+44; }; diff --git a/LEGO1/mxdsparallelaction.h b/LEGO1/mxdsparallelaction.h index 962ba34b..e28bfe58 100644 --- a/LEGO1/mxdsparallelaction.h +++ b/LEGO1/mxdsparallelaction.h @@ -27,8 +27,8 @@ class MxDSParallelAction : public MxDSMultiAction return !strcmp(name, MxDSParallelAction::ClassName()) || MxDSMultiAction::IsA(name); } - virtual MxLong GetDuration(); // vtable+24; - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxLong GetDuration() override; // vtable+24; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSPARALLELACTION_H diff --git a/LEGO1/mxdsselectaction.cpp b/LEGO1/mxdsselectaction.cpp index 29f69022..58af9543 100644 --- a/LEGO1/mxdsselectaction.cpp +++ b/LEGO1/mxdsselectaction.cpp @@ -15,3 +15,37 @@ MxDSSelectAction::~MxDSSelectAction() if (this->m_unk0xac) delete this->m_unk0xac; } + +// OFFSET: LEGO1 0x100cb950 +void MxDSSelectAction::CopyFrom(MxDSSelectAction &p_dsSelectAction) +{ + this->m_unk0x9c = p_dsSelectAction.m_unk0x9c; + + this->m_unk0xac->DeleteAll(); + + MxStringListCursor cursor(p_dsSelectAction.m_unk0xac); + MxString string; + while (cursor.Next(string)) + this->m_unk0xac->OtherAppend(string); +} + +// OFFSET: LEGO1 0x100cbd50 +MxDSSelectAction &MxDSSelectAction::operator=(MxDSSelectAction &p_dsSelectAction) +{ + if (this != &p_dsSelectAction) { + MxDSParallelAction::operator=(p_dsSelectAction); + this->CopyFrom(p_dsSelectAction); + } + return *this; +} + +// OFFSET: LEGO1 0x100cbd80 +MxDSAction *MxDSSelectAction::Clone() +{ + MxDSSelectAction *clone = new MxDSSelectAction(); + + if (clone) + *clone = *this; + + return clone; +} \ No newline at end of file diff --git a/LEGO1/mxdsselectaction.h b/LEGO1/mxdsselectaction.h index d513efd0..746afc87 100644 --- a/LEGO1/mxdsselectaction.h +++ b/LEGO1/mxdsselectaction.h @@ -13,6 +13,9 @@ class MxDSSelectAction : public MxDSParallelAction MxDSSelectAction(); virtual ~MxDSSelectAction() override; + void CopyFrom(MxDSSelectAction &p_dsSelectAction); + MxDSSelectAction &operator=(MxDSSelectAction &p_dsSelectAction); + // OFFSET: LEGO1 0x100cb6f0 inline virtual const char *ClassName() const override // vtable+0x0c { @@ -26,6 +29,11 @@ class MxDSSelectAction : public MxDSParallelAction return !strcmp(name, MxDSSelectAction::ClassName()) || MxDSParallelAction::IsA(name); } + //virtual MxU32 GetSizeOnDisk() override; // vtable+18; + //virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; + //virtual MxLong GetDuration() override; // vtable+24; + virtual MxDSAction *Clone() override; // vtable+2c; + private: MxString m_unk0x9c; MxStringList *m_unk0xac; diff --git a/LEGO1/mxdsserialaction.h b/LEGO1/mxdsserialaction.h index e2f6cd72..4e383681 100644 --- a/LEGO1/mxdsserialaction.h +++ b/LEGO1/mxdsserialaction.h @@ -28,9 +28,9 @@ class MxDSSerialAction : public MxDSMultiAction return !strcmp(name, MxDSSerialAction::ClassName()) || MxDSMultiAction::IsA(name); } - virtual MxLong GetDuration(); // vtable+24; - virtual void SetDuration(MxLong p_duration); // vtable+28; - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxLong GetDuration() override; // vtable+24; + virtual void SetDuration(MxLong p_duration) override; // vtable+28; + virtual MxDSAction *Clone() override; // vtable+2c; private: MxDSActionListCursor *m_cursor; diff --git a/LEGO1/mxdssound.cpp b/LEGO1/mxdssound.cpp index cbb1c057..ca69ef34 100644 --- a/LEGO1/mxdssound.cpp +++ b/LEGO1/mxdssound.cpp @@ -1,4 +1,5 @@ #include "mxdssound.h" +#include "legoutil.h" DECOMP_SIZE_ASSERT(MxDSSound, 0xc0) @@ -46,8 +47,7 @@ void MxDSSound::Deserialize(char **p_source, MxS16 p_unk24) { MxDSMediaAction::Deserialize(p_source, p_unk24); - this->m_volume = *(MxS32*) *p_source; - *p_source += sizeof(MxS32); + GetScalar(p_source, this->m_volume); } // OFFSET: LEGO1 0x100c9510 diff --git a/LEGO1/mxdssound.h b/LEGO1/mxdssound.h index de345e51..514ef1ec 100644 --- a/LEGO1/mxdssound.h +++ b/LEGO1/mxdssound.h @@ -27,9 +27,9 @@ class MxDSSound : public MxDSMediaAction return !strcmp(name, MxDSSound::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxU32 GetSizeOnDisk(); // vtable+18; - virtual void Deserialize(char **p_source, MxS16 p_unk24); // vtable+1c; - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxU32 GetSizeOnDisk() override; // vtable+18; + virtual void Deserialize(char **p_source, MxS16 p_unk24) override; // vtable+1c; + virtual MxDSAction *Clone() override; // vtable+2c; private: MxU32 m_sizeOnDisk; diff --git a/LEGO1/mxdsstill.h b/LEGO1/mxdsstill.h index 084fe931..3b29c287 100644 --- a/LEGO1/mxdsstill.h +++ b/LEGO1/mxdsstill.h @@ -27,7 +27,7 @@ class MxDSStill : public MxDSMediaAction return !strcmp(name, MxDSStill::ClassName()) || MxDSMediaAction::IsA(name); } - virtual MxDSAction *Clone(); // vtable+2c; + virtual MxDSAction *Clone() override; // vtable+2c; }; #endif // MXDSSTILL_H diff --git a/LEGO1/mxdsstreamingaction.h b/LEGO1/mxdsstreamingaction.h index d50dbed8..f95621eb 100644 --- a/LEGO1/mxdsstreamingaction.h +++ b/LEGO1/mxdsstreamingaction.h @@ -24,7 +24,7 @@ class MxDSStreamingAction : public MxDSAction return *this; } - virtual MxBool HasId(MxU32 p_objectId); // vtable+34; + virtual MxBool HasId(MxU32 p_objectId) override; // vtable+34; MxResult Init(); void SetInternalAction(MxDSAction *p_dsAction); diff --git a/LEGO1/mxeventmanager.cpp b/LEGO1/mxeventmanager.cpp index 5383c25a..0861af77 100644 --- a/LEGO1/mxeventmanager.cpp +++ b/LEGO1/mxeventmanager.cpp @@ -1,4 +1,8 @@ #include "mxeventmanager.h" +#include "mxcriticalsection.h" +#include "mxthread.h" +#include "mxticklemanager.h" +#include "mxomni.h" // OFFSET: LEGO1 0x100c0360 MxEventManager::MxEventManager() @@ -9,10 +13,54 @@ MxEventManager::MxEventManager() // OFFSET: LEGO1 0x100c03f0 MxEventManager::~MxEventManager() { - // TODO: MxMediaManager::TerminateThread call + TerminateThread(TRUE); } // OFFSET: LEGO1 0x100c0450 void MxEventManager::Init() { -} \ No newline at end of file + // This is intentionally left blank +} + +// OFFSET: LEGO1 0x100c04a0 +MxResult MxEventManager::CreateEventThread(MxU32 p_frequencyMS, MxBool p_noRegister) +{ + MxResult status = FAILURE; + MxBool locked = FALSE; + + MxResult result = MxMediaManager::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; +} diff --git a/LEGO1/mxeventmanager.h b/LEGO1/mxeventmanager.h index cb89f637..1ef43748 100644 --- a/LEGO1/mxeventmanager.h +++ b/LEGO1/mxeventmanager.h @@ -2,6 +2,7 @@ #define MXEVENTMANAGER_H #include "mxmediamanager.h" +#include "decomp.h" // VTABLE 0x100dc900 // SIZE 0x2c @@ -10,7 +11,7 @@ class MxEventManager : public MxMediaManager public: MxEventManager(); virtual ~MxEventManager() override; - + virtual MxResult CreateEventThread(MxU32 p_frequencyMS, MxBool p_noRegister); // vtable+28 private: void Init(); }; diff --git a/LEGO1/mxlist.h b/LEGO1/mxlist.h index 12695f82..94798b33 100644 --- a/LEGO1/mxlist.h +++ b/LEGO1/mxlist.h @@ -4,7 +4,6 @@ #include "mxtypes.h" #include "mxcore.h" -// SIZE 0xc template class MxListEntry { @@ -15,6 +14,11 @@ class MxListEntry m_prev = p_prev; m_next = NULL; } + MxListEntry(T p_obj, MxListEntry *p_prev, MxListEntry *p_next) { + m_obj = p_obj; + m_prev = p_prev; + m_next = p_next; + } T GetValue() { return this->m_obj; } @@ -26,7 +30,6 @@ class MxListEntry MxListEntry *m_next; }; -// VTABLE 0x100d6350 // SIZE 0x10 template class MxListParent : public MxCore @@ -46,7 +49,6 @@ class MxListParent : public MxCore void (*m_customDestructor)(T); // +0xc }; -// VTABLE 0x100d6368 // SIZE 0x18 template class MxList : protected MxListParent @@ -60,6 +62,7 @@ class MxList : protected MxListParent virtual ~MxList(); void Append(T); + void OtherAppend(T p_obj) { _InsertEntry(p_obj, this->m_last, NULL); }; void DeleteAll(); MxU32 GetCount() { return m_count; } void SetDestroy(void (*p_customDestructor)(T)) { this->m_customDestructor = p_customDestructor; } @@ -71,9 +74,9 @@ class MxList : protected MxListParent private: void _DeleteEntry(MxListEntry *match); + void _InsertEntry(T, MxListEntry *, MxListEntry *); }; -// VTABLE 0x100d6488 template class MxListCursor : public MxCore { @@ -96,7 +99,6 @@ class MxListCursor : public MxCore }; // Unclear purpose -// VTABLE 0x100d6530 template class MxListCursorChild : public MxListCursor { @@ -105,7 +107,6 @@ class MxListCursorChild : public MxListCursor }; // Unclear purpose -// VTABLE 0x100d6470 template class MxListCursorChildChild : public MxListCursorChild { @@ -152,6 +153,24 @@ inline void MxList::Append(T p_newobj) this->m_count++; } +template +inline void MxList::_InsertEntry(T p_newobj, MxListEntry *p_prev, MxListEntry *p_next) +{ + MxListEntry *newEntry = new MxListEntry(p_newobj, p_prev, p_next); + + if (p_prev) + p_prev->m_next = newEntry; + else + this->m_first = newEntry; + + if (p_next) + p_next->m_prev = newEntry; + else + this->m_last = newEntry; + + this->m_count++; +} + template inline void MxList::_DeleteEntry(MxListEntry *match) { @@ -198,7 +217,7 @@ inline MxBool MxListCursor::Next(T& p_obj) m_match = m_match->m_next; if (m_match) - p_obj = m_match->m_obj; + p_obj = m_match->GetValue(); return m_match != NULL; } diff --git a/LEGO1/mxloopingflcpresenter.cpp b/LEGO1/mxloopingflcpresenter.cpp index 54002246..58b066f6 100644 --- a/LEGO1/mxloopingflcpresenter.cpp +++ b/LEGO1/mxloopingflcpresenter.cpp @@ -10,7 +10,7 @@ MxLoopingFlcPresenter::MxLoopingFlcPresenter() Init(); } -// OFFSET: LEGO1 0x100b43b0 STUB +// OFFSET: LEGO1 0x100b43b0 MxLoopingFlcPresenter::~MxLoopingFlcPresenter() { Destroy(TRUE); diff --git a/LEGO1/mxmediamanager.cpp b/LEGO1/mxmediamanager.cpp index 3fb28d37..c992cd42 100644 --- a/LEGO1/mxmediamanager.cpp +++ b/LEGO1/mxmediamanager.cpp @@ -2,6 +2,8 @@ #include "mxautolocker.h" #include "mxpresenter.h" #include "decomp.h" +#include "mxticklemanager.h" +#include "mxomni.h" DECOMP_SIZE_ASSERT(MxMediaManager, 0x2c); @@ -65,7 +67,7 @@ void MxMediaManager::Destroy() if (this->m_presenters) delete this->m_presenters; - + Init(); } @@ -97,3 +99,22 @@ void MxMediaManager::StopPresenters() while (cursor.Next(presenter)) presenter->EndAction(); } + +// OFFSET: LEGO1 0x100c0460 +void MxMediaManager::TerminateThread(MxBool p_reinit) +{ + if(m_thread != NULL) + { + m_thread->Terminate(); + delete m_thread; + } + else + { + TickleManager()->UnregisterClient(this); + } + + if(!p_reinit) + { + MxMediaManager::Destroy(); + } +} diff --git a/LEGO1/mxmediamanager.h b/LEGO1/mxmediamanager.h index ccc3ec42..c17ab300 100644 --- a/LEGO1/mxmediamanager.h +++ b/LEGO1/mxmediamanager.h @@ -15,7 +15,7 @@ class MxMediaManager : public MxCore MxMediaManager(); virtual ~MxMediaManager() override; - virtual MxResult Tickle(); // vtable+08 + virtual MxResult Tickle() override; // vtable+08 virtual MxResult InitPresenters(); // vtable+14 virtual void Destroy(); // vtable+18 virtual void AddPresenter(MxPresenter &p_presenter); // vtable+1c @@ -23,6 +23,7 @@ class MxMediaManager : public MxCore virtual void StopPresenters(); // vtable+24 MxResult Init(); + void TerminateThread(MxBool p_reinit); protected: MxPresenterList *m_presenters; diff --git a/LEGO1/mxmediapresenter.cpp b/LEGO1/mxmediapresenter.cpp index f36ecbdc..00a2b851 100644 --- a/LEGO1/mxmediapresenter.cpp +++ b/LEGO1/mxmediapresenter.cpp @@ -2,6 +2,12 @@ DECOMP_SIZE_ASSERT(MxMediaPresenter, 0x50); +// OFFSET: LEGO1 0x1000c550 +MxMediaPresenter::~MxMediaPresenter() +{ + Destroy(TRUE); +} + // OFFSET: LEGO1 0x100b5d10 STUB MxResult MxMediaPresenter::Tickle() { @@ -18,6 +24,56 @@ void MxMediaPresenter::Init() this->m_unk4c = NULL; } +// OFFSET: LEGO1 0x100b54f0 STUB +void MxMediaPresenter::Destroy(MxBool p_destroy) +{ + // TODO +} + +// OFFSET: LEGO1 0x100b5d90 STUB +void MxMediaPresenter::StreamingTickle() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b5e10 STUB +void MxMediaPresenter::RepeatingTickle() +{ + // TODO +} + +// OFFSET: LEGO1 0x100b5ef0 +void MxMediaPresenter::DoneTickle() +{ + m_previousTickleStates |= 1 << m_currentTickleState; + m_currentTickleState = TickleState_Idle; + EndAction(); +} + +// OFFSET: LEGO1 0x100b6030 STUB +void MxMediaPresenter::Enable(MxBool p_enable) +{ + // TODO +} + +// OFFSET: LEGO1 0x1000c5b0 +void MxMediaPresenter::InitVirtual() +{ + Destroy(FALSE); +} + +// OFFSET: LEGO1 0x100b5700 STUB +MxLong MxMediaPresenter::StartAction(MxStreamController * p_controller, MxDSAction * p_action) +{ + return 0; +} + +// OFFSET: LEGO1 0x100b5bc0 STUB +void MxMediaPresenter::EndAction() +{ + // TODO +} + // OFFSET: LEGO1 0x100b5f10 STUB void MxMediaPresenter::VTable0x58() { diff --git a/LEGO1/mxmediapresenter.h b/LEGO1/mxmediapresenter.h index 824dd399..167b10c1 100644 --- a/LEGO1/mxmediapresenter.h +++ b/LEGO1/mxmediapresenter.h @@ -13,8 +13,9 @@ class MxMediaPresenter : public MxPresenter { Init(); } + virtual ~MxMediaPresenter() override; - virtual MxResult Tickle() override; // vtable+0x8, override MxCore + virtual MxResult Tickle() override; // OFFSET: LEGO1 0x1000c5c0 inline virtual const char *ClassName() const override // vtable+0xc @@ -29,7 +30,14 @@ class MxMediaPresenter : public MxPresenter return !strcmp(name, MxMediaPresenter::ClassName()) || MxPresenter::IsA(name); } - virtual void VTable0x58(); // vtable+0x58 + virtual void StreamingTickle() override; + virtual void RepeatingTickle() override; + virtual void DoneTickle() override; + virtual void InitVirtual() override; + virtual MxLong StartAction(MxStreamController *, MxDSAction *) override; + virtual void EndAction() override; + virtual void Enable(MxBool p_enable) override; + virtual void VTable0x58(); undefined4 m_unk40; undefined4 m_unk44; @@ -37,6 +45,7 @@ class MxMediaPresenter : public MxPresenter undefined4 m_unk4c; private: void Init(); + void Destroy(MxBool); }; diff --git a/LEGO1/mxmidimanager.h b/LEGO1/mxmidimanager.h deleted file mode 100644 index f944d67d..00000000 --- a/LEGO1/mxmidimanager.h +++ /dev/null @@ -1,42 +0,0 @@ -#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 diff --git a/LEGO1/mxmidimanager.cpp b/LEGO1/mxmusicmanager.cpp similarity index 78% rename from LEGO1/mxmidimanager.cpp rename to LEGO1/mxmusicmanager.cpp index 62bcb6d2..6f49adcc 100644 --- a/LEGO1/mxmidimanager.cpp +++ b/LEGO1/mxmusicmanager.cpp @@ -1,161 +1,163 @@ -#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; +#include "mxmusicmanager.h" +#include "mxticklemanager.h" +#include "mxomni.h" + +#include + +DECOMP_SIZE_ASSERT(MxMusicManager, 0x58); + +// OFFSET: LEGO1 0x100c05a0 +MxMusicManager::MxMusicManager() +{ + Init(); +} + +// OFFSET: LEGO1 0x100c0630 +MxMusicManager::~MxMusicManager() +{ + LockedReinitialize(TRUE); +} + +// OFFSET: LEGO1 0x100c0b20 +void MxMusicManager::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 MxMusicManager::Init() +{ + this->m_multiplier = 100; + InitData(); +} + +// OFFSET: LEGO1 0x100c06a0 +void MxMusicManager::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 MxMusicManager::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 MxMusicManager::Destroy() +{ + LockedReinitialize(FALSE); +} + +// OFFSET: LEGO1 0x100c09a0 +MxS32 MxMusicManager::CalculateVolume(MxS32 p_volume) +{ + MxS32 result = (p_volume * 0xffff) / 100; + return (result << 0x10) | result; +} + +// OFFSET: LEGO1 0x100c07f0 +void MxMusicManager::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 MxMusicManager::SetVolume(MxS32 p_volume) +{ + MxAudioManager::SetVolume(p_volume); + this->m_criticalSection.Enter(); + SetMIDIVolume(); + this->m_criticalSection.Leave(); +} + +// OFFSET: LEGO1 0x100c0840 +MxResult MxMusicManager::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/mxmusicmanager.h b/LEGO1/mxmusicmanager.h index 4288ed1e..1a828c84 100644 --- a/LEGO1/mxmusicmanager.h +++ b/LEGO1/mxmusicmanager.h @@ -1,11 +1,42 @@ #ifndef MXMUSICMANAGER_H #define MXMUSICMANAGER_H -#include "mxcore.h" +#include "decomp.h" +#include "mxaudiomanager.h" // VTABLE 0x100dc930 -class MxMusicManager : public MxCore +// SIZE 0x58 +class MxMusicManager : public MxAudioManager { +public: + MxMusicManager(); + virtual ~MxMusicManager() 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 // MXMUSICMANAGER_H +#endif // MXMUSICMANAGER_H \ No newline at end of file diff --git a/LEGO1/mxmusicpresenter.cpp b/LEGO1/mxmusicpresenter.cpp index d33627ad..45a56679 100644 --- a/LEGO1/mxmusicpresenter.cpp +++ b/LEGO1/mxmusicpresenter.cpp @@ -1,12 +1,48 @@ #include "mxmusicpresenter.h" +#include "decomp.h" +#include "mxmusicmanager.h" +#include "mxomni.h" + +DECOMP_SIZE_ASSERT(MxMusicPresenter, 0x54); + // OFFSET: LEGO1 0x100c22c0 MxMusicPresenter::MxMusicPresenter() { Init(); } +// OFFSET: LEGO1 0x100c24e0 +MxMusicPresenter::~MxMusicPresenter() +{ + Destroy(TRUE); +} + // OFFSET: LEGO1 0x100c2540 void MxMusicPresenter::Init() { -} \ No newline at end of file +} + +// OFFSET: LEGO1 0x100c2550 STUB +void MxMusicPresenter::Destroy(MxBool) +{ + // TODO +} + +// OFFSET: LEGO1 0x100c25a0 +MxResult MxMusicPresenter::AddToMusicManager() +{ + MxResult result = FAILURE; + if (MusicManager()) { + result = SUCCESS; + MusicManager()->AddPresenter(*this); + } + return result; +} + +// OFFSET: LEGO1 0x100c25d0 +void MxMusicPresenter::vtable38() +{ + // TODO: Name this function when we know what the argument to Destroy does + Destroy(FALSE); +} diff --git a/LEGO1/mxmusicpresenter.h b/LEGO1/mxmusicpresenter.h index c8e88604..2e55aa6c 100644 --- a/LEGO1/mxmusicpresenter.h +++ b/LEGO1/mxmusicpresenter.h @@ -4,6 +4,7 @@ #include "mxaudiopresenter.h" // VTABLE 0x100dc9b8 +// SIZE 0x54 class MxMusicPresenter : public MxAudioPresenter { public: @@ -21,9 +22,14 @@ class MxMusicPresenter : public MxAudioPresenter } MxMusicPresenter(); + virtual ~MxMusicPresenter() override; + + virtual MxResult AddToMusicManager(); // vtable+0x34 + virtual void vtable38(); // vtable+0x38 private: void Init(); + void Destroy(MxBool); }; #endif // MXMUSICPRESENTER_H diff --git a/LEGO1/mxnotificationmanager.cpp b/LEGO1/mxnotificationmanager.cpp index 1b097067..cb653ba4 100644 --- a/LEGO1/mxnotificationmanager.cpp +++ b/LEGO1/mxnotificationmanager.cpp @@ -1,7 +1,8 @@ +#include "mxnotificationmanager.h" + #include "legoomni.h" #include "mxautolocker.h" -#include "mxcore.h" -#include "mxnotificationmanager.h" +#include "mxticklemanager.h" #include "mxparam.h" #include "mxtypes.h" diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index 200e5bdf..fb3251da 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -1,5 +1,18 @@ #include "mxomni.h" +#include "mxatomidcounter.h" +#include "mxeventmanager.h" +#include "mxmusicmanager.h" +#include "mxnotificationmanager.h" +#include "mxobjectfactory.h" +#include "mxomnicreateparam.h" +#include "mxsoundmanager.h" +#include "mxstreamer.h" +#include "mxticklemanager.h" +#include "mxtimer.h" +#include "mxvideomanager.h" +#include "mxautolocker.h" + // 0x101015b8 char g_hdPath[1024]; @@ -39,13 +52,19 @@ void MxOmni::Init() m_timer = NULL; m_streamer = NULL; m_atomIdCounterSet = NULL; - m_unk64 = NULL; + m_timerRunning = NULL; } -// OFFSET: LEGO1 0x100b0090 STUB -void MxOmni::vtable0x20() +// OFFSET: LEGO1 0x100b0090 +MxResult MxOmni::Start(MxDSAction* p_dsAction) { - // TODO + MxResult result = FAILURE; + if(p_dsAction->GetAtomId().GetInternal() != NULL && p_dsAction->GetObjectId() != -1 && m_streamer != NULL) + { + result = m_streamer->Unknown100b99b0(p_dsAction); + } + + return result; } // OFFSET: LEGO1 0x100b00c0 STUB @@ -80,16 +99,26 @@ void MxOmni::NotifyCurrentEntity() // TODO } -// OFFSET: LEGO1 0x100b09d0 STUB +// OFFSET: LEGO1 0x100b09d0 void MxOmni::StartTimer() { - // TODO + if (m_timerRunning == FALSE && m_timer != NULL && m_soundManager != NULL) + { + m_timer->Start(); + m_soundManager->vtable0x34(); + m_timerRunning = TRUE; + } } -// OFFSET: LEGO1 0x100b0a00 STUB -void MxOmni::vtable0x3c() +// OFFSET: LEGO1 0x100b0a00 +void MxOmni::StopTimer() { - // TODO + if (m_timerRunning != FALSE && m_timer != NULL && m_soundManager != NULL) + { + m_timer->Stop(); + m_soundManager->vtable0x38(); + m_timerRunning = FALSE; + } } // OFFSET: LEGO1 0x100b0690 @@ -154,7 +183,22 @@ void MxOmni::SetInstance(MxOmni *instance) // OFFSET: LEGO1 0x100af0c0 MxResult MxOmni::Create(MxOmniCreateParam &p) { + MxResult result = FAILURE; m_atomIdCounterSet = new MxAtomIdCounterSet(); + if (m_atomIdCounterSet == NULL) + { + goto failure; + } + m_mediaPath = p.GetMediaPath(); + m_windowHandle = p.GetWindowHandle(); + if (p.CreateFlags().CreateObjectFactory()) + { + MxObjectFactory *objectFactory = new MxObjectFactory(); + this->m_objectFactory = objectFactory; + + if (objectFactory == NULL) + goto failure; + } if (p.CreateFlags().CreateVariableTable()) { @@ -162,7 +206,7 @@ MxResult MxOmni::Create(MxOmniCreateParam &p) this->m_variableTable = variableTable; if (variableTable == NULL) - return FAILURE; + goto failure; } if (p.CreateFlags().CreateTimer()) @@ -174,7 +218,87 @@ MxResult MxOmni::Create(MxOmniCreateParam &p) return FAILURE; } - return SUCCESS; + if (p.CreateFlags().CreateTickleManager()) + { + this->m_tickleManager = new MxTickleManager(); + + if (m_tickleManager == NULL) + goto failure; + } + + if (p.CreateFlags().CreateNotificationManager()) + { + MxNotificationManager *notificationManager = new MxNotificationManager(); + this->m_notificationManager = notificationManager; + + if (notificationManager == NULL || notificationManager->Create(100, 0) != SUCCESS) + goto failure; + } + + if (p.CreateFlags().CreateStreamer()) + { + MxStreamer *streamer = new MxStreamer(); + this->m_streamer = streamer; + + if (streamer == NULL || streamer->Init() != SUCCESS) + goto failure; + } + + if (p.CreateFlags().CreateVideoManager()) + { + MxVideoManager *videoManager = new MxVideoManager(); + this->m_videoManager = videoManager; + + if (videoManager != NULL && videoManager->vtable0x2c(p.GetVideoParam(), 100, 0) != SUCCESS) + { + delete m_videoManager; + m_videoManager = NULL; + } + } + + if (p.CreateFlags().CreateSoundManager()) + { + MxSoundManager *soundManager = new MxSoundManager(); + this->m_soundManager = soundManager; + + //TODO + if (soundManager != NULL && soundManager->StartDirectSound(10, 0) != SUCCESS) + { + delete m_soundManager; + m_soundManager = NULL; + } + } + + if (p.CreateFlags().CreateMusicManager()) + { + MxMusicManager *musicManager = new MxMusicManager(); + this->m_musicManager = musicManager; + if (musicManager != NULL && musicManager->StartMIDIThread(50, 0) != SUCCESS) + { + delete m_musicManager; + m_musicManager = NULL; + } + } + + if (p.CreateFlags().CreateEventManager()) + { + MxEventManager *eventManager = new MxEventManager(); + this->m_eventManager = eventManager; + if (m_eventManager != NULL && m_eventManager->CreateEventThread(50, 0) != SUCCESS) + { + delete m_eventManager; + m_eventManager = NULL; + } + } + + result = SUCCESS; + failure: + if (result != SUCCESS) + { + Destroy(); + } + + return result; } // OFFSET: LEGO1 0x100afe90 @@ -220,8 +344,19 @@ void MxOmni::Destroy() // OFFSET: LEGO1 0x100b07f0 MxLong MxOmni::Notify(MxParam &p) { - // FIXME: Stub - return 0; + MxAutoLocker lock(&this->m_criticalsection); + + if (p.GetType() != MXSTREAMER_UNKNOWN) + return 0; + + return HandleNotificationType2(p); +} + +// OFFSET: LEGO1 0x100b0880 STUB +MxResult MxOmni::HandleNotificationType2(MxParam& p_param) +{ + // TODO STUB + return FAILURE; } // OFFSET: LEGO1 0x100acea0 @@ -258,7 +393,7 @@ MxAtomIdCounterSet *AtomIdCounterSet() MxStreamer* Streamer() { return MxOmni::GetInstance()->GetStreamer(); -} +} // OFFSET: LEGO1 0x100acf00 MxSoundManager* MSoundManager() @@ -288,4 +423,4 @@ MxMusicManager* MusicManager() MxEventManager* EventManager() { return MxOmni::GetInstance()->GetEventManager(); -} \ No newline at end of file +} diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index a8fa9db8..5290c6ed 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -1,21 +1,23 @@ #ifndef MXOMNI_H #define MXOMNI_H +#include "mxcore.h" +#include "mxstring.h" #include "mxcriticalsection.h" -#include "mxdsaction.h" -#include "mxeventmanager.h" -#include "mxmusicmanager.h" -#include "mxnotificationmanager.h" -#include "mxobjectfactory.h" -#include "mxomnicreateflags.h" -#include "mxomnicreateparam.h" -#include "mxsoundmanager.h" -#include "mxstreamer.h" -#include "mxticklemanager.h" -#include "mxtimer.h" -#include "mxvariabletable.h" -#include "mxvideomanager.h" -#include "mxatomidcounter.h" + +class MxAtomIdCounterSet; +class MxDSAction; +class MxEventManager; +class MxMusicManager; +class MxNotificationManager; +class MxObjectFactory; +class MxOmniCreateParam; +class MxSoundManager; +class MxStreamer; +class MxTickleManager; +class MxTimer; +class MxVariableTable; +class MxVideoManager; // VTABLE 0x100dc168 // SIZE 0x68 @@ -38,14 +40,14 @@ class MxOmni : public MxCore virtual void Init(); // vtable+14 virtual MxResult Create(COMPAT_CONST MxOmniCreateParam &p); // vtable+18 virtual void Destroy(); // vtable+1c - virtual void vtable0x20(); // vtable+20 + virtual MxResult Start(MxDSAction* p_dsAction); // vtable+20 virtual void DeleteObject(MxDSAction &ds); // vtable+24 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 StartTimer(); // vtable+38 - virtual void vtable0x3c(); // vtable+3c + virtual void StopTimer(); // vtable+3c static void SetInstance(MxOmni* instance); HWND GetWindowHandle() const { return this->m_windowHandle; } MxObjectFactory* GetObjectFactory() const { return this->m_objectFactory; } @@ -59,6 +61,7 @@ class MxOmni : public MxCore MxMusicManager* GetMusicManager() const { return this->m_musicManager; } MxEventManager* GetEventManager() const { return this->m_eventManager; } MxAtomIdCounterSet* GetAtomIdCounterSet() const { return this->m_atomIdCounterSet; } + MxResult HandleNotificationType2(MxParam& p_param); protected: static MxOmni* g_instance; @@ -79,7 +82,7 @@ class MxOmni : public MxCore MxCriticalSection m_criticalsection; // 0x48 - unsigned char m_unk64; // 0x64 + MxBool m_timerRunning; // 0x64 }; __declspec(dllexport) MxTickleManager * TickleManager(); __declspec(dllexport) MxTimer * Timer(); diff --git a/LEGO1/mxomnicreateparam.h b/LEGO1/mxomnicreateparam.h index 31dcd447..3c1059dd 100644 --- a/LEGO1/mxomnicreateparam.h +++ b/LEGO1/mxomnicreateparam.h @@ -14,6 +14,9 @@ class MxOmniCreateParam : public MxOmniCreateParamBase __declspec(dllexport) MxOmniCreateParam(const char *mediaPath, struct HWND__ *windowHandle, MxVideoParam &vparam, MxOmniCreateFlags flags); const MxOmniCreateFlags& CreateFlags() const { return this->m_createFlags; } + const MxString GetMediaPath() const { return m_mediaPath; } + const HWND GetWindowHandle() const { return m_windowHandle; } + MxVideoParam& GetVideoParam() { return m_videoParam; } private: MxString m_mediaPath; diff --git a/LEGO1/mxpalette.cpp b/LEGO1/mxpalette.cpp index 7fb02f4f..cdd1597f 100644 --- a/LEGO1/mxpalette.cpp +++ b/LEGO1/mxpalette.cpp @@ -1,5 +1,7 @@ #include "mxpalette.h" + #include "mxomni.h" +#include "mxvideomanager.h" // GLOBAL: LEGO1 0x10102188 0x400 PALETTEENTRY g_defaultPaletteEntries[256] = diff --git a/LEGO1/mxpalette.h b/LEGO1/mxpalette.h index b024330a..7c9568b1 100644 --- a/LEGO1/mxpalette.h +++ b/LEGO1/mxpalette.h @@ -26,6 +26,7 @@ class MxPalette : public MxCore MxResult SetSkyColor(LPPALETTEENTRY p_sky_color); void Reset(MxBool p_ignoreSkyColor); LPDIRECTDRAWPALETTE CreateNativePalette(); + inline void SetOverrideSkyColor(MxBool p_value) { this->m_overrideSkyColor = p_value; } private: LPDIRECTDRAWPALETTE m_palette; PALETTEENTRY m_entries[256]; // 0xc diff --git a/LEGO1/mxparam.h b/LEGO1/mxparam.h index ffbf1530..d76ecdb0 100644 --- a/LEGO1/mxparam.h +++ b/LEGO1/mxparam.h @@ -7,16 +7,24 @@ class MxCore; +enum MxParamType +{ + MXSTREAMER_UNKNOWN = 2, + MXPRESENTER_NOTIFICATION = 5, + MXSTREAMER_DELETE_NOTIFY = 6, + MXTRANSITIONMANAGER_TRANSITIONENDED = 24 +}; + // VTABLE 0x100d56e0 class MxParam : public MxOmniCreateParamBase { public: - inline MxParam(MxS32 p_type, MxCore *p_sender) : MxOmniCreateParamBase(), m_type(p_type), m_sender(p_sender){} + 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 MxS32 GetType() const + inline MxParamType GetType() const { return m_type; } @@ -27,7 +35,7 @@ class MxParam : public MxOmniCreateParamBase } protected: - MxS32 m_type; // 0x4 + MxParamType m_type; // 0x4 MxCore *m_sender; // 0x8 }; diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index b57af821..f8f60386 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -1,14 +1,17 @@ #include "mxpresenter.h" + +#include "legoomni.h" #include "mxautolocker.h" #include "mxparam.h" -#include "legoomni.h" #include "mxdsanim.h" #include "mxdssound.h" -#include +#include "mxnotificationmanager.h" #include "decomp.h" #include "define.h" +#include + DECOMP_SIZE_ASSERT(MxPresenter, 0x40); // OFFSET: LEGO1 0x100b4d50 @@ -46,9 +49,9 @@ void MxPresenter::ParseExtra() int val = token ? atoi(token) : 0; int result = MxOmni::GetInstance()->vtable0x30(t_token, val, this); - + m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_Parsed); - + if (result) SendTo_unkPresenter(MxOmni::GetInstance()); @@ -62,8 +65,7 @@ void MxPresenter::SendTo_unkPresenter(MxOmni *p_omni) if (m_unkPresenter) { MxAutoLocker lock(&m_criticalSection); - // TOOD: magic number used for notification type. replace with enum - NotificationManager()->Send(m_unkPresenter, &MxParam(5, this)); + NotificationManager()->Send(m_unkPresenter, &MxParam(MXPRESENTER_NOTIFICATION, this)); m_action->SetOmni(p_omni ? p_omni : MxOmni::GetInstance()); m_unkPresenter = NULL; diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 81ea14ad..959533c5 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -15,7 +15,7 @@ class MxStreamController; class MxPresenter : public MxCore { public: - enum TickleState + enum TickleState { TickleState_Idle = 0, TickleState_Ready, @@ -68,17 +68,17 @@ 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; } + inline MxS32 GetCurrentTickleState() const { return this->m_currentTickleState; } + inline MxPoint32 GetLocation() const { return this->m_location; } + inline MxS32 GetLocationX() const { return this->m_location.m_x; } + inline MxS32 GetLocationY() const { return this->m_location.m_y; } + inline MxS32 GetDisplayZ() const { return this->m_displayZ; } + inline MxDSAction *GetAction() const { return this->m_action; } protected: __declspec(dllexport) void Init(); void SendTo_unkPresenter(MxOmni *); - -private: - MxS32 m_currentTickleState; // 0x8 + TickleState m_currentTickleState; // 0x8 MxU32 m_previousTickleStates; MxPoint32 m_location; MxS32 m_displayZ; diff --git a/LEGO1/mxramstreamcontroller.cpp b/LEGO1/mxramstreamcontroller.cpp index a96046a0..9796b05a 100644 --- a/LEGO1/mxramstreamcontroller.cpp +++ b/LEGO1/mxramstreamcontroller.cpp @@ -1,3 +1,25 @@ #include "mxramstreamcontroller.h" +#include "mxramstreamprovider.h" DECOMP_SIZE_ASSERT(MxRAMStreamController, 0x98); + +// OFFSET: LEGO1 0x100c6110 STUB +MxResult MxRAMStreamController::Open(const char *p_filename) +{ + // TODO STUB + return FAILURE; +} + +// OFFSET: LEGO1 0x100c6210 STUB +MxResult MxRAMStreamController::vtable0x20(MxDSAction* p_action) +{ + // TODO STUB + return FAILURE; +} + +// OFFSET: LEGO1 0x100c6320 STUB +MxResult MxRAMStreamController::vtable0x24(undefined4 p_unknown) +{ + // TODO STUB + return FAILURE; +} diff --git a/LEGO1/mxramstreamcontroller.h b/LEGO1/mxramstreamcontroller.h index 563d9cb6..62587bca 100644 --- a/LEGO1/mxramstreamcontroller.h +++ b/LEGO1/mxramstreamcontroller.h @@ -11,6 +11,23 @@ class MxRAMStreamController : public MxStreamController public: inline MxRAMStreamController() {} + // OFFSET: LEGO1 0x100b9430 + inline virtual const char *ClassName() const override // vtable+0xc + { + // 0x10102130 + return "MxRAMStreamController"; + } + + // OFFSET: LEGO1 0x100b9440 + inline virtual MxBool IsA(const char *name) const override // vtable+0x10 + { + return !strcmp(name, MxRAMStreamController::ClassName()) || !strcmp(name, MxStreamController::ClassName()) || MxCore::IsA(name); + } + + virtual MxResult Open(const char *p_filename) override; + virtual MxResult vtable0x20(MxDSAction* p_action) override; + virtual MxResult vtable0x24(undefined4 p_unknown) override; + private: MxDSBuffer m_buffer; diff --git a/LEGO1/mxramstreamprovider.cpp b/LEGO1/mxramstreamprovider.cpp new file mode 100644 index 00000000..9b052699 --- /dev/null +++ b/LEGO1/mxramstreamprovider.cpp @@ -0,0 +1,59 @@ +#include "mxramstreamprovider.h" +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxRAMStreamProvider, 0x24); + +// OFFSET: LEGO1 0x100d0730 +MxRAMStreamProvider::MxRAMStreamProvider() +{ + m_bufferSize = 0; + m_fileSize = 0; + m_pBufferOfFileSize = NULL; + m_lengthInDWords = 0; + m_bufferForDWords = NULL; +} + +// OFFSET: LEGO1 0x100d0a50 +MxRAMStreamProvider::~MxRAMStreamProvider() +{ + m_bufferSize = 0; + m_fileSize = 0; + + free(m_pBufferOfFileSize); + m_pBufferOfFileSize = NULL; + + m_lengthInDWords = 0; + + free(m_bufferForDWords); + m_bufferForDWords = NULL; +} + +// OFFSET: LEGO1 0x100d0ae0 STUB +MxResult MxRAMStreamProvider::SetResourceToGet(void* p_resource) +{ + return FAILURE; +} + +// OFFSET: LEGO1 0x100d0930 +MxU32 MxRAMStreamProvider::GetFileSize() +{ + return m_fileSize; +} + +// OFFSET: LEGO1 0x100d0940 +MxU32 MxRAMStreamProvider::vtable0x1C() +{ + return 1; +} + +// OFFSET: LEGO1 0x100d0950 +MxU32 MxRAMStreamProvider::GetLengthInDWords() +{ + return m_lengthInDWords; +} + +// OFFSET: LEGO1 0x100d0960 +void* MxRAMStreamProvider::GetBufferForDWords() +{ + return m_bufferForDWords; +} diff --git a/LEGO1/mxramstreamprovider.h b/LEGO1/mxramstreamprovider.h index 5422d3b3..4a22b013 100644 --- a/LEGO1/mxramstreamprovider.h +++ b/LEGO1/mxramstreamprovider.h @@ -6,7 +6,22 @@ // VTABLE 0x100dd0d0 class MxRAMStreamProvider : public MxStreamProvider { +public: + MxRAMStreamProvider(); + virtual ~MxRAMStreamProvider() override; + + virtual MxResult SetResourceToGet(void* p_resource) override; //vtable+0x14 + virtual MxU32 GetFileSize() override; //vtable+0x18 + virtual MxU32 vtable0x1C() override; //vtable+0x1c + virtual MxU32 GetLengthInDWords() override; //vtable+0x24 + virtual void* GetBufferForDWords() override; //vtable+0x28 +protected: + MxU32 m_bufferSize; + MxU32 m_fileSize; + void* m_pBufferOfFileSize; + MxU32 m_lengthInDWords; + void* m_bufferForDWords; }; #endif // MXRAMSTREAMPROVIDER_H diff --git a/LEGO1/mxsmkpresenter.cpp b/LEGO1/mxsmkpresenter.cpp index cc7efec1..99faae22 100644 --- a/LEGO1/mxsmkpresenter.cpp +++ b/LEGO1/mxsmkpresenter.cpp @@ -15,3 +15,14 @@ void MxSmkPresenter::Init() { // TODO } + +// OFFSET: LEGO1 0x100b3960 +void MxSmkPresenter::VTable0x60() +{ + if (m_bitmap) { + delete m_bitmap; + } + + m_bitmap = new MxBitmap(); + m_bitmap->SetSize(m_smkWidth, m_smkHeight, NULL, NULL); +} diff --git a/LEGO1/mxsmkpresenter.h b/LEGO1/mxsmkpresenter.h index 325091bb..34a78dab 100644 --- a/LEGO1/mxsmkpresenter.h +++ b/LEGO1/mxsmkpresenter.h @@ -12,7 +12,12 @@ class MxSmkPresenter : public MxVideoPresenter public: MxSmkPresenter(); - undefined4 m_unk64[430]; + virtual void VTable0x60() override; + + undefined4 m_unk64; + MxS32 m_smkWidth; // 0x68 + MxS32 m_smkHeight; // 0x6c + undefined4 m_unk70[427]; undefined4 m_unk71c; private: void Init(); diff --git a/LEGO1/mxsoundmanager.cpp b/LEGO1/mxsoundmanager.cpp index 16d504ce..e34534f9 100644 --- a/LEGO1/mxsoundmanager.cpp +++ b/LEGO1/mxsoundmanager.cpp @@ -1,5 +1,5 @@ #include "mxsoundmanager.h" - +#include "mxticklemanager.h" #include "mxomni.h" DECOMP_SIZE_ASSERT(MxSoundManager, 0x3c); @@ -46,4 +46,23 @@ void MxSoundManager::Destroy(MxBool p_param) if (!p_param) { MxAudioManager::Destroy(); } -} \ No newline at end of file +} + +// OFFSET: LEGO1 0x100ae8b0 STUB +MxResult MxSoundManager::StartDirectSound(undefined4 p_unknown1, MxBool p_unknown2) +{ + // TODO STUB + return FAILURE; +} + +// OFFSET: LEGO1 0x100aed10 STUB +void MxSoundManager::vtable0x34() +{ + // TODO STUB +} + +// OFFSET: LEGO1 0x100aee10 STUB +void MxSoundManager::vtable0x38() +{ + // TODO STUB +} diff --git a/LEGO1/mxsoundmanager.h b/LEGO1/mxsoundmanager.h index d41c6fdb..46eef2e7 100644 --- a/LEGO1/mxsoundmanager.h +++ b/LEGO1/mxsoundmanager.h @@ -14,6 +14,10 @@ class MxSoundManager : public MxAudioManager MxSoundManager(); virtual ~MxSoundManager() override; // vtable+0x0 + virtual MxResult StartDirectSound(undefined4 p_unknown1, MxBool p_unknown2); //vtable+0x30 + virtual void vtable0x34(); // vtable+0x34 + virtual void vtable0x38(); // vtable+0x38 + private: void Init(); void Destroy(MxBool); diff --git a/LEGO1/mxstreamcontroller.cpp b/LEGO1/mxstreamcontroller.cpp index 09f2d95c..36b85ebc 100644 --- a/LEGO1/mxstreamcontroller.cpp +++ b/LEGO1/mxstreamcontroller.cpp @@ -1,6 +1,7 @@ #include "mxstreamcontroller.h" #include "mxautolocker.h" +#include "legoomni.h" // OFFSET: LEGO1 0x100c0b90 STUB MxStreamController::MxStreamController() @@ -24,9 +25,54 @@ MxBool MxStreamController::FUN_100c20d0(MxDSObject &p_obj) // OFFSET: LEGO1 0x100c1520 MxResult MxStreamController::Open(const char *p_filename) { + char sourceName [256]; MxAutoLocker locker(&m_criticalSection); - // TODO - + MakeSourceName(sourceName, p_filename); + this->atom = MxAtomId(sourceName, LookupMode_LowerCase2); return SUCCESS; } + +// OFFSET: LEGO1 0x100b9400 +MxResult MxStreamController::vtable0x18(undefined4 p_unknown, undefined4 p_unknown2) +{ + return FAILURE; +} + +// OFFSET: LEGO1 0x100b9410 +MxResult MxStreamController::vtable0x1C(undefined4 p_unknown, undefined4 p_unknown2) +{ + return FAILURE; +} + +// OFFSET: LEGO1 0x100c1690 STUB +MxResult MxStreamController::vtable0x20(MxDSAction* p_action) +{ + // TODO STUB + return FAILURE; +} + +// OFFSET: LEGO1 0x100c1740 STUB +MxResult MxStreamController::vtable0x24(undefined4 p_unknown) +{ + // TODO STUB + return FAILURE; +} + +// OFFSET: LEGO1 0x100b9420 +MxResult MxStreamController::vtable0x28() +{ + return SUCCESS; +} + +// OFFSET: LEGO1 0x100c1c10 STUB +MxResult MxStreamController::vtable0x2c(undefined4 p_unknown1, undefined4 p_unknow2) +{ + return FAILURE; +} + +// OFFSET: LEGO1 0x100c1ce0 STUB +MxResult MxStreamController::vtable0x30(undefined4 p_unknown) +{ + return FAILURE; +} diff --git a/LEGO1/mxstreamcontroller.h b/LEGO1/mxstreamcontroller.h index c7e4309e..59490d2c 100644 --- a/LEGO1/mxstreamcontroller.h +++ b/LEGO1/mxstreamcontroller.h @@ -6,6 +6,7 @@ #include "mxcriticalsection.h" #include "mxcore.h" #include "mxdsobject.h" +#include "mxdsaction.h" // VTABLE 0x100dc968 // SIZE 0x64 @@ -30,13 +31,22 @@ class MxStreamController : public MxCore } virtual MxResult Open(const char *p_filename); // vtable+0x14 + virtual MxResult vtable0x18(undefined4 p_unknown, undefined4 p_unknown2); //vtable+0x18 + virtual MxResult vtable0x1C(undefined4 p_unknown, undefined4 p_unknown2); //vtable+0x1c + virtual MxResult vtable0x20(MxDSAction* p_action); //vtable+0x20 + virtual MxResult vtable0x24(undefined4 p_unknown); //vtable+0x24 + virtual MxResult vtable0x28(); //vtable+0x28 + virtual MxResult vtable0x2c(undefined4 p_unknown1, undefined4 p_unknow2); //vtable+0x2c + virtual MxResult vtable0x30(undefined4 p_unknown); //vtable+0x30 MxBool FUN_100c20d0(MxDSObject &p_obj); + inline MxAtomId &GetAtom() { return atom; }; +protected: MxCriticalSection m_criticalSection; MxAtomId atom; - int m_unk28; - int m_unk2c; + undefined4 m_unk28; // MxStreamProvider* + undefined4 m_unk2c; undefined m_unk30[0x34]; }; diff --git a/LEGO1/mxstreamer.cpp b/LEGO1/mxstreamer.cpp index 2121773e..8e7cc231 100644 --- a/LEGO1/mxstreamer.cpp +++ b/LEGO1/mxstreamer.cpp @@ -1,15 +1,14 @@ #include "mxstreamer.h" -#include - #include "legoomni.h" #include "mxdiskstreamcontroller.h" #include "mxramstreamcontroller.h" +#include "mxnotificationmanager.h" + +#include DECOMP_SIZE_ASSERT(MxStreamer, 0x2c); -#define MXSTREAMER_DELETE_NOTIFY 6 - // OFFSET: LEGO1 0x100b8f00 MxStreamer::MxStreamer() { @@ -81,7 +80,7 @@ MxLong MxStreamer::Close(const char *p) for (list::iterator it = m_openStreams.begin(); it != m_openStreams.end(); it++) { MxStreamController *c = *it; - if (!p || !strcmp(p, c->atom.GetInternal())) { + if (!p || !strcmp(p, c->GetAtom().GetInternal())) { m_openStreams.erase(it); if (!c->FUN_100c20d0(ds)) { @@ -110,7 +109,7 @@ MxStreamController *MxStreamer::GetOpenStream(const char *p_name) { for (list::iterator it = m_openStreams.begin(); it != m_openStreams.end(); it++) { MxStreamController *c = *it; - MxAtomId &atom = c->atom; + MxAtomId &atom = c->GetAtom(); if (p_name) { if (!strcmp(atom.GetInternal(), p_name)) { return *it; @@ -133,6 +132,22 @@ MxResult MxStreamer::AddStreamControllerToOpenList(MxStreamController *stream) return FAILURE; } +// OFFSET: LEGO1 0x100b99b0 +MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action) +{ + MxStreamController* controller; + if (p_action != NULL && p_action->GetAtomId().GetInternal() != NULL && p_action->GetObjectId() != -1) + { + controller = GetOpenStream(p_action->GetAtomId().GetInternal()); + if (controller == NULL) + { + return FAILURE; + } + return controller->vtable0x20(p_action); + } + return FAILURE; +} + // OFFSET: LEGO1 0x100b9b60 MxLong MxStreamer::Notify(MxParam &p) { diff --git a/LEGO1/mxstreamer.h b/LEGO1/mxstreamer.h index 5ab02cbb..515be51b 100644 --- a/LEGO1/mxstreamer.h +++ b/LEGO1/mxstreamer.h @@ -43,7 +43,7 @@ class MxStreamerSubClass3 : public MxStreamerSubClass1 class MxStreamerNotification : public MxParam { public: - inline MxStreamerNotification(MxS32 p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxParam(p_type, p_sender) + inline MxStreamerNotification(MxParamType p_type, MxCore *p_sender, MxStreamController *p_ctrlr) : MxParam(p_type, p_sender) { m_controller = p_ctrlr; } @@ -96,6 +96,8 @@ class MxStreamer : public MxCore MxResult AddStreamControllerToOpenList(MxStreamController *p_stream); + MxResult MxStreamer::Unknown100b99b0(MxDSAction* p_action); + private: list m_openStreams; // 0x8 MxStreamerSubClass2 m_subclass1; // 0x14 diff --git a/LEGO1/mxstreamprovider.cpp b/LEGO1/mxstreamprovider.cpp new file mode 100644 index 00000000..c9dab949 --- /dev/null +++ b/LEGO1/mxstreamprovider.cpp @@ -0,0 +1,17 @@ +#include "decomp.h" +#include "mxstreamprovider.h" + +DECOMP_SIZE_ASSERT(MxStreamProvider, 0x10); + +// OFFSET: LEGO1 0x100d07c0 +MxResult MxStreamProvider::SetResourceToGet(void* p_resource) +{ + m_pLookup = p_resource; + return SUCCESS; +} + +// OFFSET: LEGO1 0x100d07d0 +void MxStreamProvider::vtable0x20(undefined4 p_unknown1) +{ + +} diff --git a/LEGO1/mxstreamprovider.h b/LEGO1/mxstreamprovider.h index 2daf75ab..3cb11144 100644 --- a/LEGO1/mxstreamprovider.h +++ b/LEGO1/mxstreamprovider.h @@ -1,17 +1,16 @@ #ifndef MXSTREAMPROVIDER_H #define MXSTREAMPROVIDER_H +#include "decomp.h" #include "mxcore.h" #include "mxdsfile.h" // VTABLE 0x100dd100 +// SIZE 0x10 class MxStreamProvider : public MxCore { public: - inline MxStreamProvider() { - this->m_pLookup = NULL; - this->m_pFile = NULL; - } + inline MxStreamProvider() : m_pLookup(NULL), m_pFile(NULL) {} // OFFSET: LEGO1 0x100d07e0 inline virtual const char *ClassName() const override // vtable+0x0c @@ -25,6 +24,13 @@ class MxStreamProvider : public MxCore return !strcmp(name, MxStreamProvider::ClassName()) || MxCore::IsA(name); } + virtual MxResult SetResourceToGet(void* p_resource); //vtable+0x14 + virtual MxU32 GetFileSize() = 0; //vtable+0x18 + virtual MxU32 vtable0x1C() = 0; //vtable+0x1c + virtual void vtable0x20(undefined4 p_unknown1); //vtable+0x20 + virtual MxU32 GetLengthInDWords() = 0; //vtable+0x24 + virtual void* GetBufferForDWords() = 0; //vtable+0x28 + protected: void *m_pLookup; MxDSFile* m_pFile; diff --git a/LEGO1/mxstring.cpp b/LEGO1/mxstring.cpp index e82d431a..fe221f94 100644 --- a/LEGO1/mxstring.cpp +++ b/LEGO1/mxstring.cpp @@ -56,14 +56,14 @@ void MxString::ToLowerCase() } // OFFSET: LEGO1 0x100ae4b0 -MxString &MxString::operator=(MxString *param) +MxString &MxString::operator=(MxString ¶m) { - if (this->m_data != param->m_data) + if (this->m_data != param.m_data) { delete[] this->m_data; - this->m_length = param->m_length; + this->m_length = param.m_length; this->m_data = new char[this->m_length + 1]; - strcpy(this->m_data, param->m_data); + strcpy(this->m_data, param.m_data); } return *this; diff --git a/LEGO1/mxstring.h b/LEGO1/mxstring.h index a24a0df1..ec20f879 100644 --- a/LEGO1/mxstring.h +++ b/LEGO1/mxstring.h @@ -15,7 +15,7 @@ class MxString : public MxCore MxString(const char *); void ToUpperCase(); void ToLowerCase(); - MxString& operator=(MxString *); + MxString& operator=(MxString &); MxString operator+(const char *); MxString& operator+=(const char *); diff --git a/LEGO1/mxstringlist.cpp b/LEGO1/mxstringlist.cpp new file mode 100644 index 00000000..8a0a2ddc --- /dev/null +++ b/LEGO1/mxstringlist.cpp @@ -0,0 +1,5 @@ +#include "mxstringlist.h" + +#include "decomp.h" + +DECOMP_SIZE_ASSERT(MxListEntry, 0x18) diff --git a/LEGO1/mxstringlist.h b/LEGO1/mxstringlist.h index dbf063f6..f92d2b7d 100644 --- a/LEGO1/mxstringlist.h +++ b/LEGO1/mxstringlist.h @@ -8,6 +8,9 @@ // SIZE 0x18 class MxStringList : public MxList {}; +// VTABLE 0x100dd058 +typedef MxListCursorChild MxStringListCursor; + // OFFSET: LEGO1 0x100cb3c0 TEMPLATE // MxListParent::Compare @@ -17,6 +20,15 @@ class MxStringList : public MxList {}; // OFFSET: LEGO1 0x100cb4c0 TEMPLATE // MxList::~MxList +// OFFSET: LEGO1 0x100cbb40 TEMPLATE +// MxList::OtherAppend + +// OFFSET: LEGO1 0x100cc2d0 TEMPLATE +// MxList::_InsertEntry + +// OFFSET: LEGO1 0x100cc3c0 TEMPLATE +// MxListEntry::MxListEntry + // OFFSET: LEGO1 0x100cc450 TEMPLATE // MxListEntry::GetValue diff --git a/LEGO1/mxthread.cpp b/LEGO1/mxthread.cpp index b63019ed..fed82eca 100644 --- a/LEGO1/mxthread.cpp +++ b/LEGO1/mxthread.cpp @@ -1,9 +1,10 @@ #include "mxthread.h" -#include - #include "mxomni.h" +#include "mxtimer.h" + +#include // OFFSET: LEGO1 0x100bf690 MxResult MxThread::Run() diff --git a/LEGO1/mxtransitionmanager.cpp b/LEGO1/mxtransitionmanager.cpp index d34df54f..66c99532 100644 --- a/LEGO1/mxtransitionmanager.cpp +++ b/LEGO1/mxtransitionmanager.cpp @@ -1,6 +1,12 @@ #include "mxtransitionmanager.h" -#include "legoutil.h" + #include "legovideomanager.h" +#include "legoinputmanager.h" +#include "legoutil.h" +#include "legoworld.h" +#include "mxbackgroundaudiomanager.h" +#include "mxparam.h" +#include "mxticklemanager.h" DECOMP_SIZE_ASSERT(MxTransitionManager, 0x900); @@ -23,7 +29,7 @@ MxTransitionManager::MxTransitionManager() // OFFSET: LEGO1 0x1004ba00 MxTransitionManager::~MxTransitionManager() { - free(m_copyBuffer); + delete[] m_copyBuffer; if (m_waitIndicator != NULL) { delete m_waitIndicator->GetAction(); @@ -79,7 +85,7 @@ void MxTransitionManager::EndTransition(MxBool p_notifyWorld) LegoWorld *world = GetCurrentWorld(); if (world) { - world->Notify(MxParam(0x18, this)); + world->Notify(MxParam(MXTRANSITIONMANAGER_TRANSITIONENDED, this)); } } } @@ -318,17 +324,17 @@ void MxTransitionManager::SubmitCopyRect(LPDDSURFACEDESC ddsc) } // Copy the copy rect onto the surface - char *dst; + MxU8 *dst; - DWORD bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; + MxU32 bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; - const char *src = (const char *)m_copyBuffer; + const MxU8 *src = (const MxU8 *)m_copyBuffer; - LONG copyPitch; + MxS32 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); + MxS32 y; + dst = (MxU8 *)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); @@ -337,7 +343,7 @@ void MxTransitionManager::SubmitCopyRect(LPDDSURFACEDESC ddsc) } // Free the copy buffer - free(m_copyBuffer); + delete[] m_copyBuffer; m_copyBuffer = NULL; } @@ -355,11 +361,11 @@ void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc) // 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; + MxU32 copyPitch = (ddsc->ddpfPixelFormat.dwRGBBitCount / 8) * (m_copyRect.right - m_copyRect.left + 1); // This uses m_copyRect, seemingly erroneously + MxU32 bytesPerPixel = ddsc->ddpfPixelFormat.dwRGBBitCount / 8; - m_copyRect.left = m_waitIndicator->GetLocation().m_x; - m_copyRect.top = m_waitIndicator->GetLocation().m_y; + m_copyRect.left = m_waitIndicator->GetLocationX(); + m_copyRect.top = m_waitIndicator->GetLocationY(); MxS32 height = m_waitIndicator->GetHeight(); MxS32 width = m_waitIndicator->GetWidth(); @@ -368,14 +374,14 @@ void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc) 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; + const MxU8 *src = (const MxU8*)ddsc->lpSurface + m_copyRect.top * ddsc->lPitch + bytesPerPixel * m_copyRect.left; - m_copyBuffer = malloc(bytesPerPixel * width * height); + m_copyBuffer = new MxU8[bytesPerPixel * width * height]; if (!m_copyBuffer) return; // Copy into the copy buffer - char *dst = (char*)m_copyBuffer; + MxU8 *dst = m_copyBuffer; for (MxS32 i = 0; i < (m_copyRect.bottom - m_copyRect.top + 1); i++) { @@ -390,11 +396,11 @@ void MxTransitionManager::SetupCopyRect(LPDDSURFACEDESC ddsc) { 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); + displaySurface->vtable2c(ddsc, m_waitIndicator->m_bitmap, 0, 0, m_waitIndicator->GetLocationX(), m_waitIndicator->GetLocationY(), 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()); + displaySurface->vtable24(ddsc, m_waitIndicator->m_bitmap, 0, 0, m_waitIndicator->GetLocationX(), m_waitIndicator->GetLocationY(), m_waitIndicator->GetWidth(), m_waitIndicator->GetHeight()); } } diff --git a/LEGO1/mxtransitionmanager.h b/LEGO1/mxtransitionmanager.h index 7f1d4ead..58a8079e 100644 --- a/LEGO1/mxtransitionmanager.h +++ b/LEGO1/mxtransitionmanager.h @@ -5,6 +5,8 @@ #include "mxvideopresenter.h" #include "legoomni.h" +#include + // VTABLE 0x100d7ea0 class MxTransitionManager : public MxCore { @@ -57,7 +59,7 @@ class MxTransitionManager : public MxCore MxVideoPresenter *m_waitIndicator; RECT m_copyRect; - void *m_copyBuffer; + MxU8 *m_copyBuffer; flag_bitfield m_copyFlags; undefined4 m_unk24; diff --git a/LEGO1/mxunklist.h b/LEGO1/mxunklist.h new file mode 100644 index 00000000..af59f47b --- /dev/null +++ b/LEGO1/mxunklist.h @@ -0,0 +1,37 @@ +#ifndef MXUNKLIST_H +#define MXUNKLIST_H + +#include "decomp.h" +#include "mxtypes.h" + +/* +* This is an as-of-yet unknown list-like data structure. +* The class hierarchy/structure isn't quite correct yet. +*/ + +struct MxUnkListNode { + MxUnkListNode *m_unk00; + MxUnkListNode *m_unk04; + undefined4 m_unk08; +}; + +class MxUnkList { +public: + inline MxUnkList() { + undefined unk; + this->m_unk00 = unk; + + MxUnkListNode *node = new MxUnkListNode(); + node->m_unk00 = node; + node->m_unk04 = node; + + this->m_head = node; + this->m_count = 0; + } + + undefined m_unk00; + MxUnkListNode *m_head; + MxU32 m_count; +}; + +#endif // MXUNKLIST_H \ No newline at end of file diff --git a/LEGO1/mxvector.h b/LEGO1/mxvector.h index ae58abd9..eef1d927 100644 --- a/LEGO1/mxvector.h +++ b/LEGO1/mxvector.h @@ -95,6 +95,8 @@ class MxVector3 : public MxVector2 virtual void EqualsCross(MxVector3 *p_a, float *p_b); virtual void EqualsCross(MxVector3 *p_a, MxVector3 *p_b); virtual void EqualsScalar(float *p_value); + + inline void Fill(float p_value) { EqualsScalar(&p_value); } }; // VTABLE 0x100d45a0 diff --git a/LEGO1/mxvideomanager.cpp b/LEGO1/mxvideomanager.cpp index 8f64dbd4..bab495fd 100644 --- a/LEGO1/mxvideomanager.cpp +++ b/LEGO1/mxvideomanager.cpp @@ -34,7 +34,7 @@ MxResult MxVideoManager::Tickle() UpdateRegion(); m_region->Reset(); - + return SUCCESS; } @@ -54,13 +54,13 @@ MxResult MxVideoManager::Init() void MxVideoManager::SortPresenterList() { if (this->m_presenters->GetCount() <= 1) - return; + return; MxPresenterListCursor a(this->m_presenters); MxPresenterListCursor b(this->m_presenters); MxU32 count = this->m_presenters->GetCount() - 1; MxBool finished; - + if (count != 0) { do { a.Reset(); @@ -111,3 +111,15 @@ MxLong MxVideoManager::RealizePalette(MxPalette *p_palette) this->m_criticalSection.Leave(); return 0; } + +// OFFSET: LEGO1 0x100be600 STUB +void MxVideoManager::vtable0x28() +{ + +} + +// OFFSET: LEGO1 0x100bebe0 STUB +MxResult MxVideoManager::vtable0x2c(MxVideoParam& p_videoParam, undefined4 p_unknown1, MxU8 p_unknown2) +{ + return FAILURE; +} diff --git a/LEGO1/mxvideomanager.h b/LEGO1/mxvideomanager.h index 7888f7e7..f6e1a726 100644 --- a/LEGO1/mxvideomanager.h +++ b/LEGO1/mxvideomanager.h @@ -13,7 +13,9 @@ class MxVideoManager : public MxMediaManager public: virtual ~MxVideoManager(); - virtual MxResult Tickle(); // vtable+0x8 + virtual MxResult Tickle() override; // vtable+0x8 + virtual void vtable0x28(); // vtable+0x28 (TODO ARGUMENTS) + virtual MxResult vtable0x2c(MxVideoParam& p_videoParam, undefined4 p_unknown1, MxU8 p_unknown2); // vtable+0x2c __declspec(dllexport) void InvalidateRect(MxRect32 &); __declspec(dllexport) virtual MxLong RealizePalette(MxPalette *); // vtable+0x30 @@ -27,7 +29,7 @@ class MxVideoManager : public MxMediaManager inline MxVideoParam& GetVideoParam() { return this->m_videoParam; } inline LPDIRECTDRAW GetDirectDraw() { return this->m_pDirectDraw; } inline MxDisplaySurface *GetDisplaySurface() { return this->m_displaySurface; } -private: +protected: MxVideoParam m_videoParam; LPDIRECTDRAW m_pDirectDraw; LPDIRECTDRAWSURFACE m_pDDSurface; diff --git a/LEGO1/mxvideopresenter.cpp b/LEGO1/mxvideopresenter.cpp index fe83a2dc..42dc34f3 100644 --- a/LEGO1/mxvideopresenter.cpp +++ b/LEGO1/mxvideopresenter.cpp @@ -8,10 +8,10 @@ void MxVideoPresenter::VTable0x5c() // TODO } -// OFFSET: LEGO1 0x1000c710 STUB +// OFFSET: LEGO1 0x1000c710 void MxVideoPresenter::VTable0x60() { - // TODO + // Empty } // OFFSET: LEGO1 0x1000c720 STUB @@ -44,24 +44,24 @@ void MxVideoPresenter::VTable0x78() // TODO } -// OFFSET: LEGO1 0x1000c7c0 STUB -void MxVideoPresenter::VTable0x7c() +// OFFSET: LEGO1 0x1000c7c0 +MxBool MxVideoPresenter::VTable0x7c() { - // TODO + return (m_bitmap != NULL) || (m_unk54 != NULL); } -// OFFSET: LEGO1 0x1000c7e0 STUB +// OFFSET: LEGO1 0x1000c7e0 MxS32 MxVideoPresenter::GetWidth() { - // TODO - return 0; + return m_unk54 ? m_unk54->width + : m_bitmap->GetBmiHeader()->biWidth; } -// OFFSET: LEGO1 0x1000c800 STUB +// OFFSET: LEGO1 0x1000c800 MxS32 MxVideoPresenter::GetHeight() { - // TODO - return 0; + return m_unk54 ? m_unk54->height + : m_bitmap->GetBmiHeader()->biHeight; } // OFFSET: LEGO1 0x100b2760 STUB diff --git a/LEGO1/mxvideopresenter.h b/LEGO1/mxvideopresenter.h index 84822f71..9c9a21a3 100644 --- a/LEGO1/mxvideopresenter.h +++ b/LEGO1/mxvideopresenter.h @@ -2,9 +2,11 @@ #define MXVIDEOPRESENTER_H #include "mxmediapresenter.h" +#include "mxbitmap.h" #include "decomp.h" +// VTABLE 0x100d4be8 class MxVideoPresenter : public MxMediaPresenter { public: @@ -41,12 +43,20 @@ class MxVideoPresenter : public MxMediaPresenter virtual void VTable0x70(); // vtable+0x70 virtual void VTable0x74(); // vtable+0x74 virtual void VTable0x78(); // vtable+0x78 - virtual void VTable0x7c(); // vtable+0x7c + virtual MxBool VTable0x7c(); // vtable+0x7c virtual MxS32 GetWidth(); // vtable+0x80 virtual MxS32 GetHeight(); // vtable+0x84 - undefined4 m_unk50; - undefined4 m_unk54; + // TODO: Not sure what this is. Seems to have size of 12 bytes + // based on 0x100b9e9a. Values are copied from the bitmap header. + typedef struct { + undefined unk0[8]; + MxU16 width; + MxU16 height; + } unknown_meta_struct; + + MxBitmap *m_bitmap; + unknown_meta_struct *m_unk54; undefined4 m_unk58; undefined2 m_unk5c; unsigned char m_flags; // 0x5e diff --git a/LEGO1/skateboard.cpp b/LEGO1/skateboard.cpp index 5c5cbf38..b67e127e 100644 --- a/LEGO1/skateboard.cpp +++ b/LEGO1/skateboard.cpp @@ -1,5 +1,7 @@ #include "skateboard.h" + #include "mxomni.h" +#include "mxnotificationmanager.h" #include "decomp.h"