From b279e8b8b959e89899f914c84817e40945e738d7 Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Sat, 23 Mar 2024 14:00:34 -0400 Subject: [PATCH] Begin LegoNavController::Notify (#716) * Partial implementation of LegoNavController::Notify * Mark as stub * Update legoanimationmanager.cpp * Rename function/style --------- Co-authored-by: Christian Semmler --- .../legoomni/include/legoanimationmanager.h | 1 + .../lego/legoomni/include/legonavcontroller.h | 2 +- LEGO1/lego/legoomni/include/legoomni.h | 1 + .../lego/legoomni/include/legovideomanager.h | 6 +- .../src/common/legoanimationmanager.cpp | 6 + .../legoomni/src/common/legogamestate.cpp | 2 +- .../legoomni/src/entity/legonavcontroller.cpp | 235 +++++++++++++++++- .../legoomni/src/video/legovideomanager.cpp | 13 + 8 files changed, 259 insertions(+), 7 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimationmanager.h b/LEGO1/lego/legoomni/include/legoanimationmanager.h index 3edb6cc9..15a05c8d 100644 --- a/LEGO1/lego/legoomni/include/legoanimationmanager.h +++ b/LEGO1/lego/legoomni/include/legoanimationmanager.h @@ -67,6 +67,7 @@ class LegoAnimationManager : public MxCore { MxResult ReadModelInfo(LegoFile* p_file, ModelInfo* p_info); void FUN_100603c0(); MxResult StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity); + void FUN_10060570(MxBool); undefined4 FUN_10060dc0( IsleScript::Script, undefined4, diff --git a/LEGO1/lego/legoomni/include/legonavcontroller.h b/LEGO1/lego/legoomni/include/legonavcontroller.h index ea10ee40..4003e6fd 100644 --- a/LEGO1/lego/legoomni/include/legonavcontroller.h +++ b/LEGO1/lego/legoomni/include/legonavcontroller.h @@ -70,7 +70,7 @@ class LegoNavController : public MxCore { float p_rs, MxBool p_urs ); - static void SetLocation(MxU32 p_location); + static MxResult UpdateCameraLocation(MxU32 p_location); static MxResult UpdateCameraLocation(const char* p_location); // SYNTHETIC: LEGO1 0x10054c10 diff --git a/LEGO1/lego/legoomni/include/legoomni.h b/LEGO1/lego/legoomni/include/legoomni.h index e8e09cbb..53fcb270 100644 --- a/LEGO1/lego/legoomni/include/legoomni.h +++ b/LEGO1/lego/legoomni/include/legoomni.h @@ -236,6 +236,7 @@ class LegoOmni : public MxOmni { } return SUCCESS; } + inline void SetUnknown13c(MxBool p_unk0x13c) { m_unk0x13c = p_unk0x13c; } inline void CloseMainWindow() { PostMessageA(m_windowHandle, WM_CLOSE, 0, 0); } diff --git a/LEGO1/lego/legoomni/include/legovideomanager.h b/LEGO1/lego/legoomni/include/legovideomanager.h index 51c97abe..6f9a7a93 100644 --- a/LEGO1/lego/legoomni/include/legovideomanager.h +++ b/LEGO1/lego/legoomni/include/legovideomanager.h @@ -24,6 +24,7 @@ class LegoVideoManager : public MxVideoManager { void EnableFullScreenMovie(MxBool p_enable); void EnableFullScreenMovie(MxBool p_enable, MxBool p_scale); void MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY); + void ToggleFPS(MxBool p_visible); MxResult Tickle() override; // vtable+0x08 void Destroy() override; // vtable+0x18 @@ -38,12 +39,14 @@ class LegoVideoManager : public MxVideoManager { void SetSkyColor(float p_red, float p_green, float p_blue); void OverrideSkyColor(MxBool p_shouldOverride); MxResult ResetPalette(MxBool p_ignoreSkyColor); + void FUN_1007c520(); inline Tgl::Renderer* GetRenderer() { return this->m_renderer; } inline Lego3DManager* Get3DManager() { return this->m_3dManager; } inline LegoROI* GetViewROI() { return this->m_viewROI; } inline MxDirect3D* GetDirect3D() { return this->m_direct3d; } + inline MxBool GetRender3D() { return this->m_render3d; } inline void SetRender3D(MxBool p_render3d) { this->m_render3d = p_render3d; } inline void SetUnk0x554(MxBool p_unk0x554) { this->m_unk0x554 = p_unk0x554; } @@ -83,7 +86,8 @@ class LegoVideoManager : public MxVideoManager { RECT m_fpsRect; // 0x530 HFONT m_arialFont; // 0x540 SIZE m_fpsSize; // 0x544 - undefined m_pad0x54c[8]; // 0x54c + MxFloat m_unk0x54c; // 0x54c + MxFloat m_unk0x550; // 0x550 MxBool m_unk0x554; // 0x554 MxBool m_paused; // 0x555 undefined m_pad0x556[0x39]; // 0x556 diff --git a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp index f922e78c..0b1dd6d9 100644 --- a/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legoanimationmanager.cpp @@ -353,6 +353,12 @@ void LegoAnimationManager::FUN_100603c0() // TODO } +// STUB: LEGO1 0x10060570 +void LegoAnimationManager::FUN_10060570(MxBool) +{ + // TODO +} + // FUNCTION: LEGO1 0x10060d00 MxResult LegoAnimationManager::StartEntityAction(MxDSAction& p_dsAction, LegoEntity* p_entity) { diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index 29cc9b07..8c61bae7 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -889,7 +889,7 @@ void LegoGameState::SwitchArea(Area p_area) LoadIsle(); VariableTable()->SetVariable("VISIBILITY", "Hide Gas"); CurrentActor()->ResetWorldTransform(FALSE); - NavController()->SetLocation(0x3b); + NavController()->UpdateCameraLocation(59); // LCAMZG1 in g_cameraLocations VideoManager()->Get3DManager()->SetFrustrum(90, 0.1f, 250.0f); InvokeAction(Extra::ActionType::e_start, *g_isleScript, IsleScript::c_GaraDoor, NULL); break; diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp index d51d13a7..27f9bece 100644 --- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp @@ -1,13 +1,19 @@ #include "legonavcontroller.h" +#include "infocenterstate.h" +#include "legoanimationmanager.h" #include "legocameralocations.h" +#include "legogamestate.h" #include "legoinputmanager.h" +#include "legoomni.h" #include "legosoundmanager.h" #include "legoutils.h" #include "legovideomanager.h" #include "misc.h" +#include "mxbackgroundaudiomanager.h" #include "mxmisc.h" #include "mxtimer.h" +#include "mxtransitionmanager.h" #include "realtime/realtime.h" #include @@ -62,6 +68,33 @@ float LegoNavController::g_defrotSensitivity = 0.4f; // GLOBAL: LEGO1 0x100f4c54 MxBool LegoNavController::g_defuseRotationalVel = FALSE; +// GLOBAL: LEGO1 0x100f66a0 +MxBool g_unk0x100f66a0 = FALSE; + +// GLOBAL: LEGO1 0x100f66a4 +MxBool g_unk0x100f66a4 = FALSE; + +// GLOBAL: LEGO1 0x100f66b0 +undefined4 g_unk0x100f66b0 = 0; + +// GLOBAL: LEGO1 0x100f66b4 +undefined4 g_unk0x100f66b4 = 0; + +// GLOBAL: LEGO1 0x100f66bc +undefined4 g_unk0x100f66bc = 2; + +// GLOBAL: LEGO1 0x100f66c0 +char* g_debugPassword = "OGEL"; + +// GLOBAL: LEGO1 0x100f66c8 +char* g_currentInput = g_debugPassword; + +// GLOBAL: LEGO1 0x100f66d0 +MxBool g_musicEnabled = TRUE; + +// GLOBAL: LEGO1 0x100f66d4 +undefined4 g_unk0x100f66d4 = 1; + // FUNCTION: LEGO1 0x10054ac0 LegoNavController::LegoNavController() { @@ -402,10 +435,40 @@ MxResult LegoNavController::UpdateCameraLocation(const char* p_location) return result; } -// STUB: LEGO1 0x10055620 -void LegoNavController::SetLocation(MxU32 p_location) +// FUNCTION: LEGO1 0x10055620 +MxResult LegoNavController::UpdateCameraLocation(MxU32 p_location) { - // TODO + MxResult result = FAILURE; + + if (p_location < _countof(g_cameraLocations)) { + MxMatrix mat; + LegoROI* viewROI = VideoManager()->GetViewROI(); + + CalcLocalTransform( + g_cameraLocations[p_location].m_position, + g_cameraLocations[p_location].m_direction, + g_cameraLocations[p_location].m_up, + mat + ); + + Mx3DPointFloat vec; + vec.Clear(); + + viewROI->FUN_100a5a30(vec); + viewROI->WrappedSetLocalTransform(mat); + VideoManager()->Get3DManager()->Moved(*viewROI); + + SoundManager()->FUN_1002a410( + viewROI->GetWorldPosition(), + viewROI->GetWorldDirection(), + viewROI->GetWorldUp(), + viewROI->GetWorldVelocity() + ); + + result = SUCCESS; + } + + return result; } // STUB: LEGO1 0x10055750 @@ -425,6 +488,170 @@ int LegoNavController::FUN_100558b0() // STUB: LEGO1 0x10055a60 MxLong LegoNavController::Notify(MxParam& p_param) { - // TODO + if (((MxNotificationParam&) p_param).GetType() == c_notificationKeyPress) { + m_unk0x5d = TRUE; + + switch (((LegoEventNotificationParam&) p_param).GetKey()) { + case VK_PAUSE: + if (Lego()->IsTimerRunning()) { + Lego()->StopTimer(); + } + else { + Lego()->StartTimer(); + } + break; + case VK_ESCAPE: { + LegoWorld* currentWorld = CurrentWorld(); + if (currentWorld) { + InfocenterState* infocenterState = (InfocenterState*) GameState()->GetState("InfocenterState"); + if (infocenterState && infocenterState->GetUnknown0x74() != 8 && currentWorld->VTable0x64()) { + BackgroundAudioManager()->Stop(); + TransitionManager()->StartTransition(MxTransitionManager::e_mosaic, 50, FALSE, FALSE); + infocenterState->SetUnknown0x74(8); + } + } + break; + } + case VK_SPACE: + AnimationManager()->FUN_10061010(1); + break; + case 'Z': + // TODO + break; + case 'k': + case 'm': + // TODO + break; + case '{': { + InfocenterState* infocenterState = (InfocenterState*) GameState()->GetState("InfocenterState"); + if (infocenterState && infocenterState->HasRegistered()) { + GameState()->Save(0); + } + break; + } + default: + // Check if the the key is part of the debug password + if (!*g_currentInput) { + // password "protected" debug shortcuts + switch (((LegoEventNotificationParam&) p_param).GetKey()) { + case VK_TAB: + VideoManager()->ToggleFPS(g_unk0x100f66d4); + if (g_unk0x100f66d4 == 0) { + g_unk0x100f66d4 = 1; + m_unk0x5d = FALSE; + break; + } + else { + g_unk0x100f66d4 = 0; + } + break; + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + // TODO + break; + case 'A': + if (g_unk0x100f66b0 == 1) { + Lego()->SetUnknown13c(TRUE); + AnimationManager()->FUN_10060570(1); + g_unk0x100f66b0 = 0; + } + else { + LegoWorld* world = CurrentWorld(); + if (world) { + MxDSAction action; + action.SetObjectId(1); + action.SetAtomId(world->GetAtom()); + LegoOmni::GetInstance()->Start(&action); + } + } + break; + case 'C': + g_unk0x100f66a4 = TRUE; + break; + case 'D': + m_unk0x60 = -1.0; + break; + case 'F': + RealtimeView::SetUserMaxLOD(0.0); + break; + case 'G': + g_unk0x100f66b4 = 1; + break; + case 'H': + RealtimeView::SetUserMaxLOD(5.0); + break; + case 'I': + // TODO + break; + case 'J': + // TODO + break; + case 'K': + // TODO + break; + case 'L': + g_unk0x100f66a0 = TRUE; + break; + case 'M': + // TODO + break; + case 'N': + if (VideoManager()) { + VideoManager()->SetRender3D(!VideoManager()->GetRender3D()); + } + break; + case 'P': + // TODO + break; + case 'S': + BackgroundAudioManager()->Enable(!g_musicEnabled); + break; + case 'U': + m_unk0x60 = 1.0; + break; + case 'V': + // TODO + case 'W': + // TODO + break; + case 'X': + RealtimeView::SetUserMaxLOD(3.6); + break; + case 'j': + // TODO + break; + case 'o': + GameState()->SetActorId(6); + break; + case 0xbd: + g_unk0x100f66bc = 1; + break; + default: + m_unk0x5d = FALSE; + break; + } + } + else { + if (*g_currentInput == ((LegoEventNotificationParam&) p_param).GetKey()) { + g_currentInput++; + break; + } + else { + g_currentInput = g_debugPassword; + break; + } + } + break; + } + } + return 0; } diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index 28b9dde6..21b06d85 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -243,6 +243,19 @@ void LegoVideoManager::MoveCursor(MxS32 p_cursorX, MxS32 p_cursorY) } } +// FUNCTION: LEGO1 0x1007b6f0 +void LegoVideoManager::ToggleFPS(MxBool p_visible) +{ + if (p_visible && !m_drawFPS) { + m_drawFPS = TRUE; + m_unk0x550 = 1.0; + m_unk0x54c = Timer()->GetTime(); + } + else { + m_drawFPS = p_visible; + } +} + // FUNCTION: LEGO1 0x1007b770 MxResult LegoVideoManager::Tickle() {