diff --git a/CMakeLists.txt b/CMakeLists.txt index 7917bb5f..bbf67460 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -147,6 +147,14 @@ set_property(TARGET roi PROPERTY ARCHIVE_OUTPUT_NAME "roi$<$:d>") target_include_directories(roi PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAKE_SOURCE_DIR}/util") target_link_libraries(roi PRIVATE) +add_library(anim STATIC + LEGO1/lego/sources/anim/legoanim.cpp +) +register_lego1_target(anim) +set_property(TARGET anim PROPERTY ARCHIVE_OUTPUT_NAME "anim$<$:d>") +target_include_directories(anim PRIVATE "${CMAKE_SOURCE_DIR}/LEGO1/omni/include" "${CMAKE_SOURCE_DIR}/LEGO1" "${CMAKE_SOURCE_DIR}/util") +target_link_libraries(anim PRIVATE) + add_library(misc STATIC LEGO1/lego/sources/misc/legoimage.cpp LEGO1/lego/sources/misc/legostorage.cpp @@ -402,7 +410,7 @@ target_include_directories(lego1 PUBLIC "${CMAKE_SOURCE_DIR}/LEGO1/lego/legoomni target_include_directories(lego1 PUBLIC "${CMAKE_SOURCE_DIR}/LEGO1/realtime") # Link libraries -target_link_libraries(lego1 PRIVATE tglrl viewmanager realtime mxdirectx roi FLIC::FLIC Vec::Vec dinput dxguid misc 3dmanager omni) +target_link_libraries(lego1 PRIVATE tglrl viewmanager realtime mxdirectx roi anim FLIC::FLIC Vec::Vec dinput dxguid misc 3dmanager omni) if (ISLE_USE_SMARTHEAP) foreach(tgt IN LISTS lego1_targets) diff --git a/LEGO1/lego/legoomni/include/legoanimpresenter.h b/LEGO1/lego/legoomni/include/legoanimpresenter.h index 221dfeb0..1f8a0058 100644 --- a/LEGO1/lego/legoomni/include/legoanimpresenter.h +++ b/LEGO1/lego/legoomni/include/legoanimpresenter.h @@ -1,8 +1,7 @@ #ifndef LEGOANIMPRESENTER_H #define LEGOANIMPRESENTER_H -#include "lego/sources/misc/legostorage.h" -#include "lego/sources/misc/legotree.h" +#include "lego/sources/anim/legoanim.h" #include "mxgeometry/mxgeometry3d.h" #include "mxvideopresenter.h" @@ -41,7 +40,7 @@ class LegoAnimPresenter : public MxVideoPresenter { void PutFrame() override; // vtable+0x6c virtual MxResult VTable0x88(MxStreamChunk* p_chunk); // vtable+0x88 - inline LegoAnimClass* GetUnknown0x64() { return m_unk0x64; } + inline LegoAnim* GetAnimation() { return m_anim; } const char* GetActionObjectName(); @@ -49,7 +48,7 @@ class LegoAnimPresenter : public MxVideoPresenter { void Init(); void Destroy(MxBool p_fromDestructor); - LegoAnimClass* m_unk0x64; // 0x64 + LegoAnim* m_anim; // 0x64 undefined4 m_unk0x68; // 0x68 undefined4 m_unk0x6c; // 0x6c undefined4 m_unk0x70; // 0x70 @@ -76,27 +75,4 @@ class LegoAnimPresenter : public MxVideoPresenter { // SYNTHETIC: LEGO1 0x10068650 // LegoAnimPresenter::`scalar deleting destructor' -// VTABLE: LEGO1 0x100db8d8 -// SIZE 0x18 -class LegoAnimClass : public LegoTree { -public: - LegoAnimClass(); - ~LegoAnimClass() override; - - LegoResult Write(LegoStorage* p_storage) override; // vtable+0x08 - LegoTreeNodeData* CreateData() override; // vtable+0x0c - virtual MxResult VTable0x10(LegoMemory* p_stream, MxS32); // vtable+0x10 - - inline MxLong GetUnknown0x8() { return m_unk0x08; } - -private: - MxLong m_unk0x08; // 0x08 - undefined4 m_unk0x0c; // 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/entity/legoworld.cpp b/LEGO1/lego/legoomni/src/entity/legoworld.cpp index dafbd063..c1fe9e39 100644 --- a/LEGO1/lego/legoomni/src/entity/legoworld.cpp +++ b/LEGO1/lego/legoomni/src/entity/legoworld.cpp @@ -302,7 +302,7 @@ void LegoWorld::Add(MxCore* p_object) if (!strcmpi(animPresenter->GetAction()->GetObjectName(), "ConfigAnimation")) { FUN_1003e050(animPresenter); - animPresenter->GetAction()->SetDuration(animPresenter->GetUnknown0x64()->GetUnknown0x8()); + animPresenter->GetAction()->SetDuration(animPresenter->GetAnimation()->GetDuration()); } } diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index e8c7344c..16b81aa4 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -8,7 +8,6 @@ #include "mxvideomanager.h" DECOMP_SIZE_ASSERT(LegoAnimPresenter, 0xc0) -DECOMP_SIZE_ASSERT(LegoAnimClass, 0x18) // FUNCTION: LEGO1 0x10068420 LegoAnimPresenter::LegoAnimPresenter() @@ -25,7 +24,7 @@ LegoAnimPresenter::~LegoAnimPresenter() // FUNCTION: LEGO1 0x100686f0 void LegoAnimPresenter::Init() { - m_unk0x64 = NULL; + m_anim = NULL; m_unk0x68 = 0; m_unk0x6c = 0; m_unk0x74 = 0; @@ -71,9 +70,9 @@ MxResult LegoAnimPresenter::VTable0x88(MxStreamChunk* p_chunk) 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) { + m_anim = new LegoAnim(); + if (m_anim) { + if (m_anim->Read(&stream, val2) == SUCCESS) { result = SUCCESS; } } @@ -86,7 +85,7 @@ MxResult LegoAnimPresenter::VTable0x88(MxStreamChunk* p_chunk) } if (result != SUCCESS) { - delete m_unk0x64; + delete m_anim; Init(); } @@ -148,7 +147,7 @@ void LegoAnimPresenter::StreamingTickle() } } else { - if (m_action->GetElapsedTime() > m_unk0x64->GetUnknown0x8() + m_action->GetStartTime()) { + if (m_action->GetElapsedTime() > m_anim->GetDuration() + m_action->GetStartTime()) { m_unk0x95 = 1; } } @@ -198,38 +197,3 @@ void LegoAnimPresenter::EndAction() // TODO MxVideoPresenter::EndAction(); } - -// FUNCTION: LEGO1 0x100a0b30 -LegoAnimClass::LegoAnimClass() -{ - m_unk0x08 = 0; - m_unk0x0c = 0; - m_unk0x10 = 0; - m_unk0x14 = 0; -} - -// STUB: LEGO1 0x100a0bc0 -LegoAnimClass::~LegoAnimClass() -{ - // TODO -} - -// STUB: LEGO1 0x100a0c70 -MxResult LegoAnimClass::VTable0x10(LegoMemory* p_stream, MxS32) -{ - return SUCCESS; -} - -// STUB: LEGO1 0x100a0e30 -LegoResult LegoAnimClass::Write(LegoStorage* p_storage) -{ - // TODO - return SUCCESS; -} - -// STUB: LEGO1 0x100a1040 -LegoTreeNodeData* LegoAnimClass::CreateData() -{ - // TODO - return NULL; -} diff --git a/LEGO1/lego/sources/anim/legoanim.cpp b/LEGO1/lego/sources/anim/legoanim.cpp new file mode 100644 index 00000000..b7dc8249 --- /dev/null +++ b/LEGO1/lego/sources/anim/legoanim.cpp @@ -0,0 +1,234 @@ +#include "legoanim.h" + +DECOMP_SIZE_ASSERT(LegoAnimKey, 0x08) +DECOMP_SIZE_ASSERT(LegoTranslationKey, 0x14) +DECOMP_SIZE_ASSERT(LegoRotationKey, 0x18) +DECOMP_SIZE_ASSERT(LegoScaleKey, 0x14) +DECOMP_SIZE_ASSERT(LegoMorphKey, 0x0c) +DECOMP_SIZE_ASSERT(LegoAnim, 0x18) + +// FUNCTION: LEGO1 0x1009f900 +LegoAnimKey::LegoAnimKey() +{ + m_unk0x00 = 0; + m_unk0x04 = 0; +} + +// STUB: LEGO1 0x1009f910 +LegoResult LegoAnimKey::Read(LegoStorage* p_storage) +{ + // TODO + return SUCCESS; +} + +// FUNCTION: LEGO1 0x1009f990 +LegoTranslationKey::LegoTranslationKey() +{ + m_x = 0.0F; + m_y = 0.0F; + m_z = 0.0F; +} + +// STUB: LEGO1 0x1009f9b0 +LegoResult LegoTranslationKey::Read(LegoStorage* p_storage) +{ + // TODO + return SUCCESS; +} + +// FUNCTION: LEGO1 0x1009faa0 +LegoRotationKey::LegoRotationKey() +{ + m_angle = 1.0F; + m_x = 0.0F; + m_y = 0.0F; + m_z = 0.0F; +} + +// STUB: LEGO1 0x1009fac0 +LegoResult LegoRotationKey::Read(LegoStorage* p_storage) +{ + // TODO + return SUCCESS; +} + +// FUNCTION: LEGO1 0x1009fba0 +LegoScaleKey::LegoScaleKey() +{ + m_x = 1.0F; + m_y = 1.0F; + m_z = 1.0F; +} + +// STUB: LEGO1 0x1009fbc0 +LegoResult LegoScaleKey::Read(LegoStorage* p_storage) +{ + // TODO + return SUCCESS; +} + +// STUB: LEGO1 0x1009fcf0 +LegoAnimNodeData::LegoAnimNodeData() +{ + // TODO +} + +// FUNCTION: LEGO1 0x1009fda0 +LegoAnimNodeData::~LegoAnimNodeData() +{ + if (m_name) { + delete[] m_name; + } + if (m_translationKeys) { + delete[] m_translationKeys; + } + if (m_rotationKeys) { + delete[] m_rotationKeys; + } + if (m_scaleKeys) { + delete[] m_scaleKeys; + } + if (m_morphKeys) { + delete[] m_morphKeys; + } +} + +// FUNCTION: LEGO1 0x1009fe60 +LegoResult LegoAnimNodeData::Read(LegoStorage* p_storage) +{ + LegoResult result; + + LegoU32 length; + if ((result = p_storage->Read(&length, sizeof(length))) != SUCCESS) { + return result; + } + + if (m_name) { + delete[] m_name; + m_name = NULL; + } + if (length) { + m_name = new LegoChar[length + 1]; + if ((result = p_storage->Read(m_name, length)) != SUCCESS) { + return result; + } + m_name[length] = '\0'; + } + + LegoU32 i; + + if ((result = p_storage->Read(&m_numTranslationKeys, sizeof(m_numTranslationKeys))) != SUCCESS) { + return result; + } + if (m_translationKeys) { + delete[] m_translationKeys; + m_translationKeys = NULL; + } + if (m_numTranslationKeys) { + m_translationKeys = new LegoTranslationKey[m_numTranslationKeys]; + for (i = 0; i < m_numTranslationKeys; i++) { + if ((result = m_translationKeys[i].Read(p_storage)) != SUCCESS) { + return result; + } + } + } + + if ((result = p_storage->Read(&m_numRotationKeys, sizeof(m_numRotationKeys))) != SUCCESS) { + return result; + } + if (m_rotationKeys) { + delete[] m_rotationKeys; + m_rotationKeys = NULL; + } + if (m_numRotationKeys) { + m_rotationKeys = new LegoRotationKey[m_numRotationKeys]; + for (i = 0; i < m_numRotationKeys; i++) { + if ((result = m_rotationKeys[i].Read(p_storage)) != SUCCESS) { + return result; + } + } + } + + if ((result = p_storage->Read(&m_numScaleKeys, sizeof(m_numScaleKeys))) != SUCCESS) { + return result; + } + if (m_scaleKeys) { + delete[] m_scaleKeys; + m_scaleKeys = NULL; + } + if (m_numScaleKeys) { + m_scaleKeys = new LegoScaleKey[m_numScaleKeys]; + for (i = 0; i < m_numScaleKeys; i++) { + if ((result = m_scaleKeys[i].Read(p_storage)) != SUCCESS) { + return result; + } + } + } + + if ((result = p_storage->Read(&m_numMorphKeys, sizeof(m_numMorphKeys))) != SUCCESS) { + return result; + } + if (m_morphKeys) { + delete[] m_morphKeys; + m_morphKeys = NULL; + } + if (m_numMorphKeys) { + m_morphKeys = new LegoMorphKey[m_numMorphKeys]; + for (i = 0; i < m_numMorphKeys; i++) { + if ((result = m_morphKeys[i].Read(p_storage)) != SUCCESS) { + return result; + } + } + } + + return SUCCESS; +} + +// STUB: LEGO1 0x100a01e0 +LegoResult LegoAnimNodeData::Write(LegoStorage* p_storage) +{ + // TODO + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100a0b30 +LegoAnim::LegoAnim() +{ + m_duration = 0; + m_unk0x0c = 0; + m_unk0x10 = 0; + m_unk0x14 = 0; +} + +// STUB: LEGO1 0x100a0bc0 +LegoAnim::~LegoAnim() +{ + // TODO +} + +// STUB: LEGO1 0x100a0c70 +LegoResult LegoAnim::Read(LegoStorage* p_storage, LegoS32) +{ + // TODO + return SUCCESS; +} + +// STUB: LEGO1 0x100a0e30 +LegoResult LegoAnim::Write(LegoStorage* p_storage) +{ + // TODO + return SUCCESS; +} + +// FUNCTION: LEGO1 0x100a0f60 +LegoMorphKey::LegoMorphKey() +{ + m_unk0x00 = NULL; +} + +// STUB: LEGO1 0x100a0f70 +LegoResult LegoMorphKey::Read(LegoStorage* p_storage) +{ + // TODO + return SUCCESS; +} diff --git a/LEGO1/lego/sources/anim/legoanim.h b/LEGO1/lego/sources/anim/legoanim.h new file mode 100644 index 00000000..65368678 --- /dev/null +++ b/LEGO1/lego/sources/anim/legoanim.h @@ -0,0 +1,114 @@ +#ifndef __LEGOANIM_H +#define __LEGOANIM_H + +#include "decomp.h" +#include "lego/sources/misc/legostorage.h" +#include "lego/sources/misc/legotree.h" + +// SIZE 0x08 +class LegoAnimKey { +public: + LegoAnimKey(); + LegoResult Read(LegoStorage* p_storage); + +protected: + undefined m_unk0x00; // 0x00 + undefined4 m_unk0x04; // 0x04 +}; + +// SIZE 0x14 +class LegoTranslationKey : public LegoAnimKey { +public: + LegoTranslationKey(); + LegoResult Read(LegoStorage* p_storage); + +protected: + LegoFloat m_x; // 0x08 + LegoFloat m_y; // 0x0c + LegoFloat m_z; // 0x10 +}; + +// SIZE 0x18 +class LegoRotationKey : public LegoAnimKey { +public: + LegoRotationKey(); + LegoResult Read(LegoStorage* p_storage); + +protected: + LegoFloat m_angle; // 0x08 + LegoFloat m_x; // 0x0c + LegoFloat m_y; // 0x10 + LegoFloat m_z; // 0x14 +}; + +// SIZE 0x14 +class LegoScaleKey : public LegoAnimKey { +public: + LegoScaleKey(); + LegoResult Read(LegoStorage* p_storage); + +protected: + LegoFloat m_x; // 0x08 + LegoFloat m_y; // 0x0c + LegoFloat m_z; // 0x10 +}; + +// SIZE 0x0c +class LegoMorphKey : public LegoAnimKey { +public: + LegoMorphKey(); + LegoResult Read(LegoStorage* p_storage); + +protected: + undefined m_unk0x00; // 0x08 +}; + +// VTABLE: LEGO1 0x100db8c8 +// SIZE 0x34 +class LegoAnimNodeData : public LegoTreeNodeData { +public: + LegoAnimNodeData(); + ~LegoAnimNodeData() override; + LegoResult Read(LegoStorage* p_storage) override; // vtable+0x04 + LegoResult Write(LegoStorage* p_storage) override; // vtable+0x08 + + // SYNTHETIC: LEGO1 0x1009fd80 + // LegoAnimNodeData::`scalar deleting destructor' + +protected: + LegoChar* m_name; // 0x04 + LegoU16 m_numTranslationKeys; // 0x08 + LegoU16 m_numRotationKeys; // 0x0a + LegoU16 m_numScaleKeys; // 0x0c + LegoU16 m_numMorphKeys; // 0x0e + LegoTranslationKey* m_translationKeys; // 0x10 + LegoRotationKey* m_rotationKeys; // 0x14 + LegoScaleKey* m_scaleKeys; // 0x18 + LegoMorphKey* m_morphKeys; // 0x1c + undefined m_unk0x20[0x14]; // 0x20 +}; + +// VTABLE: LEGO1 0x100db8d8 +// SIZE 0x18 +class LegoAnim : public LegoTree { +public: + LegoAnim(); + ~LegoAnim() override; + LegoTime GetDuration() { return m_duration; } + LegoResult Write(LegoStorage* p_storage) override; // vtable+0x08 + virtual LegoResult Read(LegoStorage* p_storage, LegoS32); // vtable+0x10 + + // SYNTHETIC: LEGO1 0x100a0ba0 + // LegoAnim::`scalar deleting destructor' + +protected: + LegoTime m_duration; // 0x08 + undefined4 m_unk0x0c; // 0x0c + undefined4 m_unk0x10; // 0x10 + undefined4 m_unk0x14; // 0x14 + + // FUNCTION: LEGO1 0x100a1040 + LegoTreeNodeData* CreateData() override { return new LegoAnimNodeData(); } // vtable+0x0c +}; + +#endif // __LEGOANIM_H diff --git a/LEGO1/lego/sources/misc/legotree.h b/LEGO1/lego/sources/misc/legotree.h index 3ee3d4e5..9d4aec69 100644 --- a/LEGO1/lego/sources/misc/legotree.h +++ b/LEGO1/lego/sources/misc/legotree.h @@ -13,6 +13,7 @@ class LegoStorage; class LegoTreeNodeData { public: LegoTreeNodeData() {} + // FUNCTION: LEGO1 0x1009a0e0 virtual ~LegoTreeNodeData() {} // FUNCTION: LEGO1 0x10099fe0 diff --git a/LEGO1/lego/sources/roi/legoroi.h b/LEGO1/lego/sources/roi/legoroi.h index 36d06e1e..64bb2b7e 100644 --- a/LEGO1/lego/sources/roi/legoroi.h +++ b/LEGO1/lego/sources/roi/legoroi.h @@ -1,6 +1,7 @@ #ifndef LEGOROI_H #define LEGOROI_H +#include "lego/sources/misc/legotypes.h" #include "viewmanager/viewroi.h" typedef unsigned char (*ROIHandler)(char*, char*, unsigned int); @@ -45,7 +46,7 @@ class LegoROI : public ViewROI { private: int m_unk0xe0; // 0xe0 - char* m_name; // 0xe4 + LegoChar* m_name; // 0xe4 BoundingSphere m_sphere; // 0xe8 undefined4 m_unk0x100; // 0x100 LegoEntity* m_unk0x104; // 0x104