diff --git a/LEGO1/lego/legoomni/include/gifmanager.h b/LEGO1/lego/legoomni/include/gifmanager.h index aa6d2d80..898ab1fb 100644 --- a/LEGO1/lego/legoomni/include/gifmanager.h +++ b/LEGO1/lego/legoomni/include/gifmanager.h @@ -3,73 +3,139 @@ #include "compat.h" #include "decomp.h" +#include "mxstl/stlcompat.h" #include "mxtypes.h" #include #include +#pragma warning(disable : 4237) + +// SIZE 0x14 struct GifData { public: - const char* m_name; - LPDIRECTDRAWSURFACE m_surface; - LPDIRECTDRAWPALETTE m_palette; - LPDIRECT3DRMTEXTURE2 m_texture; - MxU8* m_data; + char* m_name; // 0x00 + LPDIRECTDRAWSURFACE m_surface; // 0x04 + LPDIRECTDRAWPALETTE m_palette; // 0x08 + LPDIRECT3DRMTEXTURE2 m_texture; // 0x0c + MxU8* m_data; // 0x10 + + ~GifData(); }; -struct GifMapEntry { -public: - GifMapEntry* m_right; - GifMapEntry* m_parent; - GifMapEntry* m_left; - const char* m_key; - GifData* m_value; +struct GifMapComparator { + bool operator()(const char* const& p_key0, const char* const& p_key1) const { return strcmp(p_key0, p_key1) > 0; } }; -class GifMap { -public: - GifMapEntry* FindNode(const char*& p_string); - - inline GifData* Get(const char* p_string) - { - GifData* ret = NULL; - GifMapEntry* entry = FindNode(p_string); - if (((m_unk0x4 == entry || strcmp(p_string, entry->m_key) > 0) ? m_unk0x4 : entry) != entry) - ret = entry->m_value; - return ret; - } - - undefined4 m_unk0x0; - GifMapEntry* m_unk0x4; +// SIZE 0x10 +class GifMap : public map { + // SYNTHETIC: LEGO1 0x1005a400 + // GifMap::~GifMap }; +typedef list GifList; + // VTABLE: LEGO1 0x100d86d4 +// SIZE 0x18 class GifManagerBase { public: - // STUB: LEGO1 0x1005b660 - virtual ~GifManagerBase() {} + // FUNCTION: LEGO1 0x1005b660 + virtual ~GifManagerBase() + { + GifMap::iterator it; + for (it = m_map.begin(); it != m_map.end(); it++) { + // DECOMP: Use of const_cast here matches ~ViewLODListManager from 96 source. + const char* const& key = (*it).first; + delete[] const_cast(key); + + if (m_ownership) { + delete (*it).second; // GifData* + } + } + } + + inline GifData* Get(const char* p_name) + { + GifMap::iterator it = m_map.find(p_name); + if (it != m_map.end()) { + return (*it).second; + } + + return NULL; + } // SYNTHETIC: LEGO1 0x1005a310 // GifManagerBase::`scalar deleting destructor' - inline GifData* Get(const char* p_name) { return m_unk0x8.Get(p_name); } - protected: - undefined4 m_unk0x0; - undefined4 m_unk0x4; - GifMap m_unk0x8; + MxBool m_ownership; // 0x04 + GifMap m_map; // 0x08 }; // VTABLE: LEGO1 0x100d86fc +// SIZE 0x24 class GifManager : public GifManagerBase { public: + GifManager() { m_ownership = TRUE; }; virtual ~GifManager() override; // SYNTHETIC: LEGO1 0x1005a580 // GifManager::`scalar deleting destructor' + void FUN_10099cc0(GifData* p_data); + protected: - undefined m_unk0x14[0x1c]; + GifList m_list; // 0x18 }; +// TEMPLATE: LEGO1 0x10059c50 +// allocator::_Charalloc + +// clang-format off +// TEMPLATE: LEGO1 0x10001cc0 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::_Lbound + +// TEMPLATE: LEGO1 0x1004f9b0 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::_Insert + +// TEMPLATE: LEGO1 0x10059c70 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::_Color + +// TEMPLATE: LEGO1 0x10059c80 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::_Left + +// TEMPLATE: LEGO1 0x10059c90 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::_Parent + +// TEMPLATE: LEGO1 0x10059ca0 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::_Right + +// TEMPLATE: LEGO1 0x10059cb0 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::~_Tree,map >::_Kfn,GifMapComparator,allocator > + +// TEMPLATE: LEGO1 0x10059d80 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::iterator::_Inc + +// TEMPLATE: LEGO1 0x10059dc0 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::erase + +// TEMPLATE: LEGO1 0x1005a210 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::_Erase + +// TEMPLATE: LEGO1 0x1005a250 +// list >::~list > + +// TEMPLATE: LEGO1 0x1005a2c0 +// map >::~map > + +// TEMPLATE: LEGO1 0x1005a450 +// Map::~Map + +// TEMPLATE: LEGO1 0x1005a5a0 +// List::~List + +// GLOBAL: LEGO1 0x100f0100 +// _Tree,map >::_Kfn,GifMapComparator,allocator >::_Nil +// clang-format on + #endif // GIFMANAGER_H diff --git a/LEGO1/lego/legoomni/src/common/gifmanager.cpp b/LEGO1/lego/legoomni/src/common/gifmanager.cpp index c83714d4..cd485b11 100644 --- a/LEGO1/lego/legoomni/src/common/gifmanager.cpp +++ b/LEGO1/lego/legoomni/src/common/gifmanager.cpp @@ -1,32 +1,61 @@ #include "gifmanager.h" DECOMP_SIZE_ASSERT(GifData, 0x14); -DECOMP_SIZE_ASSERT(GifMapEntry, 0x14); -DECOMP_SIZE_ASSERT(GifMap, 0x08); -DECOMP_SIZE_ASSERT(GifManagerBase, 0x14); -DECOMP_SIZE_ASSERT(GifManager, 0x30); +DECOMP_SIZE_ASSERT(GifMap, 0x10); +DECOMP_SIZE_ASSERT(GifManagerBase, 0x18); +DECOMP_SIZE_ASSERT(GifManager, 0x24); -// GLOBAL: LEGO1 0x100f0100 -GifMapEntry* g_unk0x100f0100; - -// FUNCTION: LEGO1 0x10001cc0 -GifMapEntry* GifMap::FindNode(const char*& p_string) +// FUNCTION: LEGO1 0x10065c00 +GifData::~GifData() { - GifMapEntry* ret = m_unk0x4; - GifMapEntry* current = ret->m_parent; - while (current != g_unk0x100f0100) { - if (strcmp(current->m_key, p_string) <= 0) { - ret = current; - current = current->m_right; - } - else - current = current->m_left; + if (m_name) { + delete[] m_name; + m_name = NULL; + } + + if (m_palette) { + m_palette->Release(); + m_palette = NULL; + } + + if (m_surface) { + m_surface->Release(); + m_surface = NULL; + } + + if (m_texture) { + m_texture->Release(); + m_texture = NULL; } - return ret; } -// STUB: LEGO1 0x10099870 +// FUNCTION: LEGO1 0x10099870 GifManager::~GifManager() { - // TODO +} + +// FUNCTION: LEGO1 0x10099cc0 +void GifManager::FUN_10099cc0(GifData* p_data) +{ + if (p_data == NULL) + return; + +#ifdef COMPAT_MODE + GifList::iterator it; + for (it = m_list.begin(); it != m_list.end(); it++) { +#else + for (GifList::iterator it = m_list.begin(); it != m_list.end(); it++) { +#endif + if (*it == p_data) { + // TODO: This is wrong, but what is at +0xc on the iterator? + *it = NULL; + + if (p_data->m_texture->Release() == TRUE) { + delete p_data; + m_list.erase(it); + } + + return; + } + } } diff --git a/LEGO1/lego/legoomni/src/infocenter/score.cpp b/LEGO1/lego/legoomni/src/infocenter/score.cpp index c1bba3e6..5a7a95a3 100644 --- a/LEGO1/lego/legoomni/src/infocenter/score.cpp +++ b/LEGO1/lego/legoomni/src/infocenter/score.cpp @@ -227,8 +227,7 @@ void Score::VTable0x68(MxBool p_add) // FUNCTION: LEGO1 0x100019d0 void Score::Paint() { - GifManager* gm = GetGifManager(); - GifData* gd = gm->Get("bigcube.gif"); + GifData* gd = GetGifManager()->Get("bigcube.gif"); if (gd) { RaceState* l78 = (RaceState*) GameState()->GetState("JetskiRaceState"); diff --git a/tools/isledecomp/isledecomp/compare/db.py b/tools/isledecomp/isledecomp/compare/db.py index dea2b590..43d6811b 100644 --- a/tools/isledecomp/isledecomp/compare/db.py +++ b/tools/isledecomp/isledecomp/compare/db.py @@ -170,6 +170,12 @@ def skip_compare(self, orig: int): def _match_on(self, compare_type: SymbolType, addr: int, name: str) -> bool: # Update the compare_type here too since the marker tells us what we should do + + # Truncate the name to 255 characters. It will not be possible to match a name + # longer than that because MSVC truncates the debug symbols to this length. + # See also: warning C4786. + name = name[:255] + logger.debug("Looking for %s %s", compare_type.name.lower(), name) cur = self._db.execute( """UPDATE `symbols`