diff --git a/asm/MetroidPrime/CObjectList.s b/asm/MetroidPrime/CObjectList.s index 315eb8fa..1c00b2f9 100644 --- a/asm/MetroidPrime/CObjectList.s +++ b/asm/MetroidPrime/CObjectList.s @@ -3,8 +3,8 @@ .section .data .balign 8 -.global lbl_803D96D8 -lbl_803D96D8: +.global __vt__11CObjectList +__vt__11CObjectList: # ROM: 0x3D66D8 .4byte 0 .4byte 0 @@ -282,10 +282,10 @@ IsQualified__11CObjectListFRC7CEntity: __ct__11CObjectListF15EGameObjectList: /* 80010038 0000CF98 94 21 FF F0 */ stwu r1, -0x10(r1) /* 8001003C 0000CF9C 7C 08 02 A6 */ mflr r0 -/* 80010040 0000CFA0 3C A0 80 3E */ lis r5, lbl_803D96D8@ha +/* 80010040 0000CFA0 3C A0 80 3E */ lis r5, __vt__11CObjectList@ha /* 80010044 0000CFA4 38 C0 00 08 */ li r6, 8 /* 80010048 0000CFA8 90 01 00 14 */ stw r0, 0x14(r1) -/* 8001004C 0000CFAC 38 05 96 D8 */ addi r0, r5, lbl_803D96D8@l +/* 8001004C 0000CFAC 38 05 96 D8 */ addi r0, r5, __vt__11CObjectList@l /* 80010050 0000CFB0 38 A0 00 00 */ li r5, 0 /* 80010054 0000CFB4 38 E0 04 00 */ li r7, 0x400 /* 80010058 0000CFB8 93 E1 00 0C */ stw r31, 0xc(r1) diff --git a/asm/MetroidPrime/Cameras/CBallCamera.s b/asm/MetroidPrime/Cameras/CBallCamera.s index 794eccdb..bbdc7b54 100644 --- a/asm/MetroidPrime/Cameras/CBallCamera.s +++ b/asm/MetroidPrime/Cameras/CBallCamera.s @@ -10033,9 +10033,9 @@ UpdateObjectTooCloseId__11CBallCameraFR13CStateManager: /* 8008997C 000868DC 80 84 08 4C */ lwz r4, 0x84c(r4) /* 80089980 000868E0 48 1F B3 C9 */ bl GetBallPosition__7CPlayerCFv /* 80089984 000868E4 80 BF 08 48 */ lwz r5, 0x848(r31) -/* 80089988 000868E8 3C 60 80 3E */ lis r3, lbl_803D96D8@ha +/* 80089988 000868E8 3C 60 80 3E */ lis r3, __vt__11CObjectList@ha /* 8008998C 000868EC C3 9E 00 40 */ lfs f28, 0x40(r30) -/* 80089990 000868F0 38 03 96 D8 */ addi r0, r3, lbl_803D96D8@l +/* 80089990 000868F0 38 03 96 D8 */ addi r0, r3, __vt__11CObjectList@l /* 80089994 000868F4 C3 7E 00 50 */ lfs f27, 0x50(r30) /* 80089998 000868F8 38 81 00 70 */ addi r4, r1, 0x70 /* 8008999C 000868FC C3 5E 00 60 */ lfs f26, 0x60(r30) diff --git a/configure.py b/configure.py index 1f2247a4..a4ca0e00 100755 --- a/configure.py +++ b/configure.py @@ -40,7 +40,7 @@ LIBS = [ "MetroidPrime/Cameras/CCameraManager", "MetroidPrime/CControlMapper", "MetroidPrime/Cameras/CFirstPersonCamera", - "MetroidPrime/CObjectList", + ["MetroidPrime/CObjectList", True], "MetroidPrime/Player/CPlayer", ["MetroidPrime/CAxisAngle", True], "MetroidPrime/CEulerAngles", diff --git a/include/MetroidPrime/CEntity.hpp b/include/MetroidPrime/CEntity.hpp index d8481c03..791a1dc8 100644 --- a/include/MetroidPrime/CEntity.hpp +++ b/include/MetroidPrime/CEntity.hpp @@ -32,6 +32,7 @@ public: TAreaId GetAreaId() const; TAreaId GetAreaIdAlways() const { return x4_areaId; } bool GetActive() const { return x30_24_active; } + bool IsScriptingBlocked() const { return x30_26_scriptingBlocked; } // might be fake? rstl::vector< SConnection >& ConnectionList() { return x20_conns; } diff --git a/include/MetroidPrime/CObjectList.hpp b/include/MetroidPrime/CObjectList.hpp index 63ee7572..f6d03166 100644 --- a/include/MetroidPrime/CObjectList.hpp +++ b/include/MetroidPrime/CObjectList.hpp @@ -25,23 +25,23 @@ class CObjectList { CEntity* mEnt; short mNext; short mPrev; - SObjectListEntry(); + SObjectListEntry() : mEnt(nullptr), mNext(-1), mPrev(-1) {} }; public: CObjectList(EGameObjectList list); - virtual bool IsQualified(CEntity& ent); + virtual bool IsQualified(const CEntity& ent); void AddObject(CEntity& ent); void RemoveObject(TUniqueId uid); - CEntity* GetObjectById(); - const CEntity* GetObjectById() const; + CEntity* GetObjectById(TUniqueId uid); + const CEntity* GetObjectById(TUniqueId uid) const; CEntity* GetValidObjectById(TUniqueId uid); const CEntity* GetValidObjectById(TUniqueId uid) const; CEntity* operator[](int idx); const CEntity* operator[](int idx) const; - const CEntity* GetValidObjectByIndex(int idx) const; + const CEntity* GetObjectByIndex(int idx) const; int size() const { return mCount; } int GetFirstObjectIndex() const { return mFirstId; } diff --git a/obj_files.mk b/obj_files.mk index 2a3131cd..1573dcc0 100644 --- a/obj_files.mk +++ b/obj_files.mk @@ -7,7 +7,7 @@ METROIDPRIME :=\ $(BUILD_DIR)/asm/MetroidPrime/Cameras/CCameraManager.o\ $(BUILD_DIR)/asm/MetroidPrime/CControlMapper.o\ $(BUILD_DIR)/asm/MetroidPrime/Cameras/CFirstPersonCamera.o\ - $(BUILD_DIR)/asm/MetroidPrime/CObjectList.o\ + $(BUILD_DIR)/src/MetroidPrime/CObjectList.o\ $(BUILD_DIR)/asm/MetroidPrime/Player/CPlayer.o\ $(BUILD_DIR)/src/MetroidPrime/CAxisAngle.o\ $(BUILD_DIR)/asm/MetroidPrime/CEulerAngles.o\ diff --git a/src/MetroidPrime/CObjectList.cpp b/src/MetroidPrime/CObjectList.cpp index eca09163..297d5c90 100644 --- a/src/MetroidPrime/CObjectList.cpp +++ b/src/MetroidPrime/CObjectList.cpp @@ -2,15 +2,13 @@ #include "MetroidPrime/CEntity.hpp" -CObjectList::SObjectListEntry::SObjectListEntry() : mEnt(nullptr), mNext(-1), mPrev(-1) {} - CObjectList::CObjectList(EGameObjectList list) : mListType(list), mFirstId(-1), mCount(0) { for (int i = 0; i < kMaxObjects; ++i) { mObjects[i] = SObjectListEntry(); } } -bool CObjectList::IsQualified(CEntity& ent) { return true; } +bool CObjectList::IsQualified(const CEntity& ent) { return true; } void CObjectList::AddObject(CEntity& ent) { if (IsQualified(ent)) { @@ -28,18 +26,72 @@ void CObjectList::AddObject(CEntity& ent) { } } -void CObjectList::RemoveObject(TUniqueId uid) {} +void CObjectList::RemoveObject(TUniqueId uid) { + if (mObjects[uid.Value()].mEnt == nullptr) { + return; + } -CEntity* CObjectList::GetObjectById() { return nullptr; } + if (mObjects[uid.Value()].mEnt->GetUniqueId() != uid) { + return; + } -const CEntity* CObjectList::GetObjectById() const { return nullptr; } + if (mFirstId == uid.Value()) { + mFirstId = mObjects[uid.Value()].mNext; + s16 next = mObjects[uid.Value()].mNext; + if (next != -1) { + mObjects[next].mPrev = -1; + } + } else { + mObjects[mObjects[uid.Value()].mPrev].mNext = mObjects[uid.Value()].mNext; + s16 next = mObjects[uid.Value()].mNext; + if (next != -1) { + mObjects[next].mPrev = mObjects[uid.Value()].mPrev; + } + } + --mCount; + mObjects[uid.Value()].mEnt = nullptr; + u16 index = uid.Value(); + mObjects[index].mNext = -1; + mObjects[index].mPrev = -1; +} -CEntity* CObjectList::GetValidObjectById(TUniqueId uid) { return nullptr; } +CEntity* CObjectList::GetObjectById(TUniqueId uid) { + if (uid == kInvalidUniqueId) + return nullptr; + CEntity* ret = mObjects[uid.Value()].mEnt; + return ret && uid == ret->GetUniqueId() && !ret->IsScriptingBlocked() ? ret : nullptr; +} -const CEntity* CObjectList::GetValidObjectById(TUniqueId uid) const { return nullptr; } +const CEntity* CObjectList::GetObjectById(TUniqueId uid) const { + if (uid == kInvalidUniqueId) + return nullptr; + const CEntity* ret = mObjects[uid.Value()].mEnt; + return ret && uid == ret->GetUniqueId() && !ret->IsScriptingBlocked() ? ret : nullptr; +} -CEntity* CObjectList::operator[](int idx) { return nullptr; } +CEntity* CObjectList::GetValidObjectById(TUniqueId uid) { + if (uid == kInvalidUniqueId) + return nullptr; + CEntity* ret = mObjects[uid.Value()].mEnt; + return ret && uid == ret->GetUniqueId() ? ret : nullptr; +} -const CEntity* CObjectList::operator[](int idx) const { return nullptr; } +const CEntity* CObjectList::GetValidObjectById(TUniqueId uid) const { + if (uid == kInvalidUniqueId) + return nullptr; + CEntity* ret = mObjects[uid.Value()].mEnt; + return ret && uid == ret->GetUniqueId() ? ret : nullptr; +} -const CEntity* CObjectList::GetValidObjectByIndex(int idx) const { return nullptr; } +CEntity* CObjectList::operator[](int idx) { + CEntity* ret = mObjects[idx].mEnt; + return ret == nullptr || ret->IsScriptingBlocked() ? nullptr : ret; +} + +const CEntity* CObjectList::operator[](int idx) const { + const CEntity* ret = mObjects[idx].mEnt; + return ret == nullptr || ret->IsScriptingBlocked() ? nullptr : ret; +} + + +const CEntity* CObjectList::GetObjectByIndex(int idx) const { return mObjects[idx].mEnt; }