From 5b7624c32a9b542c3be97656a15ccf7ac8b0cd3b Mon Sep 17 00:00:00 2001 From: Misha <106913236+MishaProductions@users.noreply.github.com> Date: Mon, 15 Jan 2024 14:37:50 -0500 Subject: [PATCH] implement part of LegoAnimPresenter (#441) * push changes * implement + match a few functions * Update legoanimpresenter.h * reorder * Update legoanimpresenter.cpp * Update legoanimpresenter.cpp * Update legoanimpresenter.cpp * fix build * Allow isle to start * Match LegoAnimPresenter::VTable0x88 * Fixes * use EndAction in StartingTickle stub * Match StreamingTickle * Fix override * Comment about missing vtable functions --------- Co-authored-by: Christian Semmler --- .../lego/legoomni/include/legoanimpresenter.h | 79 ++++++ .../legoomni/src/video/legoanimpresenter.cpp | 234 +++++++++++++++++- LEGO1/omni/include/mxatomid.h | 3 +- 3 files changed, 310 insertions(+), 6 deletions(-) diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 3d43dd9f..5ff2f0c3 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -1,9 +1,15 @@ #ifndef LEGOANIMPRESENTER_H #define LEGOANIMPRESENTER_H +#include "mxgeometry/mxgeometry3d.h" #include "mxvideopresenter.h" +class LegoWorld; +class LegoMemoryStream; +class LegoAnimClass; + // VTABLE: LEGO1 0x100d90c8 +// SIZE 0xc0 class LegoAnimPresenter : public MxVideoPresenter { public: LegoAnimPresenter(); @@ -22,11 +28,84 @@ class LegoAnimPresenter : public MxVideoPresenter { return !strcmp(p_name, LegoAnimPresenter::ClassName()) || MxVideoPresenter::IsA(p_name); } + virtual void ReadyTickle() override; // vtable+0x18 + virtual void StartingTickle() override; // vtable+0x1c + virtual void StreamingTickle() override; // vtable+0x20 + virtual void ParseExtra() override; // vtable+0x30 + virtual void Destroy() override; // vtable+0x38 + virtual MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c + virtual void EndAction() override; // vtable+0x40 + virtual void PutFrame() override; // vtable+0x6c + virtual MxResult VTable0x88(MxStreamChunk* p_chunk); // vtable+0x88 + + // 6 more virtual functions here + private: void Init(); + void Destroy(MxBool p_fromDestructor); + + LegoAnimClass* m_unk0x64; // 0x64 + undefined4 m_unk0x68; // 0x68 + undefined4 m_unk0x6c; // 0x6c + undefined4 m_unk0x70; // 0x70 + undefined4 m_unk0x74; // 0x74 + undefined4 m_unk0x78; // 0x78 + undefined4 m_unk0x7c; // 0x7c + LegoWorld* m_currentWorld; // 0x80 + MxAtomId m_animAtom; // 0x84 + undefined4 m_unk0x88; // 0x88 + undefined4 m_unk0x8c; // 0x8c + undefined4 m_unk0x90; // 0x90 + undefined m_unk0x94; // 0x94 + undefined m_unk0x95; // 0x95 + undefined m_unk0x96; // 0x96 + undefined m_unk0x97; // 0x97 + undefined4 m_unk0x98; // 0x98 + MxS16 m_unk0x9c; // 0x9c + undefined4 m_unk0xa0; // 0xa0 + undefined4 m_unk0xa4; // 0xa4 + Mx3DPointFloat m_unk0xa8; // 0xa8 + undefined4 m_unk0xbc; // 0xbc }; // SYNTHETIC: LEGO1 0x10068650 // LegoAnimPresenter::`scalar deleting destructor' +// VTABLE: LEGO1 0x100db768 +// SIZE 0x08 +class LegoAnimClassBase { +public: + LegoAnimClassBase(); + virtual ~LegoAnimClassBase(); + + virtual void VTable0x4(); // vtable+0x04 + virtual void VTable0x8(); // vtable+0x08 + virtual void VTable0xc(); // vtable+0x0c + + undefined4 m_unk0x4; // 0x04 +}; + +// SYNTHETIC: LEGO1 0x10099de0 +// LegoAnimClassBase::`scalar deleting destructor' + +// VTABLE: LEGO1 0x100db8d8 +// SIZE 0x18 +class LegoAnimClass : public LegoAnimClassBase { +public: + LegoAnimClass(); + virtual ~LegoAnimClass() override; + + virtual void VTable0x8() override; // vtable+0x08 + virtual void VTable0xc() override; // vtable+0x0c + virtual MxResult VTable0x10(LegoMemoryStream* p_stream, MxS32); // vtable+0x10 + + MxLong m_unk0x8; // 0x08 + undefined4 m_unk0xc; // 0x0c + undefined4 m_unk0x10; // 0x10 + undefined4 m_unk0x14; // 0x14 +}; + +// SYNTHETIC: LEGO1 0x100a0ba0 +// LegoAnimClass::`scalar deleting destructor' + #endif // LEGOANIMPRESENTER_H diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index 3c0883d6..38d23b52 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -1,19 +1,243 @@ #include "legoanimpresenter.h" -// STUB: LEGO1 0x10068420 +#include "legoomni.h" +#include "legostream.h" +#include "legoworld.h" +#include "mxcompositepresenter.h" +#include "mxdsanim.h" +#include "mxstreamchunk.h" + +DECOMP_SIZE_ASSERT(LegoAnimPresenter, 0xc0) +DECOMP_SIZE_ASSERT(LegoAnimClassBase, 0x08) +DECOMP_SIZE_ASSERT(LegoAnimClass, 0x18) + +// FUNCTION: LEGO1 0x10068420 LegoAnimPresenter::LegoAnimPresenter() { - // TODO + Init(); } -// STUB: LEGO1 0x10068670 +// FUNCTION: LEGO1 0x10068670 LegoAnimPresenter::~LegoAnimPresenter() { - // TODO + Destroy(TRUE); } -// STUB: LEGO1 0x100686f0 +// FUNCTION: LEGO1 0x100686f0 void LegoAnimPresenter::Init() +{ + m_unk0x64 = NULL; + m_unk0x68 = 0; + m_unk0x6c = 0; + m_unk0x74 = 0; + m_unk0x70 = 0; + m_unk0x78 = 0; + m_unk0x7c = 0; + m_unk0xa8.Clear(); + m_unk0xa4 = 0; + m_currentWorld = NULL; + m_unk0x95 = 0; + m_unk0x88 = -1; + m_unk0x98 = 0; + m_animAtom.Clear(); + m_unk0x9c = 0; + m_unk0x8c = 0; + m_unk0x90 = 0; + m_unk0x94 = 0; + m_unk0x96 = 1; + m_unk0xa0 = 0; +} + +// STUB: LEGO1 0x10068770 +void LegoAnimPresenter::Destroy(MxBool p_fromDestructor) +{ + // TODO + MxVideoPresenter::Destroy(p_fromDestructor); +} + +// FUNCTION: LEGO1 0x10068fb0 +MxResult LegoAnimPresenter::VTable0x88(MxStreamChunk* p_chunk) +{ + MxResult result = FAILURE; + LegoMemoryStream stream((char*) p_chunk->GetData()); + + MxS32 magicSig; + MxS32 val2 = 0; + MxS32 val3; + + if (stream.Read(&magicSig, sizeof(MxS32)) == SUCCESS && magicSig == 0x11) { + if (stream.Read(&m_unk0xa4, sizeof(MxU32)) == SUCCESS) { + if (stream.Read(&m_unk0xa8[0], sizeof(float)) == SUCCESS) { + if (stream.Read(&m_unk0xa8[1], sizeof(float)) == SUCCESS) { + if (stream.Read(&m_unk0xa8[2], sizeof(float)) == SUCCESS) { + if (stream.Read(&val2, sizeof(MxS32)) == SUCCESS) { + if (stream.Read(&val3, sizeof(MxS32)) == SUCCESS) { + m_unk0x64 = new LegoAnimClass(); + if (m_unk0x64) { + if (m_unk0x64->VTable0x10(&stream, val2) == SUCCESS) { + result = SUCCESS; + } + } + } + } + } + } + } + } + } + + if (result != SUCCESS) { + delete m_unk0x64; + Init(); + } + + return result; +} + +// STUB: LEGO1 0x1006ad30 +void LegoAnimPresenter::PutFrame() +{ + // TODO +} + +// FUNCTION: LEGO1 0x1006b550 +void LegoAnimPresenter::ReadyTickle() +{ + m_currentWorld = GetCurrentWorld(); + + if (m_currentWorld) { + MxStreamChunk* chunk = m_subscriber->CurrentChunk(); + + if (chunk && chunk->GetTime() + m_action->GetStartTime() <= m_action->GetElapsedTime()) { + chunk = m_subscriber->NextChunk(); + MxResult result = VTable0x88(chunk); + m_subscriber->DestroyChunk(chunk); + + if (result == SUCCESS) { + ProgressTickleState(TickleState_Starting); + ParseExtra(); + } + else { + EndAction(); + } + } + } +} + +// STUB: LEGO1 0x1006b5e0 +void LegoAnimPresenter::StartingTickle() +{ + // TODO + ProgressTickleState(TickleState_Streaming); + EndAction(); // Allow game to start +} + +// FUNCTION: LEGO1 0x1006b840 +void LegoAnimPresenter::StreamingTickle() +{ + if (m_subscriber->CurrentChunk()) { + MxStreamChunk* chunk = m_subscriber->NextChunk(); + m_subscriber->DestroyChunk(chunk); + } + + if (m_unk0x95 == 0) { + if (m_unk0x64->m_unk0x8 + m_action->GetStartTime() < m_action->GetElapsedTime()) { + m_unk0x95 = 1; + } + } + else { + ProgressTickleState(TickleState_Done); + if (m_compositePresenter) { + if (m_compositePresenter->IsA("LegoAnimMMPresenter")) { + m_compositePresenter->VTable0x60(this); + } + } + } +} + +// FUNCTION: LEGO1 0x1006b8e0 +void LegoAnimPresenter::Destroy() +{ + Destroy(FALSE); +} + +// STUB: LEGO1 0x1006bac0 +void LegoAnimPresenter::ParseExtra() +{ + // TODO +} + +// FUNCTION: LEGO1 0x1006c620 +MxResult LegoAnimPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) +{ + MxResult result = MxVideoPresenter::StartAction(p_controller, p_action); + m_displayZ = 0; + return result; +} + +// STUB: LEGO1 0x1006c640 +void LegoAnimPresenter::EndAction() +{ + // TODO + MxVideoPresenter::EndAction(); +} + +// FUNCTION: LEGO1 0x10099dd0 +LegoAnimClassBase::LegoAnimClassBase() +{ + m_unk0x4 = 0; +} + +// STUB: LEGO1 0x10099e00 +LegoAnimClassBase::~LegoAnimClassBase() +{ + // TODO +} + +// STUB: LEGO1 0x10099e20 +void LegoAnimClassBase::VTable0x4() +{ +} + +// STUB: LEGO1 0x10099e40 +void LegoAnimClassBase::VTable0x8() +{ +} + +// STUB: LEGO1 0x10099f70 +void LegoAnimClassBase::VTable0xc() +{ +} + +// FUNCTION: LEGO1 0x100a0b30 +LegoAnimClass::LegoAnimClass() +{ + m_unk0x8 = 0; + m_unk0xc = 0; + m_unk0x10 = 0; + m_unk0x14 = 0; +} + +// STUB: LEGO1 0x100a0bc0 +LegoAnimClass::~LegoAnimClass() +{ + // TODO +} + +// STUB: LEGO1 0x100a0c70 +MxResult LegoAnimClass::VTable0x10(LegoMemoryStream* p_stream, MxS32) +{ + return SUCCESS; +} + +// STUB: LEGO1 0x100a0e30 +void LegoAnimClass::VTable0x8() +{ + // TODO +} + +// STUB: LEGO1 0x100a1040 +void LegoAnimClass::VTable0xc() { // TODO } diff --git a/LEGO1/omni/include/mxatomid.h b/LEGO1/omni/include/mxatomid.h index 3abe6479..0573cc84 100644 --- a/LEGO1/omni/include/mxatomid.h +++ b/LEGO1/omni/include/mxatomid.h @@ -11,6 +11,7 @@ enum LookupMode { LookupMode_LowerCase2 = 3 }; +// SIZE 0x04 class MxAtomId { public: __declspec(dllexport) MxAtomId(const char*, LookupMode); @@ -30,7 +31,7 @@ class MxAtomId { MxAtomIdCounter* GetCounter(const char*, LookupMode); void Destroy(); - const char* m_internal; + const char* m_internal; // 0x00 }; #endif // MXATOMID_H