From a8254c048db9a732a8f5f6e804912cc220bbd752 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Mon, 6 Nov 2023 04:00:24 -0500 Subject: [PATCH] Implement more of LegoOmni (#267) * commit code * implement a few functions * Update mxdsobject.h * more stuff * Update legoomni.cpp * Update legoomni.cpp * rename function * fix * undo useless changes * Fixes * Add global addr --------- Co-authored-by: Christian Semmler --- LEGO1/legogamestate.cpp | 6 ++ LEGO1/legogamestate.h | 2 + LEGO1/legoinputmanager.cpp | 7 ++ LEGO1/legoinputmanager.h | 1 + LEGO1/legoomni.cpp | 127 +++++++++++++++++++++++++++++---- LEGO1/legoomni.h | 22 +++--- LEGO1/mxdiskstreamprovider.cpp | 2 +- LEGO1/mxomni.cpp | 7 +- LEGO1/mxomni.h | 3 +- LEGO1/mxomnicreateparam.h | 2 +- LEGO1/mxpresenter.cpp | 2 +- 11 files changed, 151 insertions(+), 30 deletions(-) diff --git a/LEGO1/legogamestate.cpp b/LEGO1/legogamestate.cpp index 3ac770da..e95a7470 100644 --- a/LEGO1/legogamestate.cpp +++ b/LEGO1/legogamestate.cpp @@ -164,6 +164,12 @@ void LegoGameState::SerializeScoreHistory(MxS16 p) // TODO } +// OFFSET: LEGO1 0x1003cea0 +void LegoGameState::SetSomeEnumState(undefined4 p_state) +{ + m_unk10 = p_state; +} + // OFFSET: LEGO1 0x10039f00 void LegoGameState::SetSavePath(char* p_savePath) { diff --git a/LEGO1/legogamestate.h b/LEGO1/legogamestate.h index ac268a8b..82ff4d9c 100644 --- a/LEGO1/legogamestate.h +++ b/LEGO1/legogamestate.h @@ -37,6 +37,8 @@ class LegoGameState { inline MxU32 GetUnknown10() { return m_unk10; } inline void SetUnknown424(undefined4 p_unk424) { m_unk424 = p_unk424; } + void SetSomeEnumState(undefined4 p_state); + private: void RegisterState(LegoState* p_state); MxResult WriteEndOfVariables(LegoStream* p_stream); diff --git a/LEGO1/legoinputmanager.cpp b/LEGO1/legoinputmanager.cpp index 0fd1d22d..0ff25bc5 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -63,6 +63,13 @@ void LegoInputManager::Destroy() delete m_controlManager; } +// OFFSET: LEGO1 0x1005b960 STUB +MxResult LegoInputManager::Create(HWND p_hwnd) +{ + // TODO STUB + return SUCCESS; +} + // OFFSET: LEGO1 0x1005c030 void LegoInputManager::CreateAndAcquireKeyboard(HWND hwnd) { diff --git a/LEGO1/legoinputmanager.h b/LEGO1/legoinputmanager.h index d0059605..e657f81e 100644 --- a/LEGO1/legoinputmanager.h +++ b/LEGO1/legoinputmanager.h @@ -35,6 +35,7 @@ class LegoInputManager : public MxPresenter { virtual MxResult Tickle() override; // vtable+0x8 + MxResult Create(HWND p_hwnd); void Destroy(); void CreateAndAcquireKeyboard(HWND hwnd); void ReleaseDX(); diff --git a/LEGO1/legoomni.cpp b/LEGO1/legoomni.cpp index 06315059..fb5e187c 100644 --- a/LEGO1/legoomni.cpp +++ b/LEGO1/legoomni.cpp @@ -1,12 +1,23 @@ #include "legoomni.h" +#include "gifmanager.h" +#include "legoanimationmanager.h" +#include "legobuildingmanager.h" #include "legogamestate.h" #include "legoinputmanager.h" #include "legoobjectfactory.h" +#include "legoplantmanager.h" +#include "legosoundmanager.h" #include "legoutil.h" +#include "legovideomanager.h" #include "legoworld.h" +#include "mxautolocker.h" #include "mxbackgroundaudiomanager.h" #include "mxdsfile.h" +#include "mxomnicreateflags.h" +#include "mxomnicreateparam.h" +#include "mxticklemanager.h" +#include "mxtransitionmanager.h" // 0x100f451c MxAtomId* g_copterScript = NULL; @@ -92,6 +103,9 @@ MxAtomId* g_creditsScript = NULL; // 0x100f4588 MxAtomId* g_nocdSourceName = NULL; +// 0x100f6718 +const char* g_current = "current"; + // 0x101020e8 void (*g_omniUserMessage)(const char*, int); @@ -120,6 +134,13 @@ void LegoOmni::RemoveWorld(const MxAtomId& p1, MxLong p2) // TODO } +// OFFSET: LEGO1 0x1005b0c0 STUB +LegoEntity* LegoOmni::FindByEntityIdOrAtomId(const MxAtomId& p_atom, MxS32 p_entityid) +{ + // TODO + return NULL; +} + // OFFSET: LEGO1 0x1005b400 STUB int LegoOmni::GetCurrPathInfo(LegoPathBoundary**, int&) { @@ -397,16 +418,83 @@ void LegoOmni::Init() m_transitionManager = NULL; } -// OFFSET: LEGO1 0x10058e70 STUB +// OFFSET: LEGO1 0x1001a700 STUB +void FUN_1001a700() +{ + // TODO +} + +// OFFSET: LEGO1 0x10058e70 MxResult LegoOmni::Create(MxOmniCreateParam& p) { - MxOmni::Create(p); + MxResult result = FAILURE; + MxAutoLocker lock(&this->m_criticalsection); + + p.CreateFlags().CreateObjectFactory(FALSE); + p.CreateFlags().CreateVideoManager(FALSE); + p.CreateFlags().CreateSoundManager(FALSE); + p.CreateFlags().CreateTickleManager(FALSE); + + if (!(m_tickleManager = new MxTickleManager())) + return FAILURE; + + if (MxOmni::Create(p) != SUCCESS) + return FAILURE; m_objectFactory = new LegoObjectFactory(); + if (m_objectFactory == NULL) + return FAILURE; + + if (m_soundManager = new LegoSoundManager()) { + if (m_soundManager->Create(10, 0) != SUCCESS) { + delete m_soundManager; + m_soundManager = NULL; + return FAILURE; + } + } + + if (m_videoManager = new LegoVideoManager()) { + if (m_videoManager->Create(p.GetVideoParam(), 100, 0) != SUCCESS) { + delete m_videoManager; + m_videoManager = NULL; + } + } + + if (m_inputMgr = new LegoInputManager()) { + if (m_inputMgr->Create(p.GetWindowHandle()) != SUCCESS) { + delete m_inputMgr; + m_inputMgr = NULL; + } + } + + // TODO: there are a few more classes here + m_gifManager = new GifManager(); + m_plantManager = new LegoPlantManager(); + m_animationManager = new LegoAnimationManager(); + m_buildingManager = new LegoBuildingManager(); m_gameState = new LegoGameState(); - m_bkgAudioManager = new MxBackgroundAudioManager(); - RegisterScripts(); - return SUCCESS; + // TODO: initialize list at m_unk78 + + if (m_unk6c && m_gifManager && m_unk78 && m_plantManager && m_animationManager && m_buildingManager) { + // TODO: initialize a bunch of MxVariables + RegisterScripts(); + FUN_1001a700(); + // todo: another function call. in legoomni maybe? + m_bkgAudioManager = new MxBackgroundAudioManager(); + if (m_bkgAudioManager != NULL) { + m_transitionManager = new MxTransitionManager(); + if (m_transitionManager != NULL) { + if (m_transitionManager->GetDDrawSurfaceFromVideoManager() == SUCCESS) { + m_notificationManager->Register(this); + SetAppCursor(1); + m_gameState->SetSomeEnumState(0); + return SUCCESS; + } + } + } + } + + return FAILURE; } // OFFSET: LEGO1 0x10058c30 STUB @@ -432,18 +520,33 @@ MxResult LegoOmni::DeleteObject(MxDSAction& ds) return FAILURE; } -// OFFSET: LEGO1 0x1005b3c0 STUB +// OFFSET: LEGO1 0x1005b3c0 MxBool LegoOmni::DoesEntityExist(MxDSAction& ds) { - // TODO - return TRUE; + if (MxOmni::DoesEntityExist(ds)) { + if (FindByEntityIdOrAtomId(ds.GetAtomId(), ds.GetObjectId()) == NULL) { + return TRUE; + } + } + return FALSE; } -// OFFSET: LEGO1 0x1005b2f0 STUB -int LegoOmni::Vtable0x30(char*, int, MxCore*) +// OFFSET: LEGO1 0x1005b2f0 +MxEntity* LegoOmni::FindWorld(const char* p_id, MxS32 p_entityId, MxCore* p_presenter) { - // TODO - return 0; + LegoWorld* foundEntity = NULL; + if (strcmpi(p_id, g_current)) { + foundEntity = (LegoWorld*) FindByEntityIdOrAtomId(MxAtomId(p_id, LookupMode_LowerCase2), p_entityId); + } + else { + foundEntity = this->m_currentWorld; + } + + if (foundEntity != NULL) { + foundEntity->VTable0x58(p_presenter); + } + + return foundEntity; } // OFFSET: LEGO1 0x1005b3a0 diff --git a/LEGO1/legoomni.h b/LEGO1/legoomni.h index b33c6c6e..52ea2d85 100644 --- a/LEGO1/legoomni.h +++ b/LEGO1/legoomni.h @@ -83,16 +83,18 @@ class LegoOmni : public MxOmni { return !strcmp(name, LegoOmni::ClassName()) || MxOmni::IsA(name); } - virtual void Init() override; // vtable+14 - virtual MxResult Create(MxOmniCreateParam& p) override; // vtable+18 - virtual void Destroy() override; // vtable+1c - virtual MxResult Start(MxDSAction* action) override; // vtable+20 - virtual MxResult DeleteObject(MxDSAction& ds) override; // vtable+24 - virtual MxBool DoesEntityExist(MxDSAction& ds) override; // vtable+28 - virtual int Vtable0x30(char*, int, MxCore*) override; // vtable+30 - virtual void NotifyCurrentEntity(MxNotificationParam* p_param) override; // vtable+34 - virtual void StartTimer() override; // vtable+38 - virtual void StopTimer() override; // vtable+3c + virtual void Init() override; // vtable+14 + virtual MxResult Create(MxOmniCreateParam& p) override; // vtable+18 + virtual void Destroy() override; // vtable+1c + virtual MxResult Start(MxDSAction* action) override; // vtable+20 + virtual MxResult DeleteObject(MxDSAction& ds) override; // vtable+24 + virtual MxBool DoesEntityExist(MxDSAction& ds) override; // vtable+28 + virtual MxEntity* FindWorld(const char* p_id, MxS32 p_entityId, MxCore* p_presenter) override; // vtable+30 + virtual void NotifyCurrentEntity(MxNotificationParam* p_param) override; // vtable+34 + virtual void StartTimer() override; // vtable+38 + virtual void StopTimer() override; // vtable+3c + + LegoEntity* FindByEntityIdOrAtomId(const MxAtomId& p_atom, MxS32 p_entityid); LegoVideoManager* GetVideoManager() { return (LegoVideoManager*) m_videoManager; } LegoSoundManager* GetSoundManager() { return (LegoSoundManager*) m_soundManager; } diff --git a/LEGO1/mxdiskstreamprovider.cpp b/LEGO1/mxdiskstreamprovider.cpp index b5dabe4a..0c422b99 100644 --- a/LEGO1/mxdiskstreamprovider.cpp +++ b/LEGO1/mxdiskstreamprovider.cpp @@ -81,7 +81,7 @@ MxResult MxDiskStreamProvider::WaitForWorkToComplete() return SUCCESS; } -// OFFSET: LEGO1 0x100d1760 STUB +// OFFSET: LEGO1 0x100d18f0 STUB void MxDiskStreamProvider::PerformWork() { // TODO diff --git a/LEGO1/mxomni.cpp b/LEGO1/mxomni.cpp index edd71d99..b4b430a3 100644 --- a/LEGO1/mxomni.cpp +++ b/LEGO1/mxomni.cpp @@ -91,11 +91,10 @@ void MxOmni::Vtable0x2c() // TODO } -// OFFSET: LEGO1 0x100aefb0 STUB -int MxOmni::Vtable0x30(char*, int, MxCore*) +// OFFSET: LEGO1 0x100aefb0 +MxEntity* MxOmni::FindWorld(const char*, MxS32, MxCore*) { - // TODO - return 0; + return NULL; } // OFFSET: LEGO1 0x100aefc0 diff --git a/LEGO1/mxomni.h b/LEGO1/mxomni.h index 40fad828..562de18a 100644 --- a/LEGO1/mxomni.h +++ b/LEGO1/mxomni.h @@ -20,6 +20,7 @@ class MxTickleManager; class MxTimer; class MxVariableTable; class MxVideoManager; +class MxEntity; // VTABLE 0x100dc168 // SIZE 0x68 @@ -45,7 +46,7 @@ class MxOmni : public MxCore { virtual MxResult DeleteObject(MxDSAction& p_dsAction); // vtable+24 virtual MxBool DoesEntityExist(MxDSAction& p_dsAction); // vtable+28 virtual void Vtable0x2c(); // vtable+2c - virtual int Vtable0x30(char*, int, MxCore*); // vtable+30 + virtual MxEntity* FindWorld(const char*, MxS32, MxCore*); // vtable+30 virtual void NotifyCurrentEntity(MxNotificationParam* p_param); // vtable+34 virtual void StartTimer(); // vtable+38 virtual void StopTimer(); // vtable+3c diff --git a/LEGO1/mxomnicreateparam.h b/LEGO1/mxomnicreateparam.h index 12867186..a30d01df 100644 --- a/LEGO1/mxomnicreateparam.h +++ b/LEGO1/mxomnicreateparam.h @@ -17,7 +17,7 @@ class MxOmniCreateParam : public MxParam { MxOmniCreateFlags flags ); - const MxOmniCreateFlags& CreateFlags() const { return this->m_createFlags; } + MxOmniCreateFlags& CreateFlags() { return this->m_createFlags; } const MxString& GetMediaPath() const { return m_mediaPath; } const HWND GetWindowHandle() const { return m_windowHandle; } MxVideoParam& GetVideoParam() { return m_videoParam; } diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 89dfddc8..e4121602 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -47,7 +47,7 @@ void MxPresenter::ParseExtra() token = strtok(NULL, g_parseExtraTokens); MxS32 val = token ? atoi(token) : 0; - MxS32 result = MxOmni::GetInstance()->Vtable0x30(t_token, val, this); + MxEntity* result = MxOmni::GetInstance()->FindWorld(t_token, val, this); m_action->SetFlags(m_action->GetFlags() | MxDSAction::Flag_Parsed);