diff --git a/LEGO1/lego/legoomni/include/legoanimactor.h b/LEGO1/lego/legoomni/include/legoanimactor.h index 0c46f71e..8d1900e1 100644 --- a/LEGO1/lego/legoomni/include/legoanimactor.h +++ b/LEGO1/lego/legoomni/include/legoanimactor.h @@ -1,10 +1,13 @@ #ifndef LEGOANIMACTOR_H #define LEGOANIMACTOR_H +#include "decomp.h" #include "legopathactor.h" class LegoAnimActor : public LegoPathActor { public: + LegoAnimActor() {} + LegoAnimActor(undefined4); }; #endif // LEGOANIMACTOR_H diff --git a/LEGO1/lego/legoomni/include/legocharactermanager.h b/LEGO1/lego/legoomni/include/legocharactermanager.h index 69fccb21..8e657db3 100644 --- a/LEGO1/lego/legoomni/include/legocharactermanager.h +++ b/LEGO1/lego/legoomni/include/legocharactermanager.h @@ -7,28 +7,36 @@ #include "mxstl/stlcompat.h" #include "mxtypes.h" +class LegoActor; class LegoROI; #pragma warning(disable : 4237) // TODO: generic string comparator? -struct LegoUnkSaveDataMapComparator { - bool operator()(const char* const& p_a, const char* const& p_b) const { return strcmpi(p_a, p_b) > 0; } +struct LegoCharacterComparator { + MxBool operator()(const char* const& p_a, const char* const& p_b) const { return strcmpi(p_a, p_b) < 0; } }; -// TODO: pair instead? // SIZE 0x08 -struct LegoUnkSaveDataMapValue { - LegoROI* m_roi; // 0x00 - MxU32 m_counter; // 0x04 +struct LegoCharacter { + LegoROI* m_roi; // 0x00 + MxU32 m_refCount; // 0x04 + + LegoCharacter(LegoROI* p_roi) + { + m_roi = p_roi; + m_refCount = 1; + } + + inline void AddRef() { m_refCount++; } }; -typedef map LegoUnkSaveDataMap; +typedef map LegoCharacterMap; struct LegoSaveDataEntry3 { char* m_name; void* m_unk0x04; - void* m_unk0x08; + LegoActor* m_actor; MxS32 m_savePart1; MxS32 m_savePart2; MxU8 m_savePart3; @@ -57,7 +65,7 @@ public: MxResult WriteSaveData3(LegoStorage* p_storage); MxResult ReadSaveData3(LegoStorage* p_storage); - LegoROI* FUN_10083500(const char*, MxBool); + LegoROI* GetROI(const char* p_key, MxBool p_createEntity); void InitSaveData(); static void SetCustomizeAnimFile(const char* p_value); @@ -66,6 +74,7 @@ public: void FUN_100832a0(); void FUN_10083db0(LegoROI* p_roi); void FUN_10083f10(LegoROI* p_roi); + LegoSaveDataEntry3* FUN_10084c60(const char* p_key); MxBool FUN_10084ec0(LegoROI* p_roi); MxU32 FUN_10085140(LegoROI*, MxBool); LegoROI* FUN_10085210(const LegoChar*, LegoChar*, undefined); @@ -74,30 +83,38 @@ public: static const char* GetCustomizeAnimFile() { return g_customizeAnimFile; } private: + LegoROI* CreateROI(const char* p_key); + static char* g_customizeAnimFile; - LegoUnkSaveDataMap* m_map; // 0x00 + LegoCharacterMap* m_characters; // 0x00 CustomizeAnimFileVariable* m_customizeAnimFile; // 0x04 }; // clang-format off -// FUNCTION: LEGO1 0x10082b90 -// _Tree,map >::_Kfn,LegoUnkSaveDataMapComparator,allocator >::~_Tree,map >::_Kfn,LegoUnkSaveDataMapComparator,allocator > +// TEMPLATE: LEGO1 0x10082b90 +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::~_Tree,map >::_Kfn,LegoCharacterComparator,allocator > -// FUNCTION: LEGO1 0x10082c60 -// _Tree,map >::_Kfn,LegoUnkSaveDataMapComparator,allocator >::iterator::_Inc +// TEMPLATE: LEGO1 0x10082c60 +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::iterator::_Inc -// FUNCTION: LEGO1 0x10082ca0 -// _Tree,map >::_Kfn,LegoUnkSaveDataMapComparator,allocator >::erase +// TEMPLATE: LEGO1 0x10082ca0 +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::erase -// FUNCTION: LEGO1 0x100830f0 -// _Tree,map >::_Kfn,LegoUnkSaveDataMapComparator,allocator >::_Erase +// TEMPLATE: LEGO1 0x100830f0 +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::_Erase -// FUNCTION: LEGO1 0x10083130 -// map >::~map > +// TEMPLATE: LEGO1 0x10083130 +// map >::~map > + +// TEMPLATE: LEGO1 0x10083840 +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::iterator::_Dec + +// TEMPLATE: LEGO1 0x10083890 +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::_Insert // GLOBAL: LEGO1 0x100fc508 -// _Tree,map >::_Kfn,LegoUnkSaveDataMapComparator,allocator >::_Nil +// _Tree,map >::_Kfn,LegoCharacterComparator,allocator >::_Nil // clang-format on #endif // LEGOCHARACTERMANAGER_H diff --git a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp index 47d9a1b8..d7b5aca4 100644 --- a/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp +++ b/LEGO1/lego/legoomni/src/common/legocharactermanager.cpp @@ -1,9 +1,13 @@ #include "legocharactermanager.h" +#include "legoanimactor.h" #include "legogamestate.h" +#include "legovideomanager.h" +#include "misc.h" #include "mxmisc.h" #include "roi/legoroi.h" +DECOMP_SIZE_ASSERT(LegoCharacter, 0x08) DECOMP_SIZE_ASSERT(LegoCharacterManager, 0x08) DECOMP_SIZE_ASSERT(LegoSaveDataEntry3, 0x108) @@ -19,7 +23,7 @@ LegoSaveDataEntry3 g_saveData3[66]; // FUNCTION: LEGO1 0x10082a20 LegoCharacterManager::LegoCharacterManager() { - m_map = new LegoUnkSaveDataMap(); + m_characters = new LegoCharacterMap(); InitSaveData(); m_customizeAnimFile = new CustomizeAnimFileVariable("CUSTOMIZE_ANIM_FILE"); @@ -96,11 +100,51 @@ MxResult LegoCharacterManager::ReadSaveData3(LegoStorage* p_storage) return SUCCESS; } -// STUB: LEGO1 0x10083500 -LegoROI* LegoCharacterManager::FUN_10083500(const char* p_key, MxBool p_option) +// FUNCTION: LEGO1 0x10083500 +LegoROI* LegoCharacterManager::GetROI(const char* p_key, MxBool p_createEntity) { - // TODO - // involves an STL map with a _Nil node at 0x100fc508 + LegoCharacter* character = NULL; + LegoCharacterMap::iterator it = m_characters->find(p_key); + + if (it != m_characters->end()) { + character = (*it).second; + character->AddRef(); + } + + if (character == NULL) { + LegoROI* roi = CreateROI(p_key); + roi->SetUnknown0x0c(0); + + if (roi != NULL) { + character = new LegoCharacter(roi); + char* key = new char[strlen(p_key) + 1]; + + if (key != NULL) { + strcpy(key, p_key); + (*m_characters)[key] = character; + VideoManager()->Get3DManager()->Add(*roi); + } + } + } + else { + VideoManager()->Get3DManager()->Remove(*character->m_roi); + VideoManager()->Get3DManager()->Add(*character->m_roi); + } + + if (character != NULL) { + if (p_createEntity && character->m_roi->GetEntity() == NULL) { + // TODO: Match + LegoAnimActor* actor = new LegoAnimActor(1); + + actor->SetROI(character->m_roi, FALSE, FALSE); + actor->FUN_100114e0(0); + actor->SetFlag(LegoActor::c_bit2); + FUN_10084c60(p_key)->m_actor = actor; + } + + return character->m_roi; + } + return NULL; } @@ -116,6 +160,12 @@ void LegoCharacterManager::FUN_10083f10(LegoROI* p_roi) // TODO } +// STUB: LEGO1 0x10084030 +LegoROI* LegoCharacterManager::CreateROI(const char* p_key) +{ + return NULL; +} + // STUB: LEGO1 0x10084c00 MxBool LegoCharacterManager::FUN_10084c00(const LegoChar*) { @@ -123,6 +173,12 @@ MxBool LegoCharacterManager::FUN_10084c00(const LegoChar*) return FALSE; } +// STUB: LEGO1 0x10084c60 +LegoSaveDataEntry3* LegoCharacterManager::FUN_10084c60(const char* p_key) +{ + return NULL; +} + // STUB: LEGO1 0x10084ec0 MxBool LegoCharacterManager::FUN_10084ec0(LegoROI* p_roi) { diff --git a/LEGO1/lego/legoomni/src/common/legogamestate.cpp b/LEGO1/lego/legoomni/src/common/legogamestate.cpp index 628fcfbf..d151f26c 100644 --- a/LEGO1/lego/legoomni/src/common/legogamestate.cpp +++ b/LEGO1/lego/legoomni/src/common/legogamestate.cpp @@ -147,7 +147,7 @@ void LegoGameState::SetActor(MxU8 p_actorId) IslePathActor* newActor = new IslePathActor(); const char* actorName = LegoActor::GetActorName(m_actorId); - LegoROI* roi = CharacterManager()->FUN_10083500(actorName, FALSE); + LegoROI* roi = CharacterManager()->GetROI(actorName, FALSE); MxDSAction action; action.SetAtomId(*g_isleScript); diff --git a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp index d3515937..f55a5150 100644 --- a/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp +++ b/LEGO1/lego/legoomni/src/paths/legoanimactor.cpp @@ -1 +1,9 @@ #include "legoanimactor.h" + +// TODO: This might not be the actual constructor of this class, +// it only exists temporarily to match other code +// STUB: LEGO1 0x1002a500 +LegoAnimActor::LegoAnimActor(undefined4) +{ + // TODO +} diff --git a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp index b0cea4c1..6cddadaf 100644 --- a/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legoanimpresenter.cpp @@ -159,7 +159,7 @@ void LegoAnimPresenter::FUN_100692b0() src = str; } - roi = CharacterManager()->FUN_10083500(src, TRUE); + roi = CharacterManager()->GetROI(src, TRUE); if (roi != NULL && str[0] == '*') { roi->SetUnknown0x0c(0); diff --git a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp index a7fc8d5c..b1c26b0f 100644 --- a/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp +++ b/LEGO1/lego/legoomni/src/video/legomodelpresenter.cpp @@ -309,7 +309,7 @@ void LegoModelPresenter::ParseExtra() char* token = strtok(output, g_parseExtraTokens); if (m_roi == NULL) { - m_roi = CharacterManager()->FUN_10083500(token, FALSE); + m_roi = CharacterManager()->GetROI(token, FALSE); m_addedToView = FALSE; } }