From c65bc67e3dc929d0540530ecd7f3688c44f7e819 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Tue, 5 Nov 2024 21:33:51 +0100 Subject: [PATCH] Implement `FUN_10025720()` and others (#1134) * Implement `FUN_10025720()` and others * Address review comments, get 100 % --------- Co-authored-by: jonschz --- LEGO1/lego/legoomni/include/legocarbuild.h | 35 ++- LEGO1/lego/legoomni/include/legomain.h | 3 + LEGO1/lego/legoomni/include/legoutils.h | 5 +- .../src/audio/mxbackgroundaudiomanager.cpp | 1 + .../lego/legoomni/src/build/legocarbuild.cpp | 262 ++++++++++++++++-- LEGO1/lego/legoomni/src/common/legoutils.cpp | 46 ++- LEGO1/lego/legoomni/src/common/misc.cpp | 2 + LEGO1/lego/sources/roi/legoroi.cpp | 21 ++ LEGO1/lego/sources/roi/legoroi.h | 2 + LEGO1/library_msvc.h | 6 + 10 files changed, 345 insertions(+), 38 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocarbuild.h b/LEGO1/lego/legoomni/include/legocarbuild.h index a18082db..6337aafd 100644 --- a/LEGO1/lego/legoomni/include/legocarbuild.h +++ b/LEGO1/lego/legoomni/include/legocarbuild.h @@ -73,6 +73,17 @@ typedef LegoVehicleBuildState LegoJetskiBuildState; // SIZE 0x34c class LegoCarBuild : public LegoWorld { public: + // SIZE 0x1c + struct LookupTableActions { + undefined4 m_unk0x00; // 0x00 + undefined4 m_unk0x04; // 0x04 + undefined4 m_unk0x08; // 0x08 + undefined4 m_unk0x0c; // 0x0c + undefined4 m_unk0x10; // 0x10 + undefined4 m_unk0x14; // 0x14 + undefined4 m_unk0x18; // 0x18 + }; + enum Unknown0xf8 { c_unknownminusone = -1, c_unknown8 = 8 @@ -133,9 +144,10 @@ class LegoCarBuild : public LegoWorld { void SetPresentersEnabled(MxBool p_enabled); void TogglePresentersEnabled(); void FUN_100250e0(MxBool p_param); - void FUN_10025350(MxS32 p_param); + void FUN_10025350(MxS32 p_objectId); void FUN_10025450(); - undefined4 FUN_10025720(undefined4 p_param1); + void FUN_10025720(undefined4 p_param1); + void FUN_10025d10(MxS32 p_param); MxS32 FUN_10025d70(); void FUN_10025db0(const char* p_param1, undefined4 p_param2); void FUN_10025e40(); @@ -148,12 +160,18 @@ class LegoCarBuild : public LegoWorld { // LegoCarBuild::`scalar deleting destructor' private: - Unknown0xf8 m_unk0xf8; // 0xf8 - MxS16 m_unk0xfc; // 0xfc - undefined m_unk0xfe[2]; // 0xfe - MxS32 m_unk0x100; // 0x100 - undefined4 m_unk0x104; // 0x104 - MxS8 m_unk0x108; // 0x108 + // inline functions + MxU32 Beta0x10070520(); + void StopActionIn0x344(); + + Unknown0xf8 m_unk0xf8; // 0xf8 + MxS16 m_unk0xfc; // 0xfc + MxS32 m_unk0x100; // 0x100 + undefined4 m_unk0x104; // 0x104 + + // name verified by BETA10 0x1006ebba + MxS8 m_numAnimsRun; // 0x108 + MxU8 m_unk0x109; // 0x109 MxU16 m_unk0x10a; // 0x10a DWORD m_unk0x10c; // 0x10c @@ -221,6 +239,7 @@ class LegoCarBuild : public LegoWorld { static MxS16 g_unk0x100f11cc; static MxFloat g_unk0x100d65a4; static MxFloat g_rotationAngleStepYAxis; + static LookupTableActions g_unk0x100d65b0[]; }; #endif // LEGOCARBUILD_H diff --git a/LEGO1/lego/legoomni/include/legomain.h b/LEGO1/lego/legoomni/include/legomain.h index 182500c1..4ac4f309 100644 --- a/LEGO1/lego/legoomni/include/legomain.h +++ b/LEGO1/lego/legoomni/include/legomain.h @@ -147,7 +147,10 @@ class LegoOmni : public MxOmni { void SetNavController(LegoNavController* p_navController) { m_navController = p_navController; } void SetUserActor(LegoPathActor* p_userActor) { m_userActor = p_userActor; } void SetCurrentWorld(LegoWorld* p_currentWorld) { m_currentWorld = p_currentWorld; } + + // 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; } diff --git a/LEGO1/lego/legoomni/include/legoutils.h b/LEGO1/lego/legoomni/include/legoutils.h index b6143c36..8c4b44fe 100644 --- a/LEGO1/lego/legoomni/include/legoutils.h +++ b/LEGO1/lego/legoomni/include/legoutils.h @@ -10,6 +10,9 @@ #define WM_ISLE_SETCURSOR 0x5400 +// name verified by BETA10 0x100d4054 +#define DS_NOT_A_STREAM -1 + enum Cursor { e_cursorArrow = 0, e_cursorBusy, @@ -46,7 +49,7 @@ MxS16 CountTotalTreeNodes(LegoTreeNode* p_node); LegoTreeNode* GetTreeNode(LegoTreeNode* p_node, MxU32 p_index); void FUN_1003e050(LegoAnimPresenter* p_presenter); Extra::ActionType MatchActionString(const char*); -void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_targetEntityId, LegoEntity* p_sender); +void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_streamId, LegoEntity* p_sender); void SetCameraControllerFromIsle(); void ConvertHSVToRGB(float p_h, float p_s, float p_v, float* p_rOut, float* p_bOut, float* p_gOut); void PlayCamAnim(LegoPathActor* p_actor, MxBool p_unused, MxU32 p_location, MxBool p_bool); diff --git a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp index d3e08256..4a921511 100644 --- a/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/mxbackgroundaudiomanager.cpp @@ -300,6 +300,7 @@ void MxBackgroundAudioManager::Stop() } // FUNCTION: LEGO1 0x1007f570 +// FUNCTION: BETA10 0x100e94e6 void MxBackgroundAudioManager::LowerVolume() { if (m_unk0x148 == 0) { diff --git a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp index a7396bdc..68b1495f 100644 --- a/LEGO1/lego/legoomni/src/build/legocarbuild.cpp +++ b/LEGO1/lego/legoomni/src/build/legocarbuild.cpp @@ -24,6 +24,7 @@ #include "mxstillpresenter.h" #include "mxticklemanager.h" #include "mxtransitionmanager.h" +#include "mxvariabletable.h" #include "racecar.h" #include "racecar_actions.h" #include "scripts.h" @@ -40,6 +41,42 @@ DECOMP_SIZE_ASSERT(LegoCarBuild, 0x34c) DECOMP_SIZE_ASSERT(LegoVehicleBuildState, 0x50) +DECOMP_SIZE_ASSERT(LegoCarBuild::LookupTableActions, 0x1c); + +// These four structs can be matched to the vehicle types using BETA10 0x10070520 + +// GLOBAL: LEGO1 0x100d65b0 +// GLOBAL: BETA10 0x101bb7c0 +LegoCarBuild::LookupTableActions LegoCarBuild::g_unk0x100d65b0[] = { + {DunecarScript::c_igs001d3_RunAnim, + DunecarScript::c_igs002d3_RunAnim, + DunecarScript::c_igs003d3_RunAnim, + DunecarScript::c_igs004d3_RunAnim, + DunecarScript::c_igs005d3_RunAnim, + DunecarScript::c_igs004d3_RunAnim, + DunecarScript::c_igsxx1d3_RunAnim}, + {JetskiScript::c_ijs001d4_RunAnim, + JetskiScript::c_ijs003d4_RunAnim, + JetskiScript::c_ijs004d4_RunAnim, + JetskiScript::c_ijs005d4_RunAnim, + JetskiScript::c_ijs006d4_RunAnim, + JetskiScript::c_ijs007d4_RunAnim, + JetskiScript::c_ijsxx2d4_RunAnim}, + {CopterScript::c_ips001d2_RunAnim, + CopterScript::c_ips002d2_RunAnim, + CopterScript::c_ips003d2_RunAnim, + CopterScript::c_ips005d2_RunAnim, + CopterScript::c_ips004d2_RunAnim, + CopterScript::c_ips004d2_RunAnim, + CopterScript::c_ipsxx1d2_RunAnim}, + {RacecarScript::c_irt001d1_RunAnim, + RacecarScript::c_irt002d1_RunAnim, + RacecarScript::c_irt003d1_RunAnim, + RacecarScript::c_irt004d1_RunAnim, + RacecarScript::c_irt005d1_RunAnim, + RacecarScript::c_irt004d1_RunAnim, + RacecarScript::c_irtxx4d1_RunAnim} +}; // GLOBAL: LEGO1 0x100d65a4 MxFloat LegoCarBuild::g_unk0x100d65a4 = -0.1f; @@ -84,10 +121,10 @@ LegoCarBuild::LegoCarBuild() m_buildState = NULL; m_unk0x104 = 0; m_unk0x109 = 0; - m_unk0x108 = 0; + m_numAnimsRun = 0; m_unk0x338 = 0; m_destLocation = LegoGameState::e_undefined; - m_unk0x344 = 0xffffffff; + m_unk0x344 = DS_NOT_A_STREAM; m_unk0x174 = 0; NotificationManager()->Register(this); } @@ -610,8 +647,8 @@ MxLong LegoCarBuild::Notify(MxParam& p_param) break; case c_notificationEndAnim: - if (m_unk0x108 > 0) { - m_unk0x108 -= 1; + if (m_numAnimsRun > 0) { + m_numAnimsRun -= 1; } FUN_10025e40(); @@ -632,7 +669,7 @@ MxLong LegoCarBuild::Notify(MxParam& p_param) undefined4 LegoCarBuild::FUN_10024250(LegoEventNotificationParam* p_param) { if (p_param->GetKey() == ' ' && m_buildState->m_animationState != 4 && m_buildState->m_animationState != 2) { - if (m_unk0x108 > 0) { + if (m_numAnimsRun > 0) { DeleteObjects(&m_atomId, 500, 0x1fe); BackgroundAudioManager()->RaiseVolume(); m_unk0x109 = 0; @@ -815,7 +852,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) m_buildState->m_animationState != LegoVehicleBuildState::e_unknown2 && m_buildState->m_animationState != LegoVehicleBuildState::e_exiting && GameState()->GetCurrentAct() != LegoGameState::e_act2) { - if (m_unk0x108 > 0) { + if (m_numAnimsRun > 0) { DeleteObjects(&m_atomId, 500, 510); } @@ -829,7 +866,7 @@ undefined4 LegoCarBuild::FUN_10024890(MxParam* p_param) case CopterScript::c_Exit_Ctl: if (m_buildState->m_animationState != LegoVehicleBuildState::e_exiting && m_buildState->m_animationState != LegoVehicleBuildState::e_unknown4) { - if (m_unk0x108 > 0) { + if (m_numAnimsRun > 0) { DeleteObjects(&m_atomId, 500, 510); } @@ -1201,11 +1238,44 @@ void LegoCarBuild::FUN_100250e0(MxBool p_enabled) } } -// STUB: LEGO1 0x10025350 -// STUB: BETA10 0x1006e3c0 -void LegoCarBuild::FUN_10025350(MxS32 p_param) +// FUNCTION: LEGO1 0x10025350 +// FUNCTION: BETA10 0x1006e3c0 +void LegoCarBuild::FUN_10025350(MxS32 p_objectId) { - // TODO + const LegoChar* color; + LegoChar buffer[256]; + + if (!m_unk0x110) { + return; + } + + if (m_Yellow_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego yellow"; + } + else if (m_Red_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego red"; + } + else if (m_Blue_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego blue"; + } + else if (m_Green_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego green"; + } + else if (m_Gray_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego white"; + } + else if (m_Black_Ctl->GetAction()->GetObjectId() == p_objectId) { + color = "lego black"; + } + else { + return; + } + + m_Paint_Sound->Enable(FALSE); + m_Paint_Sound->Enable(TRUE); + m_unk0x110->FUN_100a93b0(color); + sprintf(buffer, "c_%s", m_unk0x110->GetName()); + VariableTable()->SetVariable(buffer, color); } // FUNCTION: LEGO1 0x10025450 @@ -1277,12 +1347,172 @@ void LegoCarBuild::Enable(MxBool p_enable) } } -// STUB: LEGO1 0x10025720 -// STUB: BETA10 0x1006e9df -undefined4 LegoCarBuild::FUN_10025720(undefined4 p_param1) +// FUNCTION: BETA10 0x10070520 +inline MxU32 LegoCarBuild::Beta0x10070520() { - // TODO - return 0; + switch (m_carId) { + case Helicopter_Actor: + return 2; + case DuneBugy_Actor: + return 0; + case Jetski_Actor: + return 1; + case RaceCar_Actor: + return 3; + default: + assert(0); + return 0; + } +} + +inline void LegoCarBuild::StopActionIn0x344() +{ + // There is no direct evidence for this inline function in LEGO1, + // but some code doesn't make much sense otherwise. For example, + // sometimes `m_unk0x344` is set to another value right below this call, + // which the original developer would likely have refactored. + if (m_unk0x344 != DS_NOT_A_STREAM) { + InvokeAction(Extra::ActionType::e_stop, m_atomId, m_unk0x344, NULL); + m_unk0x344 = DS_NOT_A_STREAM; + } +} + +// FUNCTION: LEGO1 0x10025720 +// FUNCTION: BETA10 0x1006e9df +void LegoCarBuild::FUN_10025720(undefined4 p_param) +{ + m_numAnimsRun++; + m_unk0x10a = 0; + MxS32 uVar6; + +#ifdef NDEBUG + + if (GameState()->GetCurrentAct() == LegoGameState::e_act2) { + // This is most likely related to the helicopter rebuild in Act 2 + switch (p_param) { + case 0: + case 1: + case 2: + case 3: + switch (rand() % 3) { + case 0: + m_unk0x10a = CopterScript::c_ips004d2_RunAnim; + StopActionIn0x344(); + m_unk0x344 = CopterScript::c_ips004d2_RunAnim; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, CopterScript::c_ips004d2_RunAnim, NULL); + break; + case 1: + m_unk0x10a = CopterScript::c_ips006d2_RunAnim; + StopActionIn0x344(); + m_unk0x344 = CopterScript::c_ips006d2_RunAnim; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, CopterScript::c_ips006d2_RunAnim, NULL); + break; + case 2: + m_unk0x10a = CopterScript::c_slp01xd2_RunAnim; + StopActionIn0x344(); + m_unk0x344 = CopterScript::c_slp01xd2_RunAnim; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, CopterScript::c_slp01xd2_RunAnim, NULL); + break; + } + break; + case 4: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x04); + break; + case 5: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x08); + break; + case 6: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x18; + uVar6 = m_unk0x10a; + StopActionIn0x344(); + + if (uVar6 != DS_NOT_A_STREAM) { + m_unk0x344 = uVar6; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, uVar6, NULL); + } + + break; + default: + m_numAnimsRun--; + return; + } + } + else { +#endif + // This part doesn't match BETA10 perfectly, but it's the closest we get without hundreds of #ifdef's + switch (p_param) { + case 0: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x00; + FUN_10025d10(m_unk0x10a); + break; + case 1: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x0c; + FUN_10025d10(m_unk0x10a); + + if (m_carId == 2) { + m_unk0x10a = 0; + } + + break; + case 2: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x10; + FUN_10025d10(m_unk0x10a); + + if (m_carId != 3) { + m_unk0x10a = 0; + } + + break; + case 3: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x14); + break; + case 4: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x04); + break; + case 5: + FUN_10025d10(g_unk0x100d65b0[Beta0x10070520()].m_unk0x08); + break; + case 6: + m_unk0x10a = g_unk0x100d65b0[Beta0x10070520()].m_unk0x18; + FUN_10025d10(m_unk0x10a); + break; + default: + assert(0); + m_numAnimsRun--; + + // Weird: This assertion can never be executed. The `assert(0)` above was probably introduced later. + assert(m_numAnimsRun >= 0); + return; + } +#ifdef NDEBUG + } +#endif + + if (m_unk0x10a != 0) { + m_unk0x10c = timeGetTime(); + } +} + +// FUNCTION: LEGO1 0x10025d10 +// FUNCTION: BETA10 0x10070490 +void LegoCarBuild::FUN_10025d10(MxS32 p_param) +{ + // this function has a different signature and partially different body in BETA10, but it is called in the same + // places + if (m_unk0x344 != DS_NOT_A_STREAM) { + InvokeAction(Extra::ActionType::e_stop, m_atomId, m_unk0x344, NULL); + m_unk0x344 = DS_NOT_A_STREAM; + } + + if (p_param != DS_NOT_A_STREAM) { + m_unk0x344 = p_param; + BackgroundAudioManager()->LowerVolume(); + InvokeAction(Extra::ActionType::e_start, m_atomId, p_param, NULL); + } } // FUNCTION: LEGO1 0x10025d70 diff --git a/LEGO1/lego/legoomni/src/common/legoutils.cpp b/LEGO1/lego/legoomni/src/common/legoutils.cpp index 7f70425a..e3c7dbef 100644 --- a/LEGO1/lego/legoomni/src/common/legoutils.cpp +++ b/LEGO1/lego/legoomni/src/common/legoutils.cpp @@ -240,24 +240,30 @@ void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender // FUNCTION: LEGO1 0x1003e430 // FUNCTION: BETA10 0x100d3fda -void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_targetEntityId, LegoEntity* p_sender) +void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p_streamId, LegoEntity* p_sender) { MxDSAction action; action.SetAtomId(p_pAtom); - action.SetObjectId(p_targetEntityId); + action.SetObjectId(p_streamId); switch (p_actionId) { case Extra::ActionType::e_opendisk: - if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) { + assert(p_streamId != DS_NOT_A_STREAM); + + if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId)) { Streamer()->Open(p_pAtom.GetInternal(), MxStreamer::e_diskStream); Start(&action); } + break; case Extra::ActionType::e_openram: - if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) { + assert(p_streamId != DS_NOT_A_STREAM); + + if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId)) { Streamer()->Open(p_pAtom.GetInternal(), MxStreamer::e_RAMStream); Start(&action); } + break; case Extra::ActionType::e_close: action.SetUnknown24(-2); @@ -265,35 +271,47 @@ void InvokeAction(Extra::ActionType p_actionId, const MxAtomId& p_pAtom, MxS32 p Streamer()->Close(p_pAtom.GetInternal()); break; case Extra::ActionType::e_start: - if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId)) { + assert(p_streamId != DS_NOT_A_STREAM); + + if (!CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId)) { Start(&action); } + break; case Extra::ActionType::e_stop: + assert(p_streamId != DS_NOT_A_STREAM); action.SetUnknown24(-2); - if (!RemoveFromCurrentWorld(p_pAtom, p_targetEntityId)) { + + if (!RemoveFromCurrentWorld(p_pAtom, p_streamId)) { DeleteObject(action); } + break; case Extra::ActionType::e_run: _spawnl(0, "\\lego\\sources\\main\\main.exe", "\\lego\\sources\\main\\main.exe", "/script", &p_pAtom, 0); break; + case Extra::ActionType::e_enable: + assert(p_streamId != DS_NOT_A_STREAM); + CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_streamId); + break; + case Extra::ActionType::e_disable: + assert(p_streamId != DS_NOT_A_STREAM); + CheckIfEntityExists(FALSE, p_pAtom.GetInternal(), p_streamId); + break; case Extra::ActionType::e_exit: Lego()->SetExit(TRUE); break; - case Extra::ActionType::e_enable: - CheckIfEntityExists(TRUE, p_pAtom.GetInternal(), p_targetEntityId); - break; - case Extra::ActionType::e_disable: - CheckIfEntityExists(FALSE, p_pAtom.GetInternal(), p_targetEntityId); - break; case Extra::ActionType::e_notify: - NotifyEntity(p_pAtom.GetInternal(), p_targetEntityId, p_sender); + assert(p_streamId != DS_NOT_A_STREAM); + NotifyEntity(p_pAtom.GetInternal(), p_streamId, p_sender); break; + default: + assert("Invalid Action Control" == NULL); } } // FUNCTION: LEGO1 0x1003e670 +// FUNCTION: BETA10 0x100d43f2 MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_entityId) { LegoWorld* world = FindWorld(MxAtomId(p_filename, e_lowerCase2), p_entityId); @@ -308,6 +326,7 @@ MxBool CheckIfEntityExists(MxBool p_enable, const char* p_filename, MxS32 p_enti } // FUNCTION: LEGO1 0x1003e700 +// FUNCTION: BETA10 0x100d448a void NotifyEntity(const char* p_filename, MxS32 p_entityId, LegoEntity* p_sender) { MxAtomId atom(p_filename, e_lowerCase2); @@ -444,6 +463,7 @@ void FUN_1003eda0() } // FUNCTION: LEGO1 0x1003ee00 +// FUNCTION: BETA10 0x100d4c6f MxBool RemoveFromCurrentWorld(const MxAtomId& p_atomId, MxS32 p_id) { LegoWorld* world = CurrentWorld(); diff --git a/LEGO1/lego/legoomni/src/common/misc.cpp b/LEGO1/lego/legoomni/src/common/misc.cpp index 2acc4be2..6c01313f 100644 --- a/LEGO1/lego/legoomni/src/common/misc.cpp +++ b/LEGO1/lego/legoomni/src/common/misc.cpp @@ -33,8 +33,10 @@ LegoVideoManager* VideoManager() } // FUNCTION: LEGO1 0x10015730 +// FUNCTION: BETA10 0x100e484e MxBackgroundAudioManager* BackgroundAudioManager() { + assert(LegoOmni::GetInstance()); return LegoOmni::GetInstance()->GetBackgroundAudioManager(); } diff --git a/LEGO1/lego/sources/roi/legoroi.cpp b/LEGO1/lego/sources/roi/legoroi.cpp index 94fed7c6..87b8a3a0 100644 --- a/LEGO1/lego/sources/roi/legoroi.cpp +++ b/LEGO1/lego/sources/roi/legoroi.cpp @@ -475,6 +475,7 @@ LegoResult LegoROI::SetFrame(LegoAnim* p_anim, LegoTime p_time) } // FUNCTION: LEGO1 0x100a9170 +// FUNCTION: BETA10 0x1018ae09 LegoResult LegoROI::FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha) { LegoResult result = SUCCESS; @@ -552,6 +553,13 @@ LegoResult LegoROI::GetTexture(LegoTextureInfo*& p_textureInfo) return FAILURE; } +// FUNCTION: LEGO1 0x100a9330 +// FUNCTION: BETA10 0x1018b22c +LegoResult LegoROI::FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha) +{ + return FUN_100a9170(p_red, p_green, p_blue, p_alpha); +} + // FUNCTION: LEGO1 0x100a9350 // FUNCTION: BETA10 0x1018b25c LegoResult LegoROI::FUN_100a9350(const LegoChar* p_color) @@ -564,6 +572,18 @@ LegoResult LegoROI::FUN_100a9350(const LegoChar* p_color) return SUCCESS; } +// FUNCTION: LEGO1 0x100a93b0 +// FUNCTION: BETA10 0x1018b2c0 +LegoResult LegoROI::FUN_100a93b0(const LegoChar* p_color) +{ + MxFloat red, green, blue, alpha; + if (ColorAliasLookup(p_color, red, green, blue, alpha)) { + return FUN_100a9330(red, green, blue, alpha); + } + + return 0; +} + // FUNCTION: LEGO1 0x100a9410 // FUNCTION: BETA10 0x1018b324 LegoU32 LegoROI::FUN_100a9410( @@ -746,6 +766,7 @@ LegoBool LegoROI::FUN_100a9bf0(const LegoChar* p_param, float& p_red, float& p_g } // FUNCTION: LEGO1 0x100a9c50 +// FUNCTION: BETA10 0x1018bdd9 LegoBool LegoROI::ColorAliasLookup(const LegoChar* p_param, float& p_red, float& p_green, float& p_blue, float& p_alpha) { for (LegoU32 i = 0; i < sizeOfArray(g_roiColorAliases); i++) { diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index babb566a..541cfac5 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -38,7 +38,9 @@ class LegoROI : public ViewROI { LegoResult FUN_100a9170(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha); LegoResult FUN_100a9210(LegoTextureInfo* p_textureInfo); LegoResult GetTexture(LegoTextureInfo*& p_textureInfo); + LegoResult FUN_100a9330(LegoFloat p_red, LegoFloat p_green, LegoFloat p_blue, LegoFloat p_alpha); LegoResult FUN_100a9350(const LegoChar* p_color); + LegoResult FUN_100a93b0(const LegoChar* p_color); LegoU32 FUN_100a9410(Vector3& p_v1, Vector3& p_v2, float p_f1, float p_f2, Vector3& p_v3, LegoBool p_collideBox); void SetName(const LegoChar* p_name); diff --git a/LEGO1/library_msvc.h b/LEGO1/library_msvc.h index d4770e46..c4a46848 100644 --- a/LEGO1/library_msvc.h +++ b/LEGO1/library_msvc.h @@ -732,6 +732,12 @@ // LIBRARY: BETA10 0x1018ed70 // _strupr +// LIBRARY: BETA10 0x100f9690 +// sprintf + +// LIBRARY: BETA10 0x100fb150 +// _spawnl + // LIBRARY: BETA10 0x1001d1a0 // `vector constructor iterator'