From 4edd8d1214d323b64ee18d4d19383037d033d7e3 Mon Sep 17 00:00:00 2001 From: MS Date: Sun, 20 Jul 2025 21:58:16 -0400 Subject: [PATCH 1/7] Beta match MxThread and MxSemaphore (#1644) --- LEGO1/omni/include/mxsemaphore.h | 5 +- LEGO1/omni/include/mxthread.h | 8 +++ .../omni/src/stream/mxdiskstreamprovider.cpp | 3 +- LEGO1/omni/src/system/mxsemaphore.cpp | 20 ++++++- LEGO1/omni/src/system/mxthread.cpp | 59 ++++++++++++++++--- 5 files changed, 82 insertions(+), 13 deletions(-) diff --git a/LEGO1/omni/include/mxsemaphore.h b/LEGO1/omni/include/mxsemaphore.h index a9c5f9d2..faee3b35 100644 --- a/LEGO1/omni/include/mxsemaphore.h +++ b/LEGO1/omni/include/mxsemaphore.h @@ -6,17 +6,20 @@ #include // VTABLE: LEGO1 0x100dccf0 +// VTABLE: BETA10 0x101c28ac // SIZE 0x08 class MxSemaphore { public: MxSemaphore(); // FUNCTION: LEGO1 0x100c87e0 + // FUNCTION: BETA10 0x101592a9 ~MxSemaphore() { CloseHandle(m_hSemaphore); } virtual MxResult Init(MxU32 p_initialCount, MxU32 p_maxCount); - void Wait(MxU32 p_timeoutMS); + void Acquire(MxU32 p_timeoutMS); + void TryAcquire(); void Release(MxU32 p_releaseCount); private: diff --git a/LEGO1/omni/include/mxthread.h b/LEGO1/omni/include/mxthread.h index 6d148edd..3c4f65ab 100644 --- a/LEGO1/omni/include/mxthread.h +++ b/LEGO1/omni/include/mxthread.h @@ -8,6 +8,7 @@ class MxCore; // VTABLE: LEGO1 0x100dc860 +// VTABLE: BETA10 0x101c23e8 // SIZE 0x1c class MxThread { public: @@ -19,9 +20,16 @@ class MxThread { void Terminate(); void Sleep(MxS32 p_milliseconds); + void ResumeThread(); + void SuspendThread(); + BOOL TerminateThread(MxU32 p_exitCode); + MxS32 GetThreadPriority(MxU16& p_priority); + BOOL SetThreadPriority(MxU16 p_priority); + MxBool IsRunning() { return m_running; } // SYNTHETIC: LEGO1 0x100bf580 + // SYNTHETIC: BETA10 0x10147880 // MxThread::`scalar deleting destructor' protected: diff --git a/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp b/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp index 8be19a46..3eee3477 100644 --- a/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp +++ b/LEGO1/omni/src/stream/mxdiskstreamprovider.cpp @@ -161,10 +161,11 @@ void MxDiskStreamProvider::VTable0x20(MxDSAction* p_action) } // FUNCTION: LEGO1 0x100d1750 +// FUNCTION: BETA10 0x101632b8 MxResult MxDiskStreamProvider::WaitForWorkToComplete() { while (m_remainingWork) { - m_busySemaphore.Wait(INFINITE); + m_busySemaphore.Acquire(INFINITE); if (m_unk0x35) { PerformWork(); } diff --git a/LEGO1/omni/src/system/mxsemaphore.cpp b/LEGO1/omni/src/system/mxsemaphore.cpp index f67a4d70..59559b2e 100644 --- a/LEGO1/omni/src/system/mxsemaphore.cpp +++ b/LEGO1/omni/src/system/mxsemaphore.cpp @@ -6,30 +6,44 @@ DECOMP_SIZE_ASSERT(MxSemaphore, 0x08) // FUNCTION: LEGO1 0x100c87d0 +// FUNCTION: BETA10 0x10159260 MxSemaphore::MxSemaphore() { m_hSemaphore = NULL; } // FUNCTION: LEGO1 0x100c8800 +// FUNCTION: BETA10 0x101592d5 MxResult MxSemaphore::Init(MxU32 p_initialCount, MxU32 p_maxCount) { MxResult result = FAILURE; - if ((m_hSemaphore = CreateSemaphore(NULL, p_initialCount, p_maxCount, NULL))) { - result = SUCCESS; + m_hSemaphore = CreateSemaphore(NULL, p_initialCount, p_maxCount, NULL); + if (!m_hSemaphore) { + goto done; } + result = SUCCESS; + +done: return result; } // FUNCTION: LEGO1 0x100c8830 -void MxSemaphore::Wait(MxU32 p_timeoutMS) +// FUNCTION: BETA10 0x10159332 +void MxSemaphore::Acquire(MxU32 p_timeoutMS) { WaitForSingleObject(m_hSemaphore, p_timeoutMS); } +// FUNCTION: BETA10 0x10159385 +void MxSemaphore::TryAcquire() +{ + WaitForSingleObject(m_hSemaphore, 0); +} + // FUNCTION: LEGO1 0x100c8850 +// FUNCTION: BETA10 0x101593aa void MxSemaphore::Release(MxU32 p_releaseCount) { ReleaseSemaphore(m_hSemaphore, p_releaseCount, NULL); diff --git a/LEGO1/omni/src/system/mxthread.cpp b/LEGO1/omni/src/system/mxthread.cpp index f639f74d..aef11497 100644 --- a/LEGO1/omni/src/system/mxthread.cpp +++ b/LEGO1/omni/src/system/mxthread.cpp @@ -7,14 +7,16 @@ DECOMP_SIZE_ASSERT(MxThread, 0x1c) // FUNCTION: LEGO1 0x100bf510 +// FUNCTION: BETA10 0x10147540 MxThread::MxThread() { m_hThread = NULL; - m_running = TRUE; m_threadId = 0; + m_running = TRUE; } // FUNCTION: LEGO1 0x100bf5a0 +// FUNCTION: BETA10 0x101475d0 MxThread::~MxThread() { if (m_hThread) { @@ -25,41 +27,82 @@ MxThread::~MxThread() typedef unsigned(__stdcall* ThreadFunc)(void*); // FUNCTION: LEGO1 0x100bf610 +// FUNCTION: BETA10 0x10147655 MxResult MxThread::Start(MxS32 p_stackSize, MxS32 p_flag) { MxResult result = FAILURE; - if (m_semaphore.Init(0, 1) == SUCCESS) { - if ((m_hThread = - _beginthreadex(NULL, p_stackSize * 4, (ThreadFunc) &MxThread::ThreadProc, this, p_flag, &m_threadId) - )) { - result = SUCCESS; - } + if (m_semaphore.Init(0, 1) != SUCCESS) { + goto done; } + m_hThread = _beginthreadex(NULL, p_stackSize * 4, (ThreadFunc) &MxThread::ThreadProc, this, p_flag, &m_threadId); + if (!m_hThread) { + goto done; + } + + result = SUCCESS; + +done: return result; } // FUNCTION: LEGO1 0x100bf660 +// FUNCTION: BETA10 0x101476ee void MxThread::Sleep(MxS32 p_milliseconds) { ::Sleep(p_milliseconds); } +// FUNCTION: BETA10 0x10147710 +void MxThread::ResumeThread() +{ + ::ResumeThread((HANDLE) m_hThread); +} + +// FUNCTION: BETA10 0x10147733 +void MxThread::SuspendThread() +{ + ::SuspendThread((HANDLE) m_hThread); +} + +// FUNCTION: BETA10 0x10147756 +BOOL MxThread::TerminateThread(MxU32 p_exitCode) +{ + // TerminateThread returns nonzero for success, zero for failure + return ::TerminateThread((HANDLE) m_hThread, p_exitCode) == 0; +} + +// FUNCTION: BETA10 0x10147793 +MxS32 MxThread::GetThreadPriority(MxU16& p_priority) +{ + return (p_priority = ::GetThreadPriority((HANDLE) m_hThread)); +} + +// FUNCTION: BETA10 0x101477c8 +BOOL MxThread::SetThreadPriority(MxU16 p_priority) +{ + // SetThreadPriority returns nonzero for success, zero for failure + return ::SetThreadPriority((HANDLE) m_hThread, p_priority) == 0; +} + // FUNCTION: LEGO1 0x100bf670 +// FUNCTION: BETA10 0x1014780a void MxThread::Terminate() { m_running = FALSE; - m_semaphore.Wait(INFINITE); + m_semaphore.Acquire(INFINITE); } // FUNCTION: LEGO1 0x100bf680 +// FUNCTION: BETA10 0x1014783b unsigned MxThread::ThreadProc(void* p_thread) { return static_cast(p_thread)->Run(); } // FUNCTION: LEGO1 0x100bf690 +// FUNCTION: BETA10 0x10147855 MxResult MxThread::Run() { m_semaphore.Release(1); From b1dcc26d79c6ce8a24a0c7db6bc01ed072424115 Mon Sep 17 00:00:00 2001 From: MS Date: Sun, 20 Jul 2025 23:08:26 -0400 Subject: [PATCH 2/7] Beta functions for `MxVariable` (#1645) * Beta match MxVariable classes * CustomizeAnimFileVariable --- .../legoomni/include/legocharactermanager.h | 1 + LEGO1/lego/legoomni/include/legogamestate.h | 3 +++ LEGO1/lego/legoomni/include/legovariables.h | 19 ++++++++++++++ .../src/common/legocharactermanager.cpp | 2 ++ .../legoomni/src/common/legogamestate.cpp | 5 ++++ .../legoomni/src/common/legovariables.cpp | 26 +++++++++++++++---- LEGO1/omni/include/mxvariable.h | 5 ++++ 7 files changed, 56 insertions(+), 5 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index c5a0c242..d024e2e0 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -46,6 +46,7 @@ struct LegoActorInfo; typedef map LegoCharacterMap; // VTABLE: LEGO1 0x100da878 +// VTABLE: BETA10 0x101bc028 // SIZE 0x24 class CustomizeAnimFileVariable : public MxVariable { public: diff --git a/LEGO1/lego/legoomni/include/legogamestate.h b/LEGO1/lego/legoomni/include/legogamestate.h index 99155ce0..4a797672 100644 --- a/LEGO1/lego/legoomni/include/legogamestate.h +++ b/LEGO1/lego/legoomni/include/legogamestate.h @@ -23,6 +23,7 @@ struct ColorStringStruct { }; // VTABLE: LEGO1 0x100d74a8 +// VTABLE: BETA10 0x101bc4f0 // SIZE 0x30 class LegoBackgroundColor : public MxVariable { public: @@ -43,9 +44,11 @@ class LegoBackgroundColor : public MxVariable { }; // VTABLE: LEGO1 0x100d74b8 +// VTABLE: BETA10 0x101bc500 // SIZE 0x24 class LegoFullScreenMovie : public MxVariable { public: + LegoFullScreenMovie(); LegoFullScreenMovie(const char* p_key, const char* p_value); void SetValue(const char* p_option) override; // vtable+0x04 diff --git a/LEGO1/lego/legoomni/include/legovariables.h b/LEGO1/lego/legoomni/include/legovariables.h index 9447a5f9..873ef34c 100644 --- a/LEGO1/lego/legoomni/include/legovariables.h +++ b/LEGO1/lego/legoomni/include/legovariables.h @@ -17,41 +17,60 @@ extern const char* g_varVISIBILITY; extern const char* g_varCAMERALOCATION; extern const char* g_varCURSOR; extern const char* g_varWHOAMI; +extern const char* g_varDEBUG; // VTABLE: LEGO1 0x100d86c8 +// VTABLE: BETA10 0x101bc980 // SIZE 0x24 class VisibilityVariable : public MxVariable { public: + // FUNCTION: BETA10 0x10093470 VisibilityVariable() { m_key = g_varVISIBILITY; } void SetValue(const char* p_value) override; // vtable+0x04 }; // VTABLE: LEGO1 0x100d86b8 +// VTABLE: BETA10 0x101bc990 // SIZE 0x24 class CameraLocationVariable : public MxVariable { public: + // FUNCTION: BETA10 0x10093510 CameraLocationVariable() { m_key = g_varCAMERALOCATION; } void SetValue(const char* p_value) override; // vtable+0x04 }; // VTABLE: LEGO1 0x100d86a8 +// VTABLE: BETA10 0x101bc9a0 // SIZE 0x24 class CursorVariable : public MxVariable { public: + // FUNCTION: BETA10 0x100935b0 CursorVariable() { m_key = g_varCURSOR; } void SetValue(const char* p_value) override; // vtable+0x04 }; // VTABLE: LEGO1 0x100d8698 +// VTABLE: BETA10 0x101bc9b0 // SIZE 0x24 class WhoAmIVariable : public MxVariable { public: + // FUNCTION: BETA10 0x10093650 WhoAmIVariable() { m_key = g_varWHOAMI; } void SetValue(const char* p_value) override; // vtable+0x04 }; +// VTABLE: BETA10 0x101bc9c0 +// SIZE 0x24 +class DebugVariable : public MxVariable { +public: + // FUNCTION: BETA10 0x100936f0 + DebugVariable() { m_key = g_varDEBUG; } + + void SetValue(const char* p_value) override; // vtable+0x04 +}; + #endif // LEGOVARIABLES_H diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index ff7cf23b..496bf844 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -1090,6 +1090,7 @@ LegoROI* LegoCharacterManager::FUN_10085a80(const char* p_name, const char* p_lo } // FUNCTION: LEGO1 0x10085aa0 +// FUNCTION: BETA10 0x1007703d CustomizeAnimFileVariable::CustomizeAnimFileVariable(const char* p_key) { m_key = p_key; @@ -1097,6 +1098,7 @@ CustomizeAnimFileVariable::CustomizeAnimFileVariable(const char* p_key) } // FUNCTION: LEGO1 0x10085b50 +// FUNCTION: BETA10 0x100770c8 void CustomizeAnimFileVariable::SetValue(const char* p_value) { // STRING: LEGO1 0x100fc4f4 diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index eae457ed..5096fbcf 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -1334,6 +1334,11 @@ void LegoBackgroundColor::SetLightColor() SetLightColor(convertedR, convertedG, convertedB); } +// FUNCTION: BETA10 0x10086a87 +LegoFullScreenMovie::LegoFullScreenMovie() +{ +} + // FUNCTION: LEGO1 0x1003c500 // FUNCTION: BETA10 0x10086af6 LegoFullScreenMovie::LegoFullScreenMovie(const char* p_key, const char* p_value) diff --git a/LEGO1/lego/legoomni/src/common/legovariables.cpp b/LEGO1/lego/legoomni/src/common/legovariables.cpp index 2c701074..f6d1618f 100644 --- a/LEGO1/lego/legoomni/src/common/legovariables.cpp +++ b/LEGO1/lego/legoomni/src/common/legovariables.cpp @@ -6,6 +6,7 @@ #include "legonavcontroller.h" #include "legovideomanager.h" #include "misc.h" +#include "mxdebug.h" #include "roi/legoroi.h" DECOMP_SIZE_ASSERT(VisibilityVariable, 0x24) @@ -101,6 +102,10 @@ const char* g_nick = "Nick"; // STRING: LEGO1 0x100f39e0 const char* g_laura = "Laura"; +// GLOBAL: BETA10 0x101f6ce4 +// STRING: BETA10 0x101f6d54 +const char* g_varDEBUG = "DEBUG"; + // FUNCTION: LEGO1 0x10037d00 // FUNCTION: BETA10 0x100d5620 void VisibilityVariable::SetValue(const char* p_value) @@ -130,6 +135,7 @@ void VisibilityVariable::SetValue(const char* p_value) } // FUNCTION: LEGO1 0x10037d80 +// FUNCTION: BETA10 0x100d56ee void CameraLocationVariable::SetValue(const char* p_value) { char buffer[256]; @@ -137,22 +143,25 @@ void CameraLocationVariable::SetValue(const char* p_value) strcpy(buffer, p_value); - char* location = strtok(buffer, ","); - NavController()->UpdateLocation(location); + char* token = strtok(buffer, ","); + assert(token); + NavController()->UpdateLocation(token); - location = strtok(NULL, ","); - if (location) { - MxFloat pov = (MxFloat) atof(location); + token = strtok(NULL, ","); + if (token) { + MxFloat pov = (MxFloat) atof(token); VideoManager()->Get3DManager()->SetFrustrum(pov, 0.1f, 250.0f); } } // FUNCTION: LEGO1 0x10037e30 +// FUNCTION: BETA10 0x100d57e2 void CursorVariable::SetValue(const char* p_value) { } // FUNCTION: LEGO1 0x10037e40 +// FUNCTION: BETA10 0x100d57fa void WhoAmIVariable::SetValue(const char* p_value) { MxVariable::SetValue(p_value); @@ -173,3 +182,10 @@ void WhoAmIVariable::SetValue(const char* p_value) GameState()->SetActorId(LegoActor::c_laura); } } + +// FUNCTION: BETA10 0x100d58fa +void DebugVariable::SetValue(const char* p_value) +{ + MxVariable::SetValue(p_value); + MxTrace("%s\n", p_value); +} diff --git a/LEGO1/omni/include/mxvariable.h b/LEGO1/omni/include/mxvariable.h index 8949833f..9eda281f 100644 --- a/LEGO1/omni/include/mxvariable.h +++ b/LEGO1/omni/include/mxvariable.h @@ -9,6 +9,7 @@ // SIZE 0x24 class MxVariable { public: + // FUNCTION: BETA10 0x1007b750 MxVariable() {} // FUNCTION: BETA10 0x1012a840 @@ -41,12 +42,16 @@ class MxVariable { // FUNCTION: BETA10 0x1012a7f0 const MxString* GetKey() const { return &m_key; } + // SYNTHETIC: BETA10 0x1007b8c0 + // MxVariable::`scalar deleting destructor' + protected: MxString m_key; // 0x04 MxString m_value; // 0x14 }; // SYNTHETIC: LEGO1 0x1003bf40 +// SYNTHETIC: BETA10 0x1007b910 // MxVariable::~MxVariable #endif // MXVARIABLE_H From fd299137ff1cd573a5315e1099da092645d295e8 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Mon, 21 Jul 2025 22:18:59 +0200 Subject: [PATCH 3/7] Clear unknowns `LegoCameraController` (#1647) --- .../legoomni/include/legocameracontroller.h | 12 +++++----- LEGO1/lego/legoomni/src/actors/helicopter.cpp | 4 ++-- .../src/entity/legocameracontroller.cpp | 24 +++++++++---------- LEGO1/lego/legoomni/src/entity/legoentity.cpp | 2 +- .../legoomni/src/entity/legonavcontroller.cpp | 2 +- .../lego/legoomni/src/paths/legopathactor.cpp | 2 +- LEGO1/lego/legoomni/src/race/legoracers.cpp | 2 +- .../legoomni/src/video/legoanimpresenter.cpp | 2 +- 8 files changed, 25 insertions(+), 25 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legocameracontroller.h b/LEGO1/lego/legoomni/include/legocameracontroller.h index 4dcb6c39..cf4e8f0a 100644 --- a/LEGO1/lego/legoomni/include/legocameracontroller.h +++ b/LEGO1/lego/legoomni/include/legocameracontroller.h @@ -38,17 +38,17 @@ class LegoCameraController : public LegoPointOfViewController { virtual MxResult Create(); // vtable+0x44 void SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up); - void FUN_10012290(float p_angle); - void FUN_10012320(float p_angle); - MxResult FUN_100123b0(Matrix4& p_matrix); - void FUN_100123e0(const Matrix4& p_transform, MxU32 p_und); + void RotateZ(float p_angle); + void RotateY(float p_angle); + MxResult GetPointOfView(Matrix4& p_matrix); + void TransformPointOfView(const Matrix4& p_transform, MxU32 p_multiply); Mx3DPointFloat GetWorldUp(); Mx3DPointFloat GetWorldLocation(); Mx3DPointFloat GetWorldDirection(); private: - MxMatrix m_matrix1; // 0x38 - MxMatrix m_matrix2; // 0x80 + MxMatrix m_currentTransform; // 0x38 + MxMatrix m_originalTransform; // 0x80 }; // SYNTHETIC: LEGO1 0x10011f50 diff --git a/LEGO1/lego/legoomni/src/actors/helicopter.cpp b/LEGO1/lego/legoomni/src/actors/helicopter.cpp index 358657b1..fc2addb3 100644 --- a/LEGO1/lego/legoomni/src/actors/helicopter.cpp +++ b/LEGO1/lego/legoomni/src/actors/helicopter.cpp @@ -426,7 +426,7 @@ void Helicopter::Animate(float p_time) v2 *= f2; v2 += v1; - m_world->GetCameraController()->FUN_100123e0(mat, 0); + m_world->GetCameraController()->TransformPointOfView(mat, 0); } else { if (m_state->m_unk0x08 == 4) { @@ -459,7 +459,7 @@ void Helicopter::FUN_100042a0(const Matrix4& p_matrix) // the typecast makes this function match for unknown reasons Vector3 vec6((const float*) m_unk0x1a8[3]); // locala0 // esp+0x28 - m_world->GetCameraController()->FUN_100123b0(local48); + m_world->GetCameraController()->GetPointOfView(local48); m_unk0x1a8.SetIdentity(); local90 = p_matrix; diff --git a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp index 2f192058..c15b4aac 100644 --- a/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legocameracontroller.cpp @@ -120,28 +120,28 @@ void LegoCameraController::OnMouseMove(MxU8 p_modifier, MxPoint32 p_point) // FUNCTION: LEGO1 0x10012260 void LegoCameraController::SetWorldTransform(const Vector3& p_at, const Vector3& p_dir, const Vector3& p_up) { - CalcLocalTransform(p_at, p_dir, p_up, m_matrix1); - m_matrix2 = m_matrix1; + CalcLocalTransform(p_at, p_dir, p_up, m_currentTransform); + m_originalTransform = m_currentTransform; } // FUNCTION: LEGO1 0x10012290 // FUNCTION: BETA10 0x10068c34 -void LegoCameraController::FUN_10012290(float p_angle) +void LegoCameraController::RotateZ(float p_angle) { - m_matrix1 = m_matrix2; - m_matrix1.RotateZ(p_angle); + m_currentTransform = m_originalTransform; + m_currentTransform.RotateZ(p_angle); } // FUNCTION: LEGO1 0x10012320 // FUNCTION: BETA10 0x10068c73 -void LegoCameraController::FUN_10012320(float p_angle) +void LegoCameraController::RotateY(float p_angle) { - m_matrix1 = m_matrix2; - m_matrix1.RotateY(p_angle); + m_currentTransform = m_originalTransform; + m_currentTransform.RotateY(p_angle); } // FUNCTION: LEGO1 0x100123b0 -MxResult LegoCameraController::FUN_100123b0(Matrix4& p_matrix) +MxResult LegoCameraController::GetPointOfView(Matrix4& p_matrix) { if (m_lego3DView) { ViewROI* pov = m_lego3DView->GetPointOfView(); @@ -156,7 +156,7 @@ MxResult LegoCameraController::FUN_100123b0(Matrix4& p_matrix) // FUNCTION: LEGO1 0x100123e0 // FUNCTION: BETA10 0x10068cb2 -void LegoCameraController::FUN_100123e0(const Matrix4& p_transform, MxU32 p_und) +void LegoCameraController::TransformPointOfView(const Matrix4& p_transform, MxU32 p_multiply) { if (m_lego3DView != NULL) { ViewROI* pov = m_lego3DView->GetPointOfView(); @@ -164,8 +164,8 @@ void LegoCameraController::FUN_100123e0(const Matrix4& p_transform, MxU32 p_und) if (pov != NULL) { MxMatrix mat; - if (p_und) { - MXM4(mat, m_matrix1, p_transform); + if (p_multiply) { + MXM4(mat, m_currentTransform, p_transform); } else { mat = p_transform; diff --git a/LEGO1/lego/legoomni/src/entity/legoentity.cpp b/LEGO1/lego/legoomni/src/entity/legoentity.cpp index 9ac9aad6..a87c9ebb 100644 --- a/LEGO1/lego/legoomni/src/entity/legoentity.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoentity.cpp @@ -194,7 +194,7 @@ void LegoEntity::FUN_10010c30() LegoWorld* world = CurrentWorld(); if (m_cameraFlag && world && world->GetCameraController() && m_roi) { - world->GetCameraController()->FUN_100123e0(m_roi->GetLocal2World(), 1); + world->GetCameraController()->TransformPointOfView(m_roi->GetLocal2World(), 1); } } diff --git a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp index 78d2e6d1..8410c63f 100644 --- a/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp +++ b/LEGO1/lego/legoomni/src/entity/legonavcontroller.cpp @@ -549,7 +549,7 @@ MxResult LegoNavController::ProcessJoystickInput(MxBool& p_und) LegoWorld* world = CurrentWorld(); if (world && world->GetCameraController()) { - world->GetCameraController()->FUN_10012320(DTOR(povPosition)); + world->GetCameraController()->RotateY(DTOR(povPosition)); p_und = TRUE; } } diff --git a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp index 0a8f6878..728d5649 100644 --- a/LEGO1/lego/legoomni/src/paths/legopathactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legopathactor.cpp @@ -439,7 +439,7 @@ void LegoPathActor::Animate(float p_time) LegoWorld* world = CurrentWorld(); if (world) { - world->GetCameraController()->FUN_10012290(DTOR(m_unk0x14c)); + world->GetCameraController()->RotateZ(DTOR(m_unk0x14c)); } } } diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index da3baf53..7fbc9bfa 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -340,7 +340,7 @@ void LegoRaceCar::KickCamera(float p_param) a->GetAnimTreePtr()->GetCamAnim()->FUN_1009f490(deltaTime, transformationMatrix); if (r->GetCameraController()) { - r->GetCameraController()->FUN_100123e0(transformationMatrix, 0); + r->GetCameraController()->TransformPointOfView(transformationMatrix, 0); } m_roi->SetLocal2World(transformationMatrix); diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index c7fbc845..6a3bbf73 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -941,7 +941,7 @@ void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p p_anim->GetCamAnim()->FUN_1009f490(p_time, transform); if (m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { - m_currentWorld->GetCameraController()->FUN_100123e0(transform, 0); + m_currentWorld->GetCameraController()->TransformPointOfView(transform, FALSE); } } From 36f6d963dce1926e1fedbce250229d802e5c3e84 Mon Sep 17 00:00:00 2001 From: jonschz <17198703+jonschz@users.noreply.github.com> Date: Mon, 21 Jul 2025 23:42:42 +0200 Subject: [PATCH 4/7] BETA matches for SoundManagers (#1646) --------- Co-authored-by: jonschz --- CMakeLists.txt | 2 +- .../legoomni/include/legocachesoundmanager.h | 6 ++ .../lego/legoomni/include/legosoundmanager.h | 8 +- .../src/audio/legocachesoundmanager.cpp | 2 + .../legoomni/src/audio/legosoundmanager.cpp | 96 ++++++++++--------- LEGO1/omni/include/mxaudiomanager.h | 7 +- LEGO1/omni/include/mxeventmanager.h | 4 +- ...mediamanager.h => mxpresentationmanager.h} | 16 ++-- LEGO1/omni/include/mxpresenterlist.h | 34 +++++-- LEGO1/omni/include/mxsoundmanager.h | 7 +- LEGO1/omni/include/mxvideomanager.h | 6 +- LEGO1/omni/src/audio/mxaudiomanager.cpp | 44 ++++++++- LEGO1/omni/src/audio/mxsoundmanager.cpp | 10 +- LEGO1/omni/src/common/mxmediapresenter.cpp | 1 + ...amanager.cpp => mxpresentationmanager.cpp} | 32 ++++--- LEGO1/omni/src/event/mxeventmanager.cpp | 4 +- LEGO1/omni/src/video/mxvideomanager.cpp | 14 ++- 17 files changed, 201 insertions(+), 92 deletions(-) rename LEGO1/omni/include/{mxmediamanager.h => mxpresentationmanager.h} (71%) rename LEGO1/omni/src/common/{mxmediamanager.cpp => mxpresentationmanager.cpp} (62%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f6d1746..286e3b1a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -240,7 +240,7 @@ function(add_lego_libraries NAME) LEGO1/omni/src/common/mxutilities.cpp LEGO1/omni/src/common/mxvariabletable.cpp LEGO1/omni/src/stream/mxdssubscriber.cpp - LEGO1/omni/src/common/mxmediamanager.cpp + LEGO1/omni/src/common/mxpresentationmanager.cpp LEGO1/omni/src/system/mxticklethread.cpp LEGO1/omni/src/audio/mxaudiomanager.cpp LEGO1/omni/src/system/mxautolock.cpp diff --git a/LEGO1/lego/legoomni/include/legocachesoundmanager.h b/LEGO1/lego/legoomni/include/legocachesoundmanager.h index dd9df741..33f5238a 100644 --- a/LEGO1/lego/legoomni/include/legocachesoundmanager.h +++ b/LEGO1/lego/legoomni/include/legocachesoundmanager.h @@ -46,10 +46,13 @@ typedef set Set100d6b4c; typedef list List100d6b4c; // VTABLE: LEGO1 0x100d6b4c +// VTABLE: BETA10 0x101becac // SIZE 0x20 class LegoCacheSoundManager { public: + // FUNCTION: BETA10 0x100d0a60 LegoCacheSoundManager() {} + ~LegoCacheSoundManager(); virtual MxResult Tickle(); // vtable+0x00 @@ -66,6 +69,9 @@ class LegoCacheSoundManager { List100d6b4c m_list; // 0x14 }; +// SYNTHETIC: BETA10 0x100d06b0 +// LegoCacheSoundManager::`scalar deleting destructor' + // TODO: Function names subject to change. // clang-format off diff --git a/LEGO1/lego/legoomni/include/legosoundmanager.h b/LEGO1/lego/legoomni/include/legosoundmanager.h index d0320320..e49ad34f 100644 --- a/LEGO1/lego/legoomni/include/legosoundmanager.h +++ b/LEGO1/lego/legoomni/include/legosoundmanager.h @@ -17,15 +17,15 @@ class LegoSoundManager : public MxSoundManager { void Destroy() override; // vtable+0x18 MxResult Create(MxU32 p_frequencyMS, MxBool p_createThread) override; // vtable+0x30 - // SYNTHETIC: LEGO1 0x10029920 - // SYNTHETIC: BETA10 0x100d0660 - // LegoSoundManager::`scalar deleting destructor' - void UpdateListener(const float* p_position, const float* p_direction, const float* p_up, const float* p_velocity); // FUNCTION: BETA10 0x1000f350 LegoCacheSoundManager* GetCacheSoundManager() { return m_cacheSoundManager; } + // SYNTHETIC: LEGO1 0x10029920 + // SYNTHETIC: BETA10 0x100d0660 + // LegoSoundManager::`scalar deleting destructor' + private: void Init(); void Destroy(MxBool p_fromDestructor); diff --git a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp index 34be4519..cd235b61 100644 --- a/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legocachesoundmanager.cpp @@ -7,6 +7,7 @@ DECOMP_SIZE_ASSERT(LegoCacheSoundEntry, 0x08) DECOMP_SIZE_ASSERT(LegoCacheSoundManager, 0x20) // FUNCTION: LEGO1 0x1003cf20 +// STUB: BETA10 0x100d0700 LegoCacheSoundManager::~LegoCacheSoundManager() { LegoCacheSound* sound; @@ -28,6 +29,7 @@ LegoCacheSoundManager::~LegoCacheSoundManager() } // FUNCTION: LEGO1 0x1003d050 +// STUB: BETA10 0x100652f0 MxResult LegoCacheSoundManager::Tickle() { #ifdef COMPAT_MODE diff --git a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp index a1657e46..a8bf9a07 100644 --- a/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp +++ b/LEGO1/lego/legoomni/src/audio/legosoundmanager.cpp @@ -9,18 +9,21 @@ DECOMP_SIZE_ASSERT(LegoSoundManager, 0x44) // FUNCTION: LEGO1 0x100298a0 +// FUNCTION: BETA10 0x100cffb0 LegoSoundManager::LegoSoundManager() { Init(); } // FUNCTION: LEGO1 0x10029940 +// FUNCTION: BETA10 0x100d0027 LegoSoundManager::~LegoSoundManager() { Destroy(TRUE); } // FUNCTION: LEGO1 0x100299a0 +// FUNCTION: BETA10 0x100d0099 void LegoSoundManager::Init() { m_cacheSoundManager = NULL; @@ -28,6 +31,7 @@ void LegoSoundManager::Init() } // FUNCTION: LEGO1 0x100299b0 +// FUNCTION: BETA10 0x100d00c9 void LegoSoundManager::Destroy(MxBool p_fromDestructor) { delete m_cacheSoundManager; @@ -42,38 +46,45 @@ void LegoSoundManager::Destroy(MxBool p_fromDestructor) // FUNCTION: BETA10 0x100d0129 MxResult LegoSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) { - MxBool locked = FALSE; MxResult result = FAILURE; + MxBool locked = FALSE; - if (MxSoundManager::Create(10, FALSE) == SUCCESS) { - ENTER(m_criticalSection); - locked = TRUE; + if (MxSoundManager::Create(10, FALSE) != SUCCESS) { + goto done; + } - if (MxOmni::IsSound3D()) { - if (m_dsBuffer->QueryInterface(IID_IDirectSound3DListener, (LPVOID*) &m_listener) != DS_OK) { - goto done; - } + ENTER(m_criticalSection); + locked = TRUE; - MxOmni* omni = MxOmni::GetInstance(); - LPDIRECTSOUND sound; - - if (omni && omni->GetSoundManager() && (sound = omni->GetSoundManager()->GetDirectSound())) { - DSCAPS caps; - memset(&caps, 0, sizeof(DSCAPS)); - caps.dwSize = sizeof(DSCAPS); - - if (sound->GetCaps(&caps) == S_OK && caps.dwMaxHw3DAllBuffers == 0) { - m_listener->SetDistanceFactor(0.026315790f, 0); - m_listener->SetRolloffFactor(10, 0); - } - } + if (MxOmni::IsSound3D()) { + if (m_dsBuffer->QueryInterface(IID_IDirectSound3DListener, (LPVOID*) &m_listener) != DS_OK) { + goto done; } - m_cacheSoundManager = new LegoCacheSoundManager; - assert(m_cacheSoundManager); - result = SUCCESS; +#ifdef BETA10 + m_listener->SetDistanceFactor(0.026315790f, 0); + m_listener->SetRolloffFactor(10, 0); +#else + MxOmni* omni = MxOmni::GetInstance(); + LPDIRECTSOUND sound; + + if (omni && omni->GetSoundManager() && (sound = omni->GetSoundManager()->GetDirectSound())) { + DSCAPS caps; + memset(&caps, 0, sizeof(DSCAPS)); + caps.dwSize = sizeof(DSCAPS); + + if (sound->GetCaps(&caps) == S_OK && caps.dwMaxHw3DAllBuffers == 0) { + m_listener->SetDistanceFactor(0.026315790f, 0); + m_listener->SetRolloffFactor(10, 0); + } + } +#endif } + m_cacheSoundManager = new LegoCacheSoundManager; + assert(m_cacheSoundManager); + result = SUCCESS; + done: if (result != SUCCESS) { Destroy(); @@ -112,29 +123,24 @@ void LegoSoundManager::UpdateListener( const float* p_velocity ) { - if (m_listener != NULL) { - if (p_position != NULL) { - m_listener->SetPosition(p_position[0], p_position[1], p_position[2], DS3D_DEFERRED); - } + if (!m_listener) { + return; + } - if (p_direction != NULL && p_up != NULL) { - m_listener->SetOrientation( - p_direction[0], - p_direction[1], - p_direction[2], - p_up[0], - p_up[1], - p_up[2], - DS3D_DEFERRED - ); - } + if (p_position != NULL) { + m_listener->SetPosition(p_position[0], p_position[1], p_position[2], DS3D_DEFERRED); + } - if (p_velocity != NULL) { - m_listener->SetVelocity(p_velocity[0], p_velocity[1], p_velocity[2], DS3D_DEFERRED); - } + if (p_direction != NULL && p_up != NULL) { + m_listener + ->SetOrientation(p_direction[0], p_direction[1], p_direction[2], p_up[0], p_up[1], p_up[2], DS3D_DEFERRED); + } - if (p_position != NULL || (p_direction != NULL && p_up != NULL) || p_velocity != NULL) { - m_listener->CommitDeferredSettings(); - } + if (p_velocity != NULL) { + m_listener->SetVelocity(p_velocity[0], p_velocity[1], p_velocity[2], DS3D_DEFERRED); + } + + if (p_position != NULL || (p_direction != NULL && p_up != NULL) || p_velocity != NULL) { + m_listener->CommitDeferredSettings(); } } diff --git a/LEGO1/omni/include/mxaudiomanager.h b/LEGO1/omni/include/mxaudiomanager.h index f962a16d..bab1f553 100644 --- a/LEGO1/omni/include/mxaudiomanager.h +++ b/LEGO1/omni/include/mxaudiomanager.h @@ -2,11 +2,12 @@ #define MXAUDIOMANAGER_H #include "decomp.h" -#include "mxmediamanager.h" +#include "mxpresentationmanager.h" // VTABLE: LEGO1 0x100dc6e0 +// VTABLE: BETA10 0x101c2348 // SIZE 0x30 -class MxAudioManager : public MxMediaManager { +class MxAudioManager : public MxPresentationManager { public: MxAudioManager(); ~MxAudioManager() override; @@ -15,11 +16,13 @@ class MxAudioManager : public MxMediaManager { void Destroy() override; // vtable+18 // FUNCTION: LEGO1 0x10029910 + // FUNCTION: BETA10 0x100d0630 virtual MxS32 GetVolume() { return m_volume; } // vtable+28 virtual void SetVolume(MxS32 p_volume); // vtable+2c // SYNTHETIC: LEGO1 0x100b8d70 + // SYNTHETIC: BETA10 0x10145110 // MxAudioManager::`scalar deleting destructor' private: diff --git a/LEGO1/omni/include/mxeventmanager.h b/LEGO1/omni/include/mxeventmanager.h index b23a2ad0..f17f886d 100644 --- a/LEGO1/omni/include/mxeventmanager.h +++ b/LEGO1/omni/include/mxeventmanager.h @@ -2,11 +2,11 @@ #define MXEVENTMANAGER_H #include "decomp.h" -#include "mxmediamanager.h" +#include "mxpresentationmanager.h" // VTABLE: LEGO1 0x100dc900 // SIZE 0x2c -class MxEventManager : public MxMediaManager { +class MxEventManager : public MxPresentationManager { public: MxEventManager(); ~MxEventManager() override; diff --git a/LEGO1/omni/include/mxmediamanager.h b/LEGO1/omni/include/mxpresentationmanager.h similarity index 71% rename from LEGO1/omni/include/mxmediamanager.h rename to LEGO1/omni/include/mxpresentationmanager.h index 38f611eb..f0740e6e 100644 --- a/LEGO1/omni/include/mxmediamanager.h +++ b/LEGO1/omni/include/mxpresentationmanager.h @@ -1,5 +1,5 @@ -#ifndef MXMEDIAMANGER_H -#define MXMEDIAMANGER_H +#ifndef MXPRESENTATIONMANAGER_H +#define MXPRESENTATIONMANAGER_H #include "mxcore.h" #include "mxcriticalsection.h" @@ -9,11 +9,12 @@ class MxThread; // VTABLE: LEGO1 0x100dc6b0 +// VTABLE: BETA10 0x101c2318 // SIZE 0x2c -class MxMediaManager : public MxCore { +class MxPresentationManager : public MxCore { public: - MxMediaManager(); - ~MxMediaManager() override; + MxPresentationManager(); + ~MxPresentationManager() override; MxResult Tickle() override; // vtable+08 virtual MxResult Create(); // vtable+14 @@ -25,7 +26,8 @@ class MxMediaManager : public MxCore { MxResult Init(); // SYNTHETIC: LEGO1 0x100b8540 - // MxMediaManager::`scalar deleting destructor' + // SYNTHETIC: BETA10 0x10144db0 + // MxPresentationManager::`scalar deleting destructor' protected: MxPresenterList* m_presenters; // 0x08 @@ -33,4 +35,4 @@ class MxMediaManager : public MxCore { MxCriticalSection m_criticalSection; // 0x10 }; -#endif // MXMEDIAMANGER_H +#endif // MXPRESENTATIONMANAGER_H diff --git a/LEGO1/omni/include/mxpresenterlist.h b/LEGO1/omni/include/mxpresenterlist.h index 0e8bd316..7d3000cc 100644 --- a/LEGO1/omni/include/mxpresenterlist.h +++ b/LEGO1/omni/include/mxpresenterlist.h @@ -5,12 +5,15 @@ #include "mxpresenter.h" // VTABLE: LEGO1 0x100d62f0 +// VTABLE: BETA10 0x101bf070 // class MxPtrList // VTABLE: LEGO1 0x100d6308 +// VTABLE: BETA10 0x101bf050 // SIZE 0x18 class MxPresenterList : public MxPtrList { public: + // FUNCTION: BETA10 0x100dc900 MxPresenterList(MxBool p_ownership = FALSE) : MxPtrList(p_ownership) {} // FUNCTION: LEGO1 0x1001cd00 @@ -35,6 +38,13 @@ class MxPresenterListCursor : public MxPtrListCursor { public: // FUNCTION: BETA10 0x1007d130 MxPresenterListCursor(MxPresenterList* p_list) : MxPtrListCursor(p_list) {} + + // SYNTHETIC: LEGO1 0x1001eed0 + // MxPresenterListCursor::`scalar deleting destructor' + + // SYNTHETIC: LEGO1 0x1001f0c0 + // SYNTHETIC: BETA10 0x1007d510 + // MxPresenterListCursor::~MxPresenterListCursor }; // VTABLE: LEGO1 0x100d6350 @@ -58,7 +68,11 @@ class MxPresenterListCursor : public MxPtrListCursor { // TEMPLATE: LEGO1 0x1001ce20 // MxList::~MxList +// TEMPLATE: BETA10 0x100dc9f0 +// MxPtrList::MxPtrList + // TEMPLATE: LEGO1 0x1001cf20 +// TEMPLATE: BETA10 0x100dce70 // MxPtrList::~MxPtrList // SYNTHETIC: LEGO1 0x1001cf70 @@ -73,10 +87,8 @@ class MxPresenterListCursor : public MxPtrListCursor { // SYNTHETIC: LEGO1 0x1001d100 // MxPresenterList::~MxPresenterList -// SYNTHETIC: LEGO1 0x1001eed0 -// MxPresenterListCursor::`scalar deleting destructor' - // TEMPLATE: LEGO1 0x1001ef40 +// TEMPLATE: BETA10 0x1007d370 // MxPtrListCursor::~MxPtrListCursor // SYNTHETIC: LEGO1 0x1001ef90 @@ -86,11 +98,9 @@ class MxPresenterListCursor : public MxPtrListCursor { // MxPtrListCursor::`scalar deleting destructor' // TEMPLATE: LEGO1 0x1001f070 +// TEMPLATE: BETA10 0x1007d490 // MxListCursor::~MxListCursor -// FUNCTION: LEGO1 0x1001f0c0 -// MxPresenterListCursor::~MxPresenterListCursor - // TEMPLATE: LEGO1 0x10020760 // MxListCursor::MxListCursor @@ -106,6 +116,18 @@ class MxPresenterListCursor : public MxPtrListCursor { // TEMPLATE: BETA10 0x1007d270 // MxListCursor::MxListCursor +// TEMPLATE: BETA10 0x1007dc60 +// MxListCursor::Next + +// TEMPLATE: BETA10 0x100d8f20 +// MxListCursor::Reset + +// TEMPLATE: BETA10 0x1007e070 +// MxListEntry::GetNext + +// TEMPLATE: BETA10 0x1007e0a0 +// MxListEntry::GetValue + // TEMPLATE: BETA10 0x100d9420 // ?Prev@?$MxListCursor@PAVMxPresenter@@@@QAEEAAPAVMxPresenter@@@Z diff --git a/LEGO1/omni/include/mxsoundmanager.h b/LEGO1/omni/include/mxsoundmanager.h index 3d25856b..a0b1145e 100644 --- a/LEGO1/omni/include/mxsoundmanager.h +++ b/LEGO1/omni/include/mxsoundmanager.h @@ -27,6 +27,10 @@ class MxSoundManager : public MxAudioManager { MxPresenter* FindPresenter(const MxAtomId& p_atomId, MxU32 p_objectId); + // SYNTHETIC: LEGO1 0x100ae7b0 + // SYNTHETIC: BETA10 0x10133460 + // MxSoundManager::`scalar deleting destructor' + protected: void Init(); void Destroy(MxBool p_fromDestructor); @@ -36,7 +40,4 @@ class MxSoundManager : public MxAudioManager { undefined m_unk0x38[4]; }; -// SYNTHETIC: LEGO1 0x100ae7b0 -// MxSoundManager::`scalar deleting destructor' - #endif // MXSOUNDMANAGER_H diff --git a/LEGO1/omni/include/mxvideomanager.h b/LEGO1/omni/include/mxvideomanager.h index 2ecab25d..60349d13 100644 --- a/LEGO1/omni/include/mxvideomanager.h +++ b/LEGO1/omni/include/mxvideomanager.h @@ -1,7 +1,7 @@ #ifndef MXVIDEOMANAGER_H #define MXVIDEOMANAGER_H -#include "mxmediamanager.h" +#include "mxpresentationmanager.h" #include "mxvideoparam.h" #include @@ -11,8 +11,9 @@ class MxRect32; class MxRegion; // VTABLE: LEGO1 0x100dc810 +// VTABLE: BETA10 0x101c1bf8 // SIZE 0x64 -class MxVideoManager : public MxMediaManager { +class MxVideoManager : public MxPresentationManager { public: MxVideoManager(); ~MxVideoManager() override; @@ -48,6 +49,7 @@ class MxVideoManager : public MxMediaManager { MxRegion* GetRegion() { return this->m_region; } // SYNTHETIC: LEGO1 0x100be280 + // SYNTHETIC: BETA10 0x1012de00 // MxVideoManager::`scalar deleting destructor' protected: diff --git a/LEGO1/omni/src/audio/mxaudiomanager.cpp b/LEGO1/omni/src/audio/mxaudiomanager.cpp index 34b52eda..3cef829a 100644 --- a/LEGO1/omni/src/audio/mxaudiomanager.cpp +++ b/LEGO1/omni/src/audio/mxaudiomanager.cpp @@ -3,27 +3,32 @@ DECOMP_SIZE_ASSERT(MxAudioManager, 0x30); // GLOBAL: LEGO1 0x10102108 +// GLOBAL: BETA10 0x10203a60 MxS32 MxAudioManager::g_count = 0; // FUNCTION: LEGO1 0x100b8d00 +// FUNCTION: BETA10 0x10144e90 MxAudioManager::MxAudioManager() { Init(); } // FUNCTION: LEGO1 0x100b8d90 +// STUB: BETA10 0x10144f07 MxAudioManager::~MxAudioManager() { Destroy(TRUE); } // FUNCTION: LEGO1 0x100b8df0 +// FUNCTION: BETA10 0x10144f79 void MxAudioManager::Init() { m_volume = 100; } // FUNCTION: LEGO1 0x100b8e00 +// FUNCTION: BETA10 0x10144f9c void MxAudioManager::Destroy(MxBool p_fromDestructor) { ENTER(m_criticalSection); @@ -32,17 +37,49 @@ void MxAudioManager::Destroy(MxBool p_fromDestructor) m_criticalSection.Leave(); if (!p_fromDestructor) { - MxMediaManager::Destroy(); + MxPresentationManager::Destroy(); } } +#ifdef BETA10 +// FUNCTION: BETA10 0x10144ffe +MxResult MxAudioManager::Create() +{ + MxResult result = FAILURE; + MxBool success = FALSE; + + if (MxPresentationManager::Create() != SUCCESS) { + goto exit; + } + + ENTER(m_criticalSection); + success = TRUE; + + if (!g_count++) { + // This is correct. It was likely refactored later. + } + +exit: + result = SUCCESS; + + if (result) { + Destroy(); + } + + if (success) { + m_criticalSection.Leave(); + } + + return result; +} +#else // FUNCTION: LEGO1 0x100b8e40 MxResult MxAudioManager::Create() { MxResult result = FAILURE; MxBool success = FALSE; - if (MxMediaManager::Create() == SUCCESS) { + if (MxPresentationManager::Create() == SUCCESS) { ENTER(m_criticalSection); success = TRUE; result = SUCCESS; @@ -59,14 +96,17 @@ MxResult MxAudioManager::Create() return result; } +#endif // FUNCTION: LEGO1 0x100b8e90 +// FUNCTION: BETA10 0x101450a7 void MxAudioManager::Destroy() { Destroy(FALSE); } // FUNCTION: LEGO1 0x100b8ea0 +// FUNCTION: BETA10 0x101450c7 void MxAudioManager::SetVolume(MxS32 p_volume) { ENTER(m_criticalSection); diff --git a/LEGO1/omni/src/audio/mxsoundmanager.cpp b/LEGO1/omni/src/audio/mxsoundmanager.cpp index 1e2b28a1..5bfa851c 100644 --- a/LEGO1/omni/src/audio/mxsoundmanager.cpp +++ b/LEGO1/omni/src/audio/mxsoundmanager.cpp @@ -23,18 +23,21 @@ MxS32 g_volumeAttenuation[100] = {-6643, -5643, -5058, -4643, -4321, -4058, -383 -43, -29, -14, 0}; // FUNCTION: LEGO1 0x100ae740 +// FUNCTION: BETA10 0x10132c70 MxSoundManager::MxSoundManager() { Init(); } // FUNCTION: LEGO1 0x100ae7d0 +// FUNCTION: BETA10 0x10132ce7 MxSoundManager::~MxSoundManager() { Destroy(TRUE); } // FUNCTION: LEGO1 0x100ae830 +// FUNCTION: BETA10 0x10132d59 void MxSoundManager::Init() { m_directSound = NULL; @@ -42,6 +45,7 @@ void MxSoundManager::Init() } // FUNCTION: LEGO1 0x100ae840 +// FUNCTION: BETA10 0x10132d89 void MxSoundManager::Destroy(MxBool p_fromDestructor) { if (m_thread) { @@ -156,12 +160,14 @@ MxResult MxSoundManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) } // FUNCTION: LEGO1 0x100aeab0 +// FUNCTION: BETA10 0x101331e3 void MxSoundManager::Destroy() { Destroy(FALSE); } // FUNCTION: LEGO1 0x100aeac0 +// FUNCTION: BETA10 0x10133203 void MxSoundManager::SetVolume(MxS32 p_volume) { MxAudioManager::SetVolume(p_volume); @@ -179,6 +185,7 @@ void MxSoundManager::SetVolume(MxS32 p_volume) } // FUNCTION: LEGO1 0x100aebd0 +// FUNCTION: BETA10 0x101332cf MxPresenter* MxSoundManager::FindPresenter(const MxAtomId& p_atomId, MxU32 p_objectId) { AUTOLOCK(m_criticalSection); @@ -187,8 +194,7 @@ MxPresenter* MxSoundManager::FindPresenter(const MxAtomId& p_atomId, MxU32 p_obj MxPresenterListCursor cursor(m_presenters); while (cursor.Next(presenter)) { - if (presenter->GetAction()->GetAtomId().GetInternal() == p_atomId.GetInternal() && - presenter->GetAction()->GetObjectId() == p_objectId) { + if (presenter->GetAction()->GetAtomId() == p_atomId && presenter->GetAction()->GetObjectId() == p_objectId) { return presenter; } } diff --git a/LEGO1/omni/src/common/mxmediapresenter.cpp b/LEGO1/omni/src/common/mxmediapresenter.cpp index c8b9abcd..11621f71 100644 --- a/LEGO1/omni/src/common/mxmediapresenter.cpp +++ b/LEGO1/omni/src/common/mxmediapresenter.cpp @@ -131,6 +131,7 @@ MxResult MxMediaPresenter::StartAction(MxStreamController* p_controller, MxDSAct } // FUNCTION: LEGO1 0x100b5bc0 +// STUB: BETA10 0x1013623c void MxMediaPresenter::EndAction() { AUTOLOCK(m_criticalSection); diff --git a/LEGO1/omni/src/common/mxmediamanager.cpp b/LEGO1/omni/src/common/mxpresentationmanager.cpp similarity index 62% rename from LEGO1/omni/src/common/mxmediamanager.cpp rename to LEGO1/omni/src/common/mxpresentationmanager.cpp index cc1611ae..6ef8448e 100644 --- a/LEGO1/omni/src/common/mxmediamanager.cpp +++ b/LEGO1/omni/src/common/mxpresentationmanager.cpp @@ -1,4 +1,4 @@ -#include "mxmediamanager.h" +#include "mxpresentationmanager.h" #include "decomp.h" #include "mxautolock.h" @@ -6,24 +6,27 @@ #include "mxpresenter.h" #include "mxticklemanager.h" -DECOMP_SIZE_ASSERT(MxMediaManager, 0x2c); +DECOMP_SIZE_ASSERT(MxPresentationManager, 0x2c); DECOMP_SIZE_ASSERT(MxPresenterList, 0x18); DECOMP_SIZE_ASSERT(MxPresenterListCursor, 0x10); // FUNCTION: LEGO1 0x100b84c0 -MxMediaManager::MxMediaManager() +// FUNCTION: BETA10 0x10144680 +MxPresentationManager::MxPresentationManager() { Init(); } // FUNCTION: LEGO1 0x100b8560 -MxMediaManager::~MxMediaManager() +// FUNCTION: BETA10 0x10144712 +MxPresentationManager::~MxPresentationManager() { Destroy(); } // FUNCTION: LEGO1 0x100b85d0 -MxResult MxMediaManager::Init() +// FUNCTION: BETA10 0x1014479b +MxResult MxPresentationManager::Init() { this->m_presenters = NULL; this->m_thread = NULL; @@ -31,8 +34,10 @@ MxResult MxMediaManager::Init() } // FUNCTION: LEGO1 0x100b85e0 -MxResult MxMediaManager::Create() +// FUNCTION: BETA10 0x101447c5 +MxResult MxPresentationManager::Create() { + // This validates the name of the source code file (and hence also the name of the class) AUTOLOCK(m_criticalSection); this->m_presenters = new MxPresenterList; @@ -46,7 +51,8 @@ MxResult MxMediaManager::Create() } // FUNCTION: LEGO1 0x100b8710 -void MxMediaManager::Destroy() +// FUNCTION: BETA10 0x101448e4 +void MxPresentationManager::Destroy() { AUTOLOCK(m_criticalSection); @@ -58,7 +64,8 @@ void MxMediaManager::Destroy() } // FUNCTION: LEGO1 0x100b8790 -MxResult MxMediaManager::Tickle() +// FUNCTION: BETA10 0x10144993 +MxResult MxPresentationManager::Tickle() { AUTOLOCK(m_criticalSection); MxPresenter* presenter; @@ -78,7 +85,8 @@ MxResult MxMediaManager::Tickle() } // FUNCTION: LEGO1 0x100b88c0 -void MxMediaManager::RegisterPresenter(MxPresenter& p_presenter) +// FUNCTION: BETA10 0x10144a8b +void MxPresentationManager::RegisterPresenter(MxPresenter& p_presenter) { AUTOLOCK(m_criticalSection); @@ -86,7 +94,8 @@ void MxMediaManager::RegisterPresenter(MxPresenter& p_presenter) } // FUNCTION: LEGO1 0x100b8980 -void MxMediaManager::UnregisterPresenter(MxPresenter& p_presenter) +// FUNCTION: BETA10 0x10144b0c +void MxPresentationManager::UnregisterPresenter(MxPresenter& p_presenter) { AUTOLOCK(m_criticalSection); MxPresenterListCursor cursor(this->m_presenters); @@ -97,7 +106,8 @@ void MxMediaManager::UnregisterPresenter(MxPresenter& p_presenter) } // FUNCTION: LEGO1 0x100b8ac0 -void MxMediaManager::StopPresenters() +// FUNCTION: BETA10 0x10144bc3 +void MxPresentationManager::StopPresenters() { AUTOLOCK(m_criticalSection); MxPresenter* presenter; diff --git a/LEGO1/omni/src/event/mxeventmanager.cpp b/LEGO1/omni/src/event/mxeventmanager.cpp index 2c38a123..91a22abb 100644 --- a/LEGO1/omni/src/event/mxeventmanager.cpp +++ b/LEGO1/omni/src/event/mxeventmanager.cpp @@ -35,7 +35,7 @@ void MxEventManager::Destroy(MxBool p_fromDestructor) } if (!p_fromDestructor) { - MxMediaManager::Destroy(); + MxPresentationManager::Destroy(); } } @@ -45,7 +45,7 @@ MxResult MxEventManager::Create(MxU32 p_frequencyMS, MxBool p_createThread) MxResult status = FAILURE; MxBool locked = FALSE; - MxResult result = MxMediaManager::Create(); + MxResult result = MxPresentationManager::Create(); if (result == SUCCESS) { if (p_createThread) { ENTER(this->m_criticalSection); diff --git a/LEGO1/omni/src/video/mxvideomanager.cpp b/LEGO1/omni/src/video/mxvideomanager.cpp index 9ad9005c..5649e2d1 100644 --- a/LEGO1/omni/src/video/mxvideomanager.cpp +++ b/LEGO1/omni/src/video/mxvideomanager.cpp @@ -19,17 +19,20 @@ MxVideoManager::MxVideoManager() } // FUNCTION: LEGO1 0x100be270 +// FUNCTION: BETA10 0x1012dde0 void MxVideoManager::UpdateView(MxU32 p_x, MxU32 p_y, MxU32 p_width, MxU32 p_height) { } // FUNCTION: LEGO1 0x100be2a0 +// FUNCTION: BETA10 0x1012cad8 MxVideoManager::~MxVideoManager() { Destroy(TRUE); } // FUNCTION: LEGO1 0x100be320 +// FUNCTION: BETA10 0x1012cb66 MxResult MxVideoManager::Init() { m_pDirectDraw = NULL; @@ -42,6 +45,7 @@ MxResult MxVideoManager::Init() } // FUNCTION: LEGO1 0x100be340 +// FUNCTION: BETA10 0x1012cbca void MxVideoManager::Destroy(MxBool p_fromDestructor) { if (m_thread) { @@ -79,7 +83,7 @@ void MxVideoManager::Destroy(MxBool p_fromDestructor) m_criticalSection.Leave(); if (!p_fromDestructor) { - MxMediaManager::Destroy(); + MxPresentationManager::Destroy(); } } @@ -132,6 +136,7 @@ void MxVideoManager::SortPresenterList() } // FUNCTION: LEGO1 0x100be600 +// STUB: BETA10 0x1012cfbc MxResult MxVideoManager::VTable0x28( MxVideoParam& p_videoParam, LPDIRECTDRAW p_pDirectDraw, @@ -148,7 +153,7 @@ MxResult MxVideoManager::VTable0x28( m_unk0x60 = FALSE; - if (MxMediaManager::Create() != SUCCESS) { + if (MxPresentationManager::Create() != SUCCESS) { goto done; } @@ -214,6 +219,7 @@ MxResult MxVideoManager::VTable0x28( } // FUNCTION: LEGO1 0x100be820 +// STUB: BETA10 0x1012d3f1 MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, MxBool p_createThread) { MxBool locked = FALSE; @@ -221,7 +227,7 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, m_unk0x60 = TRUE; - if (MxMediaManager::Create() != SUCCESS) { + if (MxPresentationManager::Create() != SUCCESS) { goto done; } @@ -292,6 +298,7 @@ MxResult MxVideoManager::Create(MxVideoParam& p_videoParam, MxU32 p_frequencyMS, } // FUNCTION: LEGO1 0x100bea50 +// FUNCTION: BETA10 0x1012d85f void MxVideoManager::Destroy() { Destroy(FALSE); @@ -310,6 +317,7 @@ void MxVideoManager::InvalidateRect(MxRect32& p_rect) } // FUNCTION: LEGO1 0x100bea90 +// FUNCTION: BETA10 0x1012d8e3 MxResult MxVideoManager::Tickle() { AUTOLOCK(m_criticalSection); From ed33541a2e88090cf6aa7ae23ab7b6927e8b1f3d Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Tue, 22 Jul 2025 19:45:50 +0200 Subject: [PATCH 5/7] Clear unknowns in `LegoAnimScene` (#1649) --- LEGO1/lego/legoomni/src/race/legoracers.cpp | 2 +- .../legoomni/src/video/legoanimpresenter.cpp | 2 +- LEGO1/lego/sources/anim/legoanim.cpp | 231 +++++++++--------- LEGO1/lego/sources/anim/legoanim.h | 36 +-- 4 files changed, 142 insertions(+), 129 deletions(-) diff --git a/LEGO1/lego/legoomni/src/race/legoracers.cpp b/LEGO1/lego/legoomni/src/race/legoracers.cpp index 7fbc9bfa..c45393e8 100644 --- a/LEGO1/lego/legoomni/src/race/legoracers.cpp +++ b/LEGO1/lego/legoomni/src/race/legoracers.cpp @@ -337,7 +337,7 @@ void LegoRaceCar::KickCamera(float p_param) transformationMatrix.SetIdentity(); // Possible bug in the original code: The first argument is not initialized - a->GetAnimTreePtr()->GetCamAnim()->FUN_1009f490(deltaTime, transformationMatrix); + a->GetAnimTreePtr()->GetCamAnim()->CalculateCameraTransform(deltaTime, transformationMatrix); if (r->GetCameraController()) { r->GetCameraController()->TransformPointOfView(transformationMatrix, 0); diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 6a3bbf73..b36d95e1 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -938,7 +938,7 @@ void LegoAnimPresenter::FUN_1006b9a0(LegoAnim* p_anim, MxLong p_time, Matrix4* p if (p_anim->GetCamAnim() != NULL) { MxMatrix transform(mat); - p_anim->GetCamAnim()->FUN_1009f490(p_time, transform); + p_anim->GetCamAnim()->CalculateCameraTransform(p_time, transform); if (m_currentWorld != NULL && m_currentWorld->GetCameraController() != NULL) { m_currentWorld->GetCameraController()->TransformPointOfView(transform, FALSE); diff --git a/LEGO1/lego/sources/anim/legoanim.cpp b/LEGO1/lego/sources/anim/legoanim.cpp index 9026c245..e0fb90b6 100644 --- a/LEGO1/lego/sources/anim/legoanim.cpp +++ b/LEGO1/lego/sources/anim/legoanim.cpp @@ -10,20 +10,20 @@ DECOMP_SIZE_ASSERT(LegoTranslationKey, 0x14) DECOMP_SIZE_ASSERT(LegoRotationKey, 0x18) DECOMP_SIZE_ASSERT(LegoScaleKey, 0x14) DECOMP_SIZE_ASSERT(LegoMorphKey, 0x0c) -DECOMP_SIZE_ASSERT(LegoUnknownKey, 0x0c) +DECOMP_SIZE_ASSERT(LegoRotationZKey, 0x0c) DECOMP_SIZE_ASSERT(LegoAnimNodeData, 0x34) DECOMP_SIZE_ASSERT(LegoAnimActorEntry, 0x08) DECOMP_SIZE_ASSERT(LegoAnimScene, 0x24) DECOMP_SIZE_ASSERT(LegoAnim, 0x18) // FUNCTION: LEGO1 0x1009f000 -LegoUnknownKey::LegoUnknownKey() +LegoRotationZKey::LegoRotationZKey() { m_z = 0.0f; } // FUNCTION: LEGO1 0x1009f020 -LegoResult LegoUnknownKey::Read(LegoStorage* p_storage) +LegoResult LegoRotationZKey::Read(LegoStorage* p_storage) { LegoResult result; @@ -40,7 +40,7 @@ LegoResult LegoUnknownKey::Read(LegoStorage* p_storage) // FUNCTION: LEGO1 0x1009f060 // FUNCTION: BETA10 0x1018133f -LegoResult LegoUnknownKey::Write(LegoStorage* p_storage) +LegoResult LegoRotationZKey::Write(LegoStorage* p_storage) { LegoResult result; @@ -58,33 +58,33 @@ LegoResult LegoUnknownKey::Write(LegoStorage* p_storage) // FUNCTION: LEGO1 0x1009f0a0 LegoAnimScene::LegoAnimScene() { - m_unk0x00 = 0; - m_unk0x04 = NULL; - m_unk0x08 = 0; - m_unk0x0c = NULL; - m_unk0x10 = 0; - m_unk0x14 = NULL; - m_unk0x18 = 0; - m_unk0x1c = 0; - m_unk0x20 = 0; + m_translationKeysCount = 0; + m_translationKeys = NULL; + m_targetKeysCount = 0; + m_targetKeys = NULL; + m_rotationKeysCount = 0; + m_rotationKeys = NULL; + m_targetIndex = 0; + m_translationIndex = 0; + m_rotationIndex = 0; } // FUNCTION: LEGO1 0x1009f0d0 LegoAnimScene::~LegoAnimScene() { - if (m_unk0x04 != NULL) { - delete[] m_unk0x04; - m_unk0x04 = NULL; + if (m_translationKeys != NULL) { + delete[] m_translationKeys; + m_translationKeys = NULL; } - if (m_unk0x0c != NULL) { - delete[] m_unk0x0c; - m_unk0x0c = NULL; + if (m_targetKeys != NULL) { + delete[] m_targetKeys; + m_targetKeys = NULL; } - if (m_unk0x14 != NULL) { - delete[] m_unk0x14; - m_unk0x14 = NULL; + if (m_rotationKeys != NULL) { + delete[] m_rotationKeys; + m_rotationKeys = NULL; } } @@ -95,34 +95,34 @@ LegoResult LegoAnimScene::Write(LegoStorage* p_storage) LegoResult result; LegoS32 i; - if ((result = p_storage->Write(&m_unk0x00, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Write(&m_translationKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x00 != 0) { - for (i = 0; i < m_unk0x00; i++) { - if ((result = m_unk0x04[i].Write(p_storage)) != SUCCESS) { + if (m_translationKeysCount != 0) { + for (i = 0; i < m_translationKeysCount; i++) { + if ((result = m_translationKeys[i].Write(p_storage)) != SUCCESS) { return result; } } } - if ((result = p_storage->Write(&m_unk0x08, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Write(&m_targetKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x08 != 0) { - for (i = 0; i < m_unk0x08; i++) { - if ((result = m_unk0x0c[i].Write(p_storage)) != SUCCESS) { + if (m_targetKeysCount != 0) { + for (i = 0; i < m_targetKeysCount; i++) { + if ((result = m_targetKeys[i].Write(p_storage)) != SUCCESS) { return result; } } } - if ((result = p_storage->Write(&m_unk0x10, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Write(&m_rotationKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x10 != 0) { - for (i = 0; i < m_unk0x10; i++) { - if ((result = m_unk0x14[i].Write(p_storage)) != SUCCESS) { + if (m_rotationKeysCount != 0) { + for (i = 0; i < m_rotationKeysCount; i++) { + if ((result = m_rotationKeys[i].Write(p_storage)) != SUCCESS) { return result; } } @@ -137,37 +137,37 @@ LegoResult LegoAnimScene::Read(LegoStorage* p_storage) LegoResult result; LegoS32 i; - if ((result = p_storage->Read(&m_unk0x00, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Read(&m_translationKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x00 != 0) { - m_unk0x04 = new LegoTranslationKey[m_unk0x00]; - for (i = 0; i < m_unk0x00; i++) { - if ((result = m_unk0x04[i].Read(p_storage)) != SUCCESS) { + if (m_translationKeysCount != 0) { + m_translationKeys = new LegoTranslationKey[m_translationKeysCount]; + for (i = 0; i < m_translationKeysCount; i++) { + if ((result = m_translationKeys[i].Read(p_storage)) != SUCCESS) { goto done; } } } - if ((result = p_storage->Read(&m_unk0x08, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Read(&m_targetKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x08 != 0) { - m_unk0x0c = new LegoTranslationKey[m_unk0x08]; - for (i = 0; i < m_unk0x08; i++) { - if ((result = m_unk0x0c[i].Read(p_storage)) != SUCCESS) { + if (m_targetKeysCount != 0) { + m_targetKeys = new LegoTranslationKey[m_targetKeysCount]; + for (i = 0; i < m_targetKeysCount; i++) { + if ((result = m_targetKeys[i].Read(p_storage)) != SUCCESS) { goto done; } } } - if ((result = p_storage->Read(&m_unk0x10, sizeof(LegoU16))) != SUCCESS) { + if ((result = p_storage->Read(&m_rotationKeysCount, sizeof(LegoU16))) != SUCCESS) { return result; } - if (m_unk0x10 != 0) { - m_unk0x14 = new LegoUnknownKey[m_unk0x10]; - for (i = 0; i < m_unk0x10; i++) { - if ((result = m_unk0x14[i].Read(p_storage)) != SUCCESS) { + if (m_rotationKeysCount != 0) { + m_rotationKeys = new LegoRotationZKey[m_rotationKeysCount]; + for (i = 0; i < m_rotationKeysCount; i++) { + if ((result = m_rotationKeys[i].Read(p_storage)) != SUCCESS) { goto done; } } @@ -176,22 +176,22 @@ LegoResult LegoAnimScene::Read(LegoStorage* p_storage) return SUCCESS; done: - if (m_unk0x04 != NULL) { - delete[] m_unk0x04; - m_unk0x00 = 0; - m_unk0x04 = NULL; + if (m_translationKeys != NULL) { + delete[] m_translationKeys; + m_translationKeysCount = 0; + m_translationKeys = NULL; } - if (m_unk0x0c != NULL) { - delete[] m_unk0x0c; - m_unk0x08 = 0; - m_unk0x0c = NULL; + if (m_targetKeys != NULL) { + delete[] m_targetKeys; + m_targetKeysCount = 0; + m_targetKeys = NULL; } - if (m_unk0x14 != NULL) { - delete[] m_unk0x14; - m_unk0x10 = 0; - m_unk0x14 = NULL; + if (m_rotationKeys != NULL) { + delete[] m_rotationKeys; + m_rotationKeysCount = 0; + m_rotationKeys = NULL; } return result; @@ -199,82 +199,95 @@ LegoResult LegoAnimScene::Read(LegoStorage* p_storage) // FUNCTION: LEGO1 0x1009f490 // FUNCTION: BETA10 0x10181a83 -LegoResult LegoAnimScene::FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix) +LegoResult LegoAnimScene::CalculateCameraTransform(LegoFloat p_time, Matrix4& p_matrix) { - MxMatrix localb0; - MxMatrix local4c; + MxMatrix tempMatrix; + MxMatrix original; - Vector3 local5c(localb0[0]); - Vector3 local68(localb0[1]); - Vector3 local54(localb0[2]); - Vector3 localb8(localb0[3]); + Vector3 column0(tempMatrix[0]); + Vector3 column1(tempMatrix[1]); + Vector3 column2(tempMatrix[2]); + Vector3 column3(tempMatrix[3]); - Mx3DPointFloat localcc; + Mx3DPointFloat tempTranslation; - localb0.SetIdentity(); + tempMatrix.SetIdentity(); - LegoU32 local60; - if (m_unk0x08 != 0) { - local60 = GetUnknown0x18(); - LegoAnimNodeData::GetTranslation(m_unk0x08, m_unk0x0c, p_time, localb0, local60); - SetUnknown0x18(local60); - localcc = localb8; - localb8.Clear(); + LegoU32 translationIndex; + if (m_targetKeysCount != 0) { + translationIndex = GetTargetIndex(); + LegoAnimNodeData::GetTranslation(m_targetKeysCount, m_targetKeys, p_time, tempMatrix, translationIndex); + SetTargetIndex(translationIndex); + tempTranslation = column3; + column3.Clear(); } - if (m_unk0x00 != 0) { - local60 = GetUnknown0x1c(); - LegoAnimNodeData::GetTranslation(m_unk0x00, m_unk0x04, p_time, localb0, local60); - SetUnknown0x1c(local60); + if (m_translationKeysCount != 0) { + translationIndex = GetTranslationIndex(); + LegoAnimNodeData::GetTranslation( + m_translationKeysCount, + m_translationKeys, + p_time, + tempMatrix, + translationIndex + ); + SetTranslationIndex(translationIndex); } - local54 = localcc; - local54 -= localb8; + column2 = tempTranslation; + column2 -= column3; - if (local54.Unitize() == 0) { - local5c.EqualsCross(local68, local54); + if (column2.Unitize() == 0) { + column0.EqualsCross(column1, column2); - if (local5c.Unitize() == 0) { - local68.EqualsCross(local54, local5c); + if (column0.Unitize() == 0) { + column1.EqualsCross(column2, column0); - localcc = p_matrix[3]; - localcc += localb0[3]; + tempTranslation = p_matrix[3]; + tempTranslation += tempMatrix[3]; - p_matrix[3][0] = p_matrix[3][1] = p_matrix[3][2] = localb0[3][0] = localb0[3][1] = localb0[3][2] = 0; + p_matrix[3][0] = p_matrix[3][1] = p_matrix[3][2] = tempMatrix[3][0] = tempMatrix[3][1] = tempMatrix[3][2] = + 0; - if (m_unk0x10 != 0) { - LegoU32 locald0 = -1; - LegoU32 locald8; - locald0 = GetUnknown0x20(); + if (m_rotationKeysCount != 0) { + LegoU32 old_index = -1; + LegoU32 i; + old_index = GetRotationIndex(); - LegoU32 localdc = - LegoAnimNodeData::FindKeys(p_time, m_unk0x10, m_unk0x14, sizeof(*m_unk0x14), locald8, locald0); + LegoU32 count = LegoAnimNodeData::FindKeys( + p_time, + m_rotationKeysCount, + m_rotationKeys, + sizeof(*m_rotationKeys), + i, + old_index + ); - SetUnknown0x20(locald0); + SetRotationIndex(old_index); - switch (localdc) { + switch (count) { case 1: - p_matrix.RotateZ(m_unk0x14[locald8].GetZ()); + p_matrix.RotateZ(m_rotationKeys[i].GetZ()); break; case 2: // Seems to be unused LegoFloat z = LegoAnimNodeData::Interpolate( p_time, - m_unk0x14[locald8], - m_unk0x14[locald8].GetZ(), - m_unk0x14[locald8 + 1], - m_unk0x14[locald8 + 1].GetZ() + m_rotationKeys[i], + m_rotationKeys[i].GetZ(), + m_rotationKeys[i + 1], + m_rotationKeys[i + 1].GetZ() ); - p_matrix.RotateZ(m_unk0x14[locald8].GetZ()); + p_matrix.RotateZ(m_rotationKeys[i].GetZ()); break; } } - local4c = p_matrix; - p_matrix.Product(local4c.GetData(), localb0.GetData()); - p_matrix[3][0] = localcc[0]; - p_matrix[3][1] = localcc[1]; - p_matrix[3][2] = localcc[2]; + original = p_matrix; + p_matrix.Product(original.GetData(), tempMatrix.GetData()); + p_matrix[3][0] = tempTranslation[0]; + p_matrix[3][1] = tempTranslation[1]; + p_matrix[3][2] = tempTranslation[2]; } } diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h index 7a03d99c..1c297c4d 100644 --- a/LEGO1/lego/sources/anim/legoanim.h +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -137,9 +137,9 @@ class LegoMorphKey : public LegoAnimKey { }; // SIZE 0x0c -class LegoUnknownKey : public LegoAnimKey { +class LegoRotationZKey : public LegoAnimKey { public: - LegoUnknownKey(); + LegoRotationZKey(); LegoResult Read(LegoStorage* p_storage); LegoResult Write(LegoStorage* p_storage); @@ -309,26 +309,26 @@ class LegoAnimScene { ~LegoAnimScene(); LegoResult Read(LegoStorage* p_storage); LegoResult Write(LegoStorage* p_storage); - LegoResult FUN_1009f490(LegoFloat p_time, Matrix4& p_matrix); + LegoResult CalculateCameraTransform(LegoFloat p_time, Matrix4& p_matrix); - LegoU32 GetUnknown0x18() { return m_unk0x18; } - LegoU32 GetUnknown0x1c() { return m_unk0x1c; } - LegoU32 GetUnknown0x20() { return m_unk0x20; } + LegoU32 GetTargetIndex() { return m_targetIndex; } + LegoU32 GetTranslationIndex() { return m_translationIndex; } + LegoU32 GetRotationIndex() { return m_rotationIndex; } - void SetUnknown0x18(LegoU32 p_unk0x18) { m_unk0x18 = p_unk0x18; } - void SetUnknown0x1c(LegoU32 p_unk0x1c) { m_unk0x1c = p_unk0x1c; } - void SetUnknown0x20(LegoU32 p_unk0x20) { m_unk0x20 = p_unk0x20; } + void SetTargetIndex(LegoU32 p_targetIndex) { m_targetIndex = p_targetIndex; } + void SetTranslationIndex(LegoU32 p_translationIndex) { m_translationIndex = p_translationIndex; } + void SetRotationIndex(LegoU32 p_rotationIndex) { m_rotationIndex = p_rotationIndex; } private: - LegoU16 m_unk0x00; // 0x00 - LegoTranslationKey* m_unk0x04; // 0x04 - LegoU16 m_unk0x08; // 0x08 - LegoTranslationKey* m_unk0x0c; // 0x0c - LegoU16 m_unk0x10; // 0x10 - LegoUnknownKey* m_unk0x14; // 0x14 - LegoU32 m_unk0x18; // 0x18 - LegoU32 m_unk0x1c; // 0x1c - LegoU32 m_unk0x20; // 0x20 + LegoU16 m_translationKeysCount; // 0x00 + LegoTranslationKey* m_translationKeys; // 0x04 + LegoU16 m_targetKeysCount; // 0x08 + LegoTranslationKey* m_targetKeys; // 0x0c + LegoU16 m_rotationKeysCount; // 0x10 + LegoRotationZKey* m_rotationKeys; // 0x14 + LegoU32 m_targetIndex; // 0x18 + LegoU32 m_translationIndex; // 0x1c + LegoU32 m_rotationIndex; // 0x20 }; // VTABLE: LEGO1 0x100db8d8 From eae038f6a9b13f4efdae9d83d07cd02e9cfbf963 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Tue, 22 Jul 2025 20:58:00 +0200 Subject: [PATCH 6/7] Clear unknowns in `MxVideoParamFlags` (#1648) --- ISLE/isleapp.cpp | 2 +- LEGO1/lego/legoomni/src/video/legovideomanager.cpp | 8 ++++---- LEGO1/omni/include/mxvideoparamflags.h | 8 ++++---- LEGO1/omni/src/video/mxdisplaysurface.cpp | 6 +++--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/ISLE/isleapp.cpp b/ISLE/isleapp.cpp index 3f5f485a..7793ef16 100644 --- a/ISLE/isleapp.cpp +++ b/ISLE/isleapp.cpp @@ -221,7 +221,7 @@ void IsleApp::SetupVideoFlags( m_videoParam.Flags().SetLacksLightSupport(!hasLightSupport); m_videoParam.Flags().SetF1bit7(param_7); m_videoParam.Flags().SetWideViewAngle(wideViewAngle); - m_videoParam.Flags().SetF2bit1(1); + m_videoParam.Flags().SetEnabled(TRUE); m_videoParam.SetDeviceName(deviceId); if (using8bit) { m_videoParam.Flags().Set16Bit(0); diff --git a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp index c9c79097..23e4c55d 100644 --- a/LEGO1/lego/legoomni/src/video/legovideomanager.cpp +++ b/LEGO1/lego/legoomni/src/video/legovideomanager.cpp @@ -592,14 +592,14 @@ void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable, MxBool p_scale) m_palette = m_videoParam.GetPalette()->Clone(); OverrideSkyColor(FALSE); - m_displaySurface->GetVideoParam().Flags().SetF1bit3(p_scale); + m_displaySurface->GetVideoParam().Flags().SetDoubleScaling(p_scale); m_render3d = FALSE; m_fullScreenMovie = TRUE; } else { m_displaySurface->ClearScreen(); - m_displaySurface->GetVideoParam().Flags().SetF1bit3(FALSE); + m_displaySurface->GetVideoParam().Flags().SetDoubleScaling(FALSE); // restore previous pallete RealizePalette(m_palette); @@ -624,10 +624,10 @@ void LegoVideoManager::EnableFullScreenMovie(MxBool p_enable, MxBool p_scale) } if (p_enable) { - m_displaySurface->GetVideoParam().Flags().SetF1bit3(p_scale); + m_displaySurface->GetVideoParam().Flags().SetDoubleScaling(p_scale); } else { - m_displaySurface->GetVideoParam().Flags().SetF1bit3(FALSE); + m_displaySurface->GetVideoParam().Flags().SetDoubleScaling(FALSE); } } diff --git a/LEGO1/omni/include/mxvideoparamflags.h b/LEGO1/omni/include/mxvideoparamflags.h index 21ed6921..eed37cbf 100644 --- a/LEGO1/omni/include/mxvideoparamflags.h +++ b/LEGO1/omni/include/mxvideoparamflags.h @@ -19,7 +19,7 @@ class MxVideoParamFlags { void SetBackBuffers(MxBool p_e) { m_flags1.m_bit2 = p_e; } // FUNCTION: BETA10 0x100d9250 - void SetF1bit3(MxBool p_e) { m_flags1.m_bit3 = p_e; } + void SetDoubleScaling(MxBool p_e) { m_flags1.m_bit3 = p_e; } // inlined in ISLE void Set16Bit(MxBool p_e) { m_flags1.m_bit5 = p_e; } @@ -34,7 +34,7 @@ class MxVideoParamFlags { void SetLacksLightSupport(MxBool p_e) { m_flags2.m_bit0 = p_e; } // inlined in ISLE - void SetF2bit1(MxBool p_e) { m_flags2.m_bit1 = p_e; } + void SetEnabled(MxBool p_e) { m_flags2.m_bit1 = p_e; } // FUNCTION: BETA10 0x1009e770 MxBool GetFullScreen() { return m_flags1.m_bit0; } @@ -46,7 +46,7 @@ class MxVideoParamFlags { MxBool GetBackBuffers() { return m_flags1.m_bit2; } // FUNCTION: BETA10 0x10142010 - MxBool GetF1bit3() { return m_flags1.m_bit3; } + MxBool GetDoubleScaling() { return m_flags1.m_bit3; } // FUNCTION: BETA10 0x100d8150 MxBool Get16Bit() { return m_flags1.m_bit5; } @@ -58,7 +58,7 @@ class MxVideoParamFlags { MxBool GetLacksLightSupport() { return m_flags2.m_bit0; } // FUNCTION: BETA10 0x10142050 - MxBool GetF2bit1() { return m_flags2.m_bit1; } + MxBool GetEnabled() { return m_flags2.m_bit1; } private: FlagBitfield m_flags1; diff --git a/LEGO1/omni/src/video/mxdisplaysurface.cpp b/LEGO1/omni/src/video/mxdisplaysurface.cpp index ff46b5f4..6b6f4ce5 100644 --- a/LEGO1/omni/src/video/mxdisplaysurface.cpp +++ b/LEGO1/omni/src/video/mxdisplaysurface.cpp @@ -373,7 +373,7 @@ void MxDisplaySurface::VTable0x28( MxU8* data = p_bitmap->GetStart(p_left, p_top); - if (m_videoParam.Flags().GetF1bit3()) { + if (m_videoParam.Flags().GetDoubleScaling()) { p_bottom *= 2; p_right *= 2; @@ -825,7 +825,7 @@ void MxDisplaySurface::VTable0x34(MxU8* p_pixels, MxS32 p_bpp, MxS32 p_width, Mx // FUNCTION: LEGO1 0x100bba50 void MxDisplaySurface::Display(MxS32 p_left, MxS32 p_top, MxS32 p_left2, MxS32 p_top2, MxS32 p_width, MxS32 p_height) { - if (m_videoParam.Flags().GetF2bit1()) { + if (m_videoParam.Flags().GetEnabled()) { if (m_videoParam.Flags().GetFlipSurfaces()) { if (g_unk0x1010215c < 2) { g_unk0x1010215c++; @@ -1171,7 +1171,7 @@ void MxDisplaySurface::VTable0x24( MxU8* data = p_bitmap->GetStart(p_left, p_top); - if (m_videoParam.Flags().GetF1bit3()) { + if (m_videoParam.Flags().GetDoubleScaling()) { p_bottom *= 2; p_right *= 2; From 2451b041f6e9ad7f498bd8f5adb76da281e940d4 Mon Sep 17 00:00:00 2001 From: Fabian Neundorf Date: Wed, 23 Jul 2025 19:14:10 +0200 Subject: [PATCH 7/7] Clear remaining unknown in `Ambulance` (#1650) --- LEGO1/lego/legoomni/include/ambulance.h | 2 +- LEGO1/lego/legoomni/src/actors/ambulance.cpp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/LEGO1/lego/legoomni/include/ambulance.h b/LEGO1/lego/legoomni/include/ambulance.h index cb6a396a..4f0a0623 100644 --- a/LEGO1/lego/legoomni/include/ambulance.h +++ b/LEGO1/lego/legoomni/include/ambulance.h @@ -211,7 +211,7 @@ class Ambulance : public IslePathActor { MxS16 m_atPoliceTask; // 0x16c MxS16 m_atBeachTask; // 0x16e MxS16 m_taskState; // 0x170 - MxS16 m_unk0x172; // 0x172 + MxS16 m_enableRandomAudio; // 0x172 IsleScript::Script m_lastAction; // 0x174 IsleScript::Script m_lastAnimation; // 0x178 MxFloat m_fuel; // 0x17c diff --git a/LEGO1/lego/legoomni/src/actors/ambulance.cpp b/LEGO1/lego/legoomni/src/actors/ambulance.cpp index 0bc2a9e6..7049009f 100644 --- a/LEGO1/lego/legoomni/src/actors/ambulance.cpp +++ b/LEGO1/lego/legoomni/src/actors/ambulance.cpp @@ -41,7 +41,7 @@ Ambulance::Ambulance() m_atBeachTask = 0; m_taskState = Ambulance::e_none; m_lastAction = IsleScript::c_noneIsle; - m_unk0x172 = 0; + m_enableRandomAudio = 0; m_lastAnimation = IsleScript::c_noneIsle; m_fuel = 1.0; } @@ -173,7 +173,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param) m_state->m_state = AmbulanceMissionState::e_enteredAmbulance; CurrentWorld()->PlaceActor(UserActor()); HandleClick(); - m_unk0x172 = 0; + m_enableRandomAudio = 0; TickleManager()->RegisterClient(this, 40000); } else if (objectId == IsleScript::c_hpz047pe_RunAnim || objectId == IsleScript::c_hpz048pe_RunAnim || objectId == IsleScript::c_hpz049bd_RunAnim || objectId == IsleScript::c_hpz053pa_RunAnim) { @@ -198,7 +198,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param) CurrentWorld()->PlaceActor(UserActor()); HandleClick(); SpawnPlayer(LegoGameState::e_pizzeriaExterior, TRUE, 0); - m_unk0x172 = 0; + m_enableRandomAudio = 0; TickleManager()->RegisterClient(this, 40000); if (m_atPoliceTask != 0) { @@ -222,7 +222,7 @@ MxLong Ambulance::HandleEndAction(MxEndActionNotificationParam& p_param) CurrentWorld()->PlaceActor(UserActor()); HandleClick(); SpawnPlayer(LegoGameState::e_policeExited, TRUE, 0); - m_unk0x172 = 0; + m_enableRandomAudio = 0; TickleManager()->RegisterClient(this, 40000); if (m_atBeachTask != 0) { @@ -513,8 +513,8 @@ void Ambulance::ActivateSceneActions() // FUNCTION: BETA10 0x100237df MxResult Ambulance::Tickle() { - if (m_unk0x172 == 0) { - m_unk0x172 = 1; + if (m_enableRandomAudio == 0) { + m_enableRandomAudio = 1; } else if (m_lastAction == IsleScript::c_noneIsle) { IsleScript::Script objectId;