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 5b30a6b8..f11e8577 100644 --- a/LEGO1/legoinputmanager.cpp +++ b/LEGO1/legoinputmanager.cpp @@ -47,11 +47,12 @@ LegoInputManager::~LegoInputManager() } // OFFSET: LEGO1 0x1005b960 -void LegoInputManager::Create() +MxResult LegoInputManager::Create(HWND p_hwnd) { // TODO if (m_eventQueue == NULL) m_eventQueue = new LegoEventQueue(); + return SUCCESS; } // OFFSET: LEGO1 0x1005bfe0 diff --git a/LEGO1/legoinputmanager.h b/LEGO1/legoinputmanager.h index 4227165b..3fb27d76 100644 --- a/LEGO1/legoinputmanager.h +++ b/LEGO1/legoinputmanager.h @@ -37,6 +37,7 @@ class LegoInputManager : public MxPresenter { virtual MxResult Tickle() override; // vtable+0x8 + MxResult Create(HWND p_hwnd); void Create(); void Destroy(); void CreateAndAcquireKeyboard(HWND hwnd); diff --git a/LEGO1/legonavcontroller.cpp b/LEGO1/legonavcontroller.cpp index 5b5fc38d..eefbbed1 100644 --- a/LEGO1/legonavcontroller.cpp +++ b/LEGO1/legonavcontroller.cpp @@ -1,5 +1,6 @@ #include "legonavcontroller.h" +#include "legoinputmanager.h" #include "legoomni.h" #include "legoutil.h" #include "legovideomanager.h" @@ -106,18 +107,14 @@ LegoNavController::LegoNavController() MxTimer* timer = Timer(); this->m_time = timer->GetTime(); - // TODO: InputManager() - // LegoInputManager* inputManager = InputManager(); - // inputManager->Register(this); + InputManager()->Register(this); } -// TODO: InputManager() // OFFSET: LEGO1 0x10054c30 -// LegoNavController::~LegoNavController() -// { -// LegoInputManager* inputManager = InputManager(); -// inputManager->UnRegister(this); -// } +LegoNavController::~LegoNavController() +{ + InputManager()->UnRegister(this); +} // OFFSET: LEGO1 0x10054ca0 void LegoNavController::SetControlMax(int p_hMax, int p_vMax) diff --git a/LEGO1/legonavcontroller.h b/LEGO1/legonavcontroller.h index 65b9f5ab..f7cfa3da 100644 --- a/LEGO1/legonavcontroller.h +++ b/LEGO1/legonavcontroller.h @@ -37,7 +37,7 @@ class LegoNavController : public MxCore { ); LegoNavController(); - // virtual ~LegoNavController(); // vtable+0x0 + virtual ~LegoNavController() override; // vtable+0x0 // OFFSET: LEGO1 0x10054b80 inline const char* ClassName() const override // vtable+0xc diff --git a/LEGO1/legoobjectfactory.cpp b/LEGO1/legoobjectfactory.cpp index b26686df..db59ad5e 100644 --- a/LEGO1/legoobjectfactory.cpp +++ b/LEGO1/legoobjectfactory.cpp @@ -31,8 +31,8 @@ MxCore* LegoObjectFactory::Create(const char* p_name) } } -// OFFSET: LEGO1 0x1000fb30 STUB +// OFFSET: LEGO1 0x1000fb30 void LegoObjectFactory::Destroy(MxCore* p_object) { - // TODO + delete p_object; } 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/mxeventpresenter.cpp b/LEGO1/mxeventpresenter.cpp index 755b440e..48741d4f 100644 --- a/LEGO1/mxeventpresenter.cpp +++ b/LEGO1/mxeventpresenter.cpp @@ -24,11 +24,22 @@ void MxEventPresenter::Init() m_unk50 = NULL; } +// OFFSET: LEGO1 0x100c2db0 +MxResult MxEventPresenter::AddToManager() +{ + MxResult ret = FAILURE; + if (EventManager()) { + ret = SUCCESS; + EventManager()->AddPresenter(*this); + } + + return ret; +} + // OFFSET: LEGO1 0x100c2de0 void MxEventPresenter::Destroy() { - MxEventManager* eventManager = EventManager(); - if (eventManager) + if (EventManager()) EventManager()->RemovePresenter(*this); m_criticalSection.Enter(); diff --git a/LEGO1/mxeventpresenter.h b/LEGO1/mxeventpresenter.h index 35ad8ae9..91b95983 100644 --- a/LEGO1/mxeventpresenter.h +++ b/LEGO1/mxeventpresenter.h @@ -24,7 +24,8 @@ class MxEventPresenter : public MxMediaPresenter { return !strcmp(name, MxEventPresenter::ClassName()) || MxMediaPresenter::IsA(name); } - virtual void Destroy() override; // vtable+0x38 + virtual MxResult AddToManager() override; // vtable+0x34 + virtual void Destroy() override; // vtable+0x38 private: void Init(); 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); diff --git a/LEGO1/pizza.cpp b/LEGO1/pizza.cpp index e7eb0261..13df0739 100644 --- a/LEGO1/pizza.cpp +++ b/LEGO1/pizza.cpp @@ -20,7 +20,7 @@ Pizza::~Pizza() TickleManager()->UnregisterClient(this); } -// OFFSET: LEGO1 0x100388a0 +// OFFSET: LEGO1 0x100388a0 STUB MxResult Pizza::Tickle() { // TODO diff --git a/tools/reccmp/reccmp.py b/tools/reccmp/reccmp.py index d32b5ad0..41e571ab 100755 --- a/tools/reccmp/reccmp.py +++ b/tools/reccmp/reccmp.py @@ -220,12 +220,14 @@ def get_recompiled_address(self, filename, line): found = False logger.debug('Looking for %s:%d', filename, line) + filename_basename = os.path.basename(filename).lower() for fn in self.lines: # Sometimes a PDB is compiled with a relative path while we always have # an absolute path. Therefore we must try: - if os.path.samefile(fn, filename): + if (os.path.basename(fn).lower() == filename_basename and + os.path.samefile(fn, filename)): filename = fn break except FileNotFoundError as e: