diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index 24850f0efb..788b8fe884 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -128,6 +128,12 @@ class LegoAnimationManager : public MxCore { MxBool m_unk0x14; // 0x14 }; + enum PlayMode { + e_unk0 = 0, + e_unk1, + e_unk2 + }; + LegoAnimationManager(); ~LegoAnimationManager() override; @@ -166,7 +172,7 @@ class LegoAnimationManager : public MxCore { MxU32 p_objectId, MxMatrix* p_matrix, MxBool p_param3, - MxBool p_param4, + MxU8 p_param4, LegoROI* p_roi, MxBool p_param6, MxBool p_param7, diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index 117b9f8276..b96f2e669a 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -53,6 +53,8 @@ class LegoCharacterManager { MxResult Write(LegoStorage* p_storage); MxResult Read(LegoStorage* p_storage); + const char* GetActorName(MxS32 p_index); + MxU32 GetNumActors(); LegoROI* GetActorROI(const char* p_name, MxBool p_createEntity); void Init(); diff --git a/LEGO1/lego/legoomni/include/legoplantmanager.h b/LEGO1/lego/legoomni/include/legoplantmanager.h index 3b3bb97602..ed83763bdf 100644 --- a/LEGO1/lego/legoomni/include/legoplantmanager.h +++ b/LEGO1/lego/legoomni/include/legoplantmanager.h @@ -40,6 +40,7 @@ class LegoPlantManager : public MxCore { void Reset(LegoOmni::World p_worldId); MxResult Write(LegoStorage* p_storage); MxResult Read(LegoStorage* p_storage); + MxS32 GetNumPlants(); MxBool SwitchColor(LegoEntity* p_entity); MxBool SwitchVariant(LegoEntity* p_entity); MxBool SwitchSound(LegoEntity* p_entity); @@ -48,6 +49,7 @@ class LegoPlantManager : public MxCore { MxU32 GetAnimationId(LegoEntity* p_entity); MxU32 GetSoundId(LegoEntity* p_entity, MxBool p_state); LegoPlantInfo* GetInfoArray(MxS32& p_length); + LegoEntity* CreatePlant(MxS32 p_index, LegoWorld* p_world, LegoOmni::World p_worldId); MxBool FUN_10026c50(LegoEntity* p_entity); void ScheduleAnimation(LegoEntity* p_entity, MxLong p_length); MxResult FUN_10026410(); @@ -61,7 +63,6 @@ class LegoPlantManager : public MxCore { // LegoPlantManager::`scalar deleting destructor' private: - LegoEntity* CreatePlant(MxS32 p_index, LegoWorld* p_world, LegoOmni::World p_worldId); void RemovePlant(MxS32 p_index, LegoOmni::World p_worldId); void FUN_10026860(MxS32 p_index); LegoPlantInfo* GetInfo(LegoEntity* p_entity); diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp index f89610b8f8..c2234f0a66 100644 --- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp +++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp @@ -595,7 +595,8 @@ void Ambulance::FUN_10037250() // FUNCTION: BETA10 0x100241a0 void Ambulance::PlayAnimation(IsleScript::Script p_objectId) { - AnimationManager()->FUN_10060dc0(p_objectId, NULL, TRUE, FALSE, NULL, FALSE, FALSE, FALSE, TRUE); + AnimationManager() + ->FUN_10060dc0(p_objectId, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, FALSE, FALSE, FALSE, TRUE); m_lastAnimation = p_objectId; } @@ -603,7 +604,8 @@ void Ambulance::PlayAnimation(IsleScript::Script p_objectId) // FUNCTION: BETA10 0x10024440 void Ambulance::PlayFinalAnimation(IsleScript::Script p_objectId) { - AnimationManager()->FUN_10060dc0(p_objectId, NULL, TRUE, TRUE, NULL, FALSE, FALSE, TRUE, TRUE); + AnimationManager() + ->FUN_10060dc0(p_objectId, NULL, TRUE, LegoAnimationManager::e_unk1, NULL, FALSE, FALSE, TRUE, TRUE); m_lastAnimation = p_objectId; } diff --git a/LEGO1/lego/legoomni/src/actors/bike.cpp b/LEGO1/lego/legoomni/src/actors/bike.cpp index 4793a2a2c8..d395c6d9f1 100644 --- a/LEGO1/lego/legoomni/src/actors/bike.cpp +++ b/LEGO1/lego/legoomni/src/actors/bike.cpp @@ -117,7 +117,16 @@ void Bike::ActivateSceneActions() MxMatrix mat(UserActor()->GetROI()->GetLocal2World()); mat.TranslateBy(mat[2][0] * 2.5, mat[2][1] + 0.7, mat[2][2] * 2.5); - AnimationManager() - ->FUN_10060dc0(IsleScript::c_sns006in_RunAnim, &mat, TRUE, FALSE, NULL, FALSE, TRUE, TRUE, TRUE); + AnimationManager()->FUN_10060dc0( + IsleScript::c_sns006in_RunAnim, + &mat, + TRUE, + LegoAnimationManager::e_unk0, + NULL, + FALSE, + TRUE, + TRUE, + TRUE + ); } } diff --git a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp index 59890fedb3..d01f83522a 100644 --- a/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp +++ b/LEGO1/lego/legoomni/src/actors/dunebuggy.cpp @@ -195,7 +195,16 @@ void DuneBuggy::ActivateSceneActions() MxMatrix mat(UserActor()->GetROI()->GetLocal2World()); mat.TranslateBy(mat[2][0] * 2.5, mat[2][1] + 0.7, mat[2][2] * 2.5); - AnimationManager() - ->FUN_10060dc0(IsleScript::c_sns005in_RunAnim, &mat, TRUE, FALSE, NULL, FALSE, TRUE, TRUE, TRUE); + AnimationManager()->FUN_10060dc0( + IsleScript::c_sns005in_RunAnim, + &mat, + TRUE, + LegoAnimationManager::e_unk0, + NULL, + FALSE, + TRUE, + TRUE, + TRUE + ); } } diff --git a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp index 470839d4e9..f1d1394935 100644 --- a/LEGO1/lego/legoomni/src/actors/islepathactor.cpp +++ b/LEGO1/lego/legoomni/src/actors/islepathactor.cpp @@ -582,7 +582,8 @@ void IslePathActor::SpawnPlayer(LegoGameState::Area p_area, MxBool p_enter, MxU8 } if (state != NULL && state->m_unk0x4d && !state->m_unk0x4e) { - if (AnimationManager()->FUN_10060dc0(anim, NULL, TRUE, FALSE, NULL, FALSE, TRUE, TRUE, TRUE) == + if (AnimationManager() + ->FUN_10060dc0(anim, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, FALSE, TRUE, TRUE, TRUE) == SUCCESS) { state->m_unk0x4e = TRUE; camAnim = FALSE; diff --git a/LEGO1/lego/legoomni/src/actors/jetski.cpp b/LEGO1/lego/legoomni/src/actors/jetski.cpp index 4db9d1193f..e1163ff06c 100644 --- a/LEGO1/lego/legoomni/src/actors/jetski.cpp +++ b/LEGO1/lego/legoomni/src/actors/jetski.cpp @@ -155,8 +155,17 @@ void Jetski::ActivateSceneActions() MxMatrix mat(user->GetROI()->GetLocal2World()); mat.TranslateBy(mat[2][0] * 2.5, mat[2][1] + 0.6, mat[2][2] * 2.5); - AnimationManager() - ->FUN_10060dc0(IsleScript::c_sjs007in_RunAnim, &mat, TRUE, FALSE, NULL, FALSE, TRUE, TRUE, TRUE); + AnimationManager()->FUN_10060dc0( + IsleScript::c_sjs007in_RunAnim, + &mat, + TRUE, + LegoAnimationManager::e_unk0, + NULL, + FALSE, + TRUE, + TRUE, + TRUE + ); } } } diff --git a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp index 1c8c73db16..333f43d479 100644 --- a/LEGO1/lego/legoomni/src/actors/motorcycle.cpp +++ b/LEGO1/lego/legoomni/src/actors/motorcycle.cpp @@ -157,7 +157,16 @@ void Motocycle::ActivateSceneActions() MxMatrix mat(UserActor()->GetROI()->GetLocal2World()); mat.TranslateBy(mat[2][0] * 2.5, mat[2][1] + 0.7, mat[2][2] * 2.5); - AnimationManager() - ->FUN_10060dc0(IsleScript::c_sns006in_RunAnim, &mat, TRUE, FALSE, NULL, FALSE, TRUE, TRUE, TRUE); + AnimationManager()->FUN_10060dc0( + IsleScript::c_sns006in_RunAnim, + &mat, + TRUE, + LegoAnimationManager::e_unk0, + NULL, + FALSE, + TRUE, + TRUE, + TRUE + ); } } diff --git a/LEGO1/lego/legoomni/src/actors/pizza.cpp b/LEGO1/lego/legoomni/src/actors/pizza.cpp index fad6c10a66..01ca5eb3f8 100644 --- a/LEGO1/lego/legoomni/src/actors/pizza.cpp +++ b/LEGO1/lego/legoomni/src/actors/pizza.cpp @@ -586,7 +586,8 @@ void Pizza::PlayAction(MxU32 p_objectId, MxBool p_param7) InvokeAction(Extra::e_stop, *g_isleScript, m_unk0x8c, NULL); } - AnimationManager()->FUN_10060dc0(p_objectId, NULL, TRUE, FALSE, NULL, FALSE, p_param7, TRUE, TRUE); + AnimationManager() + ->FUN_10060dc0(p_objectId, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, FALSE, p_param7, TRUE, TRUE); } // FUNCTION: LEGO1 0x10039030 diff --git a/LEGO1/lego/legoomni/src/actors/skateboard.cpp b/LEGO1/lego/legoomni/src/actors/skateboard.cpp index cc577c30eb..9174a00497 100644 --- a/LEGO1/lego/legoomni/src/actors/skateboard.cpp +++ b/LEGO1/lego/legoomni/src/actors/skateboard.cpp @@ -157,8 +157,17 @@ void SkateBoard::ActivateSceneActions() MxMatrix mat(UserActor()->GetROI()->GetLocal2World()); mat.TranslateBy(mat[2][0] * 2.5, mat[2][1] + 0.2, mat[2][2] * 2.5); - AnimationManager() - ->FUN_10060dc0(IsleScript::c_sns008in_RunAnim, &mat, TRUE, FALSE, NULL, FALSE, TRUE, TRUE, TRUE); + AnimationManager()->FUN_10060dc0( + IsleScript::c_sns008in_RunAnim, + &mat, + TRUE, + LegoAnimationManager::e_unk0, + NULL, + FALSE, + TRUE, + TRUE, + TRUE + ); } } } diff --git a/LEGO1/lego/legoomni/src/actors/towtrack.cpp b/LEGO1/lego/legoomni/src/actors/towtrack.cpp index 08da972770..de2cb2915d 100644 --- a/LEGO1/lego/legoomni/src/actors/towtrack.cpp +++ b/LEGO1/lego/legoomni/src/actors/towtrack.cpp @@ -565,7 +565,8 @@ void TowTrack::FUN_1004dbe0() // FUNCTION: BETA10 0x100f86a0 void TowTrack::PlayFinalAnimation(IsleScript::Script p_objectId) { - AnimationManager()->FUN_10060dc0(p_objectId, NULL, TRUE, FALSE, NULL, FALSE, FALSE, FALSE, TRUE); + AnimationManager() + ->FUN_10060dc0(p_objectId, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, FALSE, FALSE, FALSE, TRUE); m_lastAnimation = p_objectId; } @@ -573,7 +574,8 @@ void TowTrack::PlayFinalAnimation(IsleScript::Script p_objectId) void TowTrack::FUN_1004dcb0(IsleScript::Script p_objectId) { AnimationManager()->FUN_1005f6d0(TRUE); - AnimationManager()->FUN_10060dc0(p_objectId, NULL, TRUE, TRUE, NULL, FALSE, TRUE, TRUE, TRUE); + AnimationManager() + ->FUN_10060dc0(p_objectId, NULL, TRUE, LegoAnimationManager::e_unk1, NULL, FALSE, TRUE, TRUE, TRUE); m_lastAnimation = p_objectId; } diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index 379101f179..5c5400a764 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -1138,7 +1138,7 @@ MxResult LegoAnimationManager::FUN_10060dc0( MxU32 p_objectId, MxMatrix* p_matrix, MxBool p_param3, - MxBool p_param4, + MxU8 p_param4, LegoROI* p_roi, MxBool p_param6, MxBool p_param7, @@ -1159,10 +1159,10 @@ MxResult LegoAnimationManager::FUN_10060dc0( MxBool unk0x0a; switch (p_param4) { - case FALSE: + case e_unk0: unk0x0a = m_anims[i].m_unk0x0a; break; - case TRUE: + case e_unk1: unk0x0a = TRUE; break; default: diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index 57c4aa421d..f0ab9f53bb 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -221,6 +221,24 @@ MxResult LegoCharacterManager::Read(LegoStorage* p_storage) return result; } +// FUNCTION: LEGO1 0x100834d0 +// FUNCTION: BETA10 0x100742eb +const char* LegoCharacterManager::GetActorName(MxS32 p_index) +{ + if (p_index < sizeOfArray(g_actorInfo)) { + return g_actorInfo[p_index].m_name; + } + + return NULL; +} + +// FUNCTION: LEGO1 0x100834f0 +// FUNCTION: BETA10 0x1007432a +MxU32 LegoCharacterManager::GetNumActors() +{ + return sizeOfArray(g_actorInfo); +} + // FUNCTION: LEGO1 0x10083500 // FUNCTION: BETA10 0x10074345 LegoROI* LegoCharacterManager::GetActorROI(const char* p_name, MxBool p_createEntity) diff --git a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp index 401d0782fa..a483db1b52 100644 --- a/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoplantmanager.cpp @@ -98,6 +98,7 @@ void LegoPlantManager::LoadWorldInfo(LegoOmni::World p_worldId) } // FUNCTION: LEGO1 0x100263a0 +// FUNCTION: BETA10 0x100c5093 void LegoPlantManager::Reset(LegoOmni::World p_worldId) { MxU32 i; @@ -363,6 +364,13 @@ LegoPlantInfo* LegoPlantManager::GetInfo(LegoEntity* p_entity) return NULL; } +// FUNCTION: LEGO1 0x100268d0 +// FUNCTION: BETA10 0x100c5c7a +MxS32 LegoPlantManager::GetNumPlants() +{ + return sizeOfArray(g_plantInfo); +} + // FUNCTION: LEGO1 0x10026920 // FUNCTION: BETA10 0x100c5dc9 MxBool LegoPlantManager::SwitchColor(LegoEntity* p_entity) diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp index d3474ced96..290820b79a 100644 --- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp @@ -1,25 +1,30 @@ #include "legonavcontroller.h" #include "3dmanager/lego3dmanager.h" +#include "act3.h" #include "infocenter.h" #include "legoanimationmanager.h" #include "legocameracontroller.h" +#include "legocharactermanager.h" #include "legogamestate.h" #include "legoinputmanager.h" #include "legolocations.h" #include "legomain.h" +#include "legoplantmanager.h" #include "legosoundmanager.h" #include "legoutils.h" #include "legovideomanager.h" #include "legoworld.h" #include "misc.h" #include "mxbackgroundaudiomanager.h" +#include "mxdebug.h" #include "mxmisc.h" #include "mxtimer.h" #include "mxtransitionmanager.h" #include "mxutilities.h" #include "realtime/realtime.h" #include "realtime/realtimeview.h" +#include "viewmanager/viewmanager.h" #include @@ -74,19 +79,28 @@ float LegoNavController::g_defrotSensitivity = 0.4f; MxBool LegoNavController::g_defuseRotationalVel = FALSE; // GLOBAL: LEGO1 0x100f66a0 -MxBool g_unk0x100f66a0 = FALSE; +MxU32 g_changeLight = FALSE; // GLOBAL: LEGO1 0x100f66a4 -MxBool g_unk0x100f66a4 = FALSE; +MxU32 g_locationCalcStep = 0; + +// GLOBAL: LEGO1 0x100f66a8 +MxU32 g_nextLocation = 0; + +// GLOBAL: LEGO1 0x100f66ac +MxBool g_resetPlants = FALSE; // GLOBAL: LEGO1 0x100f66b0 -undefined4 g_unk0x100f66b0 = 0; +MxU32 g_animationCalcStep = 0; // GLOBAL: LEGO1 0x100f66b4 -undefined4 g_unk0x100f66b4 = 0; +MxS32 g_nextAnimation = 0; + +// GLOBAL: LEGO1 0x100f66b8 +MxU32 g_switchAct = FALSE; // GLOBAL: LEGO1 0x100f66bc -undefined4 g_unk0x100f66bc = 2; +LegoAnimationManager::PlayMode g_unk0x100f66bc = LegoAnimationManager::e_unk2; // GLOBAL: LEGO1 0x100f66c0 char g_debugPassword[] = "OGEL"; @@ -94,11 +108,14 @@ char g_debugPassword[] = "OGEL"; // GLOBAL: LEGO1 0x100f66c8 char* g_currentInput = g_debugPassword; +// GLOBAL: LEGO1 0x100f66cc +MxS32 g_unk0x100f66cc = -1; + // GLOBAL: LEGO1 0x100f66d0 -MxBool g_musicEnabled = TRUE; +MxBool g_enableMusic = TRUE; // GLOBAL: LEGO1 0x100f66d4 -undefined4 g_unk0x100f66d4 = 1; +MxU32 g_fpsEnabled = TRUE; // FUNCTION: LEGO1 0x10054ac0 LegoNavController::LegoNavController() @@ -608,14 +625,16 @@ MxResult LegoNavController::ProcessKeyboardInput() return SUCCESS; } -// STUB: LEGO1 0x10055a60 +// FUNCTION: LEGO1 0x10055a60 +// FUNCTION: BETA10 0x1009c712 MxLong LegoNavController::Notify(MxParam& p_param) { if (((MxNotificationParam&) p_param).GetNotification() == c_notificationKeyPress) { m_unk0x5d = TRUE; + MxU8 key = ((LegoEventNotificationParam&) p_param).GetKey(); - switch (((LegoEventNotificationParam&) p_param).GetKey()) { - case VK_PAUSE: + switch (key) { + case VK_PAUSE: // Pause game if (Lego()->IsPaused()) { Lego()->Resume(); } @@ -623,32 +642,95 @@ MxLong LegoNavController::Notify(MxParam& p_param) Lego()->Pause(); } break; - case VK_ESCAPE: { + case VK_ESCAPE: { // Return to infocenter LegoWorld* currentWorld = CurrentWorld(); + if (currentWorld != NULL) { + InfocenterState* state = (InfocenterState*) GameState()->GetState("InfocenterState"); + assert(state); - if (currentWorld) { - InfocenterState* infocenterState = (InfocenterState*) GameState()->GetState("InfocenterState"); - if (infocenterState && infocenterState->GetUnknown0x74() != 8 && currentWorld->Escape()) { + if (state != NULL && state->m_unk0x74 != 8 && currentWorld->Escape()) { BackgroundAudioManager()->Stop(); TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); - infocenterState->SetUnknown0x74(8); + state->m_unk0x74 = 8; } } break; } - case VK_SPACE: + case VK_SPACE: // Interrupt/end animations or free navigation AnimationManager()->FUN_10061010(TRUE); break; - case 'Z': - // TODO + case 'Z': { // Make nearby plants "dance" + LegoOmni* omni = Lego(); + + if (omni->GetCurrentWorld() != NULL && omni->GetCurrentWorld()->GetWorldId() == LegoOmni::e_act1) { + LegoVideoManager* videoMgr = LegoOmni::GetInstance()->GetVideoManager(); + ViewROI* roi = videoMgr->GetViewROI(); + ViewManager* view = videoMgr->Get3DManager()->GetLego3DView()->GetViewManager(); + LegoPlantManager* plantMgr = LegoOmni::GetInstance()->GetPlantManager(); + Mx3DPointFloat viewPosition(roi->GetWorldPosition()); + MxS32 numPlants = plantMgr->GetNumPlants(); + + for (MxS32 i = 0; i < numPlants; i++) { + LegoEntity* entity = plantMgr->CreatePlant(i, NULL, LegoOmni::e_act1); + + if (entity != NULL && !entity->GetUnknown0x10IsSet(LegoEntity::c_altBit1)) { + LegoROI* roi = entity->GetROI(); + + if (roi != NULL && roi->GetVisibility()) { + const BoundingBox& box = roi->GetWorldBoundingBox(); + + if (view->IsBoundingBoxInFrustum(box)) { + Mx3DPointFloat roiPosition(roi->GetWorldPosition()); + roiPosition -= viewPosition; + + if (roiPosition.LenSquared() < 2000.0 || roi->GetUnknown0xe0() > 0) { + entity->ClickAnimation(); + } + } + } + } + } + } break; + } case 'k': - case 'm': - // TODO + case 'm': { // Keys need to be uppercased to trigger this code, but seems dysfunctional + if (g_unk0x100f66cc == -1) { + g_unk0x100f66cc = 0; + } + else { + CharacterManager()->ReleaseActor(CharacterManager()->GetActorName(g_unk0x100f66cc)); + + if (key == 'k') { + g_unk0x100f66cc++; + if (g_unk0x100f66cc >= CharacterManager()->GetNumActors()) { + g_unk0x100f66cc = 0; + } + } + else { + g_unk0x100f66cc--; + if (g_unk0x100f66cc < 0) { + g_unk0x100f66cc = CharacterManager()->GetNumActors() - 1; + } + } + } + + LegoROI* roi = CharacterManager()->GetActorROI(CharacterManager()->GetActorName(g_unk0x100f66cc), TRUE); + if (roi != NULL) { + MxMatrix mat; + ViewROI* roi = LegoOmni::GetInstance()->GetVideoManager()->GetViewROI(); + const float* position = roi->GetWorldPosition(); + const float* direction = roi->GetWorldDirection(); + const float* up = roi->GetWorldUp(); + CalcLocalTransform(position, direction, up, mat); + mat.TranslateBy(direction[0] * 2.0f, direction[1] - 1.0, direction[2] * 2.0f); + roi->UpdateTransformationRelativeToParent(mat); + } break; - case '{': { - InfocenterState* infocenterState = (InfocenterState*) GameState()->GetState("InfocenterState"); - if (infocenterState && infocenterState->HasRegistered()) { + } + case '{': { // Saves the game. Can't actually be triggered + InfocenterState* state = (InfocenterState*) GameState()->GetState("InfocenterState"); + if (state && state->HasRegistered()) { GameState()->Save(0); } break; @@ -659,14 +741,14 @@ MxLong LegoNavController::Notify(MxParam& p_param) // password "protected" debug shortcuts switch (((LegoEventNotificationParam&) p_param).GetKey()) { case VK_TAB: - VideoManager()->ToggleFPS(g_unk0x100f66d4); - if (g_unk0x100f66d4 == 0) { - g_unk0x100f66d4 = 1; + VideoManager()->ToggleFPS(g_fpsEnabled); + if (g_fpsEnabled) { + g_fpsEnabled = FALSE; m_unk0x5d = FALSE; - break; } else { - g_unk0x100f66d4 = 0; + g_fpsEnabled = TRUE; + m_unk0x5d = FALSE; } break; case '0': @@ -679,17 +761,130 @@ MxLong LegoNavController::Notify(MxParam& p_param) case '7': case '8': case '9': - // TODO + if (g_changeLight && key <= '1') { + LegoROI* roi = VideoManager()->GetViewROI(); + Tgl::FloatMatrix4 matrix; + Matrix4 in(matrix); + roi->GetLocalTransform(in); + VideoManager()->Get3DManager()->GetLego3DView()->SetLightTransform(key - '0', matrix); + g_changeLight = FALSE; + } + else if (g_locationCalcStep) { + if (g_locationCalcStep == 1) { + // Calculate base offset into g_locations + g_nextLocation = (key - '0') * 5; + g_locationCalcStep = 2; + } + else { + // Add to base g_locations offset + g_nextLocation += key - '0'; + g_locationCalcStep = 0; + UpdateLocation(g_nextLocation); + } + } + else if (g_animationCalcStep) { + if (g_animationCalcStep == 1) { + // Calculate base offset into possible animation object IDs (up to 999) + g_nextAnimation = (key - '0') * 100; + g_animationCalcStep = 2; + } + else if (g_animationCalcStep == 2) { + // Add to animation object ID offset + g_nextAnimation += (key - '0') * 10; + g_animationCalcStep = 3; + } + else { + // Add to animation object ID offset + g_nextAnimation += key - '0'; + g_animationCalcStep = 0; + AnimationManager()->FUN_10060dc0( + g_nextAnimation, + NULL, + TRUE, + g_unk0x100f66bc, + NULL, + TRUE, + TRUE, + TRUE, + TRUE + ); + + g_unk0x100f66bc = LegoAnimationManager::e_unk2; + } + } + + if (g_switchAct && key >= '1' && key <= '5') { + switch (GameState()->GetCurrentAct()) { + case LegoGameState::e_act1: + GameState()->m_currentArea = LegoGameState::e_isle; + break; + case LegoGameState::e_act2: + GameState()->m_currentArea = LegoGameState::e_act2main; + break; + case LegoGameState::e_act3: + GameState()->m_currentArea = LegoGameState::e_act3script; + break; + } + + switch (key) { + case '1': + GameState()->SetCurrentAct(LegoGameState::e_act1); + GameState()->SwitchArea(LegoGameState::e_isle); + break; + case '2': + GameState()->SwitchArea(LegoGameState::e_act2main); + break; + case '3': + GameState()->SwitchArea(LegoGameState::e_act3script); + break; + case '4': { + Act3State* act3State = (Act3State*) GameState()->GetState("Act3State"); + if (act3State == NULL) { + act3State = new Act3State(); + assert(act3State); + GameState()->RegisterState(act3State); + } + + GameState()->SetCurrentAct(LegoGameState::e_act3); + act3State->m_unk0x08 = 2; + GameState()->m_currentArea = LegoGameState::e_act3script; + GameState()->SwitchArea(LegoGameState::e_infomain); + break; + } + case '5': { + Act3State* act3State = (Act3State*) GameState()->GetState("Act3State"); + if (act3State == NULL) { + act3State = new Act3State(); + assert(act3State); + GameState()->RegisterState(act3State); + } + + GameState()->SetCurrentAct(LegoGameState::e_act3); + act3State->m_unk0x08 = 3; + GameState()->m_currentArea = LegoGameState::e_act3script; + GameState()->SwitchArea(LegoGameState::e_infomain); + break; + } + } + + g_switchAct = FALSE; + } + else { + MxDSAction action; + action.SetObjectId(key - '0'); + action.SetAtomId(MxAtomId("q:\\lego\\media\\model\\common\\common", e_lowerCase2)); + LegoOmni::GetInstance()->Start(&action); + } break; case 'A': - if (g_unk0x100f66b0 == 1) { - Lego()->SetUnknown13c(TRUE); - AnimationManager()->FUN_10060570(1); - g_unk0x100f66b0 = 0; + if (g_animationCalcStep == 1) { + Lego()->m_unk0x13c = TRUE; + AnimationManager()->FUN_10060570(TRUE); + g_animationCalcStep = 0; } else { LegoWorld* world = CurrentWorld(); - if (world) { + if (world != NULL) { MxDSAction action; action.SetObjectId(1); action.SetAtomId(world->GetAtomId()); @@ -698,7 +893,7 @@ MxLong LegoNavController::Notify(MxParam& p_param) } break; case 'C': - g_unk0x100f66a4 = TRUE; + g_locationCalcStep = 1; break; case 'D': m_unk0x60 = -1.0; @@ -707,56 +902,121 @@ MxLong LegoNavController::Notify(MxParam& p_param) RealtimeView::SetUserMaxLOD(0.0); break; case 'G': - g_unk0x100f66b4 = 1; + g_switchAct = TRUE; break; case 'H': RealtimeView::SetUserMaxLOD(5.0); break; - case 'I': - // TODO + case 'I': { + LegoROI* roi = VideoManager()->GetViewROI(); + MxMatrix mat; + mat.SetIdentity(); + mat.RotateX(0.2618f); + roi->WrappedVTable0x24(mat); break; - case 'J': - // TODO + } + case 'J': { + LegoROI* roi = VideoManager()->GetViewROI(); + MxMatrix mat; + mat.SetIdentity(); + mat.RotateZ(0.2618f); + roi->WrappedVTable0x24(mat); break; - case 'K': - // TODO + } + case 'K': { + MxMatrix mat; + LegoROI* roi = LegoOmni::GetInstance()->GetVideoManager()->GetViewROI(); + mat.SetIdentity(); + mat.RotateZ(-0.2618f); + roi->WrappedVTable0x24(mat); break; + } case 'L': - g_unk0x100f66a0 = TRUE; + g_changeLight = TRUE; break; - case 'M': - // TODO + case 'M': { + LegoROI* roi = LegoOmni::GetInstance()->GetVideoManager()->GetViewROI(); + MxMatrix mat; + mat.SetIdentity(); + mat.RotateX(-0.2618f); + roi->WrappedVTable0x24(mat); break; + } case 'N': if (VideoManager()) { VideoManager()->SetRender3D(!VideoManager()->GetRender3D()); } break; case 'P': - // TODO + if (!g_resetPlants) { + PlantManager()->LoadWorldInfo(LegoOmni::e_act1); + g_resetPlants = TRUE; + } + else { + PlantManager()->Reset(LegoOmni::e_act1); + g_resetPlants = FALSE; + } break; case 'S': - BackgroundAudioManager()->Enable(!g_musicEnabled); + g_enableMusic = g_enableMusic == FALSE; + BackgroundAudioManager()->Enable(g_enableMusic); break; case 'U': m_unk0x60 = 1.0; break; case 'V': - // TODO - case 'W': - // TODO + if (g_nextAnimation > 0 && g_animationCalcStep == 0) { + AnimationManager()->FUN_10061010(FALSE); + } + + if (g_animationCalcStep != 0) { + g_unk0x100f66bc = LegoAnimationManager::e_unk2; + } + + g_nextAnimation = 0; + g_animationCalcStep = 1; + break; + case 'W': { + MxMatrix mat; + LegoROI* roi = LegoOmni::GetInstance()->GetVideoManager()->GetViewROI(); + const float* position = roi->GetWorldPosition(); + const float* direction = roi->GetWorldDirection(); + const float* up = roi->GetWorldUp(); + + MxTrace( + "pos: %f, %f, %f\ndir: %f, %f, %f\nup: %f, %f, %f\n", + EXPAND3(position), + EXPAND3(direction), + EXPAND3(up) + ); break; + } case 'X': RealtimeView::SetUserMaxLOD(3.6); break; - case 'j': - // TODO + case 'j': { + MxU8 newActor = GameState()->GetActorId() + 1; + + if (newActor > LegoActor::c_laura) { + newActor = LegoActor::c_pepper; + } + + GameState()->SetActorId(newActor); break; + } case 'o': - GameState()->SetActorId(6); + GameState()->SetActorId(LegoActor::c_brickster); + break; + case 'z': + if (GameState()->m_isDirty) { + GameState()->m_isDirty = FALSE; + } + else { + GameState()->m_isDirty = TRUE; + } break; case 0xbd: - g_unk0x100f66bc = 1; + g_unk0x100f66bc = LegoAnimationManager::e_unk1; break; default: m_unk0x5d = FALSE; @@ -766,14 +1026,11 @@ MxLong LegoNavController::Notify(MxParam& p_param) else { if (*g_currentInput == ((LegoEventNotificationParam&) p_param).GetKey()) { g_currentInput++; - break; } else { g_currentInput = g_debugPassword; - break; } } - break; } } diff --git a/LEGO1/lego/legoomni/src/race/carrace.cpp b/LEGO1/lego/legoomni/src/race/carrace.cpp index c979db0bfd..9c5d6d4c9e 100644 --- a/LEGO1/lego/legoomni/src/race/carrace.cpp +++ b/LEGO1/lego/legoomni/src/race/carrace.cpp @@ -129,7 +129,8 @@ void CarRace::ReadyWorld() m_unk0x144 = g_unk0x100d5d10[rand() & 7]; - AnimationManager()->FUN_10060dc0(m_unk0x144, NULL, TRUE, FALSE, NULL, FALSE, TRUE, FALSE, TRUE); + AnimationManager() + ->FUN_10060dc0(m_unk0x144, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, FALSE, TRUE, FALSE, TRUE); m_unk0x128 = (MxStillPresenter*) Find("MxPresenter", "CarLocator2"); m_unk0x128->SetPosition(m_unk0x130.GetLeft(), m_unk0x130.GetTop()); @@ -162,7 +163,8 @@ MxLong CarRace::HandleEndAction(MxEndActionNotificationParam& p_param) result = 1; } else if (m_unk0x148 == objectId) { - AnimationManager()->FUN_10060dc0(m_unk0x14c, NULL, TRUE, FALSE, NULL, FALSE, TRUE, FALSE, TRUE); + AnimationManager() + ->FUN_10060dc0(m_unk0x14c, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, FALSE, TRUE, FALSE, TRUE); } else if (m_unk0x14c == objectId) { NotificationManager()->Send(this, MxNotificationParam()); @@ -253,7 +255,17 @@ MxLong CarRace::HandlePathStruct(LegoPathStructNotificationParam& p_param) raceState->m_score = position; } - AnimationManager()->FUN_10060dc0(m_unk0x148, NULL, TRUE, FALSE, NULL, FALSE, TRUE, FALSE, TRUE); + AnimationManager()->FUN_10060dc0( + m_unk0x148, + NULL, + TRUE, + LegoAnimationManager::e_unk0, + NULL, + FALSE, + TRUE, + FALSE, + TRUE + ); } result = 1; diff --git a/LEGO1/lego/legoomni/src/worlds/act3.cpp b/LEGO1/lego/legoomni/src/worlds/act3.cpp index 15b9791349..48c687558f 100644 --- a/LEGO1/lego/legoomni/src/worlds/act3.cpp +++ b/LEGO1/lego/legoomni/src/worlds/act3.cpp @@ -676,7 +676,8 @@ void Act3::ReadyWorld() VideoManager()->Get3DManager()->SetFrustrum(90.0f, 0.1f, 125.0f); m_unk0x426c = g_unk0x100d95e8[rand() % 3]; - AnimationManager()->FUN_10060dc0(m_unk0x426c, NULL, TRUE, FALSE, NULL, TRUE, FALSE, FALSE, FALSE); + AnimationManager() + ->FUN_10060dc0(m_unk0x426c, NULL, TRUE, LegoAnimationManager::e_unk0, NULL, TRUE, FALSE, FALSE, FALSE); m_state->m_unk0x08 = 1; } diff --git a/LEGO1/lego/legoomni/src/worlds/isle.cpp b/LEGO1/lego/legoomni/src/worlds/isle.cpp index 0a51604303..604d514e14 100644 --- a/LEGO1/lego/legoomni/src/worlds/isle.cpp +++ b/LEGO1/lego/legoomni/src/worlds/isle.cpp @@ -757,7 +757,8 @@ void Isle::Enable(MxBool p_enable) break; } - AnimationManager()->FUN_10060dc0(script, NULL, TRUE, TRUE, NULL, FALSE, FALSE, TRUE, FALSE); + AnimationManager() + ->FUN_10060dc0(script, NULL, TRUE, LegoAnimationManager::e_unk1, NULL, FALSE, FALSE, TRUE, FALSE); } m_act1state->m_unk0x018 = 0; @@ -790,7 +791,8 @@ void Isle::Enable(MxBool p_enable) break; } - AnimationManager()->FUN_10060dc0(script, NULL, TRUE, TRUE, NULL, FALSE, FALSE, TRUE, FALSE); + AnimationManager() + ->FUN_10060dc0(script, NULL, TRUE, LegoAnimationManager::e_unk1, NULL, FALSE, FALSE, TRUE, FALSE); } m_act1state->m_unk0x018 = 0; diff --git a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp index 6397ac6607..ea400a24db 100644 --- a/LEGO1/lego/legoomni/src/worlds/legoact2.cpp +++ b/LEGO1/lego/legoomni/src/worlds/legoact2.cpp @@ -1167,12 +1167,30 @@ MxResult LegoAct2::FUN_10052560( MxResult result; if (p_objectId == Act2mainScript::c_tja009ni_RunAnim) { - result = - AnimationManager()->FUN_10060dc0(p_objectId, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, TRUE); + result = AnimationManager()->FUN_10060dc0( + p_objectId, + pmatrix, + TRUE, + LegoAnimationManager::e_unk0, + NULL, + TRUE, + TRUE, + TRUE, + TRUE + ); } else { - result = - AnimationManager()->FUN_10060dc0(p_objectId, pmatrix, TRUE, FALSE, NULL, TRUE, TRUE, TRUE, FALSE); + result = AnimationManager()->FUN_10060dc0( + p_objectId, + pmatrix, + TRUE, + LegoAnimationManager::e_unk0, + NULL, + TRUE, + TRUE, + TRUE, + FALSE + ); } if (result == SUCCESS) {