Refactor MxList cursors (#313)

* LegoWorldList

* Refactor list cursors

* Add decomp markers for list cursors

* Fix decomp markers

* MxRegionListCursor edit to prevent accuracy drop

* Better fix for MxRegionListCursor
This commit is contained in:
MS 2023-12-07 14:14:49 -05:00 committed by GitHub
parent f87c96f1bb
commit ce686705f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 236 additions and 27 deletions

View file

@ -98,6 +98,7 @@ add_library(lego1 SHARED
LEGO1/legovehiclebuildstate.cpp LEGO1/legovehiclebuildstate.cpp
LEGO1/legovideomanager.cpp LEGO1/legovideomanager.cpp
LEGO1/legoworld.cpp LEGO1/legoworld.cpp
LEGO1/legoworldlist.cpp
LEGO1/legoworldpresenter.cpp LEGO1/legoworldpresenter.cpp
LEGO1/motorcycle.cpp LEGO1/motorcycle.cpp
LEGO1/mxactionnotificationparam.cpp LEGO1/mxactionnotificationparam.cpp

View file

@ -11,6 +11,7 @@
#include "legoutil.h" #include "legoutil.h"
#include "legovideomanager.h" #include "legovideomanager.h"
#include "legoworld.h" #include "legoworld.h"
#include "legoworldlist.h"
#include "mxautolocker.h" #include "mxautolocker.h"
#include "mxbackgroundaudiomanager.h" #include "mxbackgroundaudiomanager.h"
#include "mxdsfile.h" #include "mxdsfile.h"
@ -358,7 +359,7 @@ void LegoOmni::Init()
m_inputMgr = NULL; m_inputMgr = NULL;
m_unk6c = 0; m_unk6c = 0;
m_gifManager = NULL; m_gifManager = NULL;
m_unk78 = 0; m_worldList = NULL;
m_currentWorld = NULL; m_currentWorld = NULL;
m_unk80 = FALSE; m_unk80 = FALSE;
m_currentVehicle = NULL; m_currentVehicle = NULL;
@ -427,9 +428,9 @@ MxResult LegoOmni::Create(MxOmniCreateParam& p)
m_animationManager = new LegoAnimationManager(); m_animationManager = new LegoAnimationManager();
m_buildingManager = new LegoBuildingManager(); m_buildingManager = new LegoBuildingManager();
m_gameState = new LegoGameState(); m_gameState = new LegoGameState();
// TODO: initialize list at m_unk78 m_worldList = new LegoWorldList();
if (m_unk6c && m_gifManager && m_unk78 && m_plantManager && m_animationManager && m_buildingManager) { if (m_unk6c && m_gifManager && m_worldList && m_plantManager && m_animationManager && m_buildingManager) {
// TODO: initialize a bunch of MxVariables // TODO: initialize a bunch of MxVariables
RegisterScripts(); RegisterScripts();
FUN_1001a700(); FUN_1001a700();

View file

@ -21,6 +21,7 @@ class LegoSoundManager;
class LegoUnkSaveDataWriter; class LegoUnkSaveDataWriter;
class LegoVideoManager; class LegoVideoManager;
class LegoWorld; class LegoWorld;
class LegoWorldList;
class MxAtomId; class MxAtomId;
class MxBackgroundAudioManager; class MxBackgroundAudioManager;
class MxDSFile; class MxDSFile;
@ -117,7 +118,7 @@ class LegoOmni : public MxOmni {
undefined4 m_unk6c; undefined4 m_unk6c;
LegoInputManager* m_inputMgr; // 0x70 LegoInputManager* m_inputMgr; // 0x70
GifManager* m_gifManager; GifManager* m_gifManager;
undefined4 m_unk78; LegoWorldList* m_worldList; // 0x78
LegoWorld* m_currentWorld; LegoWorld* m_currentWorld;
MxBool m_unk80; MxBool m_unk80;
LegoNavController* m_navController; // 0x84 LegoNavController* m_navController; // 0x84

View file

@ -67,6 +67,24 @@ MxResult LegoWorld::SetAsCurrentWorld(MxDSObject& p_dsObject)
return SUCCESS; return SUCCESS;
} }
// SYNTHETIC: LEGO1 0x1001eed0
// MxPresenterListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1001ef40
// MxPtrListCursor<MxPresenter>::~MxPtrListCursor<MxPresenter>
// SYNTHETIC: LEGO1 0x1001ef90
// MxListCursor<MxPresenter *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x1001f000
// MxPtrListCursor<MxPresenter>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1001f070
// MxListCursor<MxPresenter *>::~MxListCursor<MxPresenter *>
// FUNCTION: LEGO1 0x1001f0c0
// MxPresenterListCursor::~MxPresenterListCursor
// FUNCTION: LEGO1 0x1001f5e0 // FUNCTION: LEGO1 0x1001f5e0
MxLong LegoWorld::Notify(MxParam& p_param) MxLong LegoWorld::Notify(MxParam& p_param)
{ {

36
LEGO1/legoworldlist.cpp Normal file
View file

@ -0,0 +1,36 @@
#include "legoworldlist.h"
#include "legoworld.h"
// FUNCTION: LEGO1 0x100598d0
MxS8 LegoWorldList::Compare(LegoWorld* p_a, LegoWorld* p_b)
{
return p_a == p_b ? 0 : p_a < p_b ? -1 : 1;
}
// TEMPLATE: LEGO1 0x100598f0
// MxCollection<LegoWorld *>::Compare
// TEMPLATE: LEGO1 0x10059900
// MxCollection<LegoWorld *>::~MxCollection<LegoWorld *>
// TEMPLATE: LEGO1 0x10059950
// MxCollection<LegoWorld *>::Destroy
// TEMPLATE: LEGO1 0x10059960
// MxList<LegoWorld *>::~MxList<LegoWorld *>
// FUNCTION: LEGO1 0x100599f0
void LegoWorldList::Destroy(LegoWorld* p_world)
{
delete p_world;
}
// SYNTHETIC: LEGO1 0x10059ac0
// MxCollection<LegoWorld *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x10059b30
// MxList<LegoWorld *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x10059be0
// MxPtrList<LegoWorld>::`scalar deleting destructor'

27
LEGO1/legoworldlist.h Normal file
View file

@ -0,0 +1,27 @@
#ifndef LEGOWORLDLIST_H
#define LEGOWORLDLIST_H
#include "mxlist.h"
#include "mxtypes.h"
class LegoWorld;
// VTABLE: LEGO1 0x100d8700
// class MxCollection<LegoWorld *>
// VTABLE: LEGO1 0x100d8718
// class MxList<LegoWorld *>
// VTABLE: LEGO1 0x100d8730
// class MxPtrList<LegoWorld>
// VTABLE: LEGO1 0x100d8680
// SIZE 0x18
class LegoWorldList : public MxPtrList<LegoWorld> {
public:
LegoWorldList() : MxPtrList<LegoWorld>(Destroy) {}
virtual MxS8 Compare(LegoWorld*, LegoWorld*) override; // vtable+0x14
static void Destroy(LegoWorld*);
};
#endif // LEGOWORLDLIST_H

View file

@ -26,6 +26,13 @@ class MxDSActionList : public MxList<MxDSAction*> {
undefined m_unk18; undefined m_unk18;
}; };
typedef MxListCursorChild<MxDSAction*> MxDSActionListCursor; // VTABLE: LEGO1 0x100d7e68
// class MxListCursor<MxDSAction *>
// VTABLE: LEGO1 0x100d7e50
class MxDSActionListCursor : public MxListCursor<MxDSAction*> {
public:
MxDSActionListCursor(MxDSActionList* p_list) : MxListCursor<MxDSAction*>(p_list){};
};
#endif // MXDSACTIONLIST_H #endif // MXDSACTIONLIST_H

View file

@ -2,6 +2,19 @@
DECOMP_SIZE_ASSERT(MxDSMultiAction, 0x9c) DECOMP_SIZE_ASSERT(MxDSMultiAction, 0x9c)
// TODO: Should be moved later
// SYNTHETIC: LEGO1 0x1004ad10
// MxDSActionListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x1004ad80
// MxListCursor<MxDSAction *>::~MxListCursor<MxDSAction *>
// SYNTHETIC: LEGO1 0x1004add0
// MxListCursor<MxDSAction *>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x1004ae40
// MxDSActionListCursor::~MxDSActionListCursor
// FUNCTION: LEGO1 0x100c9b90 // FUNCTION: LEGO1 0x100c9b90
MxDSMultiAction::MxDSMultiAction() MxDSMultiAction::MxDSMultiAction()
{ {

View file

@ -33,6 +33,18 @@ void MxDSSelectAction::CopyFrom(MxDSSelectAction& p_dsSelectAction)
this->m_unk0xac->Append(string); this->m_unk0xac->Append(string);
} }
// SYNTHETIC: LEGO1 0x100cbbd0
// MxStringListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100cbc40
// MxListCursor<MxString>::~MxListCursor<MxString>
// SYNTHETIC: LEGO1 0x100cbc90
// MxListCursor<MxString>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100cbd00
// MxStringListCursor::~MxStringListCursor
// FUNCTION: LEGO1 0x100cbd50 // FUNCTION: LEGO1 0x100cbd50
MxDSSelectAction& MxDSSelectAction::operator=(MxDSSelectAction& p_dsSelectAction) MxDSSelectAction& MxDSSelectAction::operator=(MxDSSelectAction& p_dsSelectAction)
{ {
@ -130,3 +142,6 @@ void MxDSSelectAction::Deserialize(char** p_source, MxS16 p_unk24)
*p_source += extraFlag; *p_source += extraFlag;
} }
// TEMPLATE: LEGO1 0x100cc450
// MxListEntry<MxString>::GetValue

View file

@ -100,18 +100,10 @@ class MxListCursor : public MxCore {
MxListEntry<T>* m_match; MxListEntry<T>* m_match;
}; };
// Unclear purpose
template <class T> template <class T>
class MxListCursorChild : public MxListCursor<T> { class MxPtrListCursor : public MxListCursor<T*> {
public: public:
MxListCursorChild(MxList<T>* p_list) : MxListCursor<T>(p_list) {} MxPtrListCursor(MxPtrList<T>* p_list) : MxListCursor<T*>(p_list){};
};
// Unclear purpose
template <class T>
class MxListCursorChildChild : public MxListCursorChild<T> {
public:
MxListCursorChildChild(MxList<T>* p_list) : MxListCursorChild<T>(p_list) {}
}; };
template <class T> template <class T>

View file

@ -21,6 +21,19 @@ void MxMediaPresenter::Destroy()
Destroy(FALSE); Destroy(FALSE);
} }
// TODO: These probably belong in another class
// SYNTHETIC: LEGO1 0x100b46e0
// MxStreamChunkListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100b4750
// MxListCursor<MxStreamChunk *>::~MxListCursor<MxStreamChunk *>
// SYNTHETIC: LEGO1 0x100b47a0
// MxListCursor<MxStreamChunk *>::`scalar deleting destructor'
// FUNCTION: LEGO1 0x100b4810
// MxStreamChunkListCursor::~MxStreamChunkListCursor
// FUNCTION: LEGO1 0x100b54e0 // FUNCTION: LEGO1 0x100b54e0
void MxMediaPresenter::Init() void MxMediaPresenter::Init()
{ {

View file

@ -15,7 +15,17 @@ class MxPresenterList : public MxPtrList<MxPresenter> {
virtual MxS8 Compare(MxPresenter*, MxPresenter*) override; // vtable+0x14 virtual MxS8 Compare(MxPresenter*, MxPresenter*) override; // vtable+0x14
}; };
typedef MxListCursorChildChild<MxPresenter*> MxPresenterListCursor; // VTABLE: LEGO1 0x100d6488
// class MxListCursor<MxPresenter *>
// VTABLE: LEGO1 0x100d6530
// class MxPtrListCursor<MxPresenter>
// VTABLE: LEGO1 0x100d6470
class MxPresenterListCursor : public MxPtrListCursor<MxPresenter> {
public:
MxPresenterListCursor(MxPresenterList* p_list) : MxPtrListCursor<MxPresenter>(p_list){};
};
// VTABLE: LEGO1 0x100d6350 // VTABLE: LEGO1 0x100d6350
// class MxCollection<MxPresenter *> // class MxCollection<MxPresenter *>

View file

@ -86,6 +86,24 @@ void MxRegion::vtable18(MxRect32& p_rect)
m_rect.UpdateBounds(p_rect); m_rect.UpdateBounds(p_rect);
} }
// SYNTHETIC: LEGO1 0x100c3be0
// MxRegionListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c3c50
// MxPtrListCursor<MxRegionTopBottom>::~MxPtrListCursor<MxRegionTopBottom>
// SYNTHETIC: LEGO1 0x100c3ca0
// MxListCursor<MxRegionTopBottom *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c3d10
// MxPtrListCursor<MxRegionTopBottom>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c3d80
// MxListCursor<MxRegionTopBottom *>::~MxListCursor<MxRegionTopBottom *>
// FUNCTION: LEGO1 0x100c3dd0
// MxRegionListCursor::~MxRegionListCursor
// FUNCTION: LEGO1 0x100c3e20 // FUNCTION: LEGO1 0x100c3e20
MxBool MxRegion::vtable1c(MxRect32& p_rect) MxBool MxRegion::vtable1c(MxRect32& p_rect)
{ {
@ -105,6 +123,21 @@ MxBool MxRegion::vtable1c(MxRect32& p_rect)
return FALSE; return FALSE;
} }
// SYNTHETIC: LEGO1 0x100c4790
// MxRegionLeftRightListCursor::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c4800
// MxPtrListCursor<MxRegionLeftRight>::~MxPtrListCursor<MxRegionLeftRight>
// SYNTHETIC: LEGO1 0x100c4850
// MxListCursor<MxRegionLeftRight *>::`scalar deleting destructor'
// SYNTHETIC: LEGO1 0x100c48c0
// MxPtrListCursor<MxRegionLeftRight>::`scalar deleting destructor'
// TEMPLATE: LEGO1 0x100c4930
// MxListCursor<MxRegionLeftRight *>::~MxListCursor<MxRegionLeftRight *>
// FUNCTION: LEGO1 0x100c4c90 // FUNCTION: LEGO1 0x100c4c90
MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom) MxRegionTopBottom::MxRegionTopBottom(MxS32 p_top, MxS32 p_bottom)
{ {
@ -167,6 +200,15 @@ void MxRegionTopBottom::FUN_100c5280(MxS32 p_left, MxS32 p_right)
} }
} }
// TEMPLATE: LEGO1 0x100c54f0
// MxListCursor<MxRegionLeftRight *>::MxListCursor<MxRegionLeftRight *>
// FUNCTION: LEGO1 0x100c5560
// MxRegionLeftRightListCursor::~MxRegionLeftRightListCursor
// TEMPLATE: LEGO1 0x100c55b0
// MxListCursor<MxRegionLeftRight *>::operator=
// FUNCTION: LEGO1 0x100c55d0 // FUNCTION: LEGO1 0x100c55d0
MxRegionTopBottom* MxRegionTopBottom::Clone() MxRegionTopBottom* MxRegionTopBottom::Clone()
{ {

View file

@ -23,13 +23,21 @@ class MxRegionList : public MxPtrList<MxRegionTopBottom> {
static void Destroy(MxRegionTopBottom*); static void Destroy(MxRegionTopBottom*);
}; };
// VTABLE: LEGO1 0x100dcb88 // VTABLE: LEGO1 0x100dcb70
// class MxListCursorChildChild<MxRegionTopBottom *> // class MxPtrListCursor<MxRegionTopBottom>
typedef MxListCursorChildChild<MxRegionTopBottom*> MxRegionListCursor;
// VTABLE: LEGO1 0x100dcc10 // VTABLE: LEGO1 0x100dcba0
// class MxListCursorChildChild<MxRegionLeftRight *> // class MxListCursor<MxRegionTopBottom *>
typedef MxListCursorChildChild<MxRegionLeftRight*> MxRegionLeftRightListCursor;
// TODO: The initialize list param type should be MxRegionList, but doing that
// drastically reduced the match percentage for MxRegion::vtable18.
// It also works with MxPtrList, so we'll do that until we figure this out.
// VTABLE: LEGO1 0x100dcb88
class MxRegionListCursor : public MxPtrListCursor<MxRegionTopBottom> {
public:
MxRegionListCursor(MxPtrList<MxRegionTopBottom>* p_list) : MxPtrListCursor<MxRegionTopBottom>(p_list){};
};
// VTABLE: LEGO1 0x100dcc40 // VTABLE: LEGO1 0x100dcc40
// class MxCollection<MxRegionLeftRight *> // class MxCollection<MxRegionLeftRight *>
@ -48,4 +56,16 @@ class MxRegionLeftRightList : public MxPtrList<MxRegionLeftRight> {
static void Destroy(MxRegionLeftRight*); static void Destroy(MxRegionLeftRight*);
}; };
// VTABLE: LEGO1 0x100dcbf8
// class MxPtrListCursor<MxRegionLeftRight>
// VTABLE: LEGO1 0x100dcc28
// class MxListCursor<MxRegionLeftRight *>
// VTABLE: LEGO1 0x100dcc10
class MxRegionLeftRightListCursor : public MxPtrListCursor<MxRegionLeftRight> {
public:
MxRegionLeftRightListCursor(MxRegionLeftRightList* p_list) : MxPtrListCursor<MxRegionLeftRight>(p_list){};
};
#endif // MXREGIONLIST_H #endif // MXREGIONLIST_H

View file

@ -23,6 +23,13 @@ class MxStreamChunkList : public MxList<MxStreamChunk*> {
static void Destroy(MxStreamChunk* p_chunk); static void Destroy(MxStreamChunk* p_chunk);
}; };
typedef MxListCursorChild<MxStreamChunk*> MxStreamChunkListCursor; // VTABLE: LEGO1 0x100dc510
class MxStreamChunkListCursor : public MxListCursor<MxStreamChunk*> {
public:
MxStreamChunkListCursor(MxStreamChunkList* p_list) : MxListCursor<MxStreamChunk*>(p_list){};
};
// VTABLE: LEGO1 0x100dc528
// class MxListCursor<MxStreamChunk *>
#endif // MXSTREAMCHUNKLIST_H #endif // MXSTREAMCHUNKLIST_H

View file

@ -51,13 +51,13 @@ MxStreamController::MxStreamController()
// TEMPLATE: LEGO1 0x100c0ee0 // TEMPLATE: LEGO1 0x100c0ee0
// list<MxNextActionDataStart *,allocator<MxNextActionDataStart *> >::_Buynode // list<MxNextActionDataStart *,allocator<MxNextActionDataStart *> >::_Buynode
// TEMPLATE: LEGO1 0x100c0fc0 // FUNCTION: LEGO1 0x100c0fc0
// MxStreamListMxDSSubscriber::~MxStreamListMxDSSubscriber // MxStreamListMxDSSubscriber::~MxStreamListMxDSSubscriber
// TEMPLATE: LEGO1 0x100c1010 // FUNCTION: LEGO1 0x100c1010
// MxStreamListMxDSAction::~MxStreamListMxDSAction // MxStreamListMxDSAction::~MxStreamListMxDSAction
// TEMPLATE: LEGO1 0x100c1060 // FUNCTION: LEGO1 0x100c1060
// MxStreamListMxNextActionDataStart::~MxStreamListMxNextActionDataStart // MxStreamListMxNextActionDataStart::~MxStreamListMxNextActionDataStart
// TEMPLATE: LEGO1 0x100c10b0 // TEMPLATE: LEGO1 0x100c10b0

View file

@ -9,6 +9,12 @@
class MxStringList : public MxList<MxString> {}; class MxStringList : public MxList<MxString> {};
// VTABLE: LEGO1 0x100dd058 // VTABLE: LEGO1 0x100dd058
typedef MxListCursorChild<MxString> MxStringListCursor; class MxStringListCursor : public MxListCursor<MxString> {
public:
MxStringListCursor(MxStringList* p_list) : MxListCursor<MxString>(p_list){};
};
// VTABLE: LEGO1 0x100dd070
// class MxListCursor<MxString>
#endif // MXSTRINGLIST_H #endif // MXSTRINGLIST_H