diff --git a/CMakeLists.txt b/CMakeLists.txt index 406edcab..47617b10 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -323,6 +323,7 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/actors/act3shark.cpp LEGO1/lego/legoomni/src/actors/ambulance.cpp LEGO1/lego/legoomni/src/actors/bike.cpp + LEGO1/lego/legoomni/src/actors/buildingentity.cpp LEGO1/lego/legoomni/src/actors/buildings.cpp LEGO1/lego/legoomni/src/actors/bumpbouy.cpp LEGO1/lego/legoomni/src/actors/doors.cpp @@ -346,8 +347,6 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp - LEGO1/lego/legoomni/src/build/buildingentity.cpp - LEGO1/lego/legoomni/src/build/legobuildingmanager.cpp LEGO1/lego/legoomni/src/build/legocarbuild.cpp LEGO1/lego/legoomni/src/build/legocarbuildpresenter.cpp LEGO1/lego/legoomni/src/common/legoactioncontrolpresenter.cpp @@ -355,6 +354,7 @@ add_library(lego1 SHARED LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp LEGO1/lego/legoomni/src/common/legobackgroundcolor.cpp + LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp LEGO1/lego/legoomni/src/common/legocharactermanager.cpp LEGO1/lego/legoomni/src/common/legofullscreenmovie.cpp LEGO1/lego/legoomni/src/common/legogamestate.cpp diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index cd997896..8d5a703a 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -160,7 +160,7 @@ void IsleApp::Close() Lego()->RemoveWorld(ds.GetAtomId(), ds.GetObjectId()); Lego()->DeleteObject(ds); TransitionManager()->SetWaitIndicator(NULL); - Lego()->StopTimer(); + Lego()->Resume(); while (Streamer()->Close(NULL) == SUCCESS) { } @@ -284,7 +284,7 @@ int SDL_AppIterate(void* appstate) g_reqEnableRMDevice = FALSE; VideoManager()->EnableRMDevice(); g_rmDisabled = FALSE; - Lego()->StopTimer(); + Lego()->Resume(); } if (g_closed) { @@ -595,7 +595,7 @@ inline void IsleApp::Tick() return; } - if (!Lego()->IsTimerRunning()) { + if (!Lego()->IsPaused()) { TickleManager()->Tickle(); } g_lastFrameTime = currentTime; diff --git a/LEGO1/lego/legoomni/include/ambulance.h b/LEGO1/lego/legoomni/include/ambulance.h index aa357385..54e163e8 100644 --- a/LEGO1/lego/legoomni/include/ambulance.h +++ b/LEGO1/lego/legoomni/include/ambulance.h @@ -98,13 +98,15 @@ class Ambulance : public IslePathActor { void CreateState(); void FUN_10036e60(); void FUN_10037060(); - void FUN_10037240(); + void StopActions(); void FUN_10037250(); // SYNTHETIC: LEGO1 0x10036130 // Ambulance::`scalar deleting destructor' private: + void StopAction(MxS32 p_entityId); + undefined m_unk0x160[4]; // 0x160 AmbulanceMissionState* m_state; // 0x164 MxS16 m_unk0x168; // 0x168 diff --git a/LEGO1/lego/legoomni/include/carrace.h b/LEGO1/lego/legoomni/include/carrace.h index 67332197..30b2cf76 100644 --- a/LEGO1/lego/legoomni/include/carrace.h +++ b/LEGO1/lego/legoomni/include/carrace.h @@ -44,13 +44,13 @@ class CarRace : public LegoRace { return !strcmp(p_name, CarRace::ClassName()) || LegoRace::IsA(p_name); } - MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - void ReadyWorld() override; // vtable+0x50 - MxBool Escape() override; // vtable+0x64 - undefined4 VTable0x6c(undefined4) override; // vtable+0x6c - undefined4 VTable0x70(undefined4) override; // vtable+0x70 - undefined4 VTable0x74(undefined4) override; // vtable+0x74 - undefined4 VTable0x78(undefined4) override; // vtable+0x78 + MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 + void ReadyWorld() override; // vtable+0x50 + MxBool Escape() override; // vtable+0x64 + MxLong HandleClick(LegoEventNotificationParam&) override; // vtable+0x6c + MxLong HandleType19Notification(MxType19NotificationParam&) override; // vtable+0x70 + MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74 + MxLong HandleType0Notification(MxNotificationParam&) override; // vtable+0x78 // SYNTHETIC: LEGO1 0x10016c70 // CarRace::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/jetskirace.h b/LEGO1/lego/legoomni/include/jetskirace.h index b51496c4..1fe28293 100644 --- a/LEGO1/lego/legoomni/include/jetskirace.h +++ b/LEGO1/lego/legoomni/include/jetskirace.h @@ -48,12 +48,12 @@ class JetskiRace : public LegoRace { return !strcmp(p_name, JetskiRace::ClassName()) || LegoRace::IsA(p_name); } - MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - void ReadyWorld() override; // vtable+0x50 - MxBool Escape() override; // vtable+0x64 - undefined4 VTable0x6c(undefined4) override; // vtable+0x6c - undefined4 VTable0x70(undefined4) override; // vtable+0x70 - undefined4 VTable0x74(undefined4) override; // vtable+0x74 + MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 + void ReadyWorld() override; // vtable+0x50 + MxBool Escape() override; // vtable+0x64 + MxLong HandleClick(LegoEventNotificationParam&) override; // vtable+0x6c + MxLong HandleType19Notification(MxType19NotificationParam&) override; // vtable+0x70 + MxLong HandleEndAction(MxEndActionNotificationParam&) override; // vtable+0x74 }; // SYNTHETIC: LEGO1 0x1000f530 diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 735e31c2..504f0598 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -43,6 +43,8 @@ class LegoAct2State : public LegoState { // SIZE 0x1154 class LegoAct2 : public LegoWorld { public: + ~LegoAct2() override; + MxLong Notify(MxParam& p_param) override; // vtable+0x04 MxResult Tickle() override; // vtable+0x08 MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 @@ -58,6 +60,8 @@ class LegoAct2 : public LegoWorld { // LegoAct2::`scalar deleting destructor' private: + void FUN_10051900(); + Act2Brick m_bricks[10]; // 0x00f8 undefined m_unk0x10c0; // 0x10c0 undefined m_unk0x10c1; // 0x10c1 diff --git a/LEGO1/lego/legoomni/include/legoflctexturepresenter.h b/LEGO1/lego/legoomni/include/legoflctexturepresenter.h index 706b953d..bb90a14b 100644 --- a/LEGO1/lego/legoomni/include/legoflctexturepresenter.h +++ b/LEGO1/lego/legoomni/include/legoflctexturepresenter.h @@ -4,6 +4,8 @@ #include "decomp.h" #include "mxflcpresenter.h" +class LegoTextureInfo; + // VTABLE: LEGO1 0x100d89e0 // SIZE 0x70 class LegoFlcTexturePresenter : public MxFlcPresenter { @@ -34,8 +36,8 @@ class LegoFlcTexturePresenter : public MxFlcPresenter { private: void Init(); - undefined4 m_unk0x68; // 0x68 - undefined4 m_unk0x6c; // 0x6c + MxS32 m_rectCount; // 0x68 + LegoTextureInfo* m_texture; // 0x6c }; #endif // LEGOFLCTEXTUREPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legomain.h b/LEGO1/lego/legoomni/include/legomain.h index e3264e06..98245c5c 100644 --- a/LEGO1/lego/legoomni/include/legomain.h +++ b/LEGO1/lego/legoomni/include/legomain.h @@ -75,33 +75,33 @@ class LegoOmni : public MxOmni { }; LegoOmni(); - ~LegoOmni() override; // vtable+00 + ~LegoOmni() override; - MxLong Notify(MxParam& p_param) override; // vtable+04 + MxLong Notify(MxParam& p_param) override; // vtable+0x04 // FUNCTION: LEGO1 0x10058aa0 - inline const char* ClassName() const override // vtable+0c + inline const char* ClassName() const override // vtable+0x0c { // STRING: LEGO1 0x100f671c return "LegoOmni"; } // FUNCTION: LEGO1 0x10058ab0 - inline MxBool IsA(const char* p_name) const override // vtable+10 + inline MxBool IsA(const char* p_name) const override // vtable+0x10 { return !strcmp(p_name, LegoOmni::ClassName()) || MxOmni::IsA(p_name); } - void Init() override; // vtable+14 - MxResult Create(MxOmniCreateParam& p_param) override; // vtable+18 - void Destroy() override; // vtable+1c - MxResult Start(MxDSAction* p_dsAction) override; // vtable+20 - void DeleteObject(MxDSAction& p_dsAction) override; // vtable+24 - MxBool DoesEntityExist(MxDSAction& p_dsAction) override; // vtable+28 - MxEntity* AddToWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter) override; // vtable+30 - void NotifyCurrentEntity(const MxNotificationParam& p_param) override; // vtable+34 - void StartTimer() override; // vtable+38 - void StopTimer() override; // vtable+3c + void Init() override; // vtable+0x14 + MxResult Create(MxOmniCreateParam& p_param) override; // vtable+0x18 + void Destroy() override; // vtable+0x1c + MxResult Start(MxDSAction* p_dsAction) override; // vtable+0x20 + void DeleteObject(MxDSAction& p_dsAction) override; // vtable+0x24 + MxBool DoesEntityExist(MxDSAction& p_dsAction) override; // vtable+0x28 + MxEntity* AddToWorld(const char* p_id, MxS32 p_entityId, MxPresenter* p_presenter) override; // vtable+0x30 + void NotifyCurrentEntity(const MxNotificationParam& p_param) override; // vtable+0x34 + void Pause() override; // vtable+0x38 + void Resume() override; // vtable+0x3c LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid); LegoROI* FindROI(const char* p_name); diff --git a/LEGO1/lego/legoomni/include/legorace.h b/LEGO1/lego/legoomni/include/legorace.h index 76282d0b..3d41633d 100644 --- a/LEGO1/lego/legoomni/include/legorace.h +++ b/LEGO1/lego/legoomni/include/legorace.h @@ -2,11 +2,19 @@ #define LEGORACE_H #include "decomp.h" +#include "legogamestate.h" #include "legostate.h" #include "legoworld.h" #include "mxrect32.h" #include "mxtypes.h" +class Act1State; +class LegoEventNotificationParam; +class LegoPathActor; +class MxEndActionNotificationParam; +class MxNotificationParam; +class MxType19NotificationParam; + // VTABLE: LEGO1 0x100d5e30 // SIZE 0x2c class RaceState : public LegoState { @@ -86,39 +94,42 @@ class LegoRace : public LegoWorld { } MxResult Create(MxDSAction& p_dsAction) override; // vtable+0x18 - MxBool VTable0x5c() override; // vtable+0x5c - MxBool Escape() override; // vtable+0x64 - void Enable(MxBool p_enable) override; // vtable+0x68 - virtual undefined4 VTable0x6c(undefined4) = 0; // vtable+0x6c - virtual undefined4 VTable0x70(undefined4); // vtable+0x70 - virtual undefined4 VTable0x74(undefined4); // vtable+0x74 - virtual undefined4 VTable0x78(undefined4); // vtable+0x78 - virtual void VTable0x7c(undefined4, undefined4); // vtable+0x7c + + // FUNCTION: LEGO1 0x1000dae0 + MxBool VTable0x5c() override { return TRUE; } // vtable+0x5c + + MxBool Escape() override; // vtable+0x64 + void Enable(MxBool p_enable) override; // vtable+0x68 + virtual MxLong HandleClick(LegoEventNotificationParam&) = 0; // vtable+0x6c + virtual MxLong HandleType19Notification(MxType19NotificationParam&); // vtable+0x70 + virtual MxLong HandleEndAction(MxEndActionNotificationParam&); // vtable+0x74 + + // FUNCTION: LEGO1 0x1000dab0 + virtual MxLong HandleType0Notification(MxNotificationParam&) { return 0; } // vtable+0x78 + + // STUB: LEGO1 0x1000dac0 + virtual void VTable0x7c(undefined4, undefined4) {} // vtable+0x7c // SYNTHETIC: LEGO1 0x10015cc0 // LegoRace::`scalar deleting destructor' -private: - undefined4 m_unk0xf8; // 0xf8 - undefined4 m_unk0xfc; // 0xfc - undefined4 m_unk0x100; // 0x100 - undefined4 m_unk0x104; // 0x104 - undefined4 m_unk0x108; // 0x108 - undefined4 m_unk0x10c; // 0x10c - undefined4 m_unk0x110; // 0x110 - undefined4 m_unk0x114; // 0x114 - undefined4 m_unk0x118; // 0x118 - undefined4 m_unk0x11c; // 0x11c - undefined4 m_unk0x120; // 0x120 - undefined4 m_unk0x124; // 0x124 - undefined4 m_unk0x128; // 0x128 - undefined4 m_unk0x12c; // 0x12c - protected: - MxRect32 m_unk0x130; // 0x130 - -private: - undefined4 m_unk0x140; // 0x140 + undefined4 m_unk0xf8; // 0xf8 + undefined4 m_unk0xfc; // 0xfc + undefined4 m_unk0x100; // 0x100 + undefined4 m_unk0x104; // 0x104 + undefined4 m_unk0x108; // 0x108 + undefined4 m_unk0x10c; // 0x10c + undefined4 m_unk0x110; // 0x110 + undefined4 m_unk0x114; // 0x114 + undefined4 m_unk0x118; // 0x118 + LegoGameState::Area m_destLocation; // 0x11c + LegoPathActor* m_pathActor; // 0x120 + Act1State* m_act1State; // 0x124 + undefined4 m_unk0x128; // 0x128 + undefined4 m_unk0x12c; // 0x12c + MxRect32 m_unk0x130; // 0x130 + undefined4 m_unk0x140; // 0x140 }; #endif // LEGORACE_H diff --git a/LEGO1/lego/legoomni/include/legoworld.h b/LEGO1/lego/legoomni/include/legoworld.h index 766d5ca5..f1de12c9 100644 --- a/LEGO1/lego/legoomni/include/legoworld.h +++ b/LEGO1/lego/legoomni/include/legoworld.h @@ -91,7 +91,7 @@ class LegoWorld : public LegoEntity { inline LegoCameraController* GetCamera() { return m_cameraController; } inline LegoEntityList* GetEntityList() { return m_entityList; } inline MxS32 GetScriptIndex() { return m_scriptIndex; } - inline MxCoreSet& GetUnknown0xd0() { return m_set0xd0; } + inline MxBool GetUnknown0xd0Empty() { return m_set0xd0.empty(); } inline list& GetROIList() { return m_roiList; } inline LegoHideAnimPresenter* GetHideAnimPresenter() { return m_hideAnimPresenter; } diff --git a/LEGO1/lego/legoomni/include/towtrack.h b/LEGO1/lego/legoomni/include/towtrack.h index ee91b5a5..e25e8137 100644 --- a/LEGO1/lego/legoomni/include/towtrack.h +++ b/LEGO1/lego/legoomni/include/towtrack.h @@ -67,6 +67,7 @@ class TowTrackMissionState : public LegoState { class TowTrack : public IslePathActor { public: TowTrack(); + ~TowTrack() override; // FUNCTION: LEGO1 0x1004c7c0 inline const char* ClassName() const override // vtable+0x0c diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp index 2474c7b9..20d12b35 100644 --- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp +++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp @@ -1,8 +1,10 @@ #include "ambulance.h" #include "decomp.h" +#include "isle_actions.h" #include "legocontrolmanager.h" #include "legogamestate.h" +#include "legoutils.h" #include "legovariables.h" #include "legoworld.h" #include "misc.h" @@ -123,6 +125,7 @@ MxLong Ambulance::Notify(MxParam& p_param) } // STUB: LEGO1 0x100364d0 +// FUNCTION: BETA10 0x10022cc2 MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param) { // TODO @@ -182,10 +185,10 @@ MxResult Ambulance::Tickle() return SUCCESS; } -// STUB: LEGO1 0x10037240 -void Ambulance::FUN_10037240() +// FUNCTION: LEGO1 0x10037240 +void Ambulance::StopActions() { - // TODO + StopAction(IsleScript::c_pns018rd_RunAnim); } // STUB: LEGO1 0x10037250 @@ -194,6 +197,14 @@ void Ambulance::FUN_10037250() // TODO } +// FUNCTION: LEGO1 0x10037340 +void Ambulance::StopAction(MxS32 p_entityId) +{ + if (p_entityId != -1) { + InvokeAction(Extra::e_stop, *g_isleScript, p_entityId, NULL); + } +} + // FUNCTION: LEGO1 0x100373a0 AmbulanceMissionState::AmbulanceMissionState() { diff --git a/LEGO1/lego/legoomni/src/build/buildingentity.cpp b/LEGO1/lego/legoomni/src/actors/buildingentity.cpp similarity index 100% rename from LEGO1/lego/legoomni/src/build/buildingentity.cpp rename to LEGO1/lego/legoomni/src/actors/buildingentity.cpp diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp index 461777cf..c487def5 100644 --- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp +++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp @@ -1,5 +1,6 @@ #include "towtrack.h" +#include "legocontrolmanager.h" #include "legogamestate.h" #include "legovariables.h" #include "legoworld.h" @@ -25,6 +26,12 @@ TowTrack::TowTrack() m_unk0x178 = 1.0; } +// FUNCTION: LEGO1 0x1004c970 +TowTrack::~TowTrack() +{ + ControlManager()->Unregister(this); +} + // FUNCTION: LEGO1 0x1004c9e0 // FUNCTION: BETA10 0x100f6bf1 MxResult TowTrack::Create(MxDSAction& p_dsAction) diff --git a/LEGO1/lego/legoomni/src/build/legobuildingmanager.cpp b/LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp similarity index 100% rename from LEGO1/lego/legoomni/src/build/legobuildingmanager.cpp rename to LEGO1/lego/legoomni/src/common/legobuildingmanager.cpp diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index b7882a3c..5e1fcdeb 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -780,7 +780,7 @@ inline void LoadIsle() { LegoWorld* world = FindWorld(*g_isleScript, 0); if (world != NULL) { - if (!world->GetUnknown0xd0().empty()) { + if (!world->GetUnknown0xd0Empty()) { NotificationManager()->Send(world, MxNotificationParam(c_notificationType20, NULL)); } } diff --git a/LEGO1/lego/legoomni/src/entity/act2policestation.cpp b/LEGO1/lego/legoomni/src/entity/act2policestation.cpp index a8636335..728b0441 100644 --- a/LEGO1/lego/legoomni/src/entity/act2policestation.cpp +++ b/LEGO1/lego/legoomni/src/entity/act2policestation.cpp @@ -1,11 +1,21 @@ #include "act2policestation.h" +#include "legoworld.h" +#include "misc.h" +#include "mxmisc.h" +#include "mxnotificationmanager.h" +#include "mxnotificationparam.h" + DECOMP_SIZE_ASSERT(Act2PoliceStation, 0x68) -// STUB: LEGO1 0x1004e0e0 +// FUNCTION: LEGO1 0x1004e0e0 MxLong Act2PoliceStation::Notify(MxParam& p_param) { - // TODO + if (((MxNotificationParam&) p_param).GetType() == c_notificationClick) { + MxNotificationParam param(c_notificationType23, NULL); + NotificationManager()->Send(CurrentWorld(), param); + return 1; + } return 0; } diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp index 70c2bb88..24ac051b 100644 --- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp @@ -607,11 +607,11 @@ MxLong LegoNavController::Notify(MxParam& p_param) switch (((LegoEventNotificationParam&) p_param).GetKey()) { case VK_PAUSE: - if (Lego()->IsTimerRunning()) { - Lego()->StopTimer(); + if (Lego()->IsPaused()) { + Lego()->Resume(); } else { - Lego()->StartTimer(); + Lego()->Pause(); } break; case VK_ESCAPE: { diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index fecff1de..d19a854a 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -225,19 +225,21 @@ void LegoWorld::Destroy(MxBool p_fromDestructor) // FUNCTION: LEGO1 0x1001f5e0 MxLong LegoWorld::Notify(MxParam& p_param) { - MxLong ret = 0; + MxLong result = 0; + switch (((MxNotificationParam&) p_param).GetNotification()) { case c_notificationEndAction: { MxPresenter* presenter = (MxPresenter*) ((MxEndActionNotificationParam&) p_param).GetSender(); Remove(presenter); - ret = 1; + result = 1; break; } case c_notificationNewPresenter: TickleManager()->RegisterClient(this, 100); break; } - return ret; + + return result; } // FUNCTION: LEGO1 0x1001f630 @@ -477,6 +479,7 @@ void LegoWorld::Add(MxCore* p_object) } // FUNCTION: LEGO1 0x10020f10 +// FUNCTION: BETA10 0x100dad2a void LegoWorld::Remove(MxCore* p_object) { if (p_object) { diff --git a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp index 1cd0aba3..1d6d38d6 100644 --- a/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp +++ b/LEGO1/lego/legoomni/src/input/legoinputmanager.cpp @@ -309,7 +309,7 @@ MxBool LegoInputManager::ProcessOneEvent(LegoEventNotificationParam& p_param) MxBool processRoi; if (p_param.GetType() == c_notificationKeyPress) { - if (!Lego()->IsTimerRunning() || p_param.GetKey() == VK_PAUSE) { + if (!Lego()->IsPaused() || p_param.GetKey() == VK_PAUSE) { if (p_param.GetKey() == VK_SHIFT) { if (m_unk0x195) { m_unk0x80 = FALSE; @@ -335,7 +335,7 @@ MxBool LegoInputManager::ProcessOneEvent(LegoEventNotificationParam& p_param) } } else { - if (!Lego()->IsTimerRunning()) { + if (!Lego()->IsPaused()) { processRoi = TRUE; if (m_unk0x335 != 0) { diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index ba6d7d84..e6c2cdc1 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -579,15 +579,15 @@ MxLong LegoOmni::Notify(MxParam& p_param) } // FUNCTION: LEGO1 0x1005b640 -void LegoOmni::StartTimer() +void LegoOmni::Pause() { - MxOmni::StartTimer(); + MxOmni::Pause(); SetAppCursor(e_cursorNo); } // FUNCTION: LEGO1 0x1005b650 -void LegoOmni::StopTimer() +void LegoOmni::Resume() { - MxOmni::StopTimer(); + MxOmni::Resume(); SetAppCursor(e_cursorArrow); } diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index 418a74c5..5140250e 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -1,5 +1,7 @@ #include "carrace.h" +#include "mxactionnotificationparam.h" + DECOMP_SIZE_ASSERT(CarRace, 0x154) // FUNCTION: LEGO1 0x10016a90 @@ -23,28 +25,28 @@ void CarRace::ReadyWorld() } // STUB: LEGO1 0x10016f60 -undefined4 CarRace::VTable0x74(undefined4) +MxLong CarRace::HandleEndAction(MxEndActionNotificationParam&) { // TODO return 0; } // STUB: LEGO1 0x100170e0 -undefined4 CarRace::VTable0x70(undefined4) +MxLong CarRace::HandleType19Notification(MxType19NotificationParam&) { // TODO return 0; } // STUB: LEGO1 0x10017650 -undefined4 CarRace::VTable0x6c(undefined4) +MxLong CarRace::HandleClick(LegoEventNotificationParam&) { // TODO return 0; } // STUB: LEGO1 0x100177e0 -undefined4 CarRace::VTable0x78(undefined4) +MxLong CarRace::HandleType0Notification(MxNotificationParam&) { // TODO return 0; diff --git a/LEGO1/lego/legoomni/src/race/jetskirace.cpp b/LEGO1/lego/legoomni/src/race/jetskirace.cpp index 37fc198d..eeaed23a 100644 --- a/LEGO1/lego/legoomni/src/race/jetskirace.cpp +++ b/LEGO1/lego/legoomni/src/race/jetskirace.cpp @@ -14,19 +14,19 @@ void JetskiRace::ReadyWorld() } // STUB: LEGO1 0x10016520 -undefined4 JetskiRace::VTable0x74(undefined4) +MxLong JetskiRace::HandleEndAction(MxEndActionNotificationParam&) { return 0; } // STUB: LEGO1 0x100165a0 -undefined4 JetskiRace::VTable0x6c(undefined4) +MxLong JetskiRace::HandleClick(LegoEventNotificationParam&) { return 0; } // STUB: LEGO1 0x100166a0 -undefined4 JetskiRace::VTable0x70(undefined4) +MxLong JetskiRace::HandleType19Notification(MxType19NotificationParam&) { return 0; } diff --git a/LEGO1/lego/legoomni/src/race/legorace.cpp b/LEGO1/lego/legoomni/src/race/legorace.cpp index a2204345..7430f922 100644 --- a/LEGO1/lego/legoomni/src/race/legorace.cpp +++ b/LEGO1/lego/legoomni/src/race/legorace.cpp @@ -1,60 +1,48 @@ #include "legorace.h" +#include "isle.h" +#include "legocontrolmanager.h" +#include "legonavcontroller.h" +#include "misc.h" #include "mxmisc.h" #include "mxnotificationmanager.h" DECOMP_SIZE_ASSERT(LegoRace, 0x144) DECOMP_SIZE_ASSERT(RaceState::Entry, 0x06) -// TODO: Must be 0x2c but current structure is incorrect -// DECOMP_SIZE_ASSERT(RaceState, 0x2c) +DECOMP_SIZE_ASSERT(RaceState, 0x2c) -// FUNCTION: LEGO1 0x1000dab0 -undefined4 LegoRace::VTable0x78(undefined4) -{ - return 0; -} - -// STUB: LEGO1 0x1000dac0 -void LegoRace::VTable0x7c(undefined4, undefined4) -{ - // TODO -} - -// FUNCTION: LEGO1 0x1000dae0 -MxBool LegoRace::VTable0x5c() -{ - return TRUE; -} +// Defined in legopathstruct.cpp +extern MxBool g_unk0x100f119c; // FUNCTION: LEGO1 0x10015aa0 LegoRace::LegoRace() { - this->m_unk0xf8 = 0; - this->m_unk0xfc = 0; - this->m_unk0x100 = 0; - this->m_unk0x104 = 0; - this->m_unk0x108 = 0; - this->m_unk0x10c = 0; - this->m_unk0x140 = 0; - this->m_unk0x110 = 0; - this->m_unk0x114 = 0; - this->m_unk0x118 = 0; - this->m_unk0x128 = 0; - this->m_unk0x12c = 0; - this->m_unk0x120 = 0; - this->m_unk0x124 = 0; - this->m_unk0x11c = 0; + m_unk0xf8 = 0; + m_unk0xfc = 0; + m_unk0x100 = 0; + m_unk0x104 = 0; + m_unk0x108 = 0; + m_unk0x10c = 0; + m_unk0x140 = 0; + m_unk0x110 = 0; + m_unk0x114 = 0; + m_unk0x118 = 0; + m_unk0x128 = 0; + m_unk0x12c = 0; + m_pathActor = 0; + m_act1State = NULL; + m_destLocation = LegoGameState::e_undefined; NotificationManager()->Register(this); } // FUNCTION: LEGO1 0x10015b70 -undefined4 LegoRace::VTable0x70(undefined4) +MxLong LegoRace::HandleType19Notification(MxType19NotificationParam&) { return 0; } // FUNCTION: LEGO1 0x10015b80 -undefined4 LegoRace::VTable0x74(undefined4) +MxLong LegoRace::HandleEndAction(MxEndActionNotificationParam&) { return 0; } @@ -65,30 +53,79 @@ MxBool LegoRace::Escape() return FALSE; } -// STUB: LEGO1 0x10015ce0 +// FUNCTION: LEGO1 0x10015ce0 MxResult LegoRace::Create(MxDSAction& p_dsAction) { - // TODO - return SUCCESS; + MxResult result = LegoWorld::Create(p_dsAction); + + if (result == SUCCESS) { + m_act1State = (Act1State*) GameState()->GetState("Act1State"); + ControlManager()->Register(this); + m_pathActor = CurrentActor(); + m_pathActor->SetWorldSpeed(0); + SetCurrentActor(NULL); + } + + return result; } -// STUB: LEGO1 0x10015d40 +// FUNCTION: LEGO1 0x10015d40 LegoRace::~LegoRace() { - // TODO + g_unk0x100f119c = FALSE; + if (m_pathActor) { + SetCurrentActor(m_pathActor); + NavController()->ResetMaxLinearVel(m_pathActor->GetMaxLinearVel()); + m_pathActor = NULL; + } + + ControlManager()->Unregister(this); + NotificationManager()->Unregister(this); } -// STUB: LEGO1 0x10015e00 +// FUNCTION: LEGO1 0x10015e00 +// FUNCTION: BETA10 0x100c7b3d MxLong LegoRace::Notify(MxParam& p_param) { - // TODO - return 0; + LegoWorld::Notify(p_param); + + MxLong result = 0; + if (m_worldStarted) { + switch (((MxNotificationParam&) p_param).GetNotification()) { + case c_notificationType0: + HandleType0Notification((MxNotificationParam&) p_param); + break; + case c_notificationEndAction: + result = HandleEndAction((MxEndActionNotificationParam&) p_param); + break; + case c_notificationClick: + result = HandleClick((LegoEventNotificationParam&) p_param); + break; + case c_notificationType19: + result = HandleType19Notification((MxType19NotificationParam&) p_param); + break; + case c_notificationTransitioned: + GameState()->SwitchArea(m_destLocation); + break; + } + } + + return result; } -// STUB: LEGO1 0x10015ed0 +// FUNCTION: LEGO1 0x10015ed0 +// FUNCTION: BETA10 0x100c7c3f void LegoRace::Enable(MxBool p_enable) { - // TODO + if (GetUnknown0xd0Empty() != p_enable && !p_enable) { + Remove(CurrentActor()); + + MxU8 oldActorId = GameState()->GetActorId(); + GameState()->RemoveActor(); + GameState()->SetActorId(oldActorId); + } + + LegoWorld::Enable(p_enable); } // STUB: LEGO1 0x10015f30 diff --git a/LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp b/LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp index 8d77a1eb..5d37e829 100644 --- a/LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoflctexturepresenter.cpp @@ -1,5 +1,9 @@ #include "legoflctexturepresenter.h" +#include "misc.h" +#include "misc/legocontainer.h" +#include "mxdsaction.h" + DECOMP_SIZE_ASSERT(LegoFlcTexturePresenter, 0x70) // FUNCTION: LEGO1 0x1005de80 @@ -11,24 +15,56 @@ LegoFlcTexturePresenter::LegoFlcTexturePresenter() // FUNCTION: LEGO1 0x1005df70 void LegoFlcTexturePresenter::Init() { - this->m_unk0x68 = 0; - this->m_unk0x6c = 0; + m_rectCount = 0; + m_texture = NULL; } -// STUB: LEGO1 0x1005df80 +// FUNCTION: LEGO1 0x1005df80 +// FUNCTION: BETA10 0x100833a7 void LegoFlcTexturePresenter::StartingTickle() { - // TODO + MxU16 extraLength; + char* pp; + char extraCopy[128]; + m_action->GetExtra(extraLength, pp); + + if (pp != NULL) { + strcpy(extraCopy, pp); + strcat(extraCopy, ".gif"); + m_texture = TextureContainer()->Get(extraCopy); + } + + MxFlcPresenter::StartingTickle(); } -// STUB: LEGO1 0x1005e0c0 +// FUNCTION: LEGO1 0x1005e0c0 +// FUNCTION: BETA10 0x100834ce void LegoFlcTexturePresenter::LoadFrame(MxStreamChunk* p_chunk) { - // TODO + MxU8* data = p_chunk->GetData(); + + m_rectCount = *(MxS32*) data; + data += sizeof(MxS32); + + MxRect32* rects = (MxRect32*) data; + data += m_rectCount * sizeof(MxRect32); + + MxBool decodedColorMap; + DecodeFLCFrame( + &m_frameBitmap->GetBitmapInfo()->m_bmiHeader, + m_frameBitmap->GetImage(), + m_flcHeader, + (FLIC_FRAME*) data, + &decodedColorMap + ); } -// STUB: LEGO1 0x1005e100 +// FUNCTION: LEGO1 0x1005e100 +// FUNCTION: BETA10 0x10083562 void LegoFlcTexturePresenter::PutFrame() { - // TODO + if (m_texture != NULL && m_rectCount != 0) { + m_texture->FUN_10066010(m_frameBitmap->GetImage()); + m_rectCount = 0; + } } diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index de524cb2..b96d5814 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -1201,7 +1201,7 @@ MxBool Isle::Escape() break; case 10: if (CurrentActor() != NULL && !CurrentActor()->IsA("Ambulance")) { - m_ambulance->FUN_10037240(); + m_ambulance->StopActions(); m_ambulance->FUN_10037250(); } break; @@ -1242,7 +1242,7 @@ void Isle::FUN_10033350() { if (m_act1state->m_unk0x018 == 10) { if (CurrentActor() != NULL && !CurrentActor()->IsA("Ambulance")) { - m_ambulance->FUN_10037240(); + m_ambulance->StopActions(); m_ambulance->FUN_10037250(); } } diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index eb44f2b0..e09eb88d 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -1,5 +1,12 @@ #include "legoact2.h" +#include "legoanimationmanager.h" +#include "legoinputmanager.h" +#include "misc.h" +#include "mxmisc.h" +#include "mxnotificationmanager.h" +#include "mxticklemanager.h" + DECOMP_SIZE_ASSERT(LegoAct2, 0x1154) DECOMP_SIZE_ASSERT(LegoAct2State, 0x10) @@ -9,6 +16,23 @@ MxBool LegoAct2::VTable0x5c() return TRUE; } +// FUNCTION: LEGO1 0x1004fe40 +// FUNCTION: BETA10 0x1003a6f0 +LegoAct2::~LegoAct2() +{ + if (m_unk0x10c2) { + TickleManager()->UnregisterClient(this); + } + + FUN_10051900(); + InputManager()->UnRegister(this); + if (CurrentActor()) { + Remove(CurrentActor()); + } + + NotificationManager()->Unregister(this); +} + // STUB: LEGO1 0x1004ff20 MxResult LegoAct2::Create(MxDSAction& p_dsAction) { @@ -42,6 +66,20 @@ void LegoAct2::Enable(MxBool p_enable) // TODO } +// FUNCTION: LEGO1 0x10051900 +// FUNCTION: BETA10 0x1003bed1 +void LegoAct2::FUN_10051900() +{ + if (AnimationManager()) { + AnimationManager()->Suspend(); + AnimationManager()->Resume(); + AnimationManager()->FUN_10060540(FALSE); + AnimationManager()->FUN_100604d0(FALSE); + AnimationManager()->EnableCamAnims(FALSE); + AnimationManager()->FUN_1005f6d0(FALSE); + } +} + // STUB: LEGO1 0x100519c0 void LegoAct2::VTable0x60() { diff --git a/LEGO1/omni/include/mxomni.h b/LEGO1/omni/include/mxomni.h index 1b8b4573..c3839c1e 100644 --- a/LEGO1/omni/include/mxomni.h +++ b/LEGO1/omni/include/mxomni.h @@ -41,21 +41,21 @@ class MxOmni : public MxCore { MxOmni(); ~MxOmni() override; - MxLong Notify(MxParam& p_param) override; // vtable+04 - virtual void Init(); // vtable+14 - virtual MxResult Create(MxOmniCreateParam& p_param); // vtable+18 - virtual void Destroy(); // vtable+1c - virtual MxResult Start(MxDSAction* p_dsAction); // vtable+20 - virtual void DeleteObject(MxDSAction& p_dsAction); // vtable+24 - virtual MxBool DoesEntityExist(MxDSAction& p_dsAction); // vtable+28 - virtual MxResult CreatePresenter(MxStreamController* p_controller, MxDSAction& p_action); // vtable+2c - virtual MxEntity* AddToWorld(const char*, MxS32, MxPresenter*); // vtable+30 - virtual void NotifyCurrentEntity(const MxNotificationParam& p_param); // vtable+34 - virtual void StartTimer(); // vtable+38 - virtual void StopTimer(); // vtable+3c + MxLong Notify(MxParam& p_param) override; // vtable+0x04 + virtual void Init(); // vtable+0x14 + virtual MxResult Create(MxOmniCreateParam& p_param); // vtable+0x18 + virtual void Destroy(); // vtable+0x1c + virtual MxResult Start(MxDSAction* p_dsAction); // vtable+0x20 + virtual void DeleteObject(MxDSAction& p_dsAction); // vtable+0x24 + virtual MxBool DoesEntityExist(MxDSAction& p_dsAction); // vtable+0x28 + virtual MxResult CreatePresenter(MxStreamController* p_controller, MxDSAction& p_action); // vtable+0x2c + virtual MxEntity* AddToWorld(const char*, MxS32, MxPresenter*); // vtable+0x30 + virtual void NotifyCurrentEntity(const MxNotificationParam& p_param); // vtable+0x34 + virtual void Pause(); // vtable+0x38 + virtual void Resume(); // vtable+0x3c // FUNCTION: LEGO1 0x10058a90 - virtual MxBool IsTimerRunning() { return m_timerRunning; } // vtable+40 + virtual MxBool IsPaused() { return m_paused; } // vtable+0x40 static void SetInstance(MxOmni* p_instance); static MxBool ActionSourceEquals(MxDSAction* p_action, const char* p_name); @@ -117,7 +117,7 @@ class MxOmni : public MxCore { MxStreamer* m_streamer; // 0x40 MxAtomSet* m_atomSet; // 0x44 MxCriticalSection m_criticalSection; // 0x48 - MxBool m_timerRunning; // 0x64 + MxBool m_paused; // 0x64 }; #endif // MXOMNI_H diff --git a/LEGO1/omni/src/main/mxomni.cpp b/LEGO1/omni/src/main/mxomni.cpp index e2ee9c10..cdfe400d 100644 --- a/LEGO1/omni/src/main/mxomni.cpp +++ b/LEGO1/omni/src/main/mxomni.cpp @@ -68,7 +68,7 @@ void MxOmni::Init() m_timer = NULL; m_streamer = NULL; m_atomSet = NULL; - m_timerRunning = FALSE; + m_paused = FALSE; } // FUNCTION: LEGO1 0x100af0b0 @@ -409,21 +409,21 @@ MxBool MxOmni::DoesEntityExist(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x100b09d0 -void MxOmni::StartTimer() +void MxOmni::Pause() { - if (m_timerRunning == FALSE && m_timer != NULL && m_soundManager != NULL) { + if (m_paused == FALSE && m_timer != NULL && m_soundManager != NULL) { m_timer->Start(); m_soundManager->Pause(); - m_timerRunning = TRUE; + m_paused = TRUE; } } // FUNCTION: LEGO1 0x100b0a00 -void MxOmni::StopTimer() +void MxOmni::Resume() { - if (m_timerRunning != FALSE && m_timer != NULL && m_soundManager != NULL) { + if (m_paused != FALSE && m_timer != NULL && m_soundManager != NULL) { m_timer->Stop(); m_soundManager->Resume(); - m_timerRunning = FALSE; + m_paused = FALSE; } }