From bd713706028dfcd54e81c0bafa4c5330fa479fdc Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Sat, 19 Jul 2025 01:09:37 +0200 Subject: [PATCH 1/9] Clear unknown in `LegoControlManagerNotificationParam` (#1633) --- LEGO1/lego/legoomni/include/legocontrolmanager.h | 4 ++-- LEGO1/lego/legoomni/src/actors/ambulance.cpp | 4 ++-- LEGO1/lego/legoomni/src/actors/bike.cpp | 4 ++-- LEGO1/lego/legoomni/src/actors/dunebuggy.cpp | 4 ++-- LEGO1/lego/legoomni/src/actors/helicopter.cpp | 2 +- LEGO1/lego/legoomni/src/actors/jetski.cpp | 2 +- LEGO1/lego/legoomni/src/actors/motorcycle.cpp | 2 +- LEGO1/lego/legoomni/src/actors/skateboard.cpp | 2 +- LEGO1/lego/legoomni/src/actors/towtrack.cpp | 4 ++-- LEGO1/lego/legoomni/src/build/legocarbuild.cpp | 4 ++-- LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp | 4 ++-- LEGO1/lego/legoomni/src/race/carrace.cpp | 2 +- LEGO1/lego/legoomni/src/race/jetskirace.cpp | 2 +- LEGO1/lego/legoomni/src/race/legoracemap.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/gasstation.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/hospital.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/infocenter.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/isle.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/jukebox.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/police.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/registrationbook.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/score.cpp | 2 +- 24 files changed, 31 insertions(+), 31 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocontrolmanager.h b/LEGO1/lego/legoomni/include/legocontrolmanager.h index f962ee0c..680bef59 100644 --- a/LEGO1/lego/legoomni/include/legocontrolmanager.h +++ b/LEGO1/lego/legoomni/include/legocontrolmanager.h @@ -24,11 +24,11 @@ class LegoControlManagerNotificationParam : public LegoEventNotificationParam { void SetClickedObjectId(MxS32 p_clickedObjectId) { m_clickedObjectId = p_clickedObjectId; } void SetClickedAtom(const char* p_clickedAtom) { m_clickedAtom = p_clickedAtom; } - void SetUnknown0x28(MxS16 p_unk0x28) { m_unk0x28 = p_unk0x28; } + void SetEnabledChild(MxS16 p_enabledChild) { m_enabledChild = p_enabledChild; } MxS32 m_clickedObjectId; // 0x20 const char* m_clickedAtom; // 0x24 - MxS16 m_unk0x28; // 0x28 + MxS16 m_enabledChild; // 0x28 }; // SYNTHETIC: LEGO1 0x10028bf0 diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp index fa98fc65..0bc2a9e6 100644 --- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp +++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp @@ -437,7 +437,7 @@ MxLong Ambulance::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_AmbulanceArms_Ctl: Exit(); @@ -454,7 +454,7 @@ MxLong Ambulance::HandleControl(LegoControlManagerNotificationParam& p_param) case IsleScript::c_AmbulanceHorn_Ctl: MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "AmbulanceHorn_Sound"); - presenter->Enable(p_param.m_unk0x28); + presenter->Enable(p_param.m_enabledChild); break; } } diff --git a/LEGO1/lego/legoomni/src/actors/bike.cpp b/LEGO1/lego/legoomni/src/actors/bike.cpp index fa9bedcb..fbdce39e 100644 --- a/LEGO1/lego/legoomni/src/actors/bike.cpp +++ b/LEGO1/lego/legoomni/src/actors/bike.cpp @@ -81,7 +81,7 @@ MxLong Bike::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_BikeArms_Ctl: Exit(); @@ -97,7 +97,7 @@ MxLong Bike::HandleControl(LegoControlManagerNotificationParam& p_param) case IsleScript::c_BikeHorn_Ctl: MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "BikeHorn_Sound"); - presenter->Enable(p_param.m_unk0x28); + presenter->Enable(p_param.m_enabledChild); break; } } diff --git a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp index 562edfd9..d8244be4 100644 --- a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp +++ b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp @@ -121,7 +121,7 @@ MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_DuneCarArms_Ctl: Exit(); @@ -137,7 +137,7 @@ MxLong DuneBuggy::HandleControl(LegoControlManagerNotificationParam& p_param) case IsleScript::c_DuneCarHorn_Ctl: MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "DuneCarHorn_Sound"); - presenter->Enable(p_param.m_unk0x28); + presenter->Enable(p_param.m_enabledChild); break; } } diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 46353585..6cbb9675 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -189,7 +189,7 @@ MxLong Helicopter::HandleControl(LegoControlManagerNotificationParam& p_param) break; } - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { MxU32 isPizza = FALSE; switch (p_param.m_clickedObjectId) { diff --git a/LEGO1/lego/legoomni/src/actors/jetski.cpp b/LEGO1/lego/legoomni/src/actors/jetski.cpp index 2abc3862..03c3ca91 100644 --- a/LEGO1/lego/legoomni/src/actors/jetski.cpp +++ b/LEGO1/lego/legoomni/src/actors/jetski.cpp @@ -137,7 +137,7 @@ void Jetski::RemoveFromWorld() // FUNCTION: LEGO1 0x1007e8e0 MxLong Jetski::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1 && CurrentWorld()->IsA("Isle")) { + if (p_param.m_enabledChild == 1 && CurrentWorld()->IsA("Isle")) { switch (p_param.m_clickedObjectId) { case IsleScript::c_JetskiArms_Ctl: Exit(); diff --git a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp index 99810420..5dae1547 100644 --- a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp +++ b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp @@ -115,7 +115,7 @@ MxLong Motocycle::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_MotoBikeArms_Ctl: Exit(); diff --git a/LEGO1/lego/legoomni/src/actors/skateboard.cpp b/LEGO1/lego/legoomni/src/actors/skateboard.cpp index d47b2178..17730148 100644 --- a/LEGO1/lego/legoomni/src/actors/skateboard.cpp +++ b/LEGO1/lego/legoomni/src/actors/skateboard.cpp @@ -110,7 +110,7 @@ MxLong SkateBoard::HandleControl(LegoControlManagerNotificationParam& p_param) { MxU32 result = 0; - if (p_param.m_unk0x28 == 1 && p_param.m_clickedObjectId == IsleScript::c_SkateArms_Ctl) { + if (p_param.m_enabledChild == 1 && p_param.m_clickedObjectId == IsleScript::c_SkateArms_Ctl) { Exit(); GameState()->m_currentArea = LegoGameState::Area::e_vehicleExited; result = 1; diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp index 6c3f5785..7a54d593 100644 --- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp +++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp @@ -483,7 +483,7 @@ MxLong TowTrack::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case IsleScript::c_TowTrackArms_Ctl: Exit(); @@ -499,7 +499,7 @@ MxLong TowTrack::HandleControl(LegoControlManagerNotificationParam& p_param) break; case IsleScript::c_TowHorn_Ctl: MxSoundPresenter* presenter = (MxSoundPresenter*) CurrentWorld()->Find("MxSoundPresenter", "TowHorn_Sound"); - presenter->Enable(p_param.m_unk0x28); + presenter->Enable(p_param.m_enabledChild); break; } } diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index 8809cd5c..e1044c79 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -953,7 +953,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param; assert(m_buildState); - if (param->m_unk0x28) { + if (param->m_enabledChild) { switch (param->m_clickedObjectId) { // The enum values are all identical between CopterScript, DunecarScript, JetskiScript, and RacecarScript case CopterScript::c_Info_Ctl: @@ -1009,7 +1009,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) case CopterScript::c_Platform_Ctl: FUN_10024f50(); m_unk0xf8 = c_unknown8; - m_unk0xfc = param->m_unk0x28; + m_unk0xfc = param->m_enabledChild; result = 1; break; default: diff --git a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp index 9374cb9f..f39ad192 100644 --- a/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/mxcontrolpresenter.cpp @@ -154,7 +154,7 @@ MxBool MxControlPresenter::Notify(LegoControlManagerNotificationParam* p_param, p_param->SetClickedAtom(m_action->GetAtomId().GetInternal()); UpdateEnabledChild(0); p_param->SetNotification(c_notificationControl); - p_param->SetUnknown0x28(m_enabledChild); + p_param->SetEnabledChild(m_enabledChild); return TRUE; } break; @@ -164,7 +164,7 @@ MxBool MxControlPresenter::Notify(LegoControlManagerNotificationParam* p_param, p_param->SetClickedAtom(m_action->GetAtomId().GetInternal()); UpdateEnabledChild(m_stateOrCellIndex); p_param->SetNotification(c_notificationControl); - p_param->SetUnknown0x28(m_enabledChild); + p_param->SetEnabledChild(m_enabledChild); return TRUE; } break; diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index 18ea1c89..6c36223a 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -335,7 +335,7 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param) // FUNCTION: LEGO1 0x10017650 MxLong CarRace::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case 3: InvokeAction(Extra::e_stop, *g_carraceScript, CarraceScript::c_irtx08ra_PlayWav, NULL); diff --git a/LEGO1/lego/legoomni/src/race/jetskirace.cpp b/LEGO1/lego/legoomni/src/race/jetskirace.cpp index 2893868f..79391c6d 100644 --- a/LEGO1/lego/legoomni/src/race/jetskirace.cpp +++ b/LEGO1/lego/legoomni/src/race/jetskirace.cpp @@ -124,7 +124,7 @@ MxLong JetskiRace::HandleControl(LegoControlManagerNotificationParam& p_param) { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case JetraceScript::c_JetskiArms_Ctl: m_act1State->m_state = Act1State::e_none; diff --git a/LEGO1/lego/legoomni/src/race/legoracemap.cpp b/LEGO1/lego/legoomni/src/race/legoracemap.cpp index bd0a04bd..9637114d 100644 --- a/LEGO1/lego/legoomni/src/race/legoracemap.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracemap.cpp @@ -129,7 +129,7 @@ MxLong LegoRaceMap::Notify(MxParam& p_param) if (param.GetNotification() == c_notificationControl && m_Map_Ctl->GetAction()->GetObjectId() == ((LegoControlManagerNotificationParam&) p_param).m_clickedObjectId) { - if (((LegoControlManagerNotificationParam&) p_param).m_unk0x28 == 1) { + if (((LegoControlManagerNotificationParam&) p_param).m_enabledChild == 1) { m_unk0x08 = TRUE; FUN_1005d4b0(); m_stillPresenter->Enable(TRUE); diff --git a/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp b/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp index 2a9c0772..6e1d484d 100644 --- a/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp +++ b/LEGO1/lego/legoomni/src/worlds/elevatorbottom.cpp @@ -87,7 +87,7 @@ MxLong ElevatorBottom::HandleControl(LegoControlManagerNotificationParam& p_para { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case ElevbottScript::c_LeftArrow_Ctl: m_destLocation = LegoGameState::e_infodoor; diff --git a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp index 4a449ba2..271c94de 100644 --- a/LEGO1/lego/legoomni/src/worlds/gasstation.cpp +++ b/LEGO1/lego/legoomni/src/worlds/gasstation.cpp @@ -387,7 +387,7 @@ MxLong GasStation::HandleButtonDown(LegoControlManagerNotificationParam& p_param // FUNCTION: BETA10 0x10029445 MxLong GasStation::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { MxDSAction action; switch (p_param.m_clickedObjectId) { diff --git a/LEGO1/lego/legoomni/src/worlds/hospital.cpp b/LEGO1/lego/legoomni/src/worlds/hospital.cpp index 6ab9c218..2d44bc9c 100644 --- a/LEGO1/lego/legoomni/src/worlds/hospital.cpp +++ b/LEGO1/lego/legoomni/src/worlds/hospital.cpp @@ -553,7 +553,7 @@ MxLong Hospital::HandleButtonDown(LegoControlManagerNotificationParam& p_param) // FUNCTION: LEGO1 0x10075f90 MxBool Hospital::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case HospitalScript::c_Info_Ctl: BackgroundAudioManager()->RaiseVolume(); diff --git a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp index 19957ac8..67a21d69 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenter.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenter.cpp @@ -941,7 +941,7 @@ MxU8 Infocenter::HandleButtonUp(MxS32 p_x, MxS32 p_y) // FUNCTION: BETA10 0x1002ffd4 MxU8 Infocenter::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { m_infoManDialogueTimer = 0; InfomainScript::Script actionToPlay = InfomainScript::c_noneInfomain; diff --git a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp index 8f92a323..8dc21750 100644 --- a/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp +++ b/LEGO1/lego/legoomni/src/worlds/infocenterdoor.cpp @@ -96,7 +96,7 @@ MxLong InfocenterDoor::HandleControl(LegoControlManagerNotificationParam& p_para { MxLong result = 0; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { DeleteObjects(&m_atomId, InfodoorScript::c_iic037in_PlayWav, 510); switch (p_param.m_clickedObjectId) { diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 3ec9af8c..ba73754d 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -284,7 +284,7 @@ void Isle::ReadyWorld() // FUNCTION: LEGO1 0x10031030 MxLong Isle::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { MxDSAction action; switch (p_param.m_clickedObjectId) { diff --git a/LEGO1/lego/legoomni/src/worlds/jukebox.cpp b/LEGO1/lego/legoomni/src/worlds/jukebox.cpp index db244e00..aa8858cf 100644 --- a/LEGO1/lego/legoomni/src/worlds/jukebox.cpp +++ b/LEGO1/lego/legoomni/src/worlds/jukebox.cpp @@ -123,7 +123,7 @@ MxBool JukeBox::HandleControl(LegoControlManagerNotificationParam& p_param) { MxStillPresenter* presenter; - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case JukeboxwScript::c_Dback_Ctl: switch (m_state->m_music) { diff --git a/LEGO1/lego/legoomni/src/worlds/police.cpp b/LEGO1/lego/legoomni/src/worlds/police.cpp index 1c3bccd7..1cbcea48 100644 --- a/LEGO1/lego/legoomni/src/worlds/police.cpp +++ b/LEGO1/lego/legoomni/src/worlds/police.cpp @@ -101,7 +101,7 @@ void Police::ReadyWorld() // FUNCTION: LEGO1 0x1005e550 MxLong Police::HandleControl(LegoControlManagerNotificationParam& p_param) { - if (p_param.m_unk0x28 == 1) { + if (p_param.m_enabledChild == 1) { switch (p_param.m_clickedObjectId) { case PoliceScript::c_LeftArrow_Ctl: case PoliceScript::c_RightArrow_Ctl: diff --git a/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp b/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp index 6b177308..64f981ba 100644 --- a/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp +++ b/LEGO1/lego/legoomni/src/worlds/registrationbook.cpp @@ -226,7 +226,7 @@ MxLong RegistrationBook::HandleKeyPress(MxU8 p_key) // FUNCTION: LEGO1 0x100774a0 MxLong RegistrationBook::HandleControl(LegoControlManagerNotificationParam& p_param) { - MxS16 buttonId = p_param.m_unk0x28; + MxS16 buttonId = p_param.m_enabledChild; if (buttonId >= 1 && buttonId <= 28) { if (p_param.m_clickedObjectId == RegbookScript::c_Alphabet_Ctl) { diff --git a/LEGO1/lego/legoomni/src/worlds/score.cpp b/LEGO1/lego/legoomni/src/worlds/score.cpp index edc2d991..56dacaf1 100644 --- a/LEGO1/lego/legoomni/src/worlds/score.cpp +++ b/LEGO1/lego/legoomni/src/worlds/score.cpp @@ -165,7 +165,7 @@ void Score::ReadyWorld() // FUNCTION: LEGO1 0x100016d0 MxLong Score::FUN_100016d0(LegoControlManagerNotificationParam& p_param) { - MxS16 unk0x28 = p_param.m_unk0x28; + MxS16 unk0x28 = p_param.m_enabledChild; if (unk0x28 == 1 || p_param.m_clickedObjectId == InfoscorScript::c_LegoBox_Ctl) { switch (p_param.m_clickedObjectId) { From 29d7a5df8955812b7d146ac8127bc5546e2d640d Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Sat, 19 Jul 2025 12:24:49 +0200 Subject: [PATCH 2/9] Get BETA10 to compile again (#1635) Co-authored-by: jonschz --- LEGO1/lego/legoomni/src/build/legocarbuild.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index e1044c79..f50dcdfe 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -1051,7 +1051,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) LegoControlManagerNotificationParam* param = (LegoControlManagerNotificationParam*) p_param; assert(m_buildState); - if (param->m_unk0x28) { + if (param->m_enabledChild) { switch (param->m_clickedObjectId) { case CopterScript::c_Info_Ctl: m_animPresenter->SetShelfState(LegoCarBuildAnimPresenter::e_selected); @@ -1113,7 +1113,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) case CopterScript::c_Platform_Ctl: FUN_10024f50(); m_unk0xf8 = c_unknown8; - m_unk0xfc = param->m_unk0x28; + m_unk0xfc = param->m_enabledChild; result = 1; break; default: From 73d9ef1d8074665fdd43107a2befb5cd444c9e37 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Sat, 19 Jul 2025 16:28:35 +0200 Subject: [PATCH 3/9] Improve `FUN_10061010`, other fixes (#1634) Co-authored-by: jonschz --- .../legoomni/include/legoanimationmanager.h | 3 + .../lego/legoomni/include/legotraninfolist.h | 8 +++ .../src/common/legoanimationmanager.cpp | 69 ++++++++++++++----- .../src/common/legoanimmmpresenter.cpp | 21 ++++++ LEGO1/lego/legoomni/src/entity/legoworld.cpp | 2 + LEGO1/omni/include/mxlist.h | 6 +- LEGO1/realtime/orientableroi.cpp | 1 + 7 files changed, 90 insertions(+), 20 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index 60f63d4a..efe23bc2 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -303,4 +303,7 @@ class LegoAnimationManager : public MxCore { // TEMPLATE: LEGO1 0x10061750 // MxListCursor::MxListCursor +// TEMPLATE: BETA10 0x1004b5d0 +// MxListCursor::Next + #endif // LEGOANIMATIONMANAGER_H diff --git a/LEGO1/lego/legoomni/include/legotraninfolist.h b/LEGO1/lego/legoomni/include/legotraninfolist.h index 06cd2558..0bfe4bd8 100644 --- a/LEGO1/lego/legoomni/include/legotraninfolist.h +++ b/LEGO1/lego/legoomni/include/legotraninfolist.h @@ -28,9 +28,11 @@ class LegoTranInfoList : public MxPtrList { // class MxPtrListCursor // VTABLE: LEGO1 0x100d8d20 +// VTABLE: BETA10 0x101bad70 // SIZE 0x10 class LegoTranInfoListCursor : public MxPtrListCursor { public: + // FUNCTION: BETA10 0x100496d0 LegoTranInfoListCursor(LegoTranInfoList* p_list) : MxPtrListCursor(p_list) {} }; @@ -62,9 +64,14 @@ class LegoTranInfoListCursor : public MxPtrListCursor { // MxPtrList::`scalar deleting destructor' // SYNTHETIC: LEGO1 0x100612f0 +// SYNTHETIC: BETA10 0x100498c0 // LegoTranInfoListCursor::`scalar deleting destructor' +// SYNTHETIC: BETA10 0x10049770 +// MxPtrListCursor::MxPtrListCursor + // FUNCTION: LEGO1 0x10061360 +// FUNCTION: BETA10 0x10049910 // MxPtrListCursor::~MxPtrListCursor // SYNTHETIC: LEGO1 0x100613b0 @@ -77,6 +84,7 @@ class LegoTranInfoListCursor : public MxPtrListCursor { // MxListCursor::~MxListCursor // FUNCTION: LEGO1 0x100614e0 +// FUNCTION: BETA10 0x10049ab0 // LegoTranInfoListCursor::~LegoTranInfoListCursor #endif // LEGOTRANINFOLIST_H diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 616be97a..e6dd3513 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -20,6 +20,7 @@ #include "legoworld.h" #include "misc.h" #include "mxbackgroundaudiomanager.h" +#include "mxdebug.h" #include "mxmisc.h" #include "mxnotificationmanager.h" #include "mxticklemanager.h" @@ -1225,12 +1226,10 @@ void LegoAnimationManager::CameraTriggerFire(LegoPathActor* p_actor, MxBool, MxU } } -// FUNCTION: LEGO1 0x10061010 +#ifdef BETA10 // FUNCTION: BETA10 0x100422cc void LegoAnimationManager::FUN_10061010(MxBool p_und) { - MxBool unk0x39 = FALSE; - FUN_10064b50(-1); if (m_tranInfoList != NULL) { @@ -1238,17 +1237,47 @@ void LegoAnimationManager::FUN_10061010(MxBool p_und) LegoTranInfo* tranInfo; while (cursor.Next(tranInfo)) { - if (tranInfo->m_presenter != NULL) { - // TODO: Match - MxU32 flags = tranInfo->m_flags; + if (tranInfo->m_unk0x14 && tranInfo->m_location != -1) { + MxTrace("Releasing user from %d\n", tranInfo->m_objectId); + if (tranInfo->m_presenter != NULL) { + tranInfo->m_presenter->FUN_1004b8c0(); + } + + tranInfo->m_unk0x14 = FALSE; + } + else { + MxTrace("Stopping %d\n", tranInfo->m_objectId); + + if (tranInfo->m_presenter != NULL) { + tranInfo->m_presenter->FUN_1004b840(); + } + } + } + } + + m_animRunning = FALSE; + m_unk0x404 = Timer()->GetTime(); +} +#else +// FUNCTION: LEGO1 0x10061010 +void LegoAnimationManager::FUN_10061010(MxBool p_und) +{ + MxBool animRunning = FALSE; + FUN_10064b50(-1); + + if (m_tranInfoList != NULL) { + LegoTranInfoListCursor cursor(m_tranInfoList); + LegoTranInfo* tranInfo; + + while (cursor.Next(tranInfo)) { + if (tranInfo->m_presenter) { + // LINE: LEGO1 0x100610e6 if (tranInfo->m_unk0x14 && tranInfo->m_location != -1 && p_und) { - LegoAnim* anim; - - if (tranInfo->m_presenter->GetPresenter() != NULL && - (anim = tranInfo->m_presenter->GetPresenter()->GetAnimation()) != NULL && - anim->GetCamAnim() != NULL) { - if (flags & LegoTranInfo::c_bit2) { + if (tranInfo->m_presenter->GetPresenter() && + tranInfo->m_presenter->GetPresenter()->GetAnimation() && + tranInfo->m_presenter->GetPresenter()->GetAnimation()->GetCamAnim()) { + if (tranInfo->m_flags & LegoTranInfo::c_bit2) { BackgroundAudioManager()->RaiseVolume(); tranInfo->m_flags &= ~LegoTranInfo::c_bit2; } @@ -1257,37 +1286,43 @@ void LegoAnimationManager::FUN_10061010(MxBool p_und) tranInfo->m_unk0x14 = FALSE; } else { + MxTrace("Releasing user from %d\n", tranInfo->m_objectId); + // LINE: LEGO1 0x10061137 tranInfo->m_presenter->FUN_1004b8c0(); + animRunning = TRUE; tranInfo->m_unk0x14 = FALSE; - unk0x39 = TRUE; } } else { - if (flags & LegoTranInfo::c_bit2) { + if (tranInfo->m_flags & LegoTranInfo::c_bit2) { + // LINE: LEGO1 0x10061150 BackgroundAudioManager()->RaiseVolume(); tranInfo->m_flags &= ~LegoTranInfo::c_bit2; } + MxTrace("Stopping %d\n", tranInfo->m_objectId); tranInfo->m_presenter->FUN_1004b840(); } } else { if (m_tranInfoList2 != NULL) { LegoTranInfoListCursor cursor(m_tranInfoList2); - if (!cursor.Find(tranInfo)) { + // TODO: For some reason, the embedded `MxListEntry` constructor is not inlined. + // This may be the key for getting this function to match correctly. m_tranInfoList2->Append(tranInfo); } } - unk0x39 = TRUE; + animRunning = TRUE; } } } - m_animRunning = unk0x39; + m_animRunning = animRunning; m_unk0x404 = Timer()->GetTime(); } +#endif // FUNCTION: LEGO1 0x10061530 void LegoAnimationManager::FUN_10061530() diff --git a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp index ca6c2412..af32a238 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimmmpresenter.cpp @@ -425,6 +425,21 @@ MxBool LegoAnimMMPresenter::FUN_1004b6b0(MxLong p_time) // FUNCTION: BETA10 0x1004ce18 MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time) { +#ifdef BETA10 + switch (m_unk0x58) { + case 0: + break; + case 1: + break; + case 2: + break; + case 3: + break; + case 4: + break; + } +#endif + LegoROI* viewROI = VideoManager()->GetViewROI(); LegoPathActor* actor = UserActor(); @@ -455,9 +470,13 @@ MxBool LegoAnimMMPresenter::FUN_1004b6d0(MxLong p_time) m_world->PlaceActor(actor); } +#ifdef BETA10 + actor->VTable0xa8(); +#else if (m_tranInfo->m_unk0x29) { actor->VTable0xa8(); } +#endif } actor->SetActorState(LegoPathActor::c_initial); @@ -491,9 +510,11 @@ void LegoAnimMMPresenter::FUN_1004b840() FUN_1004b6d0(0); EndAction(); +#ifndef BETA10 if (action != NULL) { Streamer()->FUN_100b98f0(action); } +#endif } // FUNCTION: LEGO1 0x1004b8b0 diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index cc82fe92..f038f3b0 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -286,6 +286,7 @@ MxResult LegoWorld::PlaceActor( } // FUNCTION: LEGO1 0x1001fa70 +// FUNCTION: BETA10 0x100da328 MxResult LegoWorld::PlaceActor(LegoPathActor* p_actor) { LegoPathControllerListCursor cursor(&m_pathControllerList); @@ -301,6 +302,7 @@ MxResult LegoWorld::PlaceActor(LegoPathActor* p_actor) } // FUNCTION: LEGO1 0x1001fb70 +// FUNCTION: BETA10 0x100da3f1 MxResult LegoWorld::PlaceActor( LegoPathActor* p_actor, LegoAnimPresenter* p_presenter, diff --git a/LEGO1/omni/include/mxlist.h b/LEGO1/omni/include/mxlist.h index f6954168..980da86e 100644 --- a/LEGO1/omni/include/mxlist.h +++ b/LEGO1/omni/include/mxlist.h @@ -244,11 +244,11 @@ inline MxBool MxListCursor::Next() template inline MxBool MxListCursor::Next(T& p_obj) { - if (!m_match) { - m_match = m_list->m_first; + if (m_match) { + m_match = m_match->GetNext(); } else { - m_match = m_match->GetNext(); + m_match = m_list->m_first; } if (m_match) { diff --git a/LEGO1/realtime/orientableroi.cpp b/LEGO1/realtime/orientableroi.cpp index 92c9ac9e..3c45e90f 100644 --- a/LEGO1/realtime/orientableroi.cpp +++ b/LEGO1/realtime/orientableroi.cpp @@ -153,6 +153,7 @@ void OrientableROI::UpdateWorldDataWithTransformAndChildren(const Matrix4& p_tra } // FUNCTION: LEGO1 0x100a5a30 +// FUNCTION: BETA10 0x10167d31 void OrientableROI::SetWorldVelocity(const Vector3& p_world_velocity) { m_world_velocity = p_world_velocity; From 9e860d910cffcb85ef4ad284c8b3b4e31e0e31e7 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Sat, 19 Jul 2025 16:29:34 +0200 Subject: [PATCH 4/9] Name spawn areas (#1636) --- LEGO1/lego/legoomni/include/legogamestate.h | 10 +++++----- LEGO1/lego/legoomni/src/actors/helicopter.cpp | 2 +- LEGO1/lego/legoomni/src/actors/islepathactor.cpp | 10 +++++----- LEGO1/lego/legoomni/src/actors/jetski.cpp | 2 +- LEGO1/lego/legoomni/src/actors/towtrack.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/isle.cpp | 10 +++++----- 6 files changed, 18 insertions(+), 18 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h index e5dd9a26..99155ce0 100644 --- a/LEGO1/lego/legoomni/include/legogamestate.h +++ b/LEGO1/lego/legoomni/include/legogamestate.h @@ -103,19 +103,19 @@ class LegoGameState { e_dunecarbuild, e_jetskibuild, e_racecarbuild, - e_unk40, + e_helicopterSpawn, e_unk41, e_unk42, - e_unk43, - e_unk44, - e_unk45, + e_dunebuggySpawn, + e_racecarSpawn, + e_jetskiSpawn, e_act2main, e_act3script, e_unk48, e_unk49, e_unk50, e_unk51, - e_unk52, + e_towTrackHookedUp, e_jukeboxw, e_jukeboxExterior, e_unk55, diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 6cbb9675..358657b1 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -82,7 +82,7 @@ void Helicopter::Exit() if (GameState()->GetCurrentAct() == LegoGameState::e_act1) { SpawnPlayer( - LegoGameState::e_unk40, + LegoGameState::e_helicopterSpawn, TRUE, IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3 ); diff --git a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp index 9d5a3a22..d366761e 100644 --- a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp @@ -355,7 +355,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_PoliceStation_Music ); g_spawnLocations[16] = SpawnLocation( - LegoGameState::e_unk40, + LegoGameState::e_helicopterSpawn, g_isleScript, 0, "edg02_51", @@ -379,7 +379,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_noneJukebox ); g_spawnLocations[18] = SpawnLocation( - LegoGameState::e_unk43, + LegoGameState::e_dunebuggySpawn, g_isleScript, 0, "edg02_35", @@ -391,7 +391,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_noneJukebox ); g_spawnLocations[19] = SpawnLocation( - LegoGameState::e_unk44, + LegoGameState::e_racecarSpawn, g_isleScript, 0, "EDG03_01", @@ -403,7 +403,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_noneJukebox ); g_spawnLocations[20] = SpawnLocation( - LegoGameState::e_unk45, + LegoGameState::e_jetskiSpawn, g_isleScript, 0, "edg10_70", @@ -475,7 +475,7 @@ void IslePathActor::RegisterSpawnLocations() JukeboxScript::c_noneJukebox ); g_spawnLocations[26] = SpawnLocation( - LegoGameState::e_unk52, + LegoGameState::e_towTrackHookedUp, g_isleScript, 0, "edg02_19", diff --git a/LEGO1/lego/legoomni/src/actors/jetski.cpp b/LEGO1/lego/legoomni/src/actors/jetski.cpp index 03c3ca91..8b18b889 100644 --- a/LEGO1/lego/legoomni/src/actors/jetski.cpp +++ b/LEGO1/lego/legoomni/src/actors/jetski.cpp @@ -67,7 +67,7 @@ void Jetski::Animate(float p_time) // FUNCTION: LEGO1 0x1007e6f0 void Jetski::Exit() { - SpawnPlayer(LegoGameState::e_unk45, FALSE, c_spawnBit1 | c_playMusic | c_spawnBit3); + SpawnPlayer(LegoGameState::e_jetskiSpawn, FALSE, c_spawnBit1 | c_playMusic | c_spawnBit3); IslePathActor::Exit(); GameState()->m_currentArea = LegoGameState::e_jetski; RemoveFromWorld(); diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp index 7a54d593..c0531bb8 100644 --- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp +++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp @@ -432,7 +432,7 @@ MxLong TowTrack::HandleClick() } if (m_state->m_state == TowTrackMissionState::e_hookedUp) { - SpawnPlayer(LegoGameState::e_unk52, TRUE, 0); + SpawnPlayer(LegoGameState::e_towTrackHookedUp, TRUE, 0); FindROI("rcred")->SetVisibility(FALSE); } else { diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index ba73754d..556b09df 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -577,7 +577,7 @@ void Isle::Enable(MxBool p_enable) if (UserActor() != NULL && UserActor()->IsA("Jetski")) { IslePathActor* actor = (IslePathActor*) UserActor(); actor->SpawnPlayer( - LegoGameState::e_unk45, + LegoGameState::e_jetskiSpawn, FALSE, IslePathActor::c_spawnBit1 | IslePathActor::c_playMusic | IslePathActor::c_spawnBit3 ); @@ -1633,7 +1633,7 @@ void Act1State::PlaceActors() if (m_helicopter != NULL) { if (!m_helicopterPlane.IsPresent()) { - m_helicopter->SpawnPlayer(LegoGameState::e_unk40, FALSE, 0); + m_helicopter->SpawnPlayer(LegoGameState::e_helicopterSpawn, FALSE, 0); } else { isle->PlaceActor(m_helicopter, m_helicopterPlane.GetName(), 0, 0.5f, 1, 0.5f); @@ -1673,7 +1673,7 @@ void Act1State::PlaceActors() if (m_jetski != NULL) { if (!m_jetskiPlane.IsPresent()) { - m_jetski->SpawnPlayer(LegoGameState::e_unk45, FALSE, 0); + m_jetski->SpawnPlayer(LegoGameState::e_jetskiSpawn, FALSE, 0); } else { isle->PlaceActor(m_jetski, m_jetskiPlane.GetName(), 0, 0.5f, 1, 0.5f); @@ -1703,7 +1703,7 @@ void Act1State::PlaceActors() if (m_dunebuggy != NULL) { if (!m_dunebuggyPlane.IsPresent()) { - m_dunebuggy->SpawnPlayer(LegoGameState::e_unk43, FALSE, 0); + m_dunebuggy->SpawnPlayer(LegoGameState::e_dunebuggySpawn, FALSE, 0); } else { isle->PlaceActor(m_dunebuggy, m_dunebuggyPlane.GetName(), 0, 0.5f, 1, 0.5f); @@ -1731,7 +1731,7 @@ void Act1State::PlaceActors() if (m_racecar != NULL) { if (!m_racecarPlane.IsPresent()) { - m_racecar->SpawnPlayer(LegoGameState::e_unk44, FALSE, 0); + m_racecar->SpawnPlayer(LegoGameState::e_racecarSpawn, FALSE, 0); } else { isle->PlaceActor(m_racecar, m_racecarPlane.GetName(), 0, 0.5f, 1, 0.5f); From 6b5f3724c092b4bc185ed29c63d1d3f8974f4531 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Sun, 20 Jul 2025 07:57:26 +0200 Subject: [PATCH 5/9] Beta match `MxAutoLock` and `MxCriticalSection` (#1638) Co-authored-by: jonschz --- .../src/audio/legoloadcachesoundpresenter.cpp | 2 +- .../legoomni/src/audio/legosoundmanager.cpp | 2 +- .../src/video/legohideanimpresenter.cpp | 2 +- .../src/video/legolocomotionanimpresenter.cpp | 2 +- .../legoomni/src/video/legomodelpresenter.cpp | 2 +- .../src/video/legopalettepresenter.cpp | 2 +- .../legoomni/src/video/legopartpresenter.cpp | 2 +- LEGO1/omni/include/mxautolock.h | 12 +++++++ LEGO1/omni/include/mxcriticalsection.h | 11 +++++++ LEGO1/omni/src/audio/mxaudiomanager.cpp | 6 ++-- .../omni/src/audio/mxloopingmidipresenter.cpp | 2 +- LEGO1/omni/src/audio/mxmidipresenter.cpp | 4 +-- LEGO1/omni/src/audio/mxmusicmanager.cpp | 12 +++---- LEGO1/omni/src/audio/mxmusicpresenter.cpp | 2 +- LEGO1/omni/src/audio/mxsoundmanager.cpp | 6 ++-- LEGO1/omni/src/audio/mxsoundpresenter.cpp | 2 +- LEGO1/omni/src/audio/mxwavepresenter.cpp | 2 +- LEGO1/omni/src/event/mxeventmanager.cpp | 2 +- LEGO1/omni/src/event/mxeventpresenter.cpp | 2 +- LEGO1/omni/src/system/mxautolock.cpp | 14 ++++++++- LEGO1/omni/src/system/mxcriticalsection.cpp | 31 ++++++++++++++++++- .../omni/src/video/mxloopingflcpresenter.cpp | 4 +-- .../omni/src/video/mxloopingsmkpresenter.cpp | 2 +- LEGO1/omni/src/video/mxsmkpresenter.cpp | 2 +- LEGO1/omni/src/video/mxstillpresenter.cpp | 2 +- LEGO1/omni/src/video/mxvideomanager.cpp | 10 +++--- 26 files changed, 103 insertions(+), 39 deletions(-) diff --git a/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp b/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp index a0a66e89..0e5761b4 100644 --- a/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp +++ b/LEGO1/lego/legoomni/src/audio/legoloadcachesoundpresenter.cpp @@ -98,7 +98,7 @@ void LegoLoadCacheSoundPresenter::DoneTickle() // FUNCTION: LEGO1 0x10018700 MxResult LegoLoadCacheSoundPresenter::PutData() { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_currentTickleState == e_done) { m_cacheSound = SoundManager()->GetCacheSoundManager()->ManageSoundEntry(m_cacheSound); diff --git a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp index c92f2bea..a1657e46 100644 --- a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp @@ -46,7 +46,7 @@ MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) MxResult result = FAILURE; if (MxSoundManager::Create(10, FALSE) == SUCCESS) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; if (MxOmni::IsSound3D()) { diff --git a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp index 60f8dce5..03cc147e 100644 --- a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp @@ -29,7 +29,7 @@ void LegoHideAnimPresenter::Init() // FUNCTION: LEGO1 0x1006da60 void LegoHideAnimPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_boundaryMap) { delete[] m_boundaryMap; diff --git a/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp index 90b98e91..32e37669 100644 --- a/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp @@ -38,7 +38,7 @@ void LegoLocomotionAnimPresenter::Init() // FUNCTION: LEGO1 0x1006d0e0 void LegoLocomotionAnimPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_unk0xc4) { delete[] m_unk0xc4; diff --git a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp index dcaab81d..b09dbd60 100644 --- a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp @@ -33,7 +33,7 @@ void LegoModelPresenter::configureLegoModelPresenter(MxS32 p_modelPresenterConfi // FUNCTION: LEGO1 0x1007f670 void LegoModelPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); m_roi = NULL; m_addedToView = FALSE; m_criticalSection.Leave(); diff --git a/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp b/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp index 6ad7f6ec..f958385d 100644 --- a/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legopalettepresenter.cpp @@ -31,7 +31,7 @@ void LegoPalettePresenter::Init() // FUNCTION: LEGO1 0x1007a0e0 void LegoPalettePresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_palette) { delete m_palette; } diff --git a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp index 88e31dd6..c7edf8f3 100644 --- a/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legopartpresenter.cpp @@ -37,7 +37,7 @@ MxResult LegoPartPresenter::AddToManager() // FUNCTION: LEGO1 0x1007c9d0 void LegoPartPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); VideoManager()->UnregisterPresenter(*this); if (m_parts) { diff --git a/LEGO1/omni/include/mxautolock.h b/LEGO1/omni/include/mxautolock.h index 8a2b3c35..6a26ba47 100644 --- a/LEGO1/omni/include/mxautolock.h +++ b/LEGO1/omni/include/mxautolock.h @@ -3,15 +3,27 @@ class MxCriticalSection; +#ifdef BETA10 +#define AUTOLOCK(CS) MxAutoLock lock(&CS, __FILE__, __LINE__) +#else #define AUTOLOCK(CS) MxAutoLock lock(&CS) +#endif class MxAutoLock { public: +#ifdef BETA10 + MxAutoLock(MxCriticalSection* p_criticalSection, const char* filename, int line); +#else MxAutoLock(MxCriticalSection* p_criticalSection); +#endif ~MxAutoLock(); private: MxCriticalSection* m_criticalSection; // 0x00 + +#ifdef BETA10 + unsigned long m_currentThreadId; // 0x04 +#endif }; #endif // MXAUTOLOCK_H diff --git a/LEGO1/omni/include/mxcriticalsection.h b/LEGO1/omni/include/mxcriticalsection.h index 23c3fb76..7e24a947 100644 --- a/LEGO1/omni/include/mxcriticalsection.h +++ b/LEGO1/omni/include/mxcriticalsection.h @@ -11,7 +11,11 @@ class MxCriticalSection { static void SetDoMutex(); +#ifdef BETA10 + void Enter(unsigned long p_threadId, const char* filename, int line); +#else void Enter(); +#endif void Leave(); private: @@ -19,4 +23,11 @@ class MxCriticalSection { HANDLE m_mutex; // 0x18 }; +#ifdef BETA10 +// TODO: Not quite correct yet, the second argument becomes a relocated value +#define ENTER(criticalSection) criticalSection.Enter(-1, NULL, 0) +#else +#define ENTER(criticalSection) criticalSection.Enter() +#endif + #endif // MXCRITICALSECTION_H diff --git a/LEGO1/omni/src/audio/mxaudiomanager.cpp b/LEGO1/omni/src/audio/mxaudiomanager.cpp index 81b8922e..34b52eda 100644 --- a/LEGO1/omni/src/audio/mxaudiomanager.cpp +++ b/LEGO1/omni/src/audio/mxaudiomanager.cpp @@ -26,7 +26,7 @@ void MxAudioManager::Init() // FUNCTION: LEGO1 0x100b8e00 void MxAudioManager::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); g_count--; Init(); m_criticalSection.Leave(); @@ -43,7 +43,7 @@ MxResult MxAudioManager::Create() MxBool success = FALSE; if (MxMediaManager::Create() == SUCCESS) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); success = TRUE; result = SUCCESS; g_count++; @@ -69,7 +69,7 @@ void MxAudioManager::Destroy() // FUNCTION: LEGO1 0x100b8ea0 void MxAudioManager::SetVolume(MxS32 p_volume) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); m_volume = p_volume; m_criticalSection.Leave(); } diff --git a/LEGO1/omni/src/audio/mxloopingmidipresenter.cpp b/LEGO1/omni/src/audio/mxloopingmidipresenter.cpp index 51c305fe..9c9bfd33 100644 --- a/LEGO1/omni/src/audio/mxloopingmidipresenter.cpp +++ b/LEGO1/omni/src/audio/mxloopingmidipresenter.cpp @@ -39,7 +39,7 @@ void MxLoopingMIDIPresenter::DoneTickle() // FUNCTION: LEGO1 0x100c2b00 MxResult MxLoopingMIDIPresenter::PutData() { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_currentTickleState == e_streaming && m_chunk && !MusicManager()->GetMIDIInitialized()) { SetVolume(((MxDSSound*) m_action)->GetVolume()); diff --git a/LEGO1/omni/src/audio/mxmidipresenter.cpp b/LEGO1/omni/src/audio/mxmidipresenter.cpp index d3c990c5..decf848a 100644 --- a/LEGO1/omni/src/audio/mxmidipresenter.cpp +++ b/LEGO1/omni/src/audio/mxmidipresenter.cpp @@ -34,7 +34,7 @@ void MxMIDIPresenter::Destroy(MxBool p_fromDestructor) MusicManager()->DeinitializeMIDI(); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_subscriber && m_chunk) { m_subscriber->FreeDataChunk(m_chunk); @@ -98,7 +98,7 @@ void MxMIDIPresenter::Destroy() // FUNCTION: LEGO1 0x100c2970 MxResult MxMIDIPresenter::PutData() { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_currentTickleState == e_streaming && m_chunk && !MusicManager()->GetMIDIInitialized()) { SetVolume(((MxDSSound*) m_action)->GetVolume()); diff --git a/LEGO1/omni/src/audio/mxmusicmanager.cpp b/LEGO1/omni/src/audio/mxmusicmanager.cpp index 1a25cfc5..beef67bb 100644 --- a/LEGO1/omni/src/audio/mxmusicmanager.cpp +++ b/LEGO1/omni/src/audio/mxmusicmanager.cpp @@ -53,7 +53,7 @@ void MxMusicManager::Destroy(MxBool p_fromDestructor) TickleManager()->UnregisterClient(this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); DeinitializeMIDI(); Init(); m_criticalSection.Leave(); @@ -146,7 +146,7 @@ MxResult MxMusicManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) if (MxAudioManager::Create() == SUCCESS) { if (p_createThread) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; m_thread = new MxTickleThread(this, p_frequencyMS); @@ -183,7 +183,7 @@ void MxMusicManager::Destroy() void MxMusicManager::SetVolume(MxS32 p_volume) { MxAudioManager::SetVolume(p_volume); - m_criticalSection.Enter(); + ENTER(m_criticalSection); SetMIDIVolume(); m_criticalSection.Leave(); } @@ -191,7 +191,7 @@ void MxMusicManager::SetVolume(MxS32 p_volume) // FUNCTION: LEGO1 0x100c0970 void MxMusicManager::SetMultiplier(MxS32 p_multiplier) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); m_multiplier = p_multiplier; SetMIDIVolume(); m_criticalSection.Leave(); @@ -209,7 +209,7 @@ MxResult MxMusicManager::InitializeMIDI(MxU8* p_data, MxS32 p_loopCount) { MxResult result = FAILURE; - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (!m_midiInitialized) { MxU32 total = midiOutGetNumDevs(); @@ -278,7 +278,7 @@ MxResult MxMusicManager::InitializeMIDI(MxU8* p_data, MxS32 p_loopCount) // FUNCTION: LEGO1 0x100c0b20 void MxMusicManager::DeinitializeMIDI() { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_midiInitialized) { m_midiInitialized = FALSE; diff --git a/LEGO1/omni/src/audio/mxmusicpresenter.cpp b/LEGO1/omni/src/audio/mxmusicpresenter.cpp index 9f327ae4..6da836e7 100644 --- a/LEGO1/omni/src/audio/mxmusicpresenter.cpp +++ b/LEGO1/omni/src/audio/mxmusicpresenter.cpp @@ -30,7 +30,7 @@ void MxMusicPresenter::Destroy(MxBool p_fromDestructor) MusicManager()->UnregisterPresenter(*this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); Init(); m_criticalSection.Leave(); diff --git a/LEGO1/omni/src/audio/mxsoundmanager.cpp b/LEGO1/omni/src/audio/mxsoundmanager.cpp index ccfe2dc2..e77e9f93 100644 --- a/LEGO1/omni/src/audio/mxsoundmanager.cpp +++ b/LEGO1/omni/src/audio/mxsoundmanager.cpp @@ -52,7 +52,7 @@ void MxSoundManager::Destroy(MxBool p_fromDestructor) TickleManager()->UnregisterClient(this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_dsBuffer) { m_dsBuffer->Release(); @@ -77,7 +77,7 @@ MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) goto done; } - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; if (DirectSoundCreate(NULL, &m_directSound, NULL) != DS_OK) { @@ -166,7 +166,7 @@ void MxSoundManager::SetVolume(MxS32 p_volume) { MxAudioManager::SetVolume(p_volume); - m_criticalSection.Enter(); + ENTER(m_criticalSection); MxPresenter* presenter; MxPresenterListCursor cursor(m_presenters); diff --git a/LEGO1/omni/src/audio/mxsoundpresenter.cpp b/LEGO1/omni/src/audio/mxsoundpresenter.cpp index 9d784532..3fa2cfaa 100644 --- a/LEGO1/omni/src/audio/mxsoundpresenter.cpp +++ b/LEGO1/omni/src/audio/mxsoundpresenter.cpp @@ -13,7 +13,7 @@ void MxSoundPresenter::Destroy(MxBool p_fromDestructor) MSoundManager()->UnregisterPresenter(*this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); MxMediaPresenter::Init(); m_criticalSection.Leave(); diff --git a/LEGO1/omni/src/audio/mxwavepresenter.cpp b/LEGO1/omni/src/audio/mxwavepresenter.cpp index 37a75e5e..ca55f73b 100644 --- a/LEGO1/omni/src/audio/mxwavepresenter.cpp +++ b/LEGO1/omni/src/audio/mxwavepresenter.cpp @@ -294,7 +294,7 @@ void MxWavePresenter::EndAction() // FUNCTION: LEGO1 0x100b2300 void MxWavePresenter::SetVolume(MxS32 p_volume) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); m_volume = p_volume; if (m_dsBuffer != NULL) { diff --git a/LEGO1/omni/src/event/mxeventmanager.cpp b/LEGO1/omni/src/event/mxeventmanager.cpp index 29b8aba0..2c38a123 100644 --- a/LEGO1/omni/src/event/mxeventmanager.cpp +++ b/LEGO1/omni/src/event/mxeventmanager.cpp @@ -48,7 +48,7 @@ MxResult MxEventManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) MxResult result = MxMediaManager::Create(); if (result == SUCCESS) { if (p_createThread) { - this->m_criticalSection.Enter(); + ENTER(this->m_criticalSection); locked = TRUE; this->m_thread = new MxTickleThread(this, p_frequencyMS); diff --git a/LEGO1/omni/src/event/mxeventpresenter.cpp b/LEGO1/omni/src/event/mxeventpresenter.cpp index f819b68c..8134465e 100644 --- a/LEGO1/omni/src/event/mxeventpresenter.cpp +++ b/LEGO1/omni/src/event/mxeventpresenter.cpp @@ -50,7 +50,7 @@ void MxEventPresenter::Destroy() EventManager()->UnregisterPresenter(*this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_data) { delete[] m_data; diff --git a/LEGO1/omni/src/system/mxautolock.cpp b/LEGO1/omni/src/system/mxautolock.cpp index 4508663e..227085dd 100644 --- a/LEGO1/omni/src/system/mxautolock.cpp +++ b/LEGO1/omni/src/system/mxautolock.cpp @@ -2,8 +2,19 @@ #include "mxcriticalsection.h" -// FUNCTION: LEGO1 0x100b8ed0 +#ifdef BETA10 // FUNCTION: BETA10 0x101386f0 +MxAutoLock::MxAutoLock(MxCriticalSection* p_criticalSection, const char* filename, int line) +{ + m_criticalSection = p_criticalSection; + m_currentThreadId = GetCurrentThreadId(); + + if (m_criticalSection != NULL) { + m_criticalSection->Enter(m_currentThreadId, filename, line); + } +} +#else +// FUNCTION: LEGO1 0x100b8ed0 MxAutoLock::MxAutoLock(MxCriticalSection* p_criticalSection) { m_criticalSection = p_criticalSection; @@ -12,6 +23,7 @@ MxAutoLock::MxAutoLock(MxCriticalSection* p_criticalSection) m_criticalSection->Enter(); } } +#endif // FUNCTION: LEGO1 0x100b8ef0 // FUNCTION: BETA10 0x10138744 diff --git a/LEGO1/omni/src/system/mxcriticalsection.cpp b/LEGO1/omni/src/system/mxcriticalsection.cpp index 01c54c15..dd49e7ae 100644 --- a/LEGO1/omni/src/system/mxcriticalsection.cpp +++ b/LEGO1/omni/src/system/mxcriticalsection.cpp @@ -35,8 +35,35 @@ MxCriticalSection::~MxCriticalSection() } } -// FUNCTION: LEGO1 0x100b6d80 +#ifdef BETA10 // FUNCTION: BETA10 0x1013c725 +void MxCriticalSection::Enter(unsigned long p_threadId, const char* filename, int line) +{ + DWORD result; + FILE* file; + + if (m_mutex != NULL) { + result = WaitForSingleObject(m_mutex, 5000); + if (result == WAIT_FAILED) { + file = fopen("C:\\DEADLOCK.TXT", "a"); + if (file != NULL) { + fprintf(file, "mutex timeout occurred!\n"); + fprintf(file, "file: %s, line: %d\n", filename, line); + fclose(file); + } + + abort(); + } + } + else { + EnterCriticalSection(&m_criticalSection); + } + + // There is way more structure in here, and the MxCriticalSection class is much larger in BETA10. + // The LEGO1 compilation is very unlikely to profit from a further decompilation here. +} +#else +// FUNCTION: LEGO1 0x100b6d80 void MxCriticalSection::Enter() { DWORD result; @@ -58,8 +85,10 @@ void MxCriticalSection::Enter() EnterCriticalSection(&m_criticalSection); } } +#endif // FUNCTION: LEGO1 0x100b6de0 +// FUNCTION: BETA10 0x1013c7ef void MxCriticalSection::Leave() { if (m_mutex != NULL) { diff --git a/LEGO1/omni/src/video/mxloopingflcpresenter.cpp b/LEGO1/omni/src/video/mxloopingflcpresenter.cpp index a828296c..fb0e3134 100644 --- a/LEGO1/omni/src/video/mxloopingflcpresenter.cpp +++ b/LEGO1/omni/src/video/mxloopingflcpresenter.cpp @@ -29,7 +29,7 @@ void MxLoopingFlcPresenter::Init() // FUNCTION: LEGO1 0x100b4430 void MxLoopingFlcPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); Init(); m_criticalSection.Leave(); @@ -117,7 +117,7 @@ MxResult MxLoopingFlcPresenter::AddToManager() MxBool locked = FALSE; if (MxFlcPresenter::AddToManager() == SUCCESS) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; result = SUCCESS; } diff --git a/LEGO1/omni/src/video/mxloopingsmkpresenter.cpp b/LEGO1/omni/src/video/mxloopingsmkpresenter.cpp index 72f663e0..7933b3f3 100644 --- a/LEGO1/omni/src/video/mxloopingsmkpresenter.cpp +++ b/LEGO1/omni/src/video/mxloopingsmkpresenter.cpp @@ -29,7 +29,7 @@ void MxLoopingSmkPresenter::Init() // FUNCTION: LEGO1 0x100b49d0 void MxLoopingSmkPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); Init(); m_criticalSection.Leave(); diff --git a/LEGO1/omni/src/video/mxsmkpresenter.cpp b/LEGO1/omni/src/video/mxsmkpresenter.cpp index aa21f6ee..e6bbc1d9 100644 --- a/LEGO1/omni/src/video/mxsmkpresenter.cpp +++ b/LEGO1/omni/src/video/mxsmkpresenter.cpp @@ -32,7 +32,7 @@ void MxSmkPresenter::Init() // FUNCTION: LEGO1 0x100b3900 void MxSmkPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); MxSmk::Destroy(&m_mxSmk); Init(); diff --git a/LEGO1/omni/src/video/mxstillpresenter.cpp b/LEGO1/omni/src/video/mxstillpresenter.cpp index a9731233..db2f2ebb 100644 --- a/LEGO1/omni/src/video/mxstillpresenter.cpp +++ b/LEGO1/omni/src/video/mxstillpresenter.cpp @@ -17,7 +17,7 @@ DECOMP_SIZE_ASSERT(MxStillPresenter, 0x6c); // FUNCTION: LEGO1 0x100b9c70 void MxStillPresenter::Destroy(MxBool p_fromDestructor) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_bitmapInfo) { delete[] ((MxU8*) m_bitmapInfo); diff --git a/LEGO1/omni/src/video/mxvideomanager.cpp b/LEGO1/omni/src/video/mxvideomanager.cpp index cde2e1ca..9ad9005c 100644 --- a/LEGO1/omni/src/video/mxvideomanager.cpp +++ b/LEGO1/omni/src/video/mxvideomanager.cpp @@ -52,7 +52,7 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor) TickleManager()->UnregisterClient(this); } - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_displaySurface) { delete m_displaySurface; @@ -152,7 +152,7 @@ MxResult MxVideoManager::VTable0x28( goto done; } - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; m_videoParam = p_videoParam; @@ -225,7 +225,7 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, goto done; } - m_criticalSection.Enter(); + ENTER(m_criticalSection); locked = TRUE; m_videoParam = p_videoParam; @@ -300,7 +300,7 @@ void MxVideoManager::Destroy() // FUNCTION: LEGO1 0x100bea60 void MxVideoManager::InvalidateRect(MxRect32& p_rect) { - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (m_region) { m_region->AddRect(p_rect); @@ -340,7 +340,7 @@ MxResult MxVideoManager::RealizePalette(MxPalette* p_palette) { PALETTEENTRY paletteEntries[256]; - m_criticalSection.Enter(); + ENTER(m_criticalSection); if (p_palette && m_videoParam.GetPalette()) { p_palette->GetEntries(paletteEntries); From 56c15699dae597f7efa97c5f1ef8cc41b2415662 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Sun, 20 Jul 2025 16:05:28 +0200 Subject: [PATCH 6/9] Clear unknown in `MxSoundManager` (#1641) --- LEGO1/lego/legoomni/src/build/legocarbuild.cpp | 2 +- LEGO1/omni/include/mxsoundmanager.h | 2 +- LEGO1/omni/src/audio/mxsoundmanager.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index f50dcdfe..899ebeac 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -1230,7 +1230,7 @@ undefined4 LegoCarBuild::FUN_10024c20(MxNotificationParam* p_param) jukeboxScript = JukeboxScript::c_RaceCarBuild_Music; } - m_unk0x338 = SoundManager()->FUN_100aebd0(*g_jukeboxScript, jukeboxScript); + m_unk0x338 = SoundManager()->FindPresenter(*g_jukeboxScript, jukeboxScript); if (m_unk0x338) { BackgroundAudioManager()->SetPendingPresenter(m_unk0x338, 5, MxPresenter::e_repeating); diff --git a/LEGO1/omni/include/mxsoundmanager.h b/LEGO1/omni/include/mxsoundmanager.h index 36568ef3..3d25856b 100644 --- a/LEGO1/omni/include/mxsoundmanager.h +++ b/LEGO1/omni/include/mxsoundmanager.h @@ -25,7 +25,7 @@ class MxSoundManager : public MxAudioManager { MxS32 GetAttenuation(MxU32 p_volume); - MxPresenter* FUN_100aebd0(const MxAtomId& p_atomId, MxU32 p_objectId); + MxPresenter* FindPresenter(const MxAtomId& p_atomId, MxU32 p_objectId); protected: void Init(); diff --git a/LEGO1/omni/src/audio/mxsoundmanager.cpp b/LEGO1/omni/src/audio/mxsoundmanager.cpp index e77e9f93..1e2b28a1 100644 --- a/LEGO1/omni/src/audio/mxsoundmanager.cpp +++ b/LEGO1/omni/src/audio/mxsoundmanager.cpp @@ -179,7 +179,7 @@ void MxSoundManager::SetVolume(MxS32 p_volume) } // FUNCTION: LEGO1 0x100aebd0 -MxPresenter* MxSoundManager::FUN_100aebd0(const MxAtomId& p_atomId, MxU32 p_objectId) +MxPresenter* MxSoundManager::FindPresenter(const MxAtomId& p_atomId, MxU32 p_objectId) { AUTOLOCK(m_criticalSection); From 0a58d112e8eaf4d36cde8e445c5d90ae908596f9 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Sun, 20 Jul 2025 17:18:59 +0200 Subject: [PATCH 7/9] Clear unknowns in `LegoOmni` and `misc.h` (#1642) --- LEGO1/lego/legoomni/include/legomain.h | 6 +++--- LEGO1/lego/legoomni/include/misc.h | 2 +- .../lego/legoomni/src/common/legoanimationmanager.cpp | 10 +++++----- LEGO1/lego/legoomni/src/common/misc.cpp | 4 ++-- LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp | 2 +- LEGO1/lego/legoomni/src/main/legomain.cpp | 2 +- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 2 +- 7 files changed, 14 insertions(+), 14 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legomain.h b/LEGO1/lego/legoomni/include/legomain.h index 423d715c..9246a642 100644 --- a/LEGO1/lego/legoomni/include/legomain.h +++ b/LEGO1/lego/legoomni/include/legomain.h @@ -180,8 +180,8 @@ class LegoOmni : public MxOmni { // FUNCTION: BETA10 0x100d55c0 void SetExit(MxBool p_exit) { m_exit = p_exit; } - MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) { return m_unk0x13c ? Start(&p_dsAction) : SUCCESS; } - void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; } + MxResult StartActionIfInitialized(MxDSAction& p_dsAction) { return m_initialized ? Start(&p_dsAction) : SUCCESS; } + void SetInitialized(MxBool p_unk0x13c) { m_initialized = p_unk0x13c; } void CloseMainWindow() { PostMessage(m_windowHandle, WM_CLOSE, 0, 0); } @@ -208,7 +208,7 @@ class LegoOmni : public MxOmni { MxTransitionManager* m_transitionManager; // 0x138 public: - MxBool m_unk0x13c; // 0x13c + MxBool m_initialized; // 0x13c }; #endif // LEGOMAIN_H diff --git a/LEGO1/lego/legoomni/include/misc.h b/LEGO1/lego/legoomni/include/misc.h index f9a26e8b..52fe63d9 100644 --- a/LEGO1/lego/legoomni/include/misc.h +++ b/LEGO1/lego/legoomni/include/misc.h @@ -52,7 +52,7 @@ void Disable(MxBool p_disable, MxU16 p_flags); LegoROI* FindROI(const char* p_name); void SetROIVisible(const char* p_name, MxBool p_visible); void SetUserActor(LegoPathActor* p_userActor); -MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction); +MxResult StartActionIfInitialized(MxDSAction& p_dsAction); void DeleteAction(); LegoWorld* FindWorld(const MxAtomId& p_atom, MxS32 p_entityid); MxDSAction& GetCurrentAction(); diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index e6dd3513..aab443e2 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -1016,7 +1016,7 @@ MxResult LegoAnimationManager::FUN_100605e0( action.SetUnknown24(-1); action.AppendExtra(strlen(buf) + 1, buf); - if (StartActionIfUnknown0x13c(action) == SUCCESS) { + if (StartActionIfInitialized(action) == SUCCESS) { BackgroundAudioManager()->LowerVolume(); tranInfo->m_flags |= LegoTranInfo::c_bit2; animInfo.m_unk0x22++; @@ -1083,7 +1083,7 @@ MxResult LegoAnimationManager::FUN_100609f0(MxU32 p_objectId, MxMatrix* p_matrix action.SetUnknown24(-1); action.AppendExtra(strlen(buf) + 1, buf); - if (StartActionIfUnknown0x13c(action) == SUCCESS) { + if (StartActionIfInitialized(action) == SUCCESS) { BackgroundAudioManager()->LowerVolume(); info->m_flags |= LegoTranInfo::c_bit2; m_animRunning = TRUE; @@ -1126,7 +1126,7 @@ MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEnt } } - if (LegoOmni::GetInstance()->StartActionIfUnknown0x13c(p_dsAction) == SUCCESS) { + if (LegoOmni::GetInstance()->StartActionIfInitialized(p_dsAction) == SUCCESS) { result = SUCCESS; } @@ -1150,7 +1150,7 @@ MxResult LegoAnimationManager::FUN_10060dc0( MxResult result = FAILURE; MxBool found = FALSE; - if (!Lego()->m_unk0x13c) { + if (!Lego()->m_initialized) { return SUCCESS; } @@ -1187,7 +1187,7 @@ MxResult LegoAnimationManager::FUN_10060dc0( // FUNCTION: BETA10 0x1004206c void LegoAnimationManager::CameraTriggerFire(LegoPathActor* p_actor, MxBool, MxU32 p_location, MxBool p_bool) { - if (Lego()->m_unk0x13c && m_enableCamAnims && !m_animRunning) { + if (Lego()->m_initialized && m_enableCamAnims && !m_animRunning) { LegoLocation* location = LegoNavController::GetLocation(p_location); if (location != NULL) { diff --git a/LEGO1/lego/legoomni/src/common/misc.cpp b/LEGO1/lego/legoomni/src/common/misc.cpp index 6b231b56..19ff0a21 100644 --- a/LEGO1/lego/legoomni/src/common/misc.cpp +++ b/LEGO1/lego/legoomni/src/common/misc.cpp @@ -172,9 +172,9 @@ void SetUserActor(LegoPathActor* p_userActor) // FUNCTION: LEGO1 0x10015890 // FUNCTION: BETA10 0x100e4d80 -MxResult StartActionIfUnknown0x13c(MxDSAction& p_dsAction) +MxResult StartActionIfInitialized(MxDSAction& p_dsAction) { - return LegoOmni::GetInstance()->StartActionIfUnknown0x13c(p_dsAction); + return LegoOmni::GetInstance()->StartActionIfInitialized(p_dsAction); } // FUNCTION: LEGO1 0x100158b0 diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp index fa8158da..78d2e6d1 100644 --- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp @@ -896,7 +896,7 @@ MxLong LegoNavController::Notify(MxParam& p_param) break; case 'A': if (g_animationCalcStep == 1) { - Lego()->m_unk0x13c = TRUE; + Lego()->m_initialized = TRUE; AnimationManager()->FUN_10060570(TRUE); g_animationCalcStep = 0; } diff --git a/LEGO1/lego/legoomni/src/main/legomain.cpp b/LEGO1/lego/legoomni/src/main/legomain.cpp index 0da66855..932ae247 100644 --- a/LEGO1/lego/legoomni/src/main/legomain.cpp +++ b/LEGO1/lego/legoomni/src/main/legomain.cpp @@ -71,7 +71,7 @@ void LegoOmni::Init() m_animationManager = NULL; m_buildingManager = NULL; m_bkgAudioManager = NULL; - m_unk0x13c = TRUE; + m_initialized = TRUE; m_transitionManager = NULL; } diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 49936b28..a3c4f7c0 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -1116,7 +1116,7 @@ MxResult LegoAct2::FUN_10052560( action.SetDirection(*p_direction); } - StartActionIfUnknown0x13c(action); + StartActionIfInitialized(action); } else { MxMatrix matrix; From 132d9c817fde4e06c42aedff098d2ac8b8d3bc20 Mon Sep 17 00:00:00 2001 From: MS Date: Sun, 20 Jul 2025 11:47:08 -0400 Subject: [PATCH 8/9] Build BETA10 in CI (#1639) --- .github/workflows/build.yml | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 982d9468..4327d20a 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -100,6 +100,43 @@ jobs: build/LEGO1.DLL build/LEGO1.PDB + build-beta: + name: 'MSVC 4.20 (BETA10)' + runs-on: windows-latest + + steps: + - uses: actions/checkout@v4 + + - uses: actions/checkout@v4 + with: + repository: itsmattkc/msvc420 + path: msvc420 + + - name: Setup cmake + uses: jwlawson/actions-setup-cmake@v2 + with: + # Use minimum supported version + cmake-version: '3.15.x' + + - name: Patch MSVC 4.2 + run: | + tools/patch_c2.py msvc420/bin/C2.EXE + + - name: Build + shell: cmd + run: | + call .\msvc420\bin\VCVARS32.BAT x86 + cmake -B build -DCMAKE_BUILD_TYPE=Debug -DISLE_INCLUDE_ENTROPY=OFF -DISLE_BUILD_BETA10=ON -DISLE_BUILD_LEGO1=OFF -DISLE_BUILD_APP=OFF -DISLE_BUILD_CONFIG=OFF -G "NMake Makefiles" + cmake --build build + + - name: Upload Artifact + uses: actions/upload-artifact@main + with: + name: Win32-beta + path: | + build/BETA10.DLL + build/BETA10.PDB + verify: name: Verify decomp needs: [build, fetch-deps] From 2980f88bb0b73e468569d52524f60e91f7f9cdcb Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Sun, 20 Jul 2025 18:20:40 +0200 Subject: [PATCH 9/9] Fix filenames based on BETA10 `MxAutoLock` (#1640) * Inline LegoAnimPresenters --------- Co-authored-by: jonschz --- CMakeLists.txt | 3 - .../lego/legoomni/include/legoanimpresenter.h | 209 ++++++++- .../legoomni/include/legohideanimpresenter.h | 111 ----- .../include/legolocomotionanimpresenter.h | 71 --- .../include/legoloopinganimpresenter.h | 43 -- LEGO1/lego/legoomni/src/actors/act3actors.cpp | 2 +- .../src/common/legoanimationmanager.cpp | 1 - .../legoomni/src/common/legoobjectfactory.cpp | 5 +- .../src/common/mxcompositemediapresenter.cpp | 1 + LEGO1/lego/legoomni/src/entity/legoworld.cpp | 1 - .../lego/legoomni/src/paths/legoanimactor.cpp | 2 +- .../legoomni/src/paths/legoextraactor.cpp | 2 +- .../legoomni/src/paths/legopathboundary.cpp | 2 +- .../legoomni/src/paths/legopathstruct.cpp | 2 +- LEGO1/lego/legoomni/src/race/carrace.cpp | 2 +- LEGO1/lego/legoomni/src/race/jetskirace.cpp | 2 +- .../legoomni/src/video/legoanimpresenter.cpp | 441 ++++++++++++++++++ .../src/video/legohideanimpresenter.cpp | 216 --------- .../src/video/legolocomotionanimpresenter.cpp | 164 ------- .../src/video/legoloopinganimpresenter.cpp | 83 ---- LEGO1/lego/legoomni/src/worlds/legoact2.cpp | 2 +- .../omni/src/common/mxcompositepresenter.cpp | 2 +- 22 files changed, 659 insertions(+), 708 deletions(-) delete mode 100644 LEGO1/lego/legoomni/include/legohideanimpresenter.h delete mode 100644 LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h delete mode 100644 LEGO1/lego/legoomni/include/legoloopinganimpresenter.h delete mode 100644 LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp delete mode 100644 LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp delete mode 100644 LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index c8d030e6..0f6d1746 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -376,9 +376,6 @@ function(add_lego_libraries NAME) LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp LEGO1/lego/legoomni/src/actors/dunebuggy.cpp LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp - LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp - LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp - LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp LEGO1/lego/legoomni/src/worlds/infocenter.cpp LEGO1/lego/legoomni/src/race/raceskel.cpp LEGO1/lego/legoomni/src/worlds/act3.cpp diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 802e8917..6e983144 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -2,6 +2,7 @@ #define LEGOANIMPRESENTER_H #include "legoroilist.h" +#include "legoroimaplist.h" #include "mxatom.h" #include "mxvideopresenter.h" @@ -147,14 +148,191 @@ class LegoAnimPresenter : public MxVideoPresenter { MxS16 m_unk0x9c; // 0x9c Matrix4* m_unk0xa0; // 0xa0 + // SYNTHETIC: LEGO1 0x10068650 + // LegoAnimPresenter::`scalar deleting destructor' + public: float m_unk0xa4; // 0xa4 Mx3DPointFloat m_unk0xa8; // 0xa8 }; +// VTABLE: LEGO1 0x100d4900 +// SIZE 0xc0 +class LegoLoopingAnimPresenter : public LegoAnimPresenter { +public: + // FUNCTION: BETA10 0x1005c6f0 + static const char* HandlerClassName() + { + // STRING: LEGO1 0x100f0700 + return "LegoLoopingAnimPresenter"; + } + + // FUNCTION: LEGO1 0x1000c9a0 + // FUNCTION: BETA10 0x1005c6c0 + const char* ClassName() const override // vtable+0x0c + { + return HandlerClassName(); + } + + // FUNCTION: LEGO1 0x1000c9b0 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name); + } + + void StreamingTickle() override; // vtable+0x20 + void PutFrame() override; // vtable+0x6c + + // SYNTHETIC: LEGO1 0x1006d000 + // LegoLoopingAnimPresenter::~LegoLoopingAnimPresenter + + // SYNTHETIC: LEGO1 0x1000f440 + // LegoLoopingAnimPresenter::`scalar deleting destructor' + +private: + undefined4 m_unk0xbc; // 0xbc +}; + +class LegoAnimActor; + +// VTABLE: LEGO1 0x100d9170 +// SIZE 0xd8 +class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter { +public: + LegoLocomotionAnimPresenter(); + ~LegoLocomotionAnimPresenter() override; + + // FUNCTION: BETA10 0x1005c4e0 + static const char* HandlerClassName() + { + // STRING: LEGO1 0x100f06e4 + return "LegoLocomotionAnimPresenter"; + } + + // FUNCTION: LEGO1 0x1006ce50 + // FUNCTION: BETA10 0x1005c4b0 + const char* ClassName() const override // vtable+0x0c + { + return HandlerClassName(); + } + + // FUNCTION: LEGO1 0x1006ce60 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, ClassName()) || LegoLoopingAnimPresenter::IsA(p_name); + } + + void ReadyTickle() override; // vtable+0x18 + void StartingTickle() override; // vtable+0x1c + void StreamingTickle() override; // vtable+0x20 + MxResult AddToManager() override; // vtable+0x34 + void Destroy() override; // vtable+0x38 + void EndAction() override; // vtable+0x40 + void PutFrame() override; // vtable+0x6c + MxResult CreateAnim(MxStreamChunk* p_chunk) override; // vtable+0x88 + + void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value); + + void DecrementUnknown0xd4() + { + if (m_unk0xd4) { + --m_unk0xd4; + } + } + + undefined2 GetUnknown0xd4() { return m_unk0xd4; } + + // SYNTHETIC: LEGO1 0x1006cfe0 + // LegoLocomotionAnimPresenter::`scalar deleting destructor' + +private: + void Init(); + void Destroy(MxBool p_fromDestructor); + + undefined4 m_unk0xc0; // 0xc0 + undefined4* m_unk0xc4; // 0xc4 + LegoROIMapList* m_roiMapList; // 0xc8 + MxS32 m_unk0xcc; // 0xcc + MxS32 m_unk0xd0; // 0xd0 + undefined2 m_unk0xd4; // 0xd4 +}; + +class LegoPathBoundary; + +struct LegoHideAnimStructComparator { + MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; } +}; + +// SIZE 0x08 +struct LegoHideAnimStruct { + LegoPathBoundary* m_boundary; // 0x00 + MxU32 m_index; // 0x04 +}; + +typedef map LegoHideAnimStructMap; + +// VTABLE: LEGO1 0x100d9278 +// SIZE 0xc4 +class LegoHideAnimPresenter : public LegoLoopingAnimPresenter { +public: + LegoHideAnimPresenter(); + ~LegoHideAnimPresenter() override; + + // FUNCTION: LEGO1 0x1006d860 + void VTable0x8c() override {} // vtable+0x8c + + // FUNCTION: LEGO1 0x1006d870 + void VTable0x90() override {} // vtable+0x90 + + // FUNCTION: BETA10 0x1005d4a0 + static const char* HandlerClassName() + { + // STRING: LEGO1 0x100f06cc + return "LegoHideAnimPresenter"; + } + + // FUNCTION: LEGO1 0x1006d880 + // FUNCTION: BETA10 0x1005d470 + const char* ClassName() const override // vtable+0x0c + { + return HandlerClassName(); + } + + // FUNCTION: LEGO1 0x1006d890 + MxBool IsA(const char* p_name) const override // vtable+0x10 + { + return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name); + } + + void ReadyTickle() override; // vtable+0x18 + void StartingTickle() override; // vtable+0x18 + MxResult AddToManager() override; // vtable+0x34 + void Destroy() override; // vtable+0x38 + void EndAction() override; // vtable+0x40 + void PutFrame() override; // vtable+0x6c + + void FUN_1006db40(LegoTime p_time); + + // SYNTHETIC: LEGO1 0x1006d9d0 + // LegoHideAnimPresenter::`scalar deleting destructor' + +private: + void Init(); + void Destroy(MxBool p_fromDestructor); + void FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time); + void FUN_1006dc10(); + void FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node); + void FUN_1006e470( + LegoHideAnimStructMap& p_map, + LegoAnimNodeData* p_data, + const char* p_name, + LegoPathBoundary* p_boundary + ); + + LegoPathBoundary** m_boundaryMap; // 0xc0 +}; + // clang-format off -// SYNTHETIC: LEGO1 0x10068650 -// LegoAnimPresenter::`scalar deleting destructor' // TEMPLATE: LEGO1 0x100689c0 // map >::~map > @@ -212,6 +390,33 @@ class LegoAnimPresenter : public MxVideoPresenter { // GLOBAL: LEGO1 0x100f7688 // _Tree,map >::_Kfn,LegoAnimStructComparator,allocator >::_Nil + +// TEMPLATE: LEGO1 0x1006ddb0 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::~_Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Inc + +// TEMPLATE: LEGO1 0x1006dec0 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::erase + +// TEMPLATE: LEGO1 0x1006e310 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Erase + +// TEMPLATE: LEGO1 0x1006e350 +// Map::~Map + +// TEMPLATE: LEGO1 0x1006e3a0 +// map >::~map > + +// TEMPLATE: LEGO1 0x1006e6d0 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Dec + +// TEMPLATE: LEGO1 0x1006e720 +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Insert + +// GLOBAL: LEGO1 0x100f768c +// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Nil // clang-format on #endif // LEGOANIMPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legohideanimpresenter.h b/LEGO1/lego/legoomni/include/legohideanimpresenter.h deleted file mode 100644 index b2bbb7b8..00000000 --- a/LEGO1/lego/legoomni/include/legohideanimpresenter.h +++ /dev/null @@ -1,111 +0,0 @@ -#ifndef LEGOHIDEANIMPRESENTER_H -#define LEGOHIDEANIMPRESENTER_H - -#include "decomp.h" -#include "legoloopinganimpresenter.h" - -class LegoPathBoundary; - -struct LegoHideAnimStructComparator { - MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmp(p_a, p_b) < 0; } -}; - -// SIZE 0x08 -struct LegoHideAnimStruct { - LegoPathBoundary* m_boundary; // 0x00 - MxU32 m_index; // 0x04 -}; - -typedef map LegoHideAnimStructMap; - -// VTABLE: LEGO1 0x100d9278 -// SIZE 0xc4 -class LegoHideAnimPresenter : public LegoLoopingAnimPresenter { -public: - LegoHideAnimPresenter(); - ~LegoHideAnimPresenter() override; - - // FUNCTION: LEGO1 0x1006d860 - void VTable0x8c() override {} // vtable+0x8c - - // FUNCTION: LEGO1 0x1006d870 - void VTable0x90() override {} // vtable+0x90 - - // FUNCTION: BETA10 0x1005d4a0 - static const char* HandlerClassName() - { - // STRING: LEGO1 0x100f06cc - return "LegoHideAnimPresenter"; - } - - // FUNCTION: LEGO1 0x1006d880 - // FUNCTION: BETA10 0x1005d470 - const char* ClassName() const override // vtable+0x0c - { - return HandlerClassName(); - } - - // FUNCTION: LEGO1 0x1006d890 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name); - } - - void ReadyTickle() override; // vtable+0x18 - void StartingTickle() override; // vtable+0x18 - MxResult AddToManager() override; // vtable+0x34 - void Destroy() override; // vtable+0x38 - void EndAction() override; // vtable+0x40 - void PutFrame() override; // vtable+0x6c - - void FUN_1006db40(LegoTime p_time); - -private: - void Init(); - void Destroy(MxBool p_fromDestructor); - void FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time); - void FUN_1006dc10(); - void FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node); - void FUN_1006e470( - LegoHideAnimStructMap& p_map, - LegoAnimNodeData* p_data, - const char* p_name, - LegoPathBoundary* p_boundary - ); - - LegoPathBoundary** m_boundaryMap; // 0xc0 -}; - -// clang-format off -// SYNTHETIC: LEGO1 0x1006d9d0 -// LegoHideAnimPresenter::`scalar deleting destructor' - -// TEMPLATE: LEGO1 0x1006ddb0 -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::~_Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Inc - -// TEMPLATE: LEGO1 0x1006dec0 -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::erase - -// TEMPLATE: LEGO1 0x1006e310 -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Erase - -// TEMPLATE: LEGO1 0x1006e350 -// Map::~Map - -// TEMPLATE: LEGO1 0x1006e3a0 -// map >::~map > - -// TEMPLATE: LEGO1 0x1006e6d0 -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::iterator::_Dec - -// TEMPLATE: LEGO1 0x1006e720 -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Insert - -// GLOBAL: LEGO1 0x100f768c -// _Tree,map >::_Kfn,LegoHideAnimStructComparator,allocator >::_Nil -// clang-format on - -#endif // LEGOHIDEANIMPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h b/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h deleted file mode 100644 index df2f872e..00000000 --- a/LEGO1/lego/legoomni/include/legolocomotionanimpresenter.h +++ /dev/null @@ -1,71 +0,0 @@ -#ifndef LEGOLOCOMOTIONANIMPRESENTER_H -#define LEGOLOCOMOTIONANIMPRESENTER_H - -#include "legoloopinganimpresenter.h" -#include "legoroimaplist.h" - -class LegoAnimActor; - -// VTABLE: LEGO1 0x100d9170 -// SIZE 0xd8 -class LegoLocomotionAnimPresenter : public LegoLoopingAnimPresenter { -public: - LegoLocomotionAnimPresenter(); - ~LegoLocomotionAnimPresenter() override; - - // FUNCTION: BETA10 0x1005c4e0 - static const char* HandlerClassName() - { - // STRING: LEGO1 0x100f06e4 - return "LegoLocomotionAnimPresenter"; - } - - // FUNCTION: LEGO1 0x1006ce50 - // FUNCTION: BETA10 0x1005c4b0 - const char* ClassName() const override // vtable+0x0c - { - return HandlerClassName(); - } - - // FUNCTION: LEGO1 0x1006ce60 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, ClassName()) || LegoLoopingAnimPresenter::IsA(p_name); - } - - void ReadyTickle() override; // vtable+0x18 - void StartingTickle() override; // vtable+0x1c - void StreamingTickle() override; // vtable+0x20 - MxResult AddToManager() override; // vtable+0x34 - void Destroy() override; // vtable+0x38 - void EndAction() override; // vtable+0x40 - void PutFrame() override; // vtable+0x6c - MxResult CreateAnim(MxStreamChunk* p_chunk) override; // vtable+0x88 - - // SYNTHETIC: LEGO1 0x1006cfe0 - // LegoLocomotionAnimPresenter::`scalar deleting destructor' - - void FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value); - - void DecrementUnknown0xd4() - { - if (m_unk0xd4) { - --m_unk0xd4; - } - } - - undefined2 GetUnknown0xd4() { return m_unk0xd4; } - -private: - void Init(); - void Destroy(MxBool p_fromDestructor); - - undefined4 m_unk0xc0; // 0xc0 - undefined4* m_unk0xc4; // 0xc4 - LegoROIMapList* m_roiMapList; // 0xc8 - MxS32 m_unk0xcc; // 0xcc - MxS32 m_unk0xd0; // 0xd0 - undefined2 m_unk0xd4; // 0xd4 -}; - -#endif // LEGOLOCOMOTIONANIMPRESENTER_H diff --git a/LEGO1/lego/legoomni/include/legoloopinganimpresenter.h b/LEGO1/lego/legoomni/include/legoloopinganimpresenter.h deleted file mode 100644 index 8952cbba..00000000 --- a/LEGO1/lego/legoomni/include/legoloopinganimpresenter.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef LEGOLOOPINGANIMPRESENTER_H -#define LEGOLOOPINGANIMPRESENTER_H - -#include "legoanimpresenter.h" - -// VTABLE: LEGO1 0x100d4900 -// SIZE 0xc0 -class LegoLoopingAnimPresenter : public LegoAnimPresenter { -public: - // FUNCTION: BETA10 0x1005c6f0 - static const char* HandlerClassName() - { - // STRING: LEGO1 0x100f0700 - return "LegoLoopingAnimPresenter"; - } - - // FUNCTION: LEGO1 0x1000c9a0 - // FUNCTION: BETA10 0x1005c6c0 - const char* ClassName() const override // vtable+0x0c - { - return HandlerClassName(); - } - - // FUNCTION: LEGO1 0x1000c9b0 - MxBool IsA(const char* p_name) const override // vtable+0x10 - { - return !strcmp(p_name, ClassName()) || LegoAnimPresenter::IsA(p_name); - } - - void StreamingTickle() override; // vtable+0x20 - void PutFrame() override; // vtable+0x6c - -private: - undefined4 m_unk0xbc; // 0xbc -}; - -// SYNTHETIC: LEGO1 0x1006d000 -// LegoLoopingAnimPresenter::~LegoLoopingAnimPresenter - -// SYNTHETIC: LEGO1 0x1000f440 -// LegoLoopingAnimPresenter::`scalar deleting destructor' - -#endif // LEGOLOOPINGANIMPRESENTER_H diff --git a/LEGO1/lego/legoomni/src/actors/act3actors.cpp b/LEGO1/lego/legoomni/src/actors/act3actors.cpp index 9a2acd16..0d89f2f4 100644 --- a/LEGO1/lego/legoomni/src/actors/act3actors.cpp +++ b/LEGO1/lego/legoomni/src/actors/act3actors.cpp @@ -4,9 +4,9 @@ #include "act3ammo.h" #include "anim/legoanim.h" #include "define.h" +#include "legoanimpresenter.h" #include "legobuildingmanager.h" #include "legocachesoundmanager.h" -#include "legolocomotionanimpresenter.h" #include "legopathedgecontainer.h" #include "legoplantmanager.h" #include "legoplants.h" diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index aab443e2..1b9dffcb 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -11,7 +11,6 @@ #include "legoentitylist.h" #include "legoextraactor.h" #include "legogamestate.h" -#include "legolocomotionanimpresenter.h" #include "legomain.h" #include "legonavcontroller.h" #include "legoroilist.h" diff --git a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp index 68a3b35a..b8514020 100644 --- a/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp +++ b/LEGO1/lego/legoomni/src/common/legoobjectfactory.cpp @@ -10,7 +10,7 @@ #include "legoentity.h" #include "legopathactor.h" // The below header inclusions should be sound. -#include "legoloopinganimpresenter.h" +#include "legoanimpresenter.h" #include "mxcompositemediapresenter.h" #include "legoactorpresenter.h" #include "legomodelpresenter.h" @@ -71,10 +71,7 @@ #include "legoentity.h" #include "legoentitypresenter.h" #include "legoflctexturepresenter.h" -#include "legohideanimpresenter.h" #include "legoloadcachesoundpresenter.h" -#include "legolocomotionanimpresenter.h" -#include "legoloopinganimpresenter.h" #include "legometerpresenter.h" #include "legomodelpresenter.h" #include "legopalettepresenter.h" diff --git a/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp b/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp index 04437877..7c6a788d 100644 --- a/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp +++ b/LEGO1/lego/legoomni/src/common/mxcompositemediapresenter.cpp @@ -27,6 +27,7 @@ MxCompositeMediaPresenter::~MxCompositeMediaPresenter() } // FUNCTION: LEGO1 0x10074090 +// FUNCTION: BETA10 0x100e9d37 MxResult MxCompositeMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) { AUTOLOCK(m_criticalSection); diff --git a/LEGO1/lego/legoomni/src/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index f038f3b0..f975f5b6 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -9,7 +9,6 @@ #include "legocontrolmanager.h" #include "legogamestate.h" #include "legoinputmanager.h" -#include "legolocomotionanimpresenter.h" #include "legonavcontroller.h" #include "legoplantmanager.h" #include "legosoundmanager.h" diff --git a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp index f6ca062c..0a1e6d98 100644 --- a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp @@ -2,7 +2,7 @@ #include "anim/legoanim.h" #include "define.h" -#include "legolocomotionanimpresenter.h" +#include "legoanimpresenter.h" #include "legopathboundary.h" #include "legoworld.h" #include "misc.h" diff --git a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp index b9cd25bb..13afdb32 100644 --- a/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoextraactor.cpp @@ -1,8 +1,8 @@ #include "legoextraactor.h" #include "anim/legoanim.h" +#include "legoanimpresenter.h" #include "legocachesoundmanager.h" -#include "legolocomotionanimpresenter.h" #include "legosoundmanager.h" #include "legoworld.h" #include "misc.h" diff --git a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp index 458a79b9..8ef3c323 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathboundary.cpp @@ -2,7 +2,7 @@ #include "decomp.h" #include "geom/legoorientededge.h" -#include "legolocomotionanimpresenter.h" +#include "legoanimpresenter.h" #include "legopathactor.h" #include "legopathstruct.h" diff --git a/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp b/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp index e269f727..276b66ab 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathstruct.cpp @@ -3,7 +3,7 @@ #include "isle.h" #include "jukebox.h" #include "jukebox_actions.h" -#include "legohideanimpresenter.h" +#include "legoanimpresenter.h" #include "legopathactor.h" #include "legoutils.h" #include "misc.h" diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index 6c36223a..fa52edba 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -5,8 +5,8 @@ #include "isle.h" #include "jukebox_actions.h" #include "legoanimationmanager.h" +#include "legoanimpresenter.h" #include "legocontrolmanager.h" -#include "legohideanimpresenter.h" #include "legomain.h" #include "legonavcontroller.h" #include "legopathstruct.h" diff --git a/LEGO1/lego/legoomni/src/race/jetskirace.cpp b/LEGO1/lego/legoomni/src/race/jetskirace.cpp index 79391c6d..54d6b4be 100644 --- a/LEGO1/lego/legoomni/src/race/jetskirace.cpp +++ b/LEGO1/lego/legoomni/src/race/jetskirace.cpp @@ -6,8 +6,8 @@ #include "jetski_actions.h" #include "jukebox_actions.h" #include "legoanimationmanager.h" +#include "legoanimpresenter.h" #include "legocontrolmanager.h" -#include "legohideanimpresenter.h" #include "legomain.h" #include "legopathstruct.h" #include "legoracers.h" diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index d3f38b22..c7fbc845 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -3,6 +3,7 @@ #include "3dmanager/lego3dmanager.h" #include "anim/legoanim.h" #include "define.h" +#include "legoanimactor.h" #include "legoanimationmanager.h" #include "legoanimmmpresenter.h" #include "legocameracontroller.h" @@ -27,6 +28,10 @@ #include "viewmanager/viewmanager.h" DECOMP_SIZE_ASSERT(LegoAnimPresenter, 0xbc) +DECOMP_SIZE_ASSERT(LegoLoopingAnimPresenter, 0xc0) +DECOMP_SIZE_ASSERT(LegoLocomotionAnimPresenter, 0xd8) +DECOMP_SIZE_ASSERT(LegoHideAnimPresenter, 0xc4) +DECOMP_SIZE_ASSERT(LegoHideAnimStruct, 0x08) // FUNCTION: LEGO1 0x10068420 // FUNCTION: BETA10 0x1004e5f0 @@ -1216,3 +1221,439 @@ MxResult LegoAnimPresenter::VTable0x98(LegoPathBoundary* p_boundary) return SUCCESS; } + +// FUNCTION: LEGO1 0x1006caa0 +// FUNCTION: BETA10 0x1005223d +void LegoLoopingAnimPresenter::StreamingTickle() +{ + if (m_subscriber->PeekData()) { + MxStreamChunk* chunk = m_subscriber->PopData(); + m_subscriber->FreeDataChunk(chunk); + } + + if (m_unk0x95) { + ProgressTickleState(e_done); + if (m_compositePresenter) { + if (m_compositePresenter->IsA("LegoAnimMMPresenter")) { + m_compositePresenter->VTable0x60(this); + } + } + } + else { + if (m_action->GetDuration() != -1) { + if (m_action->GetElapsedTime() > m_action->GetDuration() + m_action->GetStartTime()) { + m_unk0x95 = TRUE; + } + } + } +} + +// FUNCTION: LEGO1 0x1006cb40 +// FUNCTION: BETA10 0x1005239a +void LegoLoopingAnimPresenter::PutFrame() +{ + MxLong time; + + if (m_action->GetStartTime() <= m_action->GetElapsedTime()) { + time = (m_action->GetElapsedTime() - m_action->GetStartTime()) % m_anim->GetDuration(); + } + else { + time = 0; + } + + FUN_1006b9a0(m_anim, time, m_unk0x78); + + if (m_unk0x8c != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { + for (MxS32 i = 0; i < m_unk0x94; i++) { + if (m_unk0x8c[i] != NULL) { + MxMatrix mat(m_unk0x8c[i]->GetLocal2World()); + + Vector3 pos(mat[0]); + Vector3 dir(mat[1]); + Vector3 up(mat[2]); + Vector3 und(mat[3]); + + float possqr = sqrt(pos.LenSquared()); + float dirsqr = sqrt(dir.LenSquared()); + float upsqr = sqrt(up.LenSquared()); + + up = und; + + up -= m_currentWorld->GetCameraController()->GetWorldLocation(); + dir /= dirsqr; + pos.EqualsCross(dir, up); + pos.Unitize(); + up.EqualsCross(pos, dir); + pos *= possqr; + dir *= dirsqr; + up *= upsqr; + + m_unk0x8c[i]->SetLocal2World(mat); + m_unk0x8c[i]->WrappedUpdateWorldData(); + } + } + } +} + +// FUNCTION: LEGO1 0x1006cdd0 +LegoLocomotionAnimPresenter::LegoLocomotionAnimPresenter() +{ + Init(); +} + +// FUNCTION: LEGO1 0x1006d050 +LegoLocomotionAnimPresenter::~LegoLocomotionAnimPresenter() +{ + Destroy(TRUE); +} + +// FUNCTION: LEGO1 0x1006d0b0 +void LegoLocomotionAnimPresenter::Init() +{ + m_unk0xc0 = 0; + m_unk0xc4 = NULL; + m_unk0xcc = -1; + m_unk0xd0 = -1; + m_roiMapList = NULL; + m_unk0xd4 = 0; +} + +// FUNCTION: LEGO1 0x1006d0e0 +void LegoLocomotionAnimPresenter::Destroy(MxBool p_fromDestructor) +{ + ENTER(m_criticalSection); + + if (m_unk0xc4) { + delete[] m_unk0xc4; + } + + if (m_roiMapList) { + delete m_roiMapList; + } + + m_roiMap = NULL; + Init(); + + m_criticalSection.Leave(); + + if (!p_fromDestructor) { + LegoLoopingAnimPresenter::Destroy(); + } +} + +// FUNCTION: LEGO1 0x1006d140 +MxResult LegoLocomotionAnimPresenter::CreateAnim(MxStreamChunk* p_chunk) +{ + MxResult result = LegoAnimPresenter::CreateAnim(p_chunk); + return result == SUCCESS ? SUCCESS : result; +} + +// FUNCTION: LEGO1 0x1006d160 +// FUNCTION: BETA10 0x100528c7 +MxResult LegoLocomotionAnimPresenter::AddToManager() +{ + m_roiMapList = new LegoROIMapList(); + + if (m_roiMapList == NULL) { + return FAILURE; + } + + return LegoAnimPresenter::AddToManager(); +} + +// FUNCTION: LEGO1 0x1006d5b0 +void LegoLocomotionAnimPresenter::Destroy() +{ + Destroy(FALSE); +} + +// FUNCTION: LEGO1 0x1006d5c0 +void LegoLocomotionAnimPresenter::PutFrame() +{ + // Empty +} + +// FUNCTION: LEGO1 0x1006d5d0 +void LegoLocomotionAnimPresenter::ReadyTickle() +{ + LegoLoopingAnimPresenter::ReadyTickle(); + + if (m_currentWorld != NULL && m_currentTickleState == e_starting) { + m_currentWorld->Add(this); + if (m_compositePresenter != NULL) { + SendToCompositePresenter(Lego()); + } + + m_unk0xd4++; + } +} + +// FUNCTION: LEGO1 0x1006d610 +// FUNCTION: BETA10 0x10052a34 +void LegoLocomotionAnimPresenter::StartingTickle() +{ + if (m_subscriber->PeekData()) { + MxStreamChunk* chunk = m_subscriber->PopData(); + m_subscriber->FreeDataChunk(chunk); + } + + if (m_roiMapList->GetNumElements() != 0) { + ProgressTickleState(e_streaming); + } +} + +// FUNCTION: LEGO1 0x1006d660 +void LegoLocomotionAnimPresenter::StreamingTickle() +{ + if (m_unk0xd4 == 0) { + EndAction(); + } +} + +// FUNCTION: LEGO1 0x1006d670 +void LegoLocomotionAnimPresenter::EndAction() +{ + if (m_action) { + MxVideoPresenter::EndAction(); + } +} + +// FUNCTION: LEGO1 0x1006d680 +// FUNCTION: BETA10 0x10052b3d +void LegoLocomotionAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value) +{ + // This asserts that LegoLocomotionAnimPresenter is contained in legoanimpresenter.cpp + AUTOLOCK(m_criticalSection); + + MxVariableTable* variableTable = VariableTable(); + + const char* key = ((LegoAnimNodeData*) m_anim->GetRoot()->GetData())->GetName(); + variableTable->SetVariable(key, p_actor->GetROI()->GetName()); + + FUN_100695c0(); + FUN_10069b10(); + + if (m_roiMap != NULL) { + m_roiMapList->Append(m_roiMap); + p_actor->FUN_1001c450(m_anim, p_value, m_roiMap, m_roiMapSize); + m_roiMap = NULL; + } + + variableTable->SetVariable(key, ""); + + if (m_sceneROIs != NULL) { + delete m_sceneROIs; + m_sceneROIs = NULL; + } +} + +// We do not have any hard evidence that `LegoHideAnimPresenter` is part of this file as well. +// However, since all of the other AnimPresenters are in the same file, it is reasonable to assume +// that the same holds here. + +// FUNCTION: LEGO1 0x1006d7e0 +LegoHideAnimPresenter::LegoHideAnimPresenter() +{ + Init(); +} + +// FUNCTION: LEGO1 0x1006d9f0 +LegoHideAnimPresenter::~LegoHideAnimPresenter() +{ + Destroy(TRUE); +} + +// FUNCTION: LEGO1 0x1006da50 +void LegoHideAnimPresenter::Init() +{ + m_boundaryMap = NULL; +} + +// FUNCTION: LEGO1 0x1006da60 +void LegoHideAnimPresenter::Destroy(MxBool p_fromDestructor) +{ + ENTER(m_criticalSection); + + if (m_boundaryMap) { + delete[] m_boundaryMap; + } + Init(); + + m_criticalSection.Leave(); + + // This appears to be a bug, since it results in an endless loop + if (!p_fromDestructor) { + LegoHideAnimPresenter::Destroy(); + } +} + +// FUNCTION: LEGO1 0x1006dab0 +MxResult LegoHideAnimPresenter::AddToManager() +{ + return LegoAnimPresenter::AddToManager(); +} + +// FUNCTION: LEGO1 0x1006dac0 +void LegoHideAnimPresenter::Destroy() +{ + Destroy(FALSE); +} + +// FUNCTION: LEGO1 0x1006dad0 +void LegoHideAnimPresenter::PutFrame() +{ +} + +// FUNCTION: LEGO1 0x1006dae0 +// FUNCTION: BETA10 0x100530f4 +void LegoHideAnimPresenter::ReadyTickle() +{ + LegoLoopingAnimPresenter::ReadyTickle(); + + if (m_currentWorld) { + if (m_currentTickleState == e_starting && m_compositePresenter != NULL) { + SendToCompositePresenter(Lego()); + } + + m_currentWorld->Add(this); + } +} + +// FUNCTION: LEGO1 0x1006db20 +// FUNCTION: BETA10 0x1005316b +void LegoHideAnimPresenter::StartingTickle() +{ + LegoLoopingAnimPresenter::StartingTickle(); + + if (m_currentTickleState == e_streaming) { + FUN_1006dc10(); + FUN_1006db40(0); + } +} + +// FUNCTION: LEGO1 0x1006db40 +// FUNCTION: BETA10 0x100531ab +void LegoHideAnimPresenter::FUN_1006db40(LegoTime p_time) +{ + FUN_1006db60(m_anim->GetRoot(), p_time); +} + +// FUNCTION: LEGO1 0x1006db60 +// FUNCTION: BETA10 0x100531de +void LegoHideAnimPresenter::FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time) +{ + LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData(); + MxBool newB = FALSE; + MxBool previousB = FALSE; + + if (m_roiMap != NULL) { + LegoROI* roi = m_roiMap[data->GetROIIndex()]; + + if (roi != NULL) { + newB = data->GetVisibility(p_time); + previousB = roi->GetVisibility(); + roi->SetVisibility(newB); + } + } + + if (m_boundaryMap != NULL) { + LegoPathBoundary* boundary = m_boundaryMap[data->GetBoundaryIndex()]; + + if (boundary != NULL) { + newB = data->GetVisibility(p_time); + previousB = boundary->GetFlag0x10(); + boundary->SetFlag0x10(newB); + } + } + + for (MxS32 i = 0; i < p_node->GetNumChildren(); i++) { + FUN_1006db60(p_node->GetChild(i), p_time); + } +} + +// FUNCTION: LEGO1 0x1006dc10 +// FUNCTION: BETA10 0x100532fd +void LegoHideAnimPresenter::FUN_1006dc10() +{ + LegoHideAnimStructMap anims; + + FUN_1006e3f0(anims, m_anim->GetRoot()); + + if (m_boundaryMap != NULL) { + delete[] m_boundaryMap; + } + + m_boundaryMap = new LegoPathBoundary*[anims.size() + 1]; + m_boundaryMap[0] = NULL; + + for (LegoHideAnimStructMap::iterator it = anims.begin(); !(it == anims.end()); it++) { + m_boundaryMap[(*it).second.m_index] = (*it).second.m_boundary; + delete[] const_cast((*it).first); + } +} + +// FUNCTION: LEGO1 0x1006e3f0 +// FUNCTION: BETA10 0x1005345e +void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node) +{ + LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData(); + const char* name = data->GetName(); + + if (name != NULL) { + LegoPathBoundary* boundary = m_currentWorld->FindPathBoundary(name); + + if (boundary != NULL) { + FUN_1006e470(p_map, data, name, boundary); + } + else { + data->SetBoundaryIndex(0); + } + } + + MxS32 count = p_node->GetNumChildren(); + for (MxS32 i = 0; i < count; i++) { + FUN_1006e3f0(p_map, p_node->GetChild(i)); + } +} + +// FUNCTION: LEGO1 0x1006e470 +// FUNCTION: BETA10 0x10053520 +void LegoHideAnimPresenter::FUN_1006e470( + LegoHideAnimStructMap& p_map, + LegoAnimNodeData* p_data, + const char* p_name, + LegoPathBoundary* p_boundary +) +{ + LegoHideAnimStructMap::iterator it; + + it = p_map.find(p_name); + if (it == p_map.end()) { + LegoHideAnimStruct animStruct; + animStruct.m_index = p_map.size() + 1; + animStruct.m_boundary = p_boundary; + + p_data->SetBoundaryIndex(animStruct.m_index); + + char* name = new char[strlen(p_name) + 1]; + strcpy(name, p_name); + + p_map[name] = animStruct; + } + else { + p_data->SetBoundaryIndex((*it).second.m_index); + } +} + +// FUNCTION: LEGO1 0x1006e9e0 +// FUNCTION: BETA10 0x100535ef +void LegoHideAnimPresenter::EndAction() +{ + if (m_action) { + MxVideoPresenter::EndAction(); + + if (m_currentWorld) { + m_currentWorld->Remove(this); + } + } +} diff --git a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp deleted file mode 100644 index 03cc147e..00000000 --- a/LEGO1/lego/legoomni/src/video/legohideanimpresenter.cpp +++ /dev/null @@ -1,216 +0,0 @@ -#include "legohideanimpresenter.h" - -#include "anim/legoanim.h" -#include "legomain.h" -#include "legoworld.h" -#include "misc.h" - -DECOMP_SIZE_ASSERT(LegoHideAnimPresenter, 0xc4) -DECOMP_SIZE_ASSERT(LegoHideAnimStruct, 0x08) - -// FUNCTION: LEGO1 0x1006d7e0 -LegoHideAnimPresenter::LegoHideAnimPresenter() -{ - Init(); -} - -// FUNCTION: LEGO1 0x1006d9f0 -LegoHideAnimPresenter::~LegoHideAnimPresenter() -{ - Destroy(TRUE); -} - -// FUNCTION: LEGO1 0x1006da50 -void LegoHideAnimPresenter::Init() -{ - m_boundaryMap = NULL; -} - -// FUNCTION: LEGO1 0x1006da60 -void LegoHideAnimPresenter::Destroy(MxBool p_fromDestructor) -{ - ENTER(m_criticalSection); - - if (m_boundaryMap) { - delete[] m_boundaryMap; - } - Init(); - - m_criticalSection.Leave(); - - // This appears to be a bug, since it results in an endless loop - if (!p_fromDestructor) { - LegoHideAnimPresenter::Destroy(); - } -} - -// FUNCTION: LEGO1 0x1006dab0 -MxResult LegoHideAnimPresenter::AddToManager() -{ - return LegoAnimPresenter::AddToManager(); -} - -// FUNCTION: LEGO1 0x1006dac0 -void LegoHideAnimPresenter::Destroy() -{ - Destroy(FALSE); -} - -// FUNCTION: LEGO1 0x1006dad0 -void LegoHideAnimPresenter::PutFrame() -{ -} - -// FUNCTION: LEGO1 0x1006dae0 -// FUNCTION: BETA10 0x100530f4 -void LegoHideAnimPresenter::ReadyTickle() -{ - LegoLoopingAnimPresenter::ReadyTickle(); - - if (m_currentWorld) { - if (m_currentTickleState == e_starting && m_compositePresenter != NULL) { - SendToCompositePresenter(Lego()); - } - - m_currentWorld->Add(this); - } -} - -// FUNCTION: LEGO1 0x1006db20 -// FUNCTION: BETA10 0x1005316b -void LegoHideAnimPresenter::StartingTickle() -{ - LegoLoopingAnimPresenter::StartingTickle(); - - if (m_currentTickleState == e_streaming) { - FUN_1006dc10(); - FUN_1006db40(0); - } -} - -// FUNCTION: LEGO1 0x1006db40 -// FUNCTION: BETA10 0x100531ab -void LegoHideAnimPresenter::FUN_1006db40(LegoTime p_time) -{ - FUN_1006db60(m_anim->GetRoot(), p_time); -} - -// FUNCTION: LEGO1 0x1006db60 -// FUNCTION: BETA10 0x100531de -void LegoHideAnimPresenter::FUN_1006db60(LegoTreeNode* p_node, LegoTime p_time) -{ - LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData(); - MxBool newB = FALSE; - MxBool previousB = FALSE; - - if (m_roiMap != NULL) { - LegoROI* roi = m_roiMap[data->GetROIIndex()]; - - if (roi != NULL) { - newB = data->GetVisibility(p_time); - previousB = roi->GetVisibility(); - roi->SetVisibility(newB); - } - } - - if (m_boundaryMap != NULL) { - LegoPathBoundary* boundary = m_boundaryMap[data->GetBoundaryIndex()]; - - if (boundary != NULL) { - newB = data->GetVisibility(p_time); - previousB = boundary->GetFlag0x10(); - boundary->SetFlag0x10(newB); - } - } - - for (MxS32 i = 0; i < p_node->GetNumChildren(); i++) { - FUN_1006db60(p_node->GetChild(i), p_time); - } -} - -// FUNCTION: LEGO1 0x1006dc10 -// FUNCTION: BETA10 0x100532fd -void LegoHideAnimPresenter::FUN_1006dc10() -{ - LegoHideAnimStructMap anims; - - FUN_1006e3f0(anims, m_anim->GetRoot()); - - if (m_boundaryMap != NULL) { - delete[] m_boundaryMap; - } - - m_boundaryMap = new LegoPathBoundary*[anims.size() + 1]; - m_boundaryMap[0] = NULL; - - for (LegoHideAnimStructMap::iterator it = anims.begin(); !(it == anims.end()); it++) { - m_boundaryMap[(*it).second.m_index] = (*it).second.m_boundary; - delete[] const_cast((*it).first); - } -} - -// FUNCTION: LEGO1 0x1006e3f0 -// FUNCTION: BETA10 0x1005345e -void LegoHideAnimPresenter::FUN_1006e3f0(LegoHideAnimStructMap& p_map, LegoTreeNode* p_node) -{ - LegoAnimNodeData* data = (LegoAnimNodeData*) p_node->GetData(); - const char* name = data->GetName(); - - if (name != NULL) { - LegoPathBoundary* boundary = m_currentWorld->FindPathBoundary(name); - - if (boundary != NULL) { - FUN_1006e470(p_map, data, name, boundary); - } - else { - data->SetBoundaryIndex(0); - } - } - - MxS32 count = p_node->GetNumChildren(); - for (MxS32 i = 0; i < count; i++) { - FUN_1006e3f0(p_map, p_node->GetChild(i)); - } -} - -// FUNCTION: LEGO1 0x1006e470 -// FUNCTION: BETA10 0x10053520 -void LegoHideAnimPresenter::FUN_1006e470( - LegoHideAnimStructMap& p_map, - LegoAnimNodeData* p_data, - const char* p_name, - LegoPathBoundary* p_boundary -) -{ - LegoHideAnimStructMap::iterator it; - - it = p_map.find(p_name); - if (it == p_map.end()) { - LegoHideAnimStruct animStruct; - animStruct.m_index = p_map.size() + 1; - animStruct.m_boundary = p_boundary; - - p_data->SetBoundaryIndex(animStruct.m_index); - - char* name = new char[strlen(p_name) + 1]; - strcpy(name, p_name); - - p_map[name] = animStruct; - } - else { - p_data->SetBoundaryIndex((*it).second.m_index); - } -} - -// FUNCTION: LEGO1 0x1006e9e0 -// FUNCTION: BETA10 0x100535ef -void LegoHideAnimPresenter::EndAction() -{ - if (m_action) { - MxVideoPresenter::EndAction(); - - if (m_currentWorld) { - m_currentWorld->Remove(this); - } - } -} diff --git a/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp deleted file mode 100644 index 32e37669..00000000 --- a/LEGO1/lego/legoomni/src/video/legolocomotionanimpresenter.cpp +++ /dev/null @@ -1,164 +0,0 @@ -#include "legolocomotionanimpresenter.h" - -#include "anim/legoanim.h" -#include "legoanimactor.h" -#include "legomain.h" -#include "legoworld.h" -#include "misc.h" -#include "mxautolock.h" -#include "mxdssubscriber.h" -#include "mxmisc.h" -#include "mxvariabletable.h" - -DECOMP_SIZE_ASSERT(LegoLocomotionAnimPresenter, 0xd8) - -// FUNCTION: LEGO1 0x1006cdd0 -LegoLocomotionAnimPresenter::LegoLocomotionAnimPresenter() -{ - Init(); -} - -// FUNCTION: LEGO1 0x1006d050 -LegoLocomotionAnimPresenter::~LegoLocomotionAnimPresenter() -{ - Destroy(TRUE); -} - -// FUNCTION: LEGO1 0x1006d0b0 -void LegoLocomotionAnimPresenter::Init() -{ - m_unk0xc0 = 0; - m_unk0xc4 = NULL; - m_unk0xcc = -1; - m_unk0xd0 = -1; - m_roiMapList = NULL; - m_unk0xd4 = 0; -} - -// FUNCTION: LEGO1 0x1006d0e0 -void LegoLocomotionAnimPresenter::Destroy(MxBool p_fromDestructor) -{ - ENTER(m_criticalSection); - - if (m_unk0xc4) { - delete[] m_unk0xc4; - } - - if (m_roiMapList) { - delete m_roiMapList; - } - - m_roiMap = NULL; - Init(); - - m_criticalSection.Leave(); - - if (!p_fromDestructor) { - LegoLoopingAnimPresenter::Destroy(); - } -} - -// FUNCTION: LEGO1 0x1006d140 -MxResult LegoLocomotionAnimPresenter::CreateAnim(MxStreamChunk* p_chunk) -{ - MxResult result = LegoAnimPresenter::CreateAnim(p_chunk); - return result == SUCCESS ? SUCCESS : result; -} - -// FUNCTION: LEGO1 0x1006d160 -// FUNCTION: BETA10 0x100528c7 -MxResult LegoLocomotionAnimPresenter::AddToManager() -{ - m_roiMapList = new LegoROIMapList(); - - if (m_roiMapList == NULL) { - return FAILURE; - } - - return LegoAnimPresenter::AddToManager(); -} - -// FUNCTION: LEGO1 0x1006d5b0 -void LegoLocomotionAnimPresenter::Destroy() -{ - Destroy(FALSE); -} - -// FUNCTION: LEGO1 0x1006d5c0 -void LegoLocomotionAnimPresenter::PutFrame() -{ - // Empty -} - -// FUNCTION: LEGO1 0x1006d5d0 -void LegoLocomotionAnimPresenter::ReadyTickle() -{ - LegoLoopingAnimPresenter::ReadyTickle(); - - if (m_currentWorld != NULL && m_currentTickleState == e_starting) { - m_currentWorld->Add(this); - if (m_compositePresenter != NULL) { - SendToCompositePresenter(Lego()); - } - - m_unk0xd4++; - } -} - -// FUNCTION: LEGO1 0x1006d610 -// FUNCTION: BETA10 0x10052a34 -void LegoLocomotionAnimPresenter::StartingTickle() -{ - if (m_subscriber->PeekData()) { - MxStreamChunk* chunk = m_subscriber->PopData(); - m_subscriber->FreeDataChunk(chunk); - } - - if (m_roiMapList->GetNumElements() != 0) { - ProgressTickleState(e_streaming); - } -} - -// FUNCTION: LEGO1 0x1006d660 -void LegoLocomotionAnimPresenter::StreamingTickle() -{ - if (m_unk0xd4 == 0) { - EndAction(); - } -} - -// FUNCTION: LEGO1 0x1006d670 -void LegoLocomotionAnimPresenter::EndAction() -{ - if (m_action) { - MxVideoPresenter::EndAction(); - } -} - -// FUNCTION: LEGO1 0x1006d680 -// FUNCTION: BETA10 0x10052b3d -void LegoLocomotionAnimPresenter::FUN_1006d680(LegoAnimActor* p_actor, MxFloat p_value) -{ - AUTOLOCK(m_criticalSection); - - MxVariableTable* variableTable = VariableTable(); - - const char* key = ((LegoAnimNodeData*) m_anim->GetRoot()->GetData())->GetName(); - variableTable->SetVariable(key, p_actor->GetROI()->GetName()); - - FUN_100695c0(); - FUN_10069b10(); - - if (m_roiMap != NULL) { - m_roiMapList->Append(m_roiMap); - p_actor->FUN_1001c450(m_anim, p_value, m_roiMap, m_roiMapSize); - m_roiMap = NULL; - } - - variableTable->SetVariable(key, ""); - - if (m_sceneROIs != NULL) { - delete m_sceneROIs; - m_sceneROIs = NULL; - } -} diff --git a/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp deleted file mode 100644 index cf75ce47..00000000 --- a/LEGO1/lego/legoomni/src/video/legoloopinganimpresenter.cpp +++ /dev/null @@ -1,83 +0,0 @@ -#include "legoloopinganimpresenter.h" - -#include "anim/legoanim.h" -#include "legocameracontroller.h" -#include "legoworld.h" -#include "mxcompositepresenter.h" -#include "mxdsaction.h" -#include "mxdssubscriber.h" - -DECOMP_SIZE_ASSERT(LegoLoopingAnimPresenter, 0xc0) - -// FUNCTION: LEGO1 0x1006caa0 -// FUNCTION: BETA10 0x1005223d -void LegoLoopingAnimPresenter::StreamingTickle() -{ - if (m_subscriber->PeekData()) { - MxStreamChunk* chunk = m_subscriber->PopData(); - m_subscriber->FreeDataChunk(chunk); - } - - if (m_unk0x95) { - ProgressTickleState(e_done); - if (m_compositePresenter) { - if (m_compositePresenter->IsA("LegoAnimMMPresenter")) { - m_compositePresenter->VTable0x60(this); - } - } - } - else { - if (m_action->GetDuration() != -1) { - if (m_action->GetElapsedTime() > m_action->GetDuration() + m_action->GetStartTime()) { - m_unk0x95 = TRUE; - } - } - } -} - -// FUNCTION: LEGO1 0x1006cb40 -// FUNCTION: BETA10 0x1005239a -void LegoLoopingAnimPresenter::PutFrame() -{ - MxLong time; - - if (m_action->GetStartTime() <= m_action->GetElapsedTime()) { - time = (m_action->GetElapsedTime() - m_action->GetStartTime()) % m_anim->GetDuration(); - } - else { - time = 0; - } - - FUN_1006b9a0(m_anim, time, m_unk0x78); - - if (m_unk0x8c != NULL && m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { - for (MxS32 i = 0; i < m_unk0x94; i++) { - if (m_unk0x8c[i] != NULL) { - MxMatrix mat(m_unk0x8c[i]->GetLocal2World()); - - Vector3 pos(mat[0]); - Vector3 dir(mat[1]); - Vector3 up(mat[2]); - Vector3 und(mat[3]); - - float possqr = sqrt(pos.LenSquared()); - float dirsqr = sqrt(dir.LenSquared()); - float upsqr = sqrt(up.LenSquared()); - - up = und; - - up -= m_currentWorld->GetCameraController()->GetWorldLocation(); - dir /= dirsqr; - pos.EqualsCross(dir, up); - pos.Unitize(); - up.EqualsCross(pos, dir); - pos *= possqr; - dir *= dirsqr; - up *= upsqr; - - m_unk0x8c[i]->SetLocal2World(mat); - m_unk0x8c[i]->WrappedUpdateWorldData(); - } - } - } -} diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index a3c4f7c0..9d088e3b 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -7,10 +7,10 @@ #include "islepathactor.h" #include "jukebox_actions.h" #include "legoanimationmanager.h" +#include "legoanimpresenter.h" #include "legocachesoundmanager.h" #include "legogamestate.h" #include "legoinputmanager.h" -#include "legolocomotionanimpresenter.h" #include "legomain.h" #include "legopathstruct.h" #include "legosoundmanager.h" diff --git a/LEGO1/omni/src/common/mxcompositepresenter.cpp b/LEGO1/omni/src/common/mxcompositepresenter.cpp index 4e83d86c..b3d56875 100644 --- a/LEGO1/omni/src/common/mxcompositepresenter.cpp +++ b/LEGO1/omni/src/common/mxcompositepresenter.cpp @@ -25,7 +25,7 @@ MxCompositePresenter::~MxCompositePresenter() } // FUNCTION: LEGO1 0x100b6410 -// FUNCTION: BETA10 0x100e9d37 +// FUNCTION: BETA10 0x10137344 MxResult MxCompositePresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) { AUTOLOCK(m_criticalSection);