From b9a1da6a7a229347af744349bd2a8c503908fe36 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Mon, 25 Nov 2024 14:08:57 -0700 Subject: [PATCH 01/13] Implement/match Act2Brick (#1169) * Implement/match Act2Brick * Rename functions * Naming --- LEGO1/lego/legoomni/include/act2brick.h | 18 ++-- .../legoomni/include/legocachesoundmanager.h | 1 + LEGO1/lego/legoomni/include/legocachsound.h | 2 +- .../src/audio/legocachesoundmanager.cpp | 44 ++++++++- .../lego/legoomni/src/audio/legocachsound.cpp | 2 +- LEGO1/lego/legoomni/src/entity/act2brick.cpp | 93 ++++++++++++++++--- LEGO1/lego/legoomni/src/entity/legoactor.cpp | 2 +- 7 files changed, 132 insertions(+), 30 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act2brick.h b/LEGO1/lego/legoomni/include/act2brick.h index 332a3cc6..1ff4529e 100644 --- a/LEGO1/lego/legoomni/include/act2brick.h +++ b/LEGO1/lego/legoomni/include/act2brick.h @@ -26,18 +26,22 @@ class Act2Brick : public LegoPathActor { return !strcmp(p_name, Act2Brick::ClassName()) || LegoEntity::IsA(p_name); } - MxResult VTable0x94(LegoPathActor* p_actor, MxBool p_bool) override; // vtable+0x94 + MxResult VTable0x94(LegoPathActor* p_actor, MxBool) override; // vtable+0x94 // SYNTHETIC: LEGO1 0x1007a450 // Act2Brick::`scalar deleting destructor' + void StopSound(); + private: - undefined4 m_unk0x154; // 0x154 - undefined m_unk0x158[0x0c]; // 0x158 - undefined4 m_unk0x164; // 0x164 - Mx3DPointFloat m_unk0x168; // 0x168 - Mx3DPointFloat m_unk0x17c; // 0x17c - undefined4 m_unk0x190; // 0x190 + static MxLong g_lastHitActorTime; + + LegoCacheSound* m_whistleSound; // 0x154 + undefined m_unk0x158[0x0c]; // 0x158 + undefined4 m_unk0x164; // 0x164 + Mx3DPointFloat m_unk0x168; // 0x168 + Mx3DPointFloat m_unk0x17c; // 0x17c + MxS32 m_unk0x190; // 0x190 }; #endif // ACT2BRICK_H diff --git a/LEGO1/lego/legoomni/include/legocachesoundmanager.h b/LEGO1/lego/legoomni/include/legocachesoundmanager.h index 51133c7e..dd9df741 100644 --- a/LEGO1/lego/legoomni/include/legocachesoundmanager.h +++ b/LEGO1/lego/legoomni/include/legocachesoundmanager.h @@ -58,6 +58,7 @@ class LegoCacheSoundManager { LegoCacheSound* ManageSoundEntry(LegoCacheSound* p_sound); LegoCacheSound* Play(const char* p_key, const char* p_name, MxBool p_looping); LegoCacheSound* Play(LegoCacheSound* p_sound, const char* p_name, MxBool p_looping); + void Stop(LegoCacheSound*& p_sound); void Destroy(LegoCacheSound*& p_sound); private: diff --git a/LEGO1/lego/legoomni/include/legocachsound.h b/LEGO1/lego/legoomni/include/legocachsound.h index 593be9d2..196bfb55 100644 --- a/LEGO1/lego/legoomni/include/legocachsound.h +++ b/LEGO1/lego/legoomni/include/legocachsound.h @@ -41,7 +41,7 @@ class LegoCacheSound : public MxCore { LegoCacheSound* Clone(); MxResult Play(const char* p_name, MxBool p_looping); - void FUN_10006b80(); + void Stop(); void FUN_10006be0(); void SetDistance(MxS32 p_min, MxS32 p_max); void Mute(MxBool p_mute); diff --git a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp index c18d5dcb..6338b281 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp @@ -14,14 +14,14 @@ LegoCacheSoundManager::~LegoCacheSoundManager() while (!m_set.empty()) { sound = (*m_set.begin()).GetSound(); m_set.erase(m_set.begin()); - sound->FUN_10006b80(); + sound->Stop(); delete sound; } while (!m_list.empty()) { sound = (*m_list.begin()).GetSound(); m_list.erase(m_list.begin()); - sound->FUN_10006b80(); + sound->Stop(); // DECOMP: delete should not be inlined here delete sound; } @@ -51,7 +51,7 @@ MxResult LegoCacheSoundManager::Tickle() listIter++; } else { - sound->FUN_10006b80(); + sound->Stop(); m_list.erase(listIter++); delete sound; } @@ -132,6 +132,40 @@ LegoCacheSound* LegoCacheSoundManager::Play(LegoCacheSound* p_sound, const char* return NULL; } +// FUNCTION: LEGO1 0x1003db80 +// FUNCTION: BETA10 0x100656a7 +void LegoCacheSoundManager::Stop(LegoCacheSound*& p_sound) +{ +#ifdef COMPAT_MODE + Set100d6b4c::iterator setIter; + for (setIter = m_set.begin(); setIter != m_set.end(); setIter++) { +#else + for (Set100d6b4c::iterator setIter = m_set.begin(); setIter != m_set.end(); setIter++) { +#endif + if ((*setIter).GetSound() == p_sound) { + p_sound->Stop(); + return; + } + } + +#ifdef COMPAT_MODE + List100d6b4c::iterator listIter; + for (listIter = m_list.begin();; listIter++) { +#else + for (List100d6b4c::iterator listIter = m_list.begin();; listIter++) { +#endif + if (listIter == m_list.end()) { + return; + } + + LegoCacheSound* sound = (*listIter).GetSound(); + if (sound == p_sound) { + p_sound->Stop(); + return; + } + } +} + // FUNCTION: LEGO1 0x1003dc40 void LegoCacheSoundManager::Destroy(LegoCacheSound*& p_sound) { @@ -142,7 +176,7 @@ void LegoCacheSoundManager::Destroy(LegoCacheSound*& p_sound) for (Set100d6b4c::iterator setIter = m_set.begin(); setIter != m_set.end(); setIter++) { #endif if ((*setIter).GetSound() == p_sound) { - p_sound->FUN_10006b80(); + p_sound->Stop(); delete p_sound; m_set.erase(setIter); @@ -162,7 +196,7 @@ void LegoCacheSoundManager::Destroy(LegoCacheSound*& p_sound) LegoCacheSound* sound = (*listIter).GetSound(); if (sound == p_sound) { - p_sound->FUN_10006b80(); + p_sound->Stop(); delete sound; m_list.erase(listIter); diff --git a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp index 7665e5d7..47e9b98c 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachsound.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachsound.cpp @@ -181,7 +181,7 @@ MxResult LegoCacheSound::Play(const char* p_name, MxBool p_looping) } // FUNCTION: LEGO1 0x10006b80 -void LegoCacheSound::FUN_10006b80() +void LegoCacheSound::Stop() { DWORD dwStatus; m_dsBuffer->GetStatus(&dwStatus); diff --git a/LEGO1/lego/legoomni/src/entity/act2brick.cpp b/LEGO1/lego/legoomni/src/entity/act2brick.cpp index fa1408aa..a5811f26 100644 --- a/LEGO1/lego/legoomni/src/entity/act2brick.cpp +++ b/LEGO1/lego/legoomni/src/entity/act2brick.cpp @@ -1,38 +1,101 @@ #include "act2brick.h" +#include "legocachesoundmanager.h" +#include "legosoundmanager.h" +#include "legoworld.h" +#include "misc.h" +#include "mxmisc.h" +#include "mxnotificationmanager.h" +#include "mxnotificationparam.h" +#include "mxticklemanager.h" +#include "mxtimer.h" +#include "roi/legoroi.h" + +#include + DECOMP_SIZE_ASSERT(Act2Brick, 0x194) -// STUB: LEGO1 0x1007a2b0 +// GLOBAL: LEGO1 0x100f7a60 +MxLong Act2Brick::g_lastHitActorTime = 0; + +// FUNCTION: LEGO1 0x1007a2b0 +// FUNCTION: BETA10 0x10012a30 Act2Brick::Act2Brick() { - // TODO + m_whistleSound = NULL; + m_unk0x164 = 0; } -// STUB: LEGO1 0x1007a470 +// FUNCTION: LEGO1 0x1007a470 Act2Brick::~Act2Brick() { - // TODO + TickleManager()->UnregisterClient(this); } -// STUB: LEGO1 0x1007a750 -MxResult Act2Brick::VTable0x94(LegoPathActor* p_actor, MxBool p_bool) +// FUNCTION: LEGO1 0x1007a750 +MxResult Act2Brick::VTable0x94(LegoPathActor* p_actor, MxBool) { - // TODO - return 0; -} + MxLong time = Timer()->GetTime(); + MxLong diff = time - g_lastHitActorTime; -// STUB: LEGO1 0x1007a7f0 -MxResult Act2Brick::Tickle() -{ - // TODO + if (strcmp(p_actor->GetROI()->GetName(), "pepper")) { + return SUCCESS; + } + + g_lastHitActorTime = time; + if (diff > 1000) { + SoundManager()->GetCacheSoundManager()->Play("hitactor", NULL, FALSE); + } return SUCCESS; } -// STUB: LEGO1 0x1007a8c0 +// FUNCTION: LEGO1 0x1007a7f0 +// FUNCTION: BETA10 0x10012d46 +MxResult Act2Brick::Tickle() +{ + MxMatrix local2world(m_roi->GetLocal2World()); + m_unk0x190++; + + if (m_unk0x190 >= 8) { + local2world.SetTranslation(m_unk0x17c[0], m_unk0x17c[1], m_unk0x17c[2]); + m_unk0x164 = 3; + TickleManager()->UnregisterClient(this); + } + else { + VPV3(local2world[3], local2world[3], m_unk0x168); + } + + m_roi->FUN_100a58f0(local2world); + m_roi->VTable0x14(); + return SUCCESS; +} + +// FUNCTION: LEGO1 0x1007a8c0 +// FUNCTION: BETA10 0x10012ec4 MxLong Act2Brick::Notify(MxParam& p_param) { - // TODO + if (((MxNotificationParam&) p_param).GetNotification() == c_notificationClick && m_roi->GetVisibility()) { + m_roi->SetVisibility(FALSE); + + if (m_whistleSound != NULL) { + StopSound(); + } + + MxNotificationParam param(c_notificationType22, this); + NotificationManager()->Send(CurrentWorld(), param); + return 1; + } return 0; } + +// FUNCTION: LEGO1 0x1007a9d0 +// FUNCTION: BETA10 0x1001300f +void Act2Brick::StopSound() +{ + if (m_whistleSound != NULL) { + SoundManager()->GetCacheSoundManager()->Stop(m_whistleSound); + m_whistleSound = NULL; + } +} diff --git a/LEGO1/lego/legoomni/src/entity/legoactor.cpp b/LEGO1/lego/legoomni/src/entity/legoactor.cpp index 927ad4a4..93f7c94b 100644 --- a/LEGO1/lego/legoomni/src/entity/legoactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoactor.cpp @@ -26,7 +26,7 @@ LegoActor::LegoActor() LegoActor::~LegoActor() { if (m_sound) { - m_sound->FUN_10006b80(); + m_sound->Stop(); } } From 83b85f26a73589f1cac400cd2d2d0becadd4b6b5 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Mon, 25 Nov 2024 23:24:46 +0100 Subject: [PATCH 02/13] Implement `LegoAct2::Tickle()` and others (#1168) * Implement `LegoAct2::Tickle()` and others * Fix decomplint errors * Minor cleanup * Address review comments --------- Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/act2actor.h | 2 + LEGO1/lego/legoomni/include/legoact2.h | 13 +- .../legoomni/include/legoanimationmanager.h | 3 + LEGO1/lego/legoomni/include/legopathactor.h | 3 +- LEGO1/lego/legoomni/src/actors/act2actor.cpp | 7 + LEGO1/lego/legoomni/src/actors/helicopter.cpp | 4 +- .../src/common/legoanimationmanager.cpp | 25 ++- LEGO1/lego/legoomni/src/common/misc.cpp | 2 + LEGO1/lego/legoomni/src/main/legomain.cpp | 1 + .../legoomni/src/paths/legoextraactor.cpp | 2 +- .../lego/legoomni/src/paths/legopathactor.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 167 +++++++++++++++++- LEGO1/lego/sources/roi/legoroi.h | 2 + reccmp-project.yml | 2 + 14 files changed, 221 insertions(+), 14 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act2actor.h b/LEGO1/lego/legoomni/include/act2actor.h index 27a5fe22..b2446936 100644 --- a/LEGO1/lego/legoomni/include/act2actor.h +++ b/LEGO1/lego/legoomni/include/act2actor.h @@ -18,6 +18,8 @@ class Act2Actor : public LegoAnimActor { MxResult VTable0x9c() override; // vtable+0x9c MxS32 VTable0xa0() override; // vtable+0xa0 + void FUN_10019520(); + // SYNTHETIC: LEGO1 0x1001a0a0 // Act2Actor::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 7482f0ce..b1db65ea 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -66,6 +66,15 @@ class LegoAct2 : public LegoWorld { void SetUnknown0x1138(Act2Actor* p_unk0x1138) { m_unk0x1138 = p_unk0x1138; } void SetUnknown0x1150(undefined4 p_unk0x1150) { m_unk0x1150 = p_unk0x1150; } + undefined4 FUN_10052560( + undefined4 p_param1, + MxBool p_param2, + MxBool p_param3, + Mx3DPointFloat* p_param4, + Mx3DPointFloat* p_param5, + Mx3DPointFloat* p_param6 + ); + // SYNTHETIC: LEGO1 0x1004fe20 // LegoAct2::`scalar deleting destructor' @@ -79,9 +88,9 @@ class LegoAct2 : public LegoWorld { undefined4 m_unk0x10c4; // 0x10c4 undefined4 m_unk0x10c8; // 0x10c8 LegoAct2State* m_gameState; // 0x10cc - undefined4 m_unk0x10d0; // 0x10d0 + MxS32 m_unk0x10d0; // 0x10d0 char* m_unk0x10d4; // 0x10d4 - undefined4 m_unk0x10d8; // 0x10d8 + LegoROI* m_unk0x10d8; // 0x10d8 MxMatrix m_unk0x10dc; // 0x10dc undefined4 m_unk0x1124; // 0x1124 undefined4 m_unk0x1128; // 0x1128 diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index 64727b1e..3a05cc22 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -155,7 +155,9 @@ class LegoAnimationManager : public MxCore { MxBool FindVehicle(const char* p_name, MxU32& p_index); MxResult ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info); MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info); + void FUN_10060480(LegoChar* p_param1[], undefined4 p_param2); void FUN_100604d0(MxBool p_unk0x08); + void FUN_100604f0(MxS32* p_param1, undefined4 p_param2); void FUN_10060540(MxBool p_unk0x29); void FUN_10060570(MxBool p_unk0x1a); MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity); @@ -181,6 +183,7 @@ class LegoAnimationManager : public MxCore { MxResult FUN_10064670(Vector3* p_position); MxResult FUN_10064740(Vector3* p_position); MxResult FUN_10064880(const char* p_name, MxS32 p_unk0x0c, MxS32 p_unk0x10); + undefined FUN_10064ee0(MxU32 p_param); static void configureLegoAnimationManager(MxS32 p_legoAnimationManagerConfig); diff --git a/LEGO1/lego/legoomni/include/legopathactor.h b/LEGO1/lego/legoomni/include/legopathactor.h index d82e771c..896d6ccd 100644 --- a/LEGO1/lego/legoomni/include/legopathactor.h +++ b/LEGO1/lego/legoomni/include/legopathactor.h @@ -22,7 +22,8 @@ extern const char* g_strHIT_WALL_SOUND; class LegoPathActor : public LegoActor { public: enum { - c_bit3 = 0x04 + c_bit3 = 0x04, + c_bit9 = 0x100 }; LegoPathActor(); diff --git a/LEGO1/lego/legoomni/src/actors/act2actor.cpp b/LEGO1/lego/legoomni/src/actors/act2actor.cpp index c978c3ed..6c10caae 100644 --- a/LEGO1/lego/legoomni/src/actors/act2actor.cpp +++ b/LEGO1/lego/legoomni/src/actors/act2actor.cpp @@ -67,6 +67,13 @@ void Act2Actor::SetWorldSpeed(MxFloat p_worldSpeed) m_unk0x44 = 0; } +// STUB: LEGO1 0x10019520 +// STUB: BETA10 0x1000d4d6 +void Act2Actor::FUN_10019520() +{ + // TODO +} + // STUB: LEGO1 0x100195a0 MxS32 Act2Actor::VTable0xa0() { diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 3aff5575..20088cf3 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -133,7 +133,7 @@ MxLong Helicopter::HandleClick() ((Isle*) CurrentWorld())->SetDestLocation(LegoGameState::e_copter); FUN_10015820(TRUE, 0); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, TRUE); - SetState(4); + SetState(LegoPathActor::c_bit3); PlayMusic(JukeboxScript::c_Jail_Music); break; case LegoGameState::e_act2: @@ -206,7 +206,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param) m_state->SetUnknown8(3); m_world->RemoveActor(this); InvokeAction(Extra::ActionType::e_start, script, IsleScript::c_HelicopterLand_Anim, NULL); - SetState(4); + SetState(LegoPathActor::c_bit3); } ret = 1; break; diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 9d34a28b..3ca3b1f7 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -878,6 +878,13 @@ void LegoAnimationManager::DeleteAnimations() m_suspended = suspended; } +// STUB: LEGO1 0x10060480 +// STUB: BETA10 0x100412a9 +void LegoAnimationManager::FUN_10060480(LegoChar* p_param1[], undefined4 p_param2) +{ + // TODO +} + // FUNCTION: LEGO1 0x100604d0 // FUNCTION: BETA10 0x10041335 void LegoAnimationManager::FUN_100604d0(MxBool p_unk0x08) @@ -887,6 +894,13 @@ void LegoAnimationManager::FUN_100604d0(MxBool p_unk0x08) } } +// STUB: LEGO1 0x100604f0 +// STUB: BETA10 0x1004137b +void LegoAnimationManager::FUN_100604f0(MxS32* p_param1, undefined4 p_param2) +{ + // TODO +} + // FUNCTION: LEGO1 0x10060540 // FUNCTION: BETA10 0x1004140f void LegoAnimationManager::FUN_10060540(MxBool p_unk0x29) @@ -1001,7 +1015,7 @@ MxResult LegoAnimationManager::FUN_100605e0( LegoPathActor* actor = UserActor(); if (actor != NULL) { - actor->SetState(4); + actor->SetState(LegoPathActor::c_bit3); actor->SetWorldSpeed(0.0f); } } @@ -2762,7 +2776,7 @@ void LegoAnimationManager::FUN_100648f0(LegoTranInfo* p_tranInfo, MxLong p_unk0x LegoPathActor* actor = UserActor(); if (actor != NULL) { - actor->SetState(4); + actor->SetState(LegoPathActor::c_bit3); actor->SetWorldSpeed(0.0f); } @@ -2823,6 +2837,13 @@ void LegoAnimationManager::FUN_10064b50(MxLong p_time) } } +// STUB: LEGO1 0x10064ee0 +undefined LegoAnimationManager::FUN_10064ee0(MxU32 p_param) +{ + // TODO + return FALSE; +} + // FUNCTION: LEGO1 0x10064ff0 AnimState::AnimState() { diff --git a/LEGO1/lego/legoomni/src/common/misc.cpp b/LEGO1/lego/legoomni/src/common/misc.cpp index a0ff5d0a..654a4b3d 100644 --- a/LEGO1/lego/legoomni/src/common/misc.cpp +++ b/LEGO1/lego/legoomni/src/common/misc.cpp @@ -143,8 +143,10 @@ void FUN_10015820(MxBool p_disable, MxU16 p_flags) } // FUNCTION: LEGO1 0x10015840 +// FUNCTION: BETA10 0x100e4ce4 LegoROI* FindROI(const char* p_name) { + assert(LegoOmni::GetInstance()); return LegoOmni::GetInstance()->FindROI(p_name); } diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index 2d39165d..4641d548 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -405,6 +405,7 @@ void LegoOmni::DeleteObject(MxDSAction& p_dsAction) } // FUNCTION: LEGO1 0x1005b270 +// FUNCTION: BETA10 0x1008ea6d LegoROI* LegoOmni::FindROI(const char* p_name) { ViewManager* viewManager = GetVideoManager()->Get3DManager()->GetLego3DView()->GetViewManager(); diff --git a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp index 0e8aeff8..abeaad10 100644 --- a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp @@ -454,7 +454,7 @@ MxU32 LegoExtraActor::VTable0x6c( if (plpas.find(*itpa) != plpas.end()) { LegoPathActor* actor = *itpa; - if (this != actor && !(actor->GetState() & 0x100)) { + if (this != actor && !(actor->GetState() & LegoPathActor::c_bit9)) { LegoROI* roi = actor->GetROI(); if ((roi != NULL && roi->GetVisibility()) || actor->GetCameraFlag()) { diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 32bcc24c..f5795934 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -455,7 +455,7 @@ MxU32 LegoPathActor::VTable0x6c( if (plpas.find(*itpa) != plpas.end()) { LegoPathActor* actor = *itpa; - if (this != actor && !(actor->GetState() & 0x100)) { + if (this != actor && !(actor->GetState() & LegoPathActor::c_bit9)) { LegoROI* roi = actor->GetROI(); if (roi != NULL && (roi->GetVisibility() || actor->GetCameraFlag())) { diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index cc8f5d73..ab76d03f 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -1,24 +1,63 @@ #include "legoact2.h" +#include "act2actor.h" #include "act2main_actions.h" +#include "actions/act2main_actions.h" #include "islepathactor.h" #include "legoanimationmanager.h" #include "legogamestate.h" #include "legoinputmanager.h" +#include "legomain.h" #include "misc.h" #include "mxbackgroundaudiomanager.h" #include "mxmisc.h" #include "mxnotificationmanager.h" #include "mxticklemanager.h" +#include + DECOMP_SIZE_ASSERT(LegoAct2, 0x1154) DECOMP_SIZE_ASSERT(LegoAct2State, 0x10) -// STUB: LEGO1 0x1004fce0 -// STUB: BETA10 0x1003a5a0 +// GLOBAL: LEGO1 0x100f4474 +static undefined4 g_unk0x100f4474 = 0; + +// GLOBAL: LEGO1 0x100f43f0 +// GLOBAL: BETA10 0x101e14a8 +static MxS32 g_unk0x100f43f0[] = { + Act2mainScript::c_tns030bd_RunAnim, + Act2mainScript::c_tns030pg_RunAnim, + Act2mainScript::c_tns030rd_RunAnim, + Act2mainScript::c_tns030sy_RunAnim, + Act2mainScript::c_tns051in_RunAnim, + Act2mainScript::c_tra045la_RunAnim, + Act2mainScript::c_tns030bd_RunAnim, + Act2mainScript::c_snsx48cl_RunAnim +}; + +// GLOBAL: LEGO1 0x100f4410 +static LegoChar* g_unk0x100f4410[] = {"bd", "pg", "rd", "sy", "ro", "cl"}; + +// FUNCTION: LEGO1 0x1004fce0 +// FUNCTION: BETA10 0x1003a5a0 LegoAct2::LegoAct2() { - // TODO + m_unk0x10c4 = 0; + m_gameState = NULL; + m_unk0x10d8 = NULL; + m_unk0x1128 = 0; + m_unk0x10c2 = 0; + m_unk0x1130 = 0; + m_unk0x10c0 = 0; + m_unk0x10c1 = 0; + m_unk0x1138 = NULL; + m_unk0x1140 = 0; + m_unk0x1144 = 0; + m_unk0x1150 = 0; + m_unk0x10c8 = 0; + m_unk0x10d4 = ""; + m_unk0x113c = 5; + NotificationManager()->Register(this); } // FUNCTION: LEGO1 0x1004fe10 @@ -90,14 +129,116 @@ MxResult LegoAct2::Create(MxDSAction& p_dsAction) return result; } -// STUB: LEGO1 0x10050040 +// FUNCTION: LEGO1 0x10050040 +// FUNCTION: BETA10 0x1003a976 MxResult LegoAct2::Tickle() { - // TODO + MxFloat distance; + + if (!m_worldStarted) { + LegoWorld::Tickle(); + return SUCCESS; + } + + switch (m_unk0x10c4) { + case 0: + m_unk0x10c4 = 1; + break; + case 1: + ((LegoPathActor*) m_unk0x10d8->GetEntity())->SetState(LegoPathActor::c_bit3); + + switch (rand() % 3) { + case 0: + g_unk0x100f4474 = Act2mainScript::c_tns002br_RunAnim; + break; + case 1: + g_unk0x100f4474 = Act2mainScript::c_tns003br_RunAnim; + break; + case 2: + g_unk0x100f4474 = Act2mainScript::c_tns004br_RunAnim; + break; + } + + FUN_10052560(g_unk0x100f4474, TRUE, TRUE, NULL, NULL, NULL); + m_unk0x10d0 = 0; + m_unk0x10c4 = 2; + break; + case 2: + if (g_unk0x100f4474) { + if (AnimationManager()->FUN_10064ee0(g_unk0x100f4474)) { + FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); + g_unk0x100f4474 = 0; + } + } + + m_unk0x10d0 += 50; + break; + case 3: + FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); + m_unk0x10d0 = 0; + m_unk0x10c4 = 4; + FUN_10052560(Act2mainScript::c_tja009ni_RunAnim, TRUE, TRUE, NULL, NULL, NULL); + + AnimationManager()->EnableCamAnims(TRUE); + AnimationManager()->FUN_1005f6d0(TRUE); + AnimationManager()->FUN_100604f0(g_unk0x100f43f0, sizeOfArray(g_unk0x100f43f0)); + AnimationManager()->FUN_10060480(g_unk0x100f4410, sizeOfArray(g_unk0x100f4410)); + break; + case 4: + m_unk0x10d0 += 50; + break; + case 5: + m_unk0x10d0 += 50; + + if (m_unk0x10d0 == 20000) { + const MxFloat* pepperPosition = FindROI("pepper")->GetWorldPosition(); + MxFloat otherPoint[] = {-52.0f, 5.25f, -16.5f}; + + distance = DISTSQRD3(pepperPosition, otherPoint); + + if (m_unk0x1144 == 0 && distance > 50.0f && pepperPosition[0] > -57.0f) { + FUN_10052560(Act2mainScript::c_Avo906In_PlayWav, FALSE, FALSE, NULL, NULL, NULL); + m_unk0x1144 = Act2mainScript::c_Avo906In_PlayWav; + } + } + else if (m_unk0x10d0 >= 90000 && m_unk0x10d0 % 90000 == 0 && m_unk0x1144 == 0) { + FUN_10052560(Act2mainScript::c_Avo908In_PlayWav, FALSE, FALSE, NULL, NULL, NULL); + m_unk0x1144 = Act2mainScript::c_Avo908In_PlayWav; + } + + break; + case 6: + m_unk0x10d0 += 50; + break; + case 9: + m_unk0x10d0 += 50; + + if (m_unk0x10d0 >= 200) { + if (m_unk0x10c0 < 5) { + m_unk0x10c4 = 7; + } + else { + m_unk0x10c4 = 10; + m_unk0x10d0 = 0; + m_unk0x1138->FUN_10019520(); + } + } + + break; + case 10: + m_unk0x10d0 += 50; + break; + case 11: + break; + case 12: + break; + } + return SUCCESS; } // STUB: LEGO1 0x10050380 +// STUB: BETA10 0x1003b049 MxLong LegoAct2::Notify(MxParam& p_param) { // TODO @@ -111,6 +252,7 @@ void LegoAct2::ReadyWorld() } // STUB: LEGO1 0x10050cf0 +// STUB: BETA10 0x1003bb2d void LegoAct2::Enable(MxBool p_enable) { // TODO @@ -156,3 +298,18 @@ MxBool LegoAct2::Escape() m_unk0x1150 = 2; return TRUE; } + +// STUB: LEGO1 0x10052560 +// STUB: BETA10 0x100145c6 +undefined4 LegoAct2::FUN_10052560( + undefined4 p_param1, + MxBool p_param2, + MxBool p_param3, + Mx3DPointFloat* p_param4, + Mx3DPointFloat* p_param5, + Mx3DPointFloat* p_param6 +) +{ + // TODO + return 0; +} diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index 82fe10af..3e5d4b12 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -68,7 +68,9 @@ class LegoROI : public ViewROI { // FUNCTION: BETA10 0x1000f320 const LegoChar* GetName() const { return m_name; } + // FUNCTION: BETA10 0x10015180 LegoEntity* GetEntity() { return m_entity; } + BoundingSphere& GetBoundingSphere() { return m_sphere; } void SetEntity(LegoEntity* p_entity) { m_entity = p_entity; } diff --git a/reccmp-project.yml b/reccmp-project.yml index e91334c8..d71478bc 100644 --- a/reccmp-project.yml +++ b/reccmp-project.yml @@ -22,6 +22,8 @@ targets: ghidra: ignore-types: # these classes have been changed by hand to account for changes between LEGO1 and BETA10 + - Act2Brick + - LegoAct2 - LegoCarBuild - LegoCarBuildAnimPresenter - LegoRace From bd011c67242bbc21d837e2eebf202fc0ea778eac Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Tue, 26 Nov 2024 16:33:18 -0700 Subject: [PATCH 03/13] Remove static storage specifier so vars can be found through datacmp (#1171) --- .../lego/legoomni/src/entity/legojetskiraceactor.cpp | 10 +++++----- LEGO1/lego/legoomni/src/race/carrace.cpp | 6 +++--- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 12 ++++++------ 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp index 0e64d2d0..79084b69 100644 --- a/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp +++ b/LEGO1/lego/legoomni/src/entity/legojetskiraceactor.cpp @@ -12,7 +12,7 @@ DECOMP_SIZE_ASSERT(LegoJetskiRaceActor, 0x1a8) // GLOBAL: LEGO1 0x100da044 // GLOBAL: BETA10 0x101be9fc -const MxFloat g_eight = 8.0f; +MxFloat g_unk0x100da044 = 8.0f; // FUNCTION: LEGO1 0x10080ef0 // FUNCTION: BETA10 0x100a8990 @@ -60,8 +60,8 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ if (p_edge == LegoPathController::GetControlEdgeA(12)) { m_state = 1; - if (m_worldSpeed < g_eight) { - m_worldSpeed = g_eight; + if (m_worldSpeed < g_unk0x100da044) { + m_worldSpeed = g_unk0x100da044; } m_destEdge = LegoPathController::GetControlEdgeA(13); @@ -70,8 +70,8 @@ MxS32 LegoJetskiRaceActor::VTable0x1c(LegoPathBoundary* p_boundary, LegoEdge* p_ else if (p_edge == LegoPathController::GetControlEdgeA(14)) { m_state = 1; - if (m_worldSpeed < g_eight) { - m_worldSpeed = g_eight; + if (m_worldSpeed < g_unk0x100da044) { + m_worldSpeed = g_unk0x100da044; } m_destEdge = LegoPathController::GetControlEdgeA(15); diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index 332a4064..8600fc3e 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -66,13 +66,13 @@ LegoChar* g_strCRCFRNTY6 = "C_RCFRNTY6"; LegoChar* g_strCRCEDGEY0 = "C_RCEDGEY0"; // GLOBAL: LEGO1 0x100f0c7c -static MxS32 g_unk0x100f0c7c = 2; +MxS32 g_unk0x100f0c7c = 2; // FUNCTION: LEGO1 0x10016a90 CarRace::CarRace() { - this->m_skeleton = NULL; - this->m_unk0x130 = MxRect32(0x16c, 0x154, 0x1ec, 0x15e); + m_skeleton = NULL; + m_unk0x130 = MxRect32(0x16c, 0x154, 0x1ec, 0x15e); } // FUNCTION: LEGO1 0x10016ce0 diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index ab76d03f..65f9cf22 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -20,23 +20,23 @@ DECOMP_SIZE_ASSERT(LegoAct2, 0x1154) DECOMP_SIZE_ASSERT(LegoAct2State, 0x10) // GLOBAL: LEGO1 0x100f4474 -static undefined4 g_unk0x100f4474 = 0; +undefined4 g_unk0x100f4474 = 0; // GLOBAL: LEGO1 0x100f43f0 // GLOBAL: BETA10 0x101e14a8 -static MxS32 g_unk0x100f43f0[] = { +MxS32 g_unk0x100f43f0[] = { Act2mainScript::c_tns030bd_RunAnim, Act2mainScript::c_tns030pg_RunAnim, Act2mainScript::c_tns030rd_RunAnim, Act2mainScript::c_tns030sy_RunAnim, - Act2mainScript::c_tns051in_RunAnim, - Act2mainScript::c_tra045la_RunAnim, - Act2mainScript::c_tns030bd_RunAnim, + Act2mainScript::c_snsx35ro_RunAnim, + Act2mainScript::c_snsx36ro_RunAnim, + Act2mainScript::c_snsx37ro_RunAnim, Act2mainScript::c_snsx48cl_RunAnim }; // GLOBAL: LEGO1 0x100f4410 -static LegoChar* g_unk0x100f4410[] = {"bd", "pg", "rd", "sy", "ro", "cl"}; +LegoChar* g_unk0x100f4410[] = {"bd", "pg", "rd", "sy", "ro", "cl"}; // FUNCTION: LEGO1 0x1004fce0 // FUNCTION: BETA10 0x1003a5a0 From 106647e5afecd4461b7d584f94bb5be118c64375 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Wed, 27 Nov 2024 18:13:37 +0100 Subject: [PATCH 04/13] Implement new functions in `LegoAnimManager` (#1170) * Implement new functions in LegoAnimManager * Address review comment --------- Co-authored-by: jonschz --- .../legoomni/include/legoanimationmanager.h | 6 +-- .../legoomni/include/legoanimmmpresenter.h | 2 +- .../src/common/legoanimationmanager.cpp | 50 +++++++++++++++---- .../src/common/legoanimmmpresenter.cpp | 6 +++ 4 files changed, 49 insertions(+), 15 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index 3a05cc22..b43dcb49 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -155,9 +155,9 @@ class LegoAnimationManager : public MxCore { MxBool FindVehicle(const char* p_name, MxU32& p_index); MxResult ReadAnimInfo(LegoFile* p_file, AnimInfo* p_info); MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info); - void FUN_10060480(LegoChar* p_param1[], undefined4 p_param2); + void FUN_10060480(LegoChar* p_characterNames[], MxU32 p_numCharacterNames); void FUN_100604d0(MxBool p_unk0x08); - void FUN_100604f0(MxS32* p_param1, undefined4 p_param2); + void FUN_100604f0(MxS32 p_objectIds[], undefined4 p_numObjectIds); void FUN_10060540(MxBool p_unk0x29); void FUN_10060570(MxBool p_unk0x1a); MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity); @@ -183,7 +183,7 @@ class LegoAnimationManager : public MxCore { MxResult FUN_10064670(Vector3* p_position); MxResult FUN_10064740(Vector3* p_position); MxResult FUN_10064880(const char* p_name, MxS32 p_unk0x0c, MxS32 p_unk0x10); - undefined FUN_10064ee0(MxU32 p_param); + MxBool FUN_10064ee0(MxU32 p_objectId); static void configureLegoAnimationManager(MxS32 p_legoAnimationManagerConfig); diff --git a/LEGO1/lego/legoomni/include/legoanimmmpresenter.h b/LEGO1/lego/legoomni/include/legoanimmmpresenter.h index bdba4f58..a0b05727 100644 --- a/LEGO1/lego/legoomni/include/legoanimmmpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimmmpresenter.h @@ -61,7 +61,7 @@ class LegoAnimMMPresenter : public MxCompositePresenter { // SYNTHETIC: LEGO1 0x1004aa40 // LegoAnimMMPresenter::`scalar deleting destructor' - + MxBool FUN_1004b830(); void FUN_1004b840(); MxBool FUN_1004b8b0(); void FUN_1004b8c0(); diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 3ca3b1f7..9f8ede5d 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -246,6 +246,7 @@ const char* g_cycles[11][17] = { }; // GLOBAL: LEGO1 0x100f7048 +// GLOBAL: BETA10 0x101e1ee8 LegoAnimationManager::Character g_characters[47] = { {"pepper", FALSE, 6, 0, FALSE, FALSE, TRUE, 1500, 20000, FALSE, 50, 1}, {"mama", FALSE, -1, 0, FALSE, FALSE, FALSE, 1500, 20000, FALSE, 0, 2}, @@ -878,11 +879,17 @@ void LegoAnimationManager::DeleteAnimations() m_suspended = suspended; } -// STUB: LEGO1 0x10060480 -// STUB: BETA10 0x100412a9 -void LegoAnimationManager::FUN_10060480(LegoChar* p_param1[], undefined4 p_param2) +// FUNCTION: LEGO1 0x10060480 +// FUNCTION: BETA10 0x100412a9 +void LegoAnimationManager::FUN_10060480(LegoChar* p_characterNames[], MxU32 p_numCharacterNames) { - // TODO + for (MxS32 i = 0; i < p_numCharacterNames; i++) { + for (MxS32 j = 0; j < sizeOfArray(g_characters); j++) { + if (!stricmp(g_characters[j].m_name, p_characterNames[i])) { + g_characters[j].m_unk0x08 = TRUE; + } + } + } } // FUNCTION: LEGO1 0x100604d0 @@ -894,11 +901,17 @@ void LegoAnimationManager::FUN_100604d0(MxBool p_unk0x08) } } -// STUB: LEGO1 0x100604f0 -// STUB: BETA10 0x1004137b -void LegoAnimationManager::FUN_100604f0(MxS32* p_param1, undefined4 p_param2) +// FUNCTION: LEGO1 0x100604f0 +// FUNCTION: BETA10 0x1004137b +void LegoAnimationManager::FUN_100604f0(MxS32 p_objectIds[], undefined4 p_numObjectIds) { - // TODO + for (MxS32 i = 0; i < p_numObjectIds; i++) { + for (MxS32 j = 0; j < m_animCount; j++) { + if (m_anims[j].m_objectId == p_objectIds[i]) { + m_anims[j].m_unk0x29 = TRUE; + } + } + } } // FUNCTION: LEGO1 0x10060540 @@ -2837,10 +2850,25 @@ void LegoAnimationManager::FUN_10064b50(MxLong p_time) } } -// STUB: LEGO1 0x10064ee0 -undefined LegoAnimationManager::FUN_10064ee0(MxU32 p_param) +// FUNCTION: LEGO1 0x10064ee0 +MxBool LegoAnimationManager::FUN_10064ee0(MxU32 p_objectId) { - // TODO + if (m_tranInfoList != NULL) { + LegoTranInfoListCursor cursor(m_tranInfoList); + LegoTranInfo* tranInfo; + + while (cursor.Next(tranInfo)) { + if (tranInfo->m_animInfo->m_objectId == p_objectId) { + if (tranInfo->m_presenter) { + return tranInfo->m_presenter->FUN_1004b830(); + } + else { + return FALSE; + } + } + } + } + return FALSE; } diff --git a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp index ed7edf34..1f854781 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp @@ -466,6 +466,12 @@ MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time) return TRUE; } +// FUNCTION: LEGO1 0x1004b830 +MxBool LegoAnimMMPresenter::FUN_1004b830() +{ + return m_unk0x58 >= e_unk6; +} + // FUNCTION: LEGO1 0x1004b840 // FUNCTION: BETA10 0x1004d033 void LegoAnimMMPresenter::FUN_1004b840() From d6796ad86a493b565a58662a38748e4bf4aed00e Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 27 Nov 2024 15:42:05 -0700 Subject: [PATCH 05/13] Implement remaining LegoGameState functions (#1172) * Implement remaining LegoGameState functions * Naming fixes * Fix naming --- LEGO1/lego/legoomni/include/legogamestate.h | 13 +- .../legoomni/src/common/legogamestate.cpp | 194 ++++++++++++++++-- .../lego/legoomni/src/worlds/historybook.cpp | 2 +- .../legoomni/src/worlds/infocenterdoor.cpp | 4 +- tools/ncc/skip.yml | 1 + 5 files changed, 189 insertions(+), 25 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h index d17e8e2c..b7eb47d9 100644 --- a/LEGO1/lego/legoomni/include/legogamestate.h +++ b/LEGO1/lego/legoomni/include/legogamestate.h @@ -111,7 +111,7 @@ class LegoGameState { Username(Username& p_other) { Set(p_other); } void Set(Username& p_other) { memcpy(m_letters, p_other.m_letters, sizeof(m_letters)); } - MxResult ReadWrite(LegoStorage* p_storage); + MxResult Serialize(LegoStorage* p_storage); Username& operator=(const Username& p_other); MxS16 m_letters[7]; // 0x00 @@ -119,8 +119,10 @@ class LegoGameState { // SIZE 0x2c struct ScoreItem { - undefined2 m_unk0x00; // 0x00 - MxU8 m_state[5][5]; // 0x02 + MxResult Serialize(LegoFile* p_file); + + MxS16 m_totalScore; // 0x00 + MxU8 m_scores[5][5]; // 0x02 Username m_name; // 0x1c undefined2 m_unk0x2a; // 0x2a }; @@ -129,7 +131,8 @@ class LegoGameState { struct History { History(); void WriteScoreHistory(); - void FUN_1003ccf0(LegoFile&); + MxResult Serialize(LegoFile* p_file); + ScoreItem* FUN_1003cc90(Username* p_player, MxU16 p_unk0x24, MxS32& p_unk0x2c); // FUNCTION: BETA10 0x1002c2b0 MxS16 GetCount() { return m_count; } @@ -207,11 +210,11 @@ class LegoGameState { LegoBackgroundColor* m_backgroundColor; // 0x18 LegoBackgroundColor* m_tempBackgroundColor; // 0x1c LegoFullScreenMovie* m_fullScreenMovie; // 0x20 - MxU16 m_unk0x24; // 0x24 // TODO: Most likely getters/setters are not used according to BETA for the following members: public: + MxU16 m_unk0x24; // 0x24 MxS16 m_playerCount; // 0x26 Username m_players[9]; // 0x28 History m_history; // 0xa6 diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index 7d4ee89a..e71fa871 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -3,6 +3,8 @@ #include "3dmanager/lego3dmanager.h" #include "act2main_actions.h" #include "act3_actions.h" +#include "ambulance.h" +#include "carrace.h" #include "carrace_actions.h" #include "carracer_actions.h" #include "copter_actions.h" @@ -25,6 +27,7 @@ #include "jetracer_actions.h" #include "jetski.h" #include "jetski_actions.h" +#include "jetskirace.h" #include "jukebox_actions.h" #include "jukeboxw_actions.h" #include "legoanimationmanager.h" @@ -48,6 +51,7 @@ #include "mxstring.h" #include "mxutilities.h" #include "mxvariabletable.h" +#include "pizza.h" #include "police_actions.h" #include "racecar.h" #include "racecar_actions.h" @@ -55,6 +59,7 @@ #include "roi/legoroi.h" #include "scripts.h" #include "sndanim_actions.h" +#include "towtrack.h" #include #include @@ -539,7 +544,7 @@ void LegoGameState::SerializePlayersInfo(MxS16 p_flags) } for (MxS16 i = 0; i < m_playerCount; i++) { - m_players[i].ReadWrite(&fileStorage); + m_players[i].Serialize(&fileStorage); } } } @@ -1079,11 +1084,11 @@ void LegoGameState::RegisterState(LegoState* p_state) newBuffer[m_stateCount++] = p_state; m_stateArray = newBuffer; - return; } - - delete m_stateArray[targetIndex]; - m_stateArray[targetIndex] = p_state; + else { + delete m_stateArray[targetIndex]; + m_stateArray[targetIndex] = p_state; + } } // FUNCTION: LEGO1 0x1003bd00 @@ -1147,17 +1152,17 @@ LegoGameState::Username::Username() } // FUNCTION: LEGO1 0x1003c690 -MxResult LegoGameState::Username::ReadWrite(LegoStorage* p_storage) +// FUNCTION: BETA10 0x10086c57 +MxResult LegoGameState::Username::Serialize(LegoStorage* p_storage) { if (p_storage->IsReadMode()) { - for (MxS16 i = 0; i < 7; i++) { - p_storage->Read(&m_letters[i], sizeof(m_letters[i])); + for (MxS16 i = 0; i < (MxS16) sizeOfArray(m_letters); i++) { + Read(p_storage, &m_letters[i]); } } else if (p_storage->IsWriteMode()) { - for (MxS16 i = 0; i < 7; i++) { - MxS16 letter = m_letters[i]; - p_storage->Write(&letter, sizeof(letter)); + for (MxS16 i = 0; i < (MxS16) sizeOfArray(m_letters); i++) { + Write(p_storage, m_letters[i]); } } @@ -1165,29 +1170,184 @@ MxResult LegoGameState::Username::ReadWrite(LegoStorage* p_storage) } // FUNCTION: LEGO1 0x1003c710 +// FUNCTION: BETA10 0x10086d0c LegoGameState::Username& LegoGameState::Username::operator=(const Username& p_other) { memcpy(m_letters, p_other.m_letters, sizeof(m_letters)); return *this; } +// FUNCTION: LEGO1 0x1003c740 +// FUNCTION: BETA10 0x10086d39 +MxResult LegoGameState::ScoreItem::Serialize(LegoFile* p_file) +{ + if (p_file->IsReadMode()) { + Read(p_file, &m_totalScore); + + for (MxS32 i = 0; i < 5; i++) { + for (MxS32 j = 0; j < 5; j++) { + Read(p_file, &m_scores[i][j]); + } + } + + m_name.Serialize(p_file); + Read(p_file, &m_unk0x2a); + } + else if (p_file->IsWriteMode()) { + Write(p_file, m_totalScore); + + for (MxS32 i = 0; i < 5; i++) { + for (MxS32 j = 0; j < 5; j++) { + Write(p_file, m_scores[i][j]); + } + } + + m_name.Serialize(p_file); + Write(p_file, m_unk0x2a); + } + + return SUCCESS; +} + // FUNCTION: LEGO1 0x1003c830 +// FUNCTION: BETA10 0x10086e87 LegoGameState::History::History() { m_count = 0; m_unk0x372 = 0; } -// STUB: LEGO1 0x1003c870 +// FUNCTION: LEGO1 0x1003c870 +// FUNCTION: BETA10 0x10086ec9 void LegoGameState::History::WriteScoreHistory() { - // TODO + MxS16 totalScore = 0; + MxU8 scores[5][5]; + + InfocenterState* state = (InfocenterState*) GameState()->GetState("InfocenterState"); + if (state->m_letters[0]) { + JetskiRaceState* jetskiRaceState = (JetskiRaceState*) GameState()->GetState("JetskiRaceState"); + CarRaceState* carRaceState = (CarRaceState*) GameState()->GetState("CarRaceState"); + TowTrackMissionState* towTrackMissionState = + (TowTrackMissionState*) GameState()->GetState("TowTrackMissionState"); + PizzaMissionState* pizzaMissionState = (PizzaMissionState*) GameState()->GetState("PizzaMissionState"); + AmbulanceMissionState* ambulanceMissionState = + (AmbulanceMissionState*) GameState()->GetState("AmbulanceMissionState"); + + for (MxS32 actor = 1; actor <= 5; actor++) { + scores[0][actor - 1] = carRaceState ? carRaceState->GetState(actor)->GetHighScore() : 0; + totalScore += scores[0][actor - 1]; + + scores[1][actor - 1] = jetskiRaceState ? jetskiRaceState->GetState(actor)->GetHighScore() : 0; + totalScore += scores[1][actor - 1]; + + scores[2][actor - 1] = pizzaMissionState ? pizzaMissionState->GetHighScore(actor) : 0; + totalScore += scores[2][actor - 1]; + + scores[3][actor - 1] = towTrackMissionState ? towTrackMissionState->GetHighScore(actor) : 0; + totalScore += scores[3][actor - 1]; + + scores[4][actor - 1] = ambulanceMissionState ? ambulanceMissionState->GetHighScore(actor) : 0; + totalScore += scores[4][actor - 1]; + } + + MxS32 unk0x2c; + ScoreItem* p_scorehist = FUN_1003cc90(&GameState()->m_players[0], GameState()->m_unk0x24, unk0x2c); + + if (p_scorehist != NULL) { + p_scorehist->m_totalScore = totalScore; + memcpy(p_scorehist->m_scores, scores, sizeof(p_scorehist->m_scores)); + } + else { + if (m_count < (MxS16) sizeOfArray(m_scores)) { + m_scores[m_count].m_totalScore = totalScore; + memcpy(m_scores[m_count].m_scores, scores, sizeof(m_scores[m_count].m_scores)); + m_scores[m_count].m_name = GameState()->m_players[0]; + m_scores[m_count].m_unk0x2a = GameState()->m_unk0x24; + m_count++; + } + else if (m_scores[19].m_totalScore <= totalScore) { + m_scores[19].m_totalScore = totalScore; + memcpy(m_scores[19].m_scores, scores, sizeof(m_scores[19].m_scores)); + m_scores[19].m_name = GameState()->m_players[0]; + m_scores[19].m_unk0x2a = GameState()->m_unk0x24; + } + } + + MxU8 tmpScores[5][5]; + Username tmpPlayer; + undefined2 tmpUnk0x2a; + + // TODO: Match bubble sort loops + for (MxS32 i = m_count - 1; i > 0; i--) { + for (MxS32 j = 1; j <= i; j++) { + if (m_scores[j - 1].m_totalScore < m_scores[j].m_totalScore) { + memcpy(tmpScores, m_scores[j - 1].m_scores, sizeof(tmpScores)); + tmpPlayer = m_scores[j - 1].m_name; + tmpUnk0x2a = m_scores[j - 1].m_unk0x2a; + + memcpy(m_scores[j - 1].m_scores, m_scores[j].m_scores, sizeof(m_scores[j - 1].m_scores)); + m_scores[j - 1].m_name = m_scores[j].m_name; + m_scores[j - 1].m_unk0x2a = m_scores[j].m_unk0x2a; + + memcpy(m_scores[j].m_scores, tmpScores, sizeof(m_scores[j].m_scores)); + m_scores[j].m_name = tmpPlayer; + m_scores[j].m_unk0x2a = tmpUnk0x2a; + } + } + } + } } -// STUB: LEGO1 0x1003ccf0 -void LegoGameState::History::FUN_1003ccf0(LegoFile&) +// FUNCTION: LEGO1 0x1003cc90 +// FUNCTION: BETA10 0x1008732a +LegoGameState::ScoreItem* LegoGameState::History::FUN_1003cc90( + LegoGameState::Username* p_player, + MxU16 p_unk0x24, + MxS32& p_unk0x2c +) { - // TODO + MxS32 i = 0; + for (; i < m_count; i++) { + if (!memcmp(p_player, &m_scores[i].m_name, sizeof(*p_player)) && m_scores[i].m_unk0x2a == p_unk0x24) { + break; + } + } + + p_unk0x2c = i; + + if (i >= m_count) { + return NULL; + } + + return &m_scores[i]; +} + +// FUNCTION: LEGO1 0x1003ccf0 +// FUNCTION: BETA10 0x100873e7 +MxResult LegoGameState::History::Serialize(LegoFile* p_file) +{ + if (p_file->IsReadMode()) { + Read(p_file, &m_unk0x372); + Read(p_file, &m_count); + + for (MxS16 i = 0; i < m_count; i++) { + MxS16 j; + Read(p_file, &j); + m_scores[i].Serialize(p_file); + } + } + else if (p_file->IsWriteMode()) { + Write(p_file, m_unk0x372); + Write(p_file, m_count); + + for (MxS16 i = 0; i < m_count; i++) { + Write(p_file, i); + m_scores[i].Serialize(p_file); + } + } + + return SUCCESS; } // FUNCTION: LEGO1 0x1003cdd0 @@ -1203,7 +1363,7 @@ void LegoGameState::SerializeScoreHistory(MxS16 p_flags) } if (stream.Open(savePath.GetData(), p_flags) == SUCCESS) { - m_history.FUN_1003ccf0(stream); + m_history.Serialize(&stream); } } diff --git a/LEGO1/lego/legoomni/src/worlds/historybook.cpp b/LEGO1/lego/legoomni/src/worlds/historybook.cpp index e9ca3b4d..39f30d14 100644 --- a/LEGO1/lego/legoomni/src/worlds/historybook.cpp +++ b/LEGO1/lego/legoomni/src/worlds/historybook.cpp @@ -139,7 +139,7 @@ void HistoryBook::ReadyWorld() for (; scoreboxRow > 0; scoreboxRow--) { for (MxS32 scoreBoxColumn = 0, scoreboxY = 1; scoreBoxColumn < 5; scoreBoxColumn++, scoreboxY += 5) { - SetColor(*scorebox, score->m_state[scoreState][scoreBoxColumn], scoreColors, scoreboxX, scoreboxY); + SetColor(*scorebox, score->m_scores[scoreState][scoreBoxColumn], scoreColors, scoreboxX, scoreboxY); } scoreState++; diff --git a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp index 5f3ae04c..506b21f5 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp @@ -121,7 +121,7 @@ MxLong InfocenterDoor::HandleControl(LegoControlManagerNotificationParam& p_para } else { MxDSAction action; - action.SetObjectId(503); + action.SetObjectId(InfodoorScript::c_iic007in_PlayWav); action.SetAtomId(*g_infodoorScript); BackgroundAudioManager()->LowerVolume(); Start(&action); @@ -130,7 +130,7 @@ MxLong InfocenterDoor::HandleControl(LegoControlManagerNotificationParam& p_para } else { MxDSAction action; - action.SetObjectId(500); + action.SetObjectId(InfodoorScript::c_iic037in_PlayWav); action.SetAtomId(*g_infodoorScript); BackgroundAudioManager()->LowerVolume(); Start(&action); diff --git a/tools/ncc/skip.yml b/tools/ncc/skip.yml index 6950fbca..4f39ddc8 100644 --- a/tools/ncc/skip.yml +++ b/tools/ncc/skip.yml @@ -52,3 +52,4 @@ m_Decals_Ctl4: "Allow original naming from beta" m_Decals_Ctl5: "Allow original naming from beta" m_Decals_Ctl6: "Allow original naming from beta" m_Decals_Ctl7: "Allow original naming from beta" +p_scorehist: "Allow original naming from beta" From 7256eeb0ad35e32644229042b11bc6da2cb697a4 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Wed, 27 Nov 2024 16:05:40 -0700 Subject: [PATCH 06/13] Replace hardcoded magic values with constants (#1173) * Replace two hardcoded magic values with constants * Replace constants --- .../legoomni/src/common/legogamestate.cpp | 102 +++++++++--------- 1 file changed, 51 insertions(+), 51 deletions(-) diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index e71fa871..6943969b 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -647,55 +647,55 @@ void LegoGameState::StopArea(Area p_area) break; case e_elevride: case e_elevride2: - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevRide_Background_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevRide_Info_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevRide_Two_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevRide_Three_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Meter1_3_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Meter2_3_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Meter3_1_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Meter3_2_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Meter2_1_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Meter1_2_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Meter3_Bitmap, *g_isleScript, 0); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevRide_Background_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevRide_Info_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevRide_Two_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevRide_Three_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Meter1_3_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Meter2_3_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Meter3_1_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Meter3_2_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Meter2_1_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Meter1_2_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Meter3_Bitmap, *g_isleScript, IsleScript::c__Isle); break; case e_elevopen: - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevOpen_Background_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevOpen_LeftArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevOpen_RightArrow_Ctl, *g_isleScript, 0); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevOpen_Background_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevOpen_LeftArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevOpen_RightArrow_Ctl, *g_isleScript, IsleScript::c__Isle); break; case e_seaview: - RemoveFromWorld(*g_isleScript, IsleScript::c_SeaView_Background_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_SeaView_LeftArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_SeaView_RightArrow_Ctl, *g_isleScript, 0); + RemoveFromWorld(*g_isleScript, IsleScript::c_SeaView_Background_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_SeaView_LeftArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_SeaView_RightArrow_Ctl, *g_isleScript, IsleScript::c__Isle); break; case e_observe: - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Background_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_LeftArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_RightArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Plane_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Sun_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Moon_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_SkyColor_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_LCab_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_RCab_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_GlobeRArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_GlobeLArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe1_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe2_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe3_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe4_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe5_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe6_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Draw1_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Draw2_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_Radio_Ctl, *g_isleScript, 0); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Background_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_LeftArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_RightArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Plane_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Sun_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Moon_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_SkyColor_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_LCab_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_RCab_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_GlobeRArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_GlobeLArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe1_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe2_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe3_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe4_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe5_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Globe6_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Draw1_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Observe_Draw2_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_Radio_Ctl, *g_isleScript, IsleScript::c__Isle); break; case e_elevdown: - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevDown_Background_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevDown_LeftArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevDown_RightArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_ElevDown_Elevator_Ctl, *g_isleScript, 0); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevDown_Background_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevDown_LeftArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevDown_RightArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_ElevDown_Elevator_Ctl, *g_isleScript, IsleScript::c__Isle); break; case e_regbook: InvokeAction(Extra::e_stop, *g_regbookScript, RegbookScript::c__StartUp, NULL); @@ -721,10 +721,10 @@ void LegoGameState::StopArea(Area p_area) InvokeAction(Extra::e_close, *g_garageScript, GarageScript::c__StartUp, NULL); break; case e_garadoor: - RemoveFromWorld(*g_isleScript, IsleScript::c_GaraDoor_Background_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_GaraDoor_LeftArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_GaraDoor_RightArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_GaraDoor_Door_Ctl, *g_isleScript, 0); + RemoveFromWorld(*g_isleScript, IsleScript::c_GaraDoor_Background_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_GaraDoor_LeftArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_GaraDoor_RightArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_GaraDoor_Door_Ctl, *g_isleScript, IsleScript::c__Isle); break; case e_hospital: InvokeAction(Extra::e_stop, *g_hospitalScript, HospitalScript::c__StartUp, NULL); @@ -735,10 +735,10 @@ void LegoGameState::StopArea(Area p_area) InvokeAction(Extra::e_close, *g_policeScript, PoliceScript::c__StartUp, NULL); break; case e_polidoor: - RemoveFromWorld(*g_isleScript, IsleScript::c_PoliDoor_Background_Bitmap, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_PoliDoor_LeftArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_PoliDoor_RightArrow_Ctl, *g_isleScript, 0); - RemoveFromWorld(*g_isleScript, IsleScript::c_PoliDoor_Door_Ctl, *g_isleScript, 0); + RemoveFromWorld(*g_isleScript, IsleScript::c_PoliDoor_Background_Bitmap, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_PoliDoor_LeftArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_PoliDoor_RightArrow_Ctl, *g_isleScript, IsleScript::c__Isle); + RemoveFromWorld(*g_isleScript, IsleScript::c_PoliDoor_Door_Ctl, *g_isleScript, IsleScript::c__Isle); break; case e_copterbuild: InvokeAction(Extra::e_stop, *g_jukeboxScript, JukeboxScript::c_HelicopterBuild_Movie, NULL); @@ -761,13 +761,13 @@ void LegoGameState::StopArea(Area p_area) InvokeAction(Extra::e_close, *g_racecarScript, RacecarScript::c__StartUp, NULL); break; case e_act2main: - if (m_currentArea != 2) { + if (m_currentArea != e_infomain) { InvokeAction(Extra::e_stop, *g_act2mainScript, Act2mainScript::c__Act2Main, NULL); InvokeAction(Extra::e_close, *g_act2mainScript, Act2mainScript::c__Act2Main, NULL); } break; case e_act3script: - if (m_currentArea != 2) { + if (m_currentArea != e_infomain) { InvokeAction(Extra::e_stop, *g_act3Script, Act3Script::c__Act3, NULL); InvokeAction(Extra::e_close, *g_act3Script, Act3Script::c__Act3, NULL); } From 29a0ae8f074c3afbc4ab34d214e9c9c36ce64131 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Fri, 29 Nov 2024 21:04:50 +0100 Subject: [PATCH 07/13] Implement/match `LegoAct2::FUN_10052560()` (#1174) * Implement/match `LegoAct2::FUN_10052560()` * Fix formatting * Fix linter errors * Address review comment --------- Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/legoact2.h | 27 +++--- LEGO1/lego/legoomni/src/main/legomain.cpp | 3 + LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 92 +++++++++++++++++++-- LEGO1/omni/include/mxdsaction.h | 6 ++ 4 files changed, 109 insertions(+), 19 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index b1db65ea..42f333e1 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -67,11 +67,11 @@ class LegoAct2 : public LegoWorld { void SetUnknown0x1150(undefined4 p_unk0x1150) { m_unk0x1150 = p_unk0x1150; } undefined4 FUN_10052560( - undefined4 p_param1, + MxS32 p_param1, MxBool p_param2, MxBool p_param3, - Mx3DPointFloat* p_param4, - Mx3DPointFloat* p_param5, + Mx3DPointFloat* p_location, + Mx3DPointFloat* p_direction, Mx3DPointFloat* p_param6 ); @@ -81,15 +81,18 @@ class LegoAct2 : public LegoWorld { private: void FUN_10051900(); - Act2Brick m_bricks[10]; // 0x00f8 - undefined m_unk0x10c0; // 0x10c0 - undefined m_unk0x10c1; // 0x10c1 - undefined m_unk0x10c2; // 0x10c2 - undefined4 m_unk0x10c4; // 0x10c4 - undefined4 m_unk0x10c8; // 0x10c8 - LegoAct2State* m_gameState; // 0x10cc - MxS32 m_unk0x10d0; // 0x10d0 - char* m_unk0x10d4; // 0x10d4 + Act2Brick m_bricks[10]; // 0x00f8 + undefined m_unk0x10c0; // 0x10c0 + undefined m_unk0x10c1; // 0x10c1 + undefined m_unk0x10c2; // 0x10c2 + undefined4 m_unk0x10c4; // 0x10c4 + undefined4 m_unk0x10c8; // 0x10c8 + LegoAct2State* m_gameState; // 0x10cc + MxS32 m_unk0x10d0; // 0x10d0 + + // variable name verified by BETA10 0x10014633 + char* m_siFile; // 0x10d4 + LegoROI* m_unk0x10d8; // 0x10d8 MxMatrix m_unk0x10dc; // 0x10dc undefined4 m_unk0x1124; // 0x1124 diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index 4641d548..7fc35185 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -488,6 +488,7 @@ const char* LegoOmni::GetWorldName(MxU32 p_id) } // FUNCTION: LEGO1 0x1005b460 +// FUNCTION: BETA10 0x1008edd8 MxAtomId* LegoOmni::GetWorldAtom(MxU32 p_id) { for (MxS32 i = 0; i < 19; i++) { @@ -496,6 +497,8 @@ MxAtomId* LegoOmni::GetWorldAtom(MxU32 p_id) } } + // A gem from BETA10 + assert("Hey, check your code. We do not have this world." == NULL); return NULL; } diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 65f9cf22..0038928c 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -3,6 +3,7 @@ #include "act2actor.h" #include "act2main_actions.h" #include "actions/act2main_actions.h" +#include "actions/infomain_actions.h" #include "islepathactor.h" #include "legoanimationmanager.h" #include "legogamestate.h" @@ -55,7 +56,7 @@ LegoAct2::LegoAct2() m_unk0x1144 = 0; m_unk0x1150 = 0; m_unk0x10c8 = 0; - m_unk0x10d4 = ""; + m_siFile = ""; m_unk0x113c = 5; NotificationManager()->Register(this); } @@ -299,17 +300,94 @@ MxBool LegoAct2::Escape() return TRUE; } -// STUB: LEGO1 0x10052560 -// STUB: BETA10 0x100145c6 +// FUNCTION: LEGO1 0x10052560 +// FUNCTION: BETA10 0x100145c6 undefined4 LegoAct2::FUN_10052560( - undefined4 p_param1, + MxS32 p_param1, MxBool p_param2, MxBool p_param3, - Mx3DPointFloat* p_param4, - Mx3DPointFloat* p_param5, + Mx3DPointFloat* p_location, + Mx3DPointFloat* p_direction, Mx3DPointFloat* p_param6 ) { - // TODO + + if (m_unk0x1140 == 0 || p_param3) { + assert(strlen(m_siFile)); + + if (!p_param2) { + MxDSAction action; + + action.SetObjectId(p_param1); + // not entirely sure about the constant + action.SetAtomId(*Lego()->GetWorldAtom(InfomainScript::c_Cop_Ctl)); + + if (p_location) { + action.SetUp(Mx3DPointFloat(0.0f, 1.0f, 0.0f)); + action.SetLocation(*p_location); + } + + if (p_direction) { + action.SetDirection(*p_direction); + } + + StartActionIfUnknown0x13c(action); + } + else { + MxMatrix matrix; + + matrix.SetIdentity(); + MxBool oneVectorNotNull = FALSE; + + if (p_location) { + matrix[3][0] = (*p_location)[0]; + matrix[3][1] = (*p_location)[1]; + matrix[3][2] = (*p_location)[2]; + oneVectorNotNull = TRUE; + } + + if (p_direction) { + matrix[2][0] = (*p_direction)[0]; + matrix[2][1] = (*p_direction)[1]; + matrix[2][2] = (*p_direction)[2]; + oneVectorNotNull = TRUE; + } + + if (p_param6) { + matrix[1][0] = (*p_param6)[0]; + matrix[1][1] = (*p_param6)[1]; + matrix[1][2] = (*p_param6)[2]; + oneVectorNotNull = TRUE; + } + + Vector3 firstColumn(matrix[0]); + Vector3 secondColumn(matrix[1]); + Vector3 thirdColumn(matrix[2]); + + firstColumn.EqualsCross(&secondColumn, &thirdColumn); + firstColumn.Unitize(); + + MxMatrix* pmatrix = NULL; + + if (oneVectorNotNull) { + pmatrix = &matrix; + } + + MxResult result; + + if (p_param1 == Act2mainScript::c_tja009ni_RunAnim) { + result = AnimationManager()->FUN_10060dc0(p_param1, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, TRUE); + } + else { + result = + AnimationManager()->FUN_10060dc0(p_param1, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, FALSE); + } + + if (result == SUCCESS) { + m_unk0x1140 = p_param1; + } + } + } + return 0; } diff --git a/LEGO1/omni/include/mxdsaction.h b/LEGO1/omni/include/mxdsaction.h index a68dbc51..b678289a 100644 --- a/LEGO1/omni/include/mxdsaction.h +++ b/LEGO1/omni/include/mxdsaction.h @@ -94,9 +94,15 @@ class MxDSAction : public MxDSObject { // FUNCTION: BETA10 0x1003dbb0 Vector3& GetUp() { return m_up; } + // FUNCTION: BETA10 0x100153b0 void SetLocation(const Vector3& p_location) { m_location = p_location; } + + // FUNCTION: BETA10 0x100153f0 void SetDirection(const Vector3& p_direction) { m_direction = p_direction; } + + // FUNCTION: BETA10 0x10015430 void SetUp(const Vector3& p_up) { m_up = p_up; } + MxCore* GetUnknown84() { return m_unk0x84; } void SetUnknown84(MxCore* p_unk0x84) { m_unk0x84 = p_unk0x84; } MxCore* GetOrigin() { return m_origin; } From a17b3168e9c9159d2a61be65f7a18412060d26b2 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 29 Nov 2024 13:11:29 -0700 Subject: [PATCH 08/13] Implement/match `LegoAct2::Notify` (#1175) * Implement LegoAct2::Notify * Fix naming * Remove unnecessary actions/ prefix in includes --- LEGO1/lego/legoomni/include/legoact2.h | 7 +- LEGO1/lego/legoomni/src/race/carrace.cpp | 4 +- LEGO1/lego/legoomni/src/race/jetskirace.cpp | 6 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 107 +++++++++++++++++++- LEGO1/mxgeometry/mxmatrix.h | 1 + 5 files changed, 114 insertions(+), 11 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 42f333e1..1b809287 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -6,6 +6,8 @@ #include "legoworld.h" class Act2Actor; +class LegoPathStructNotificationParam; +class MxEndActionNotificationParam; // VTABLE: LEGO1 0x100d4a70 // SIZE 0x10 @@ -79,6 +81,9 @@ class LegoAct2 : public LegoWorld { // LegoAct2::`scalar deleting destructor' private: + MxLong HandleEndAction(MxEndActionNotificationParam& p_param); + MxLong HandleTransitionEnd(); + MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param); void FUN_10051900(); Act2Brick m_bricks[10]; // 0x00f8 @@ -96,7 +101,7 @@ class LegoAct2 : public LegoWorld { LegoROI* m_unk0x10d8; // 0x10d8 MxMatrix m_unk0x10dc; // 0x10dc undefined4 m_unk0x1124; // 0x1124 - undefined4 m_unk0x1128; // 0x1128 + LegoROI* m_ambulance; // 0x1128 undefined4 m_unk0x112c; // 0x112c undefined4 m_unk0x1130; // 0x1130 undefined4 m_unk0x1134; // 0x1134 diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index 8600fc3e..a3f32780 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -1,9 +1,9 @@ #include "carrace.h" -#include "actions/carrace_actions.h" -#include "actions/jukebox_actions.h" +#include "carrace_actions.h" #include "dunebuggy.h" #include "isle.h" +#include "jukebox_actions.h" #include "legoanimationmanager.h" #include "legobackgroundcolor.h" #include "legocontrolmanager.h" diff --git a/LEGO1/lego/legoomni/src/race/jetskirace.cpp b/LEGO1/lego/legoomni/src/race/jetskirace.cpp index 65696e5b..e2564e92 100644 --- a/LEGO1/lego/legoomni/src/race/jetskirace.cpp +++ b/LEGO1/lego/legoomni/src/race/jetskirace.cpp @@ -1,10 +1,10 @@ #include "jetskirace.h" -#include "actions/jetrace_actions.h" -#include "actions/jetski_actions.h" -#include "actions/jukebox_actions.h" #include "dunebuggy.h" #include "isle.h" +#include "jetrace_actions.h" +#include "jetski_actions.h" +#include "jukebox_actions.h" #include "legoanimationmanager.h" #include "legocontrolmanager.h" #include "legohideanimpresenter.h" diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 0038928c..39a4a9a9 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -2,15 +2,19 @@ #include "act2actor.h" #include "act2main_actions.h" -#include "actions/act2main_actions.h" -#include "actions/infomain_actions.h" +#include "infomain_actions.h" #include "islepathactor.h" #include "legoanimationmanager.h" +#include "legocachesoundmanager.h" #include "legogamestate.h" #include "legoinputmanager.h" #include "legomain.h" +#include "legopathstruct.h" +#include "legosoundmanager.h" #include "misc.h" +#include "mxactionnotificationparam.h" #include "mxbackgroundaudiomanager.h" +#include "mxdebug.h" #include "mxmisc.h" #include "mxnotificationmanager.h" #include "mxticklemanager.h" @@ -46,7 +50,7 @@ LegoAct2::LegoAct2() m_unk0x10c4 = 0; m_gameState = NULL; m_unk0x10d8 = NULL; - m_unk0x1128 = 0; + m_ambulance = NULL; m_unk0x10c2 = 0; m_unk0x1130 = 0; m_unk0x10c0 = 0; @@ -238,9 +242,94 @@ MxResult LegoAct2::Tickle() return SUCCESS; } -// STUB: LEGO1 0x10050380 -// STUB: BETA10 0x1003b049 +// FUNCTION: LEGO1 0x10050380 +// FUNCTION: BETA10 0x1003b049 MxLong LegoAct2::Notify(MxParam& p_param) +{ + MxNotificationParam& param = (MxNotificationParam&) p_param; + MxLong result = 0; + + LegoWorld::Notify(p_param); + + if (m_worldStarted) { + switch (param.GetNotification()) { + case c_notificationEndAction: + result = HandleEndAction((MxEndActionNotificationParam&) p_param); + break; + case c_notificationPathStruct: { + MxTrace("trigger %d\n", ((LegoPathStructNotificationParam&) p_param).GetData()); + + LegoPathStructNotificationParam& param = (LegoPathStructNotificationParam&) p_param; + LegoEntity* entity = (LegoEntity*) param.GetSender(); + + if (m_ambulance == NULL) { + m_ambulance = FindROI("ambul"); + } + + if (entity->GetROI() == m_unk0x10d8) { + HandlePathStruct(param); + } + + result = 1; + break; + } + case c_notificationType22: + SoundManager()->GetCacheSoundManager()->Play("28bng", NULL, FALSE); + + m_unk0x10c1++; + if (m_unk0x10c1 == 10 && m_unk0x10c4 == 13) { + m_unk0x10c4 = 14; + + LegoEntity* entity = (LegoEntity*) param.GetSender(); + + Mx3DPointFloat entityPosition(entity->GetROI()->GetWorldPosition()); + Mx3DPointFloat unk0x10d8(m_unk0x10d8->GetWorldPosition()); + Mx3DPointFloat locala4(unk0x10d8); + + ((Vector3&) entityPosition).Sub(unk0x10d8); + + MxMatrix local2world(m_unk0x10d8->GetLocal2World()); + Vector3 local30(local2world[0]); + Vector3 localac(local2world[1]); + Vector3 local28(local2world[2]); + + local28 = entityPosition; + local28.Unitize(); + + Mx3DPointFloat local90(local28); + ((Vector3&) local90).Mul(1.25f); + ((Vector3&) locala4).Add(local90); + locala4[1] += 0.25; + local30.EqualsCross(&localac, &local28); + local30.Unitize(); + + Mx3DPointFloat direction(local2world[2]); + Mx3DPointFloat location(local2world[1]); + FUN_10052560(Act2mainScript::c_tns051in_RunAnim, TRUE, TRUE, &location, &direction, NULL); + + m_unk0x10c4 = 14; + m_unk0x10d0 = 0; + ((LegoPathActor*) m_unk0x10d8->GetEntity())->SetState(LegoPathActor::c_bit3); + } + break; + case c_notificationTransitioned: + result = HandleTransitionEnd(); + break; + } + } + + return result; +} + +// STUB: LEGO1 0x100506f0 +MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param) +{ + // TODO + return 0; +} + +// STUB: LEGO1 0x10050a50 +MxLong LegoAct2::HandleTransitionEnd() { // TODO return 0; @@ -259,6 +348,14 @@ void LegoAct2::Enable(MxBool p_enable) // TODO } +// STUB: LEGO1 0x10051460 +// STUB: BETA10 0x1003bb72 +MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param) +{ + // TODO + return 0; +} + // FUNCTION: LEGO1 0x10051900 // FUNCTION: BETA10 0x1003bed1 void LegoAct2::FUN_10051900() diff --git a/LEGO1/mxgeometry/mxmatrix.h b/LEGO1/mxgeometry/mxmatrix.h index a9249225..55a17da1 100644 --- a/LEGO1/mxgeometry/mxmatrix.h +++ b/LEGO1/mxgeometry/mxmatrix.h @@ -15,6 +15,7 @@ class MxMatrix : public Matrix4 { // FUNCTION: LEGO1 0x10032770 MxMatrix(const MxMatrix& p_matrix) : Matrix4(m_elements) { Equals(p_matrix); } + // FUNCTION: BETA10 0x1000fc20 MxMatrix(const Matrix4& p_matrix) : Matrix4(m_elements) { Equals(p_matrix); } // FUNCTION: BETA10 0x10010860 From c9a2a7203b0d2c185bc4fdd856b947022f112195 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 29 Nov 2024 13:24:14 -0700 Subject: [PATCH 09/13] Implement/match LegoAct2::HandleTransitionEnd (#1176) --- LEGO1/lego/legoomni/include/legoact2.h | 29 ++++++++++---------- LEGO1/lego/legoomni/src/actors/buildings.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 14 ++++++---- 3 files changed, 25 insertions(+), 20 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 1b809287..c73e0c55 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -2,6 +2,7 @@ #define LEGOACT2_H #include "act2brick.h" +#include "legogamestate.h" #include "legostate.h" #include "legoworld.h" @@ -66,7 +67,7 @@ class LegoAct2 : public LegoWorld { void Enable(MxBool p_enable) override; // vtable+0x68 void SetUnknown0x1138(Act2Actor* p_unk0x1138) { m_unk0x1138 = p_unk0x1138; } - void SetUnknown0x1150(undefined4 p_unk0x1150) { m_unk0x1150 = p_unk0x1150; } + void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; } undefined4 FUN_10052560( MxS32 p_param1, @@ -98,19 +99,19 @@ class LegoAct2 : public LegoWorld { // variable name verified by BETA10 0x10014633 char* m_siFile; // 0x10d4 - LegoROI* m_unk0x10d8; // 0x10d8 - MxMatrix m_unk0x10dc; // 0x10dc - undefined4 m_unk0x1124; // 0x1124 - LegoROI* m_ambulance; // 0x1128 - undefined4 m_unk0x112c; // 0x112c - undefined4 m_unk0x1130; // 0x1130 - undefined4 m_unk0x1134; // 0x1134 - Act2Actor* m_unk0x1138; // 0x1138 - undefined m_unk0x113c; // 0x113c - undefined4 m_unk0x1140; // 0x1140 - undefined4 m_unk0x1144; // 0x1144 - undefined m_unk0x1148[0x08]; // 0x1148 - undefined4 m_unk0x1150; // 0x1150 + LegoROI* m_unk0x10d8; // 0x10d8 + MxMatrix m_unk0x10dc; // 0x10dc + undefined4 m_unk0x1124; // 0x1124 + LegoROI* m_ambulance; // 0x1128 + undefined4 m_unk0x112c; // 0x112c + undefined4 m_unk0x1130; // 0x1130 + undefined4 m_unk0x1134; // 0x1134 + Act2Actor* m_unk0x1138; // 0x1138 + undefined m_unk0x113c; // 0x113c + undefined4 m_unk0x1140; // 0x1140 + undefined4 m_unk0x1144; // 0x1144 + undefined m_unk0x1148[0x08]; // 0x1148 + LegoGameState::Area m_destLocation; // 0x1150 }; #endif // LEGOACT2_H diff --git a/LEGO1/lego/legoomni/src/actors/buildings.cpp b/LEGO1/lego/legoomni/src/actors/buildings.cpp index 79e7ef23..64188031 100644 --- a/LEGO1/lego/legoomni/src/actors/buildings.cpp +++ b/LEGO1/lego/legoomni/src/actors/buildings.cpp @@ -58,7 +58,7 @@ MxLong InfoCenterEntity::HandleClick(LegoEventNotificationParam& p_param) } case LegoGameState::Act::e_act2: { LegoAct2* act2 = (LegoAct2*) FindWorld(*g_act2mainScript, Act2mainScript::c__Act2Main); - act2->SetUnknown0x1150(2); + act2->SetDestLocation(LegoGameState::e_infomain); LegoAct2State* act2state = (LegoAct2State*) GameState()->GetState("LegoAct2State"); if (act2state) { diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 39a4a9a9..7612bc34 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -58,7 +58,7 @@ LegoAct2::LegoAct2() m_unk0x1138 = NULL; m_unk0x1140 = 0; m_unk0x1144 = 0; - m_unk0x1150 = 0; + m_destLocation = LegoGameState::e_undefined; m_unk0x10c8 = 0; m_siFile = ""; m_unk0x113c = 5; @@ -328,11 +328,15 @@ MxLong LegoAct2::HandleEndAction(MxEndActionNotificationParam& p_param) return 0; } -// STUB: LEGO1 0x10050a50 +// FUNCTION: LEGO1 0x10050a50 MxLong LegoAct2::HandleTransitionEnd() { - // TODO - return 0; + if (m_destLocation != LegoGameState::e_undefined) { + GameState()->SwitchArea(m_destLocation); + m_destLocation = LegoGameState::e_undefined; + } + + return 1; } // STUB: LEGO1 0x10050a80 @@ -393,7 +397,7 @@ MxBool LegoAct2::Escape() m_gameState->m_unk0x0c = 0; } - m_unk0x1150 = 2; + m_destLocation = LegoGameState::e_infomain; return TRUE; } From 362551e2796c36e631582a09220dd29a36f6993a Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Fri, 29 Nov 2024 22:31:37 +0100 Subject: [PATCH 10/13] Clean up unused annotations to reduce errors (#1177) Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/buildings.h | 6 +++--- LEGO1/lego/legoomni/src/common/legovariables.cpp | 4 ++-- LEGO1/lego/legoomni/src/race/legoracers.cpp | 2 +- LEGO1/library_msvc.h | 3 --- LEGO1/mxdirectx/mxdirectdraw.cpp | 3 ++- LEGO1/tgl/d3drm/renderer.cpp | 2 +- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/LEGO1/lego/legoomni/include/buildings.h b/LEGO1/lego/legoomni/include/buildings.h index 57152a2a..469a4936 100644 --- a/LEGO1/lego/legoomni/include/buildings.h +++ b/LEGO1/lego/legoomni/include/buildings.h @@ -11,7 +11,7 @@ class RaceStandsEntity : public BuildingEntity { // FUNCTION: LEGO1 0x1000efa0 const char* ClassName() const override // vtable+0x0c { - // STRING: LEGO1 0x100f0300 + // at LEGO1 0x100f0300, needs no annotation return "RaceStandsEntity"; } @@ -125,7 +125,7 @@ class CaveEntity : public BuildingEntity { // FUNCTION: LEGO1 0x1000f1e0 const char* ClassName() const override // vtable+0x0c { - // STRING: LEGO1 0x100f0300 + // at LEGO1 0x100f0300, needs no annotation return "RaceStandsEntity"; } @@ -147,7 +147,7 @@ class JailEntity : public BuildingEntity { // FUNCTION: LEGO1 0x1000f0c0 const char* ClassName() const override // vtable+0x0c { - // STRING: LEGO1 0x100f0300 + // at LEGO1 0x100f0300, needs no annotation return "RaceStandsEntity"; } diff --git a/LEGO1/lego/legoomni/src/common/legovariables.cpp b/LEGO1/lego/legoomni/src/common/legovariables.cpp index da6b30fd..539983bf 100644 --- a/LEGO1/lego/legoomni/src/common/legovariables.cpp +++ b/LEGO1/lego/legoomni/src/common/legovariables.cpp @@ -56,8 +56,8 @@ const char* g_varTOWSPEED = "towSPEED"; // STRING: LEGO1 0x100f439c const char* g_varTOWFUEL = "towFUEL"; +// the STRING is already declared for GLOBAL 0x101020cc // GLOBAL: LEGO1 0x100f3a40 -// STRING: LEGO1 0x100f3808 const char* g_varVISIBILITY = "VISIBILITY"; // GLOBAL: LEGO1 0x100f3a44 @@ -72,8 +72,8 @@ const char* g_varCURSOR = "CURSOR"; // STRING: LEGO1 0x100f3a1c const char* g_varWHOAMI = "WHO_AM_I"; +// the STRING is already declared at LEGO1 0x100f3fb0 // GLOBAL: LEGO1 0x100f3a50 -// STRING: LEGO1 0x100f3a18 const char* g_delimiter2 = " \t"; // GLOBAL: LEGO1 0x100f3a54 diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index a313c610..b0214bc1 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -67,8 +67,8 @@ const SkeletonKickPhase LegoRaceCar::g_skeletonKickPhases[] = { {&LegoRaceCar::g_skBMap[3], 0.8, 0.9, LEGORACECAR_KICK2}, }; +// the STRING is already declared at LEGO1 0x101020b8 // GLOBAL: LEGO1 0x100f0b10 -// STRING: LEGO1 0x100f09cc const char* LegoRaceCar::g_strSpeed = "SPEED"; // GLOBAL: LEGO1 0x100f0b18 diff --git a/LEGO1/library_msvc.h b/LEGO1/library_msvc.h index 179f4222..94811d12 100644 --- a/LEGO1/library_msvc.h +++ b/LEGO1/library_msvc.h @@ -281,9 +281,6 @@ // LIBRARY: LEGO1 0x1008fdd0 // __dosmaperr -// LIBRARY: LEGO1 0x1008fe30 -// __unlock_file - // LIBRARY: LEGO1 0x1008fe50 // __errno diff --git a/LEGO1/mxdirectx/mxdirectdraw.cpp b/LEGO1/mxdirectx/mxdirectdraw.cpp index 50d7158b..b6279636 100644 --- a/LEGO1/mxdirectx/mxdirectdraw.cpp +++ b/LEGO1/mxdirectx/mxdirectdraw.cpp @@ -873,8 +873,9 @@ int MxDirectDraw::FlipToGDISurface() // FUNCTION: LEGO1 0x1009e830 void MxDirectDraw::Error(const char* p_message, int p_error) { - // GLOBAL: LEGO1 0x10100c70 + // at LEGO1 0x10100c70, needs no annotation static BOOL g_isInsideError = FALSE; + if (!g_isInsideError) { g_isInsideError = TRUE; Destroy(); diff --git a/LEGO1/tgl/d3drm/renderer.cpp b/LEGO1/tgl/d3drm/renderer.cpp index c310b996..e94f3592 100644 --- a/LEGO1/tgl/d3drm/renderer.cpp +++ b/LEGO1/tgl/d3drm/renderer.cpp @@ -49,7 +49,7 @@ Device* RendererImpl::CreateDevice(const DeviceDirect3DCreateData& data) // FUNCTION: LEGO1 0x100a1900 Device* RendererImpl::CreateDevice(const DeviceDirectDrawCreateData& data) { - // GLOBAL: LEGO1 0x10101040 + // at LEGO1 0x10101040, needs no annotation static int g_SetBufferCount = 1; DeviceImpl* device = new DeviceImpl(); From e8e457f01ae7c47ef6b4fb668a6835952d58a1b1 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 29 Nov 2024 14:32:40 -0700 Subject: [PATCH 11/13] Implement/match LegoAct2::Enable (#1178) --- LEGO1/lego/legoomni/include/act2brick.h | 3 +- LEGO1/lego/legoomni/include/act3.h | 11 +- LEGO1/lego/legoomni/include/legoact2.h | 30 ++-- LEGO1/lego/legoomni/include/misc.h | 2 +- LEGO1/lego/legoomni/src/actors/buildings.cpp | 4 +- LEGO1/lego/legoomni/src/actors/helicopter.cpp | 2 +- LEGO1/lego/legoomni/src/common/misc.cpp | 4 +- LEGO1/lego/legoomni/src/entity/act2brick.cpp | 13 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 131 +++++++++++++++--- 9 files changed, 156 insertions(+), 44 deletions(-) diff --git a/LEGO1/lego/legoomni/include/act2brick.h b/LEGO1/lego/legoomni/include/act2brick.h index 1ff4529e..a0399730 100644 --- a/LEGO1/lego/legoomni/include/act2brick.h +++ b/LEGO1/lego/legoomni/include/act2brick.h @@ -31,7 +31,8 @@ class Act2Brick : public LegoPathActor { // SYNTHETIC: LEGO1 0x1007a450 // Act2Brick::`scalar deleting destructor' - void StopSound(); + void PlayWhistleSound(); + void StopWhistleSound(); private: static MxLong g_lastHitActorTime; diff --git a/LEGO1/lego/legoomni/include/act3.h b/LEGO1/lego/legoomni/include/act3.h index 888fc08a..9e5a6d74 100644 --- a/LEGO1/lego/legoomni/include/act3.h +++ b/LEGO1/lego/legoomni/include/act3.h @@ -1,6 +1,7 @@ #ifndef ACT3_H #define ACT3_H +#include "legogamestate.h" #include "legostate.h" #include "legoworld.h" @@ -69,7 +70,7 @@ class Act3 : public LegoWorld { void Enable(MxBool p_enable) override; // vtable+0x68 void SetUnknown420c(MxEntity* p_entity) { m_unk0x420c = p_entity; } - void SetUnknown4270(MxU32 p_unk0x4270) { m_unk0x4270 = p_unk0x4270; } + void SetDestLocation(LegoGameState::Area p_destLocation) { m_destLocation = p_destLocation; } // SYNTHETIC: LEGO1 0x10072630 // Act3::`scalar deleting destructor' @@ -80,10 +81,10 @@ class Act3 : public LegoWorld { void FUN_10073430(); protected: - undefined m_unk0xf8[0x4114]; // 0xf8 - MxEntity* m_unk0x420c; // 0x420c - undefined m_unk0x4210[0x60]; // 0x4210 - MxU32 m_unk0x4270; // 0x4270 + undefined m_unk0xf8[0x4114]; // 0xf8 + MxEntity* m_unk0x420c; // 0x420c + undefined m_unk0x4210[0x60]; // 0x4210 + LegoGameState::Area m_destLocation; // 0x4270 }; #endif // ACT3_H diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index c73e0c55..0af48ca0 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -17,7 +17,7 @@ class LegoAct2State : public LegoState { LegoAct2State() { m_unk0x08 = 0; - m_unk0x0c = 0; + m_enabled = 0; } ~LegoAct2State() override {} @@ -41,12 +41,11 @@ class LegoAct2State : public LegoState { // LegoAct2State::`scalar deleting destructor' undefined4 GetUnknown0x08() { return m_unk0x08; } - void SetUnknown0x0c(undefined p_unk0x0c) { m_unk0x0c = p_unk0x0c; } // TODO: Most likely getters/setters are not used according to BETA. undefined4 m_unk0x08; // 0x08 - undefined m_unk0x0c; // 0x0c + MxBool m_enabled; // 0x0c }; // VTABLE: LEGO1 0x100d82e0 @@ -85,23 +84,26 @@ class LegoAct2 : public LegoWorld { MxLong HandleEndAction(MxEndActionNotificationParam& p_param); MxLong HandleTransitionEnd(); MxLong HandlePathStruct(LegoPathStructNotificationParam& p_param); + void PlayMusic(JukeboxScript::Script p_objectId); void FUN_10051900(); + void InitBricks(); + void UninitBricks(); - Act2Brick m_bricks[10]; // 0x00f8 - undefined m_unk0x10c0; // 0x10c0 - undefined m_unk0x10c1; // 0x10c1 - undefined m_unk0x10c2; // 0x10c2 - undefined4 m_unk0x10c4; // 0x10c4 - undefined4 m_unk0x10c8; // 0x10c8 - LegoAct2State* m_gameState; // 0x10cc - MxS32 m_unk0x10d0; // 0x10d0 + Act2Brick m_bricks[10]; // 0x00f8 + undefined m_unk0x10c0; // 0x10c0 + undefined m_unk0x10c1; // 0x10c1 + undefined m_unk0x10c2; // 0x10c2 + undefined4 m_unk0x10c4; // 0x10c4 + JukeboxScript::Script m_music; // 0x10c8 + LegoAct2State* m_gameState; // 0x10cc + MxS32 m_unk0x10d0; // 0x10d0 // variable name verified by BETA10 0x10014633 char* m_siFile; // 0x10d4 - LegoROI* m_unk0x10d8; // 0x10d8 + LegoROI* m_pepper; // 0x10d8 MxMatrix m_unk0x10dc; // 0x10dc - undefined4 m_unk0x1124; // 0x1124 + LegoPathBoundary* m_unk0x1124; // 0x1124 LegoROI* m_ambulance; // 0x1128 undefined4 m_unk0x112c; // 0x112c undefined4 m_unk0x1130; // 0x1130 @@ -109,7 +111,7 @@ class LegoAct2 : public LegoWorld { Act2Actor* m_unk0x1138; // 0x1138 undefined m_unk0x113c; // 0x113c undefined4 m_unk0x1140; // 0x1140 - undefined4 m_unk0x1144; // 0x1144 + Act2mainScript::Script m_unk0x1144; // 0x1144 undefined m_unk0x1148[0x08]; // 0x1148 LegoGameState::Area m_destLocation; // 0x1150 }; diff --git a/LEGO1/lego/legoomni/include/misc.h b/LEGO1/lego/legoomni/include/misc.h index 9f476ae9..374b83f2 100644 --- a/LEGO1/lego/legoomni/include/misc.h +++ b/LEGO1/lego/legoomni/include/misc.h @@ -58,7 +58,7 @@ LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid); MxDSAction& GetCurrentAction(); void SetCurrentWorld(LegoWorld* p_world); MxTransitionManager* TransitionManager(); -void PlayMusic(JukeboxScript::Script p_script); +void PlayMusic(JukeboxScript::Script p_objectId); void SetIsWorldActive(MxBool p_isWorldActive); void DeleteObjects(MxAtomId* p_id, MxS32 p_first, MxS32 p_last); diff --git a/LEGO1/lego/legoomni/src/actors/buildings.cpp b/LEGO1/lego/legoomni/src/actors/buildings.cpp index 64188031..ea7069cc 100644 --- a/LEGO1/lego/legoomni/src/actors/buildings.cpp +++ b/LEGO1/lego/legoomni/src/actors/buildings.cpp @@ -62,13 +62,13 @@ MxLong InfoCenterEntity::HandleClick(LegoEventNotificationParam& p_param) LegoAct2State* act2state = (LegoAct2State*) GameState()->GetState("LegoAct2State"); if (act2state) { - act2state->SetUnknown0x0c(0); + act2state->m_enabled = FALSE; } break; } case LegoGameState::Act::e_act3: Act3* act3 = (Act3*) FindWorld(*g_act3Script, Act3Script::c__Act3); - act3->SetUnknown4270(2); + act3->SetDestLocation(LegoGameState::e_infomain); break; } diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 20088cf3..395ef5a6 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -173,7 +173,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param) switch (p_param.GetClickedObjectId()) { case IsleScript::c_HelicopterArms_Ctl: if (*g_act3Script == script) { - ((Act3*) CurrentWorld())->SetUnknown4270(2); + ((Act3*) CurrentWorld())->SetDestLocation(LegoGameState::e_infomain); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); } else if (m_state->GetUnkown8() != 0) { diff --git a/LEGO1/lego/legoomni/src/common/misc.cpp b/LEGO1/lego/legoomni/src/common/misc.cpp index 654a4b3d..5913ff74 100644 --- a/LEGO1/lego/legoomni/src/common/misc.cpp +++ b/LEGO1/lego/legoomni/src/common/misc.cpp @@ -208,11 +208,11 @@ MxTransitionManager* TransitionManager() } // FUNCTION: LEGO1 0x10015910 -void PlayMusic(JukeboxScript::Script p_script) +void PlayMusic(JukeboxScript::Script p_objectId) { MxDSAction action; action.SetAtomId(*g_jukeboxScript); - action.SetObjectId(p_script); + action.SetObjectId(p_objectId); LegoOmni::GetInstance()->GetBackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating); } diff --git a/LEGO1/lego/legoomni/src/entity/act2brick.cpp b/LEGO1/lego/legoomni/src/entity/act2brick.cpp index a5811f26..9724f3b4 100644 --- a/LEGO1/lego/legoomni/src/entity/act2brick.cpp +++ b/LEGO1/lego/legoomni/src/entity/act2brick.cpp @@ -79,7 +79,7 @@ MxLong Act2Brick::Notify(MxParam& p_param) m_roi->SetVisibility(FALSE); if (m_whistleSound != NULL) { - StopSound(); + StopWhistleSound(); } MxNotificationParam param(c_notificationType22, this); @@ -90,9 +90,18 @@ MxLong Act2Brick::Notify(MxParam& p_param) return 0; } +// FUNCTION: LEGO1 0x1007a990 +// FUNCTION: BETA10 0x10012fca +void Act2Brick::PlayWhistleSound() +{ + if (m_whistleSound == NULL) { + m_whistleSound = SoundManager()->GetCacheSoundManager()->Play("xwhistle", m_roi->GetName(), TRUE); + } +} + // FUNCTION: LEGO1 0x1007a9d0 // FUNCTION: BETA10 0x1001300f -void Act2Brick::StopSound() +void Act2Brick::StopWhistleSound() { if (m_whistleSound != NULL) { SoundManager()->GetCacheSoundManager()->Stop(m_whistleSound); diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 7612bc34..ac120934 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -4,6 +4,7 @@ #include "act2main_actions.h" #include "infomain_actions.h" #include "islepathactor.h" +#include "jukebox_actions.h" #include "legoanimationmanager.h" #include "legocachesoundmanager.h" #include "legogamestate.h" @@ -11,6 +12,7 @@ #include "legomain.h" #include "legopathstruct.h" #include "legosoundmanager.h" +#include "legoutils.h" #include "misc.h" #include "mxactionnotificationparam.h" #include "mxbackgroundaudiomanager.h" @@ -18,6 +20,7 @@ #include "mxmisc.h" #include "mxnotificationmanager.h" #include "mxticklemanager.h" +#include "scripts.h" #include @@ -49,7 +52,7 @@ LegoAct2::LegoAct2() { m_unk0x10c4 = 0; m_gameState = NULL; - m_unk0x10d8 = NULL; + m_pepper = NULL; m_ambulance = NULL; m_unk0x10c2 = 0; m_unk0x1130 = 0; @@ -57,9 +60,9 @@ LegoAct2::LegoAct2() m_unk0x10c1 = 0; m_unk0x1138 = NULL; m_unk0x1140 = 0; - m_unk0x1144 = 0; + m_unk0x1144 = Act2mainScript::c__Act2Main; m_destLocation = LegoGameState::e_undefined; - m_unk0x10c8 = 0; + m_music = JukeboxScript::c_MusicTheme1; m_siFile = ""; m_unk0x113c = 5; NotificationManager()->Register(this); @@ -150,7 +153,7 @@ MxResult LegoAct2::Tickle() m_unk0x10c4 = 1; break; case 1: - ((LegoPathActor*) m_unk0x10d8->GetEntity())->SetState(LegoPathActor::c_bit3); + ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3); switch (rand() % 3) { case 0: @@ -201,12 +204,12 @@ MxResult LegoAct2::Tickle() distance = DISTSQRD3(pepperPosition, otherPoint); - if (m_unk0x1144 == 0 && distance > 50.0f && pepperPosition[0] > -57.0f) { + if (m_unk0x1144 == Act2mainScript::c__Act2Main && distance > 50.0f && pepperPosition[0] > -57.0f) { FUN_10052560(Act2mainScript::c_Avo906In_PlayWav, FALSE, FALSE, NULL, NULL, NULL); m_unk0x1144 = Act2mainScript::c_Avo906In_PlayWav; } } - else if (m_unk0x10d0 >= 90000 && m_unk0x10d0 % 90000 == 0 && m_unk0x1144 == 0) { + else if (m_unk0x10d0 >= 90000 && m_unk0x10d0 % 90000 == 0 && m_unk0x1144 == Act2mainScript::c__Act2Main) { FUN_10052560(Act2mainScript::c_Avo908In_PlayWav, FALSE, FALSE, NULL, NULL, NULL); m_unk0x1144 = Act2mainScript::c_Avo908In_PlayWav; } @@ -266,7 +269,7 @@ MxLong LegoAct2::Notify(MxParam& p_param) m_ambulance = FindROI("ambul"); } - if (entity->GetROI() == m_unk0x10d8) { + if (entity->GetROI() == m_pepper) { HandlePathStruct(param); } @@ -283,12 +286,12 @@ MxLong LegoAct2::Notify(MxParam& p_param) LegoEntity* entity = (LegoEntity*) param.GetSender(); Mx3DPointFloat entityPosition(entity->GetROI()->GetWorldPosition()); - Mx3DPointFloat unk0x10d8(m_unk0x10d8->GetWorldPosition()); + Mx3DPointFloat unk0x10d8(m_pepper->GetWorldPosition()); Mx3DPointFloat locala4(unk0x10d8); ((Vector3&) entityPosition).Sub(unk0x10d8); - MxMatrix local2world(m_unk0x10d8->GetLocal2World()); + MxMatrix local2world(m_pepper->GetLocal2World()); Vector3 local30(local2world[0]); Vector3 localac(local2world[1]); Vector3 local28(local2world[2]); @@ -309,7 +312,7 @@ MxLong LegoAct2::Notify(MxParam& p_param) m_unk0x10c4 = 14; m_unk0x10d0 = 0; - ((LegoPathActor*) m_unk0x10d8->GetEntity())->SetState(LegoPathActor::c_bit3); + ((LegoPathActor*) m_pepper->GetEntity())->SetState(LegoPathActor::c_bit3); } break; case c_notificationTransitioned: @@ -345,11 +348,76 @@ void LegoAct2::ReadyWorld() // TODO } -// STUB: LEGO1 0x10050cf0 -// STUB: BETA10 0x1003bb2d +// FUNCTION: LEGO1 0x10050cf0 +// FUNCTION: BETA10 0x1003bb2d void LegoAct2::Enable(MxBool p_enable) { - // TODO + if (m_set0xd0.empty() == p_enable) { + return; + } + + LegoWorld::Enable(p_enable); + + if (p_enable) { + m_gameState->m_enabled = TRUE; + + GameState()->SetActor(LegoActor::c_pepper); + m_pepper = FindROI("pepper"); + + ((IslePathActor*) m_pepper->GetEntity())->VTable0xec(m_unk0x10dc, m_unk0x1124, TRUE); + + if (GameState()->GetPreviousArea() == LegoGameState::e_infomain) { + GameState()->StopArea(LegoGameState::e_infomain); + } + + FUN_10015820(FALSE, LegoOmni::c_disableInput | LegoOmni::c_disable3d | LegoOmni::c_clearScreen); + + if (m_unk0x10c4 != 6 && m_unk0x10c4 != 12) { + PlayMusic(m_music); + } + + if (m_unk0x10c4 == 10 && m_unk0x10c0 == 6 && m_bricks[5].GetROI() != NULL) { + m_bricks[5].PlayWhistleSound(); + } + else if (m_unk0x10c4 == 13) { + InitBricks(); + } + + TickleManager()->RegisterClient(this, 20); + SetAppCursor(e_cursorArrow); + + if (m_unk0x10c4 == 2 || m_unk0x10c4 == 4 || m_unk0x10c4 == 6 || m_unk0x10c4 == 11 || m_unk0x10c4 == 12 || + m_unk0x10c4 == 14) { + MxDSAction action; + MxEndActionNotificationParam param(c_notificationEndAction, NULL, &action, FALSE); + + m_unk0x1140 = 0; + action.SetObjectId(0); + HandleEndAction(param); + } + + GameState()->m_isDirty = TRUE; + } + else { + m_unk0x10dc = m_pepper->GetLocal2World(); + m_unk0x1124 = ((LegoPathActor*) m_pepper->GetEntity())->GetBoundary(); + + FUN_10051900(); + BackgroundAudioManager()->Stop(); + UninitBricks(); + DeleteObjects(&m_atomId, Act2mainScript::c_VOhead0_PlayWav, Act2mainScript::c_VOhide_PlayWav); + + if (m_unk0x1144 != Act2mainScript::c__Act2Main) { + MxDSAction action; + action.SetAtomId(m_atomId); + action.SetUnknown24(-2); + action.SetObjectId(m_unk0x1144); + DeleteObject(action); + m_unk0x1144 = Act2mainScript::c__Act2Main; + } + + TickleManager()->UnregisterClient(this); + } } // STUB: LEGO1 0x10051460 @@ -360,6 +428,17 @@ MxLong LegoAct2::HandlePathStruct(LegoPathStructNotificationParam& p_param) return 0; } +// FUNCTION: LEGO1 0x10051840 +void LegoAct2::PlayMusic(JukeboxScript::Script p_objectId) +{ + MxDSAction action; + action.SetAtomId(*g_jukeboxScript); + action.SetObjectId(p_objectId); + + BackgroundAudioManager()->PlayMusic(action, 5, MxPresenter::e_repeating); + m_music = p_objectId; +} + // FUNCTION: LEGO1 0x10051900 // FUNCTION: BETA10 0x1003bed1 void LegoAct2::FUN_10051900() @@ -394,13 +473,33 @@ MxBool LegoAct2::Escape() } if (m_gameState != NULL) { - m_gameState->m_unk0x0c = 0; + m_gameState->m_enabled = FALSE; } m_destLocation = LegoGameState::e_infomain; return TRUE; } +// FUNCTION: LEGO1 0x10051a60 +void LegoAct2::InitBricks() +{ + for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_bricks); i++) { + if (m_bricks[i].GetROI() != NULL && m_bricks[i].GetROI()->GetVisibility()) { + m_bricks[i].PlayWhistleSound(); + } + } +} + +// FUNCTION: LEGO1 0x10051a90 +void LegoAct2::UninitBricks() +{ + for (MxS32 i = 0; i < (MxS32) sizeOfArray(m_bricks); i++) { + if (m_bricks[i].GetROI() != NULL) { + m_bricks[i].StopWhistleSound(); + } + } +} + // FUNCTION: LEGO1 0x10052560 // FUNCTION: BETA10 0x100145c6 undefined4 LegoAct2::FUN_10052560( @@ -420,8 +519,8 @@ undefined4 LegoAct2::FUN_10052560( MxDSAction action; action.SetObjectId(p_param1); - // not entirely sure about the constant - action.SetAtomId(*Lego()->GetWorldAtom(InfomainScript::c_Cop_Ctl)); + // World index: see LegoOmni::RegisterWorlds + action.SetAtomId(*Lego()->GetWorldAtom(15)); if (p_location) { action.SetUp(Mx3DPointFloat(0.0f, 1.0f, 0.0f)); From c0965039d18b9288cbe05f7abe811d3c5ce697d1 Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 29 Nov 2024 14:45:57 -0700 Subject: [PATCH 12/13] Improve Isle::Enable and LegoAct2::Enable matches (#1179) --- LEGO1/lego/legoomni/src/worlds/isle.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 190ad2ef..a01aece9 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -532,7 +532,7 @@ MxLong Isle::HandlePathStruct(LegoPathStructNotificationParam& p_param) // FUNCTION: BETA10 0x10034158 void Isle::Enable(MxBool p_enable) { - if (m_set0xd0.empty() == p_enable) { + if ((MxBool) m_set0xd0.empty() == p_enable) { return; } diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index ac120934..7f5d967c 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -352,7 +352,7 @@ void LegoAct2::ReadyWorld() // FUNCTION: BETA10 0x1003bb2d void LegoAct2::Enable(MxBool p_enable) { - if (m_set0xd0.empty() == p_enable) { + if ((MxBool) m_set0xd0.empty() == p_enable) { return; } From f56ffddfdcf70d48224e504ab403da832091853e Mon Sep 17 00:00:00 2001 From: Christian Semmler Date: Fri, 29 Nov 2024 23:22:53 +0100 Subject: [PATCH 13/13] Update legoact2.h --- LEGO1/lego/legoomni/include/legoact2.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/LEGO1/lego/legoomni/include/legoact2.h b/LEGO1/lego/legoomni/include/legoact2.h index 0af48ca0..34c694c7 100644 --- a/LEGO1/lego/legoomni/include/legoact2.h +++ b/LEGO1/lego/legoomni/include/legoact2.h @@ -17,7 +17,7 @@ class LegoAct2State : public LegoState { LegoAct2State() { m_unk0x08 = 0; - m_enabled = 0; + m_enabled = FALSE; } ~LegoAct2State() override {}