diff --git a/LEGO1/define.cpp b/LEGO1/define.cpp index 31f1e521..acd811a8 100644 --- a/LEGO1/define.cpp +++ b/LEGO1/define.cpp @@ -19,6 +19,9 @@ const char* g_strWORLD = "WORLD"; // GLOBAL: LEGO1 0x10101f20 const char* g_strSOUND = "SOUND"; +// GLOBAL: LEGO1 0x10101f58 +const char* g_strOBJECT = "OBJECT"; + // GLOBAL: LEGO1 0x10102040 const char* g_strACTION = "ACTION"; diff --git a/LEGO1/define.h b/LEGO1/define.h index 82e93375..45a536a9 100644 --- a/LEGO1/define.h +++ b/LEGO1/define.h @@ -7,6 +7,7 @@ extern MxU32 g_mxcoreCount[101]; extern const char* g_parseExtraTokens; extern const char* g_strWORLD; extern const char* g_strSOUND; +extern const char* g_strOBJECT; extern const char* g_strACTION; extern const char* g_strVISIBILITY; diff --git a/LEGO1/legoentity.cpp b/LEGO1/legoentity.cpp index 26f9daab..0f813029 100644 --- a/LEGO1/legoentity.cpp +++ b/LEGO1/legoentity.cpp @@ -76,6 +76,12 @@ void LegoEntity::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) // TODO } +// STUB: LEGO1 0x100109b0 +void LegoEntity::SetLocation(Vector3Data& p_location, Vector3Data& p_direction, Vector3Data& p_up, MxBool) +{ + // TODO +} + // STUB: LEGO1 0x10010c30 void LegoEntity::FUN_10010c30() { diff --git a/LEGO1/legoentity.h b/LEGO1/legoentity.h index cdee29c3..4d4c19b6 100644 --- a/LEGO1/legoentity.h +++ b/LEGO1/legoentity.h @@ -49,6 +49,7 @@ class LegoEntity : public MxEntity { virtual void VTable0x4c(); // vtable+0x4c void FUN_10010c30(); + void SetLocation(Vector3Data& p_location, Vector3Data& p_direction, Vector3Data& p_up, MxBool); protected: void Init(); diff --git a/LEGO1/legoentitypresenter.cpp b/LEGO1/legoentitypresenter.cpp index dc1a44eb..ea484cf1 100644 --- a/LEGO1/legoentitypresenter.cpp +++ b/LEGO1/legoentitypresenter.cpp @@ -1,5 +1,6 @@ #include "legoentitypresenter.h" +#include "islepathactor.h" #include "legoomni.h" #include "legovideomanager.h" @@ -14,7 +15,7 @@ LegoEntityPresenter::LegoEntityPresenter() // FUNCTION: LEGO1 0x100535c0 void LegoEntityPresenter::Init() { - m_unk0x4c = 0; + m_objectBackend = 0; } // FUNCTION: LEGO1 0x100535d0 @@ -24,9 +25,9 @@ LegoEntityPresenter::~LegoEntityPresenter() } // FUNCTION: LEGO1 0x10053630 -undefined4 LegoEntityPresenter::VTable0x6c(undefined4 p_unk0x4c) +undefined4 LegoEntityPresenter::SetBackend(LegoEntity* p_backend) { - m_unk0x4c = p_unk0x4c; + m_objectBackend = p_backend; return 0; } @@ -45,3 +46,52 @@ void LegoEntityPresenter::Destroy() { Destroy(FALSE); } + +// FUNCTION: LEGO1 0x10053680 +MxResult LegoEntityPresenter::StartAction(MxStreamController* p_controller, MxDSAction* p_action) +{ + MxResult result = MxCompositePresenter::StartAction(p_controller, p_action); + + if (VideoManager()) { + VideoManager()->AddPresenter(*this); + } + + return result; +} + +// FUNCTION: LEGO1 0x100536c0 +void LegoEntityPresenter::ReadyTickle() +{ + if (GetCurrentWorld()) { + m_objectBackend = (LegoEntity*) MxPresenter::CreateEntityBackend("LegoEntity"); + if (m_objectBackend) { + m_objectBackend->Create(*m_action); + m_objectBackend->SetLocation(m_action->GetLocation(), m_action->GetDirection(), m_action->GetUp(), TRUE); + ParseExtra(); + } + m_previousTickleStates |= 1 << (unsigned char) m_currentTickleState; + m_currentTickleState = TickleState_Starting; + } +} + +// FUNCTION: LEGO1 0x10053720 +void LegoEntityPresenter::RepeatingTickle() +{ + if (m_list.empty()) { + EndAction(); + } +} + +// FUNCTION: LEGO1 0x10053750 +void LegoEntityPresenter::ParseExtra() +{ + char data[512]; + MxU16 len = m_action->GetExtraLength(); + if (len) { + memcpy(data, m_action->GetExtraData(), len); + data[len] = 0; + + len &= MAXWORD; + m_objectBackend->ParseAction(data); + } +} diff --git a/LEGO1/legoentitypresenter.h b/LEGO1/legoentitypresenter.h index 9e072498..847a6b8f 100644 --- a/LEGO1/legoentitypresenter.h +++ b/LEGO1/legoentitypresenter.h @@ -3,6 +3,8 @@ #include "mxcompositepresenter.h" +class LegoEntity; + // VTABLE: LEGO1 0x100d8398 // SIZE 0x50 class LegoEntityPresenter : public MxCompositePresenter { @@ -23,14 +25,18 @@ class LegoEntityPresenter : public MxCompositePresenter { return !strcmp(p_name, LegoEntityPresenter::ClassName()) || MxCompositePresenter::IsA(p_name); } - virtual void Destroy() override; // vtable+0x38 - virtual void Init(); // vtable+0x68 - virtual undefined4 VTable0x6c(undefined4 p_unk0x4c); // vtable+0x6c + virtual void ReadyTickle() override; // vtable+0x18 + virtual void RepeatingTickle(); // vtable+0x24 + virtual void ParseExtra(); // vtable+0x30 + virtual void Destroy() override; // vtable+0x38 + virtual MxResult StartAction(MxStreamController* p_controller, MxDSAction* p_action) override; // vtable+0x3c + virtual void Init(); // vtable+0x68 + virtual undefined4 SetBackend(LegoEntity* p_unk0x4c); // vtable+0x6c private: void Destroy(MxBool p_fromDestructor); - undefined4 m_unk0x4c; + LegoEntity* m_objectBackend; // 0x4c }; #endif // LEGOENTITYPRESENTER_H diff --git a/LEGO1/mxdsaction.h b/LEGO1/mxdsaction.h index eb70b18f..4898eb91 100644 --- a/LEGO1/mxdsaction.h +++ b/LEGO1/mxdsaction.h @@ -63,7 +63,9 @@ class MxDSAction : public MxDSObject { inline MxLong GetStartTime() const { return m_startTime; } inline MxS32 GetLoopCount() { return m_loopCount; } inline void SetLoopCount(MxS32 p_loopCount) { m_loopCount = p_loopCount; } - inline const Vector3Data& GetLocation() const { return m_location; } + inline Vector3Data& GetLocation() { return m_location; } + inline Vector3Data& GetDirection() { return m_direction; } + inline Vector3Data& GetUp() { return m_up; } inline MxCore* GetUnknown84() { return m_unk0x84; } inline void SetUnknown84(MxCore* p_unk0x84) { m_unk0x84 = p_unk0x84; } inline MxCore* GetOrigin() { return m_origin; } diff --git a/LEGO1/mxpresenter.cpp b/LEGO1/mxpresenter.cpp index 31279513..b2404439 100644 --- a/LEGO1/mxpresenter.cpp +++ b/LEGO1/mxpresenter.cpp @@ -2,12 +2,14 @@ #include "decomp.h" #include "define.h" +#include "legoobjectfactory.h" #include "legoomni.h" #include "mxactionnotificationparam.h" #include "mxautolocker.h" #include "mxcompositepresenter.h" #include "mxdsanim.h" #include "mxdssound.h" +#include "mxentity.h" #include "mxnotificationmanager.h" #include "mxparam.h" #include "mxstreamer.h" @@ -304,6 +306,27 @@ const char* PresenterNameDispatch(const MxDSAction& p_action) return name; } +// FUNCTION: LEGO1 0x100b5410 +MxEntity* MxPresenter::CreateEntityBackend(const char* p_name) +{ + char buffer[512]; + char buffer2[512]; + strcpy(buffer, p_name); + + MxU16 extraLen = m_action->GetExtraLength(); + + buffer[0] = extraLen; + buffer[1] = extraLen >> 8; + if (extraLen) { + extraLen &= MAXWORD; + memcpy(buffer2 + 2, m_action->GetExtraData(), extraLen); + buffer2[extraLen + 2] = 0; + KeyValueStringParse(buffer, g_strOBJECT, buffer2 + 2); + } + + return (MxEntity*) ObjectFactory()->Create(buffer); +} + // FUNCTION: LEGO1 0x100b54c0 MxBool MxPresenter::IsEnabled() { diff --git a/LEGO1/mxpresenter.h b/LEGO1/mxpresenter.h index 160329c1..e0e91fe6 100644 --- a/LEGO1/mxpresenter.h +++ b/LEGO1/mxpresenter.h @@ -10,6 +10,7 @@ class MxCompositePresenter; class MxStreamController; +class MxEntity; // VTABLE: LEGO1 0x100d4d38 // SIZE 0x40 @@ -65,6 +66,7 @@ class MxPresenter : public MxCore { virtual MxBool IsHit(MxS32 p_x, MxS32 p_y); // vtable+0x50 __declspec(dllexport) virtual void Enable(MxBool p_enable); // vtable+0x54 + MxEntity* CreateEntityBackend(const char* p_name); MxBool IsEnabled(); inline MxS32 GetCurrentTickleState() const { return this->m_currentTickleState; }