diff --git a/LEGO1/lego/legoomni/include/legoentity.h b/LEGO1/lego/legoomni/include/legoentity.h index 68a246b5..dc3864fb 100644 --- a/LEGO1/lego/legoomni/include/legoentity.h +++ b/LEGO1/lego/legoomni/include/legoentity.h @@ -57,7 +57,7 @@ class LegoEntity : public MxEntity { void FUN_10010c30(); void FUN_100114e0(MxU8 p_unk0x59); - void SetLocation(Mx3DPointFloat& p_location, Mx3DPointFloat& p_direction, Mx3DPointFloat& p_up, MxBool); + void SetLocation(Vector3& p_location, Vector3& p_direction, Vector3& p_up, MxBool); inline LegoROI* GetROI() { return m_roi; } inline MxU8 GetFlags() { return m_flags; } diff --git a/LEGO1/lego/legoomni/include/legoentitypresenter.h b/LEGO1/lego/legoomni/include/legoentitypresenter.h index dec78dae..cf0bd60a 100644 --- a/LEGO1/lego/legoomni/include/legoentitypresenter.h +++ b/LEGO1/lego/legoomni/include/legoentitypresenter.h @@ -33,9 +33,10 @@ class LegoEntityPresenter : public MxCompositePresenter { virtual void Init(); // vtable+0x68 virtual undefined4 SetEntity(LegoEntity* p_entity); // vtable+0x6c - void SetEntityLocation(Mx3DPointFloat& p_location, Mx3DPointFloat& p_direction, Mx3DPointFloat& p_up); + void SetEntityLocation(Vector3& p_location, Vector3& p_direction, Vector3& p_up); inline LegoEntity* GetEntity() { return m_entity; } + inline void SetInternalEntity(LegoEntity* p_entity) { m_entity = p_entity; } // SYNTHETIC: LEGO1 0x100535a0 // LegoEntityPresenter::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/include/legomodelpresenter.h b/LEGO1/lego/legoomni/include/legomodelpresenter.h index b85c2c26..b8954253 100644 --- a/LEGO1/lego/legoomni/include/legomodelpresenter.h +++ b/LEGO1/lego/legoomni/include/legomodelpresenter.h @@ -4,6 +4,9 @@ #include "mxvideopresenter.h" class LegoROI; +class LegoWorld; +class LegoEntity; +class MxDSChunk; // VTABLE: LEGO1 0x100d4e50 // SIZE 0x6c (discovered through inline constructor at 0x10009ae6) @@ -31,6 +34,14 @@ class LegoModelPresenter : public MxVideoPresenter { void ParseExtra() override; // vtable+0x30 void Destroy() override; // vtable+0x38 + void FUN_1007ff70(MxDSChunk p_chunk, LegoEntity* p_entity, undefined4 p_modelUnknown0x34, LegoWorld* p_world); + + inline void Clear() + { + m_roi = NULL; + m_addedToView = FALSE; + } + // SYNTHETIC: LEGO1 0x1000cdd0 // LegoModelPresenter::`scalar deleting destructor' diff --git a/LEGO1/lego/legoomni/src/entity/legoentity.cpp b/LEGO1/lego/legoomni/src/entity/legoentity.cpp index 9ac45046..0ad52887 100644 --- a/LEGO1/lego/legoomni/src/entity/legoentity.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoentity.cpp @@ -83,7 +83,7 @@ void LegoEntity::SetROI(LegoROI* p_roi, MxBool p_bool1, MxBool p_bool2) } // STUB: LEGO1 0x100109b0 -void LegoEntity::SetLocation(Mx3DPointFloat& p_location, Mx3DPointFloat& p_direction, Mx3DPointFloat& p_up, MxBool) +void LegoEntity::SetLocation(Vector3& p_location, Vector3& p_direction, Vector3& p_up, MxBool) { // TODO } diff --git a/LEGO1/lego/legoomni/src/entity/legoentitypresenter.cpp b/LEGO1/lego/legoomni/src/entity/legoentitypresenter.cpp index ca65b767..d6b924fe 100644 --- a/LEGO1/lego/legoomni/src/entity/legoentitypresenter.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoentitypresenter.cpp @@ -82,11 +82,7 @@ void LegoEntityPresenter::RepeatingTickle() } // FUNCTION: LEGO1 0x10053730 -void LegoEntityPresenter::SetEntityLocation( - Mx3DPointFloat& p_location, - Mx3DPointFloat& p_direction, - Mx3DPointFloat& p_up -) +void LegoEntityPresenter::SetEntityLocation(Vector3& p_location, Vector3& p_direction, Vector3& p_up) { if (m_entity) { m_entity->SetLocation(p_location, p_direction, p_up, TRUE); diff --git a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp index 0b96ed04..7fe70171 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworldpresenter.cpp @@ -1,9 +1,11 @@ #include "legoworldpresenter.h" #include "define.h" +#include "legoactorpresenter.h" #include "legoanimationmanager.h" #include "legobuildingmanager.h" #include "legoentity.h" +#include "legomodelpresenter.h" #include "legoomni.h" #include "legopartpresenter.h" #include "legoplantmanager.h" @@ -314,17 +316,85 @@ MxResult LegoWorldPresenter::LoadWorld(char* p_worldName, LegoWorld* p_world) return SUCCESS; } -// STUB: LEGO1 0x10067360 +// FUNCTION: LEGO1 0x10067360 MxResult LegoWorldPresenter::FUN_10067360(ModelDbPart& p_part, FILE* p_wdbFile) { - // TODO - return SUCCESS; + MxResult result; + MxU8* buffer = new MxU8[p_part.m_partDataLength]; + fseek(p_wdbFile, p_part.m_partDataOffset, 0); + if (fread(buffer, p_part.m_partDataLength, 1, p_wdbFile) != 1) { + return FAILURE; + } + + MxDSChunk chunk; + chunk.SetLength(p_part.m_partDataLength); + chunk.SetData(buffer); + + LegoPartPresenter part; + result = part.ParsePart(chunk); + if (result == SUCCESS) { + part.FUN_1007df20(); + } + + delete buffer; + return result; } -// STUB: LEGO1 0x100674b0 +// FUNCTION: LEGO1 0x100674b0 MxResult LegoWorldPresenter::FUN_100674b0(ModelDbModel& p_model, FILE* p_wdbFile, LegoWorld* p_world) { - // TODO + MxU8* buffer = new MxU8[p_model.m_unk0x04]; + fseek(p_wdbFile, p_model.m_unk0x08, 0); + if (fread(buffer, p_model.m_unk0x04, 1, p_wdbFile) != 1) { + return FAILURE; + } + + MxDSChunk chunk; + chunk.SetLength(p_model.m_unk0x04); + chunk.SetData(buffer); + + MxDSAction action; + action.SetLocation(Vector3(p_model.m_locatation)); + action.SetDirection(Vector3(p_model.m_direction)); + Vector3 up = Vector3(Vector3(p_model.m_direction)); + action.SetUp(up); + + action.SetObjectId(m_unk0x50); + m_unk0x50++; + action.SetAtomId(MxAtomId()); + + LegoEntity* createdEntity; + + if (strcmp(p_model.m_presenterName, "LegoActorPresenter") == 0) { + LegoActorPresenter actor; + LegoEntity* entity = (LegoEntity*) actor.CreateEntity("LegoActor"); + actor.SetInternalEntity(entity); + createdEntity = entity; + actor.SetEntityLocation(Vector3(), Vector3(), Vector3()); + entity->Create(action); + } + else if (strcmp(p_model.m_presenterName, "LegoEntityPresenter") == 0) { + LegoActorPresenter actor; + LegoEntity* entity = (LegoEntity*) actor.CreateEntity("LegoEntity"); + actor.SetInternalEntity(entity); + createdEntity = entity; + actor.SetEntityLocation(Vector3(), Vector3(), Vector3()); + entity->Create(action); + } + + LegoModelPresenter modelPresenter; + modelPresenter.Clear(); + + if (createdEntity != NULL) { + action.SetLocation(Mx3DPointFloat(0.0, 0.0, 0.0)); + action.SetUp(Mx3DPointFloat(0.0, 0.0, 1.0)); + action.SetDirection(Mx3DPointFloat(0.0, 1.0, 0.0)); + } + + modelPresenter.SetAction(&action); + modelPresenter.FUN_1007ff70(chunk, createdEntity, p_model.m_unk0x34, p_world); + delete buffer; + return SUCCESS; } diff --git a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp index aa43528a..a9e0111d 100644 --- a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp @@ -202,6 +202,16 @@ MxResult LegoModelPresenter::CreateROI(MxStreamChunk* p_chunk) return result; } +// STUB: LEGO1 0x1007ff70 +void LegoModelPresenter::FUN_1007ff70( + MxDSChunk p_chunk, + LegoEntity* p_entity, + undefined4 p_modelUnknown0x34, + LegoWorld* p_world +) +{ +} + // FUNCTION: LEGO1 0x10080050 void LegoModelPresenter::ReadyTickle() { diff --git a/LEGO1/modeldb/modeldb.cpp b/LEGO1/modeldb/modeldb.cpp index 57980ec8..13a25ba4 100644 --- a/LEGO1/modeldb/modeldb.cpp +++ b/LEGO1/modeldb/modeldb.cpp @@ -35,13 +35,13 @@ MxResult ModelDbModel::Read(FILE* p_file) return FAILURE; } - if (fread(&m_unk0x10, sizeof(*m_unk0x10), 3, p_file) != 3) { + if (fread(&m_locatation, sizeof(*m_locatation), 3, p_file) != 3) { return FAILURE; } - if (fread(&m_unk0x1c, sizeof(*m_unk0x1c), 3, p_file) != 3) { + if (fread(&m_direction, sizeof(*m_direction), 3, p_file) != 3) { return FAILURE; } - if (fread(&m_unk0x28, sizeof(*m_unk0x28), 3, p_file) != 3) { + if (fread(&m_up, sizeof(*m_up), 3, p_file) != 3) { return FAILURE; } @@ -65,11 +65,11 @@ MxResult ModelDbPart::Read(FILE* p_file) m_roiName = buff; - if (fread(&m_unk0x10, sizeof(m_unk0x10), 1, p_file) != 1) { + if (fread(&m_partDataLength, sizeof(m_partDataLength), 1, p_file) != 1) { return FAILURE; } - return fread(&m_unk0x14, sizeof(m_unk0x14), 1, p_file) == 1 ? SUCCESS : FAILURE; + return fread(&m_partDataOffset, sizeof(m_partDataOffset), 1, p_file) == 1 ? SUCCESS : FAILURE; } // FUNCTION: LEGO1 0x10027910 diff --git a/LEGO1/modeldb/modeldb.h b/LEGO1/modeldb/modeldb.h index ebebae17..27980cea 100644 --- a/LEGO1/modeldb/modeldb.h +++ b/LEGO1/modeldb/modeldb.h @@ -12,9 +12,9 @@ struct ModelDbPart { MxResult Read(FILE* p_file); - MxString m_roiName; // 0x00 - undefined4 m_unk0x10; // 0x10 - undefined4 m_unk0x14; // 0x14 + MxString m_roiName; // 0x00 + undefined4 m_partDataLength; // 0x10 + undefined4 m_partDataOffset; // 0x14 }; // VTABLE: LEGO1 0x100d6888 @@ -35,8 +35,8 @@ class ModelDbPartList : public MxList { MxS32 compare = strcmpi(p_a->m_roiName.GetData(), p_b->m_roiName.GetData()); if (compare == 0) { - p_b->m_unk0x10 = p_a->m_unk0x10; - p_b->m_unk0x14 = p_a->m_unk0x14; + p_b->m_partDataLength = p_a->m_partDataLength; + p_b->m_partDataOffset = p_a->m_partDataOffset; } return compare; @@ -93,14 +93,14 @@ class ModelDbPartListCursor : public MxListCursor { struct ModelDbModel { MxResult Read(FILE* p_file); - char* m_modelName; // 0x00 - undefined4 m_unk0x04; // 0x04 - undefined4 m_unk0x08; // 0x08 - char* m_presenterName; // 0x0c - undefined4 m_unk0x10[3]; // 0x10 - undefined4 m_unk0x1c[3]; // 0x1c - undefined4 m_unk0x28[3]; // 0x28 - undefined m_unk0x34; // 0x34 + char* m_modelName; // 0x00 + undefined4 m_unk0x04; // 0x04 + undefined4 m_unk0x08; // 0x08 + char* m_presenterName; // 0x0c + float m_locatation[3]; // 0x10 + float m_direction[3]; // 0x1c + float m_up[3]; // 0x28 + undefined m_unk0x34; // 0x34 }; // SIZE 0x18 diff --git a/LEGO1/omni/include/mxdsaction.h b/LEGO1/omni/include/mxdsaction.h index f1294371..6f15b40d 100644 --- a/LEGO1/omni/include/mxdsaction.h +++ b/LEGO1/omni/include/mxdsaction.h @@ -73,6 +73,9 @@ class MxDSAction : public MxDSObject { inline Mx3DPointFloat& GetLocation() { return m_location; } inline Mx3DPointFloat& GetDirection() { return m_direction; } inline Mx3DPointFloat& GetUp() { return m_up; } + inline void SetLocation(Vector3& p_location) { m_location = p_location; } + inline void SetDirection(Vector3& p_direction) { m_direction = p_direction; } + inline void SetUp(Vector3& p_up) { m_up = p_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/omni/include/mxpresenter.h b/LEGO1/omni/include/mxpresenter.h index 606e9c5a..3ce4879a 100644 --- a/LEGO1/omni/include/mxpresenter.h +++ b/LEGO1/omni/include/mxpresenter.h @@ -117,6 +117,7 @@ class MxPresenter : public MxCore { inline MxS32 GetY() const { return this->m_location.GetY(); } inline MxS32 GetDisplayZ() const { return this->m_displayZ; } inline MxDSAction* GetAction() const { return this->m_action; } + inline void SetAction(MxDSAction* p_action) { m_action = p_action; } inline void SetCompositePresenter(MxCompositePresenter* p_compositePresenter) { diff --git a/LEGO1/realtime/vector.h b/LEGO1/realtime/vector.h index 8b41cc13..f42e1f89 100644 --- a/LEGO1/realtime/vector.h +++ b/LEGO1/realtime/vector.h @@ -13,6 +13,8 @@ class Vector2 { // FUNCTION: LEGO1 0x1000c0f0 inline Vector2(float* p_data) { SetData(p_data); } + inline Vector2() {} + // Note: virtual function overloads appear in the virtual table // in reverse order of appearance. @@ -155,6 +157,8 @@ class Vector3 : public Vector2 { // FUNCTION: LEGO1 0x1001d150 inline Vector3(float* p_data) : Vector2(p_data) {} + inline Vector3() {} + // Hack: Some code initializes a Vector3 from a (most likely) const float* source. // Example: LegoCameraController::GetWorldUp // Vector3 however is a class that can mutate its underlying source, making