From 45ec66abc2f1a6aca03419ca747359f41b5a1714 Mon Sep 17 00:00:00 2001 From: Henrique Gemignani Passos Lima Date: Tue, 15 Nov 2022 15:45:15 +0200 Subject: [PATCH] Expand CStateManager. - Expand ct/dt - Add AllocateUniqueId - Add rstl::set, multimap, reserved_vector::resize Former-commit-id: 92def96f3194715af886f4247eecb279529e0ce7 --- asm/MetroidPrime/CStateManager.s | 24 +++++------ include/MetaRender/IRenderer.hpp | 2 +- include/MetroidPrime/CActorModelParticles.hpp | 2 + include/MetroidPrime/CEnvFxManager.hpp | 2 + include/MetroidPrime/CFluidPlaneManager.hpp | 1 + include/MetroidPrime/CStateManager.hpp | 24 +++++++---- .../MetroidPrime/CStateManagerContainer.hpp | 1 + .../MetroidPrime/Cameras/CCameraBlurPass.hpp | 2 +- include/rstl/list.hpp | 24 ++++++----- include/rstl/multimap.hpp | 42 +++++++++++++++++++ include/rstl/red_black_tree.hpp | 5 +++ include/rstl/reserved_vector.hpp | 14 +++++++ include/rstl/set.hpp | 41 ++++++++++++++++++ src/MetroidPrime/CStateManager.cpp | 42 ++++++++++++++++--- 14 files changed, 189 insertions(+), 37 deletions(-) create mode 100644 include/rstl/multimap.hpp create mode 100644 include/rstl/set.hpp diff --git a/asm/MetroidPrime/CStateManager.s b/asm/MetroidPrime/CStateManager.s index 5aa6bb14..f9607f7a 100644 --- a/asm/MetroidPrime/CStateManager.s +++ b/asm/MetroidPrime/CStateManager.s @@ -11296,10 +11296,10 @@ lbl_8004D58C: lbl_8004D5A0: /* 8004D5A0 0004A500 38 7D 08 6C */ addi r3, r29, 0x86c /* 8004D5A4 0004A504 38 80 FF FF */ li r4, -1 -/* 8004D5A8 0004A508 48 00 01 05 */ bl sub_8004d6ac +/* 8004D5A8 0004A508 48 00 01 05 */ bl "__dt__Q24rstl36single_ptr<22CStateManagerContainer>Fv" /* 8004D5AC 0004A50C 38 7D 08 54 */ addi r3, r29, 0x854 /* 8004D5B0 0004A510 38 80 FF FF */ li r4, -1 -/* 8004D5B4 0004A514 48 00 30 D1 */ bl sub_80050684 +/* 8004D5B4 0004A514 48 00 30 D1 */ bl "__dt__Q24rstl72list,Q24rstl17rmemory_allocator>Fv" /* 8004D5B8 0004A518 34 1D 08 50 */ addic. r0, r29, 0x850 /* 8004D5BC 0004A51C 41 82 00 24 */ beq lbl_8004D5E0 /* 8004D5C0 0004A520 80 7D 08 50 */ lwz r3, 0x850(r29) @@ -11373,8 +11373,8 @@ lbl_8004D694: /* 8004D6A4 0004A604 38 21 00 50 */ addi r1, r1, 0x50 /* 8004D6A8 0004A608 4E 80 00 20 */ blr -.global sub_8004d6ac -sub_8004d6ac: +.global "__dt__Q24rstl36single_ptr<22CStateManagerContainer>Fv" +"__dt__Q24rstl36single_ptr<22CStateManagerContainer>Fv": /* 8004D6AC 0004A60C 94 21 FF F0 */ stwu r1, -0x10(r1) /* 8004D6B0 0004A610 7C 08 02 A6 */ mflr r0 /* 8004D6B4 0004A614 90 01 00 14 */ stw r0, 0x14(r1) @@ -12521,7 +12521,7 @@ lbl_8004E634: /* 8004E63C 0004B59C 38 7F 0D 14 */ addi r3, r31, 0xd14 /* 8004E640 0004B5A0 38 A1 00 74 */ addi r5, r1, 0x74 /* 8004E644 0004B5A4 38 80 00 09 */ li r4, 9 -/* 8004E648 0004B5A8 48 00 0C 99 */ bl sub_8004f2e0 +/* 8004E648 0004B5A8 48 00 0C 99 */ bl "__ct__Q24rstl36reserved_vector<15CCameraBlurPass,9>FiRC15CCameraBlurPass" /* 8004E64C 0004B5AC 88 01 00 80 */ lbz r0, 0x80(r1) /* 8004E650 0004B5B0 28 00 00 00 */ cmplwi r0, 0 /* 8004E654 0004B5B4 41 82 00 1C */ beq lbl_8004E670 @@ -13365,8 +13365,8 @@ lbl_8004EC74: /* 8004F2D8 0004C238 38 21 01 00 */ addi r1, r1, 0x100 /* 8004F2DC 0004C23C 4E 80 00 20 */ blr -.global sub_8004f2e0 -sub_8004f2e0: +.global "__ct__Q24rstl36reserved_vector<15CCameraBlurPass,9>FiRC15CCameraBlurPass" +"__ct__Q24rstl36reserved_vector<15CCameraBlurPass,9>FiRC15CCameraBlurPass": /* 8004F2E0 0004C240 94 21 FF F0 */ stwu r1, -0x10(r1) /* 8004F2E4 0004C244 7C 08 02 A6 */ mflr r0 /* 8004F2E8 0004C248 90 01 00 14 */ stw r0, 0x14(r1) @@ -13374,7 +13374,7 @@ sub_8004f2e0: /* 8004F2F0 0004C250 7C 7F 1B 78 */ mr r31, r3 /* 8004F2F4 0004C254 90 83 00 00 */ stw r4, 0(r3) /* 8004F2F8 0004C258 38 7F 00 04 */ addi r3, r31, 4 -/* 8004F2FC 0004C25C 48 00 00 1D */ bl sub_8004f318 +/* 8004F2FC 0004C25C 48 00 00 1D */ bl "uninitialized_fill_n__4rstlFP15CCameraBlurPassiRC15CCameraBlurPass" /* 8004F300 0004C260 80 01 00 14 */ lwz r0, 0x14(r1) /* 8004F304 0004C264 7F E3 FB 78 */ mr r3, r31 /* 8004F308 0004C268 83 E1 00 0C */ lwz r31, 0xc(r1) @@ -13382,8 +13382,8 @@ sub_8004f2e0: /* 8004F310 0004C270 38 21 00 10 */ addi r1, r1, 0x10 /* 8004F314 0004C274 4E 80 00 20 */ blr -.global sub_8004f318 -sub_8004f318: +.global "uninitialized_fill_n__4rstlFP15CCameraBlurPassiRC15CCameraBlurPass" +"uninitialized_fill_n__4rstlFP15CCameraBlurPassiRC15CCameraBlurPass": /* 8004F318 0004C278 94 21 FF E0 */ stwu r1, -0x20(r1) /* 8004F31C 0004C27C 7C 08 02 A6 */ mflr r0 /* 8004F320 0004C280 90 01 00 24 */ stw r0, 0x24(r1) @@ -14804,8 +14804,8 @@ lbl_8005065C: /* 8005067C 0004D5DC 38 21 00 10 */ addi r1, r1, 0x10 /* 80050680 0004D5E0 4E 80 00 20 */ blr -.global sub_80050684 -sub_80050684: +.global "__dt__Q24rstl72list,Q24rstl17rmemory_allocator>Fv" +"__dt__Q24rstl72list,Q24rstl17rmemory_allocator>Fv": /* 80050684 0004D5E4 94 21 FF E0 */ stwu r1, -0x20(r1) /* 80050688 0004D5E8 7C 08 02 A6 */ mflr r0 /* 8005068C 0004D5EC 90 01 00 24 */ stw r0, 0x24(r1) diff --git a/include/MetaRender/IRenderer.hpp b/include/MetaRender/IRenderer.hpp index 2b5edb8f..16a69d2d 100644 --- a/include/MetaRender/IRenderer.hpp +++ b/include/MetaRender/IRenderer.hpp @@ -16,7 +16,7 @@ class CVector3f; class IRenderer { public: - typedef void (*TDrawableCallback)(void*, void*, int); + typedef void (*TDrawableCallback)(const void*, const void*, int); enum EDrawableSorting { kDS_SortedCallback, diff --git a/include/MetroidPrime/CActorModelParticles.hpp b/include/MetroidPrime/CActorModelParticles.hpp index c1144983..068e680d 100644 --- a/include/MetroidPrime/CActorModelParticles.hpp +++ b/include/MetroidPrime/CActorModelParticles.hpp @@ -13,6 +13,8 @@ public: private: // TODO + uchar x0_pad[0xe8]; }; +CHECK_SIZEOF(CActorModelParticles, 0xe8); #endif // _CACTORMODELPARTICLES diff --git a/include/MetroidPrime/CEnvFxManager.hpp b/include/MetroidPrime/CEnvFxManager.hpp index a5626728..9590f130 100644 --- a/include/MetroidPrime/CEnvFxManager.hpp +++ b/include/MetroidPrime/CEnvFxManager.hpp @@ -69,6 +69,8 @@ private: rstl::reserved_vector< CVector3f, 16 > xb84_snowZDeltas; TLockedToken< CTexture > xc48_underwaterFlake; bool xc54_; + int xc58_; }; +CHECK_SIZEOF(CEnvFxManager, 0xc58); #endif // _CENVFXMANAGER diff --git a/include/MetroidPrime/CFluidPlaneManager.hpp b/include/MetroidPrime/CFluidPlaneManager.hpp index 1dbb9896..45dd74ac 100644 --- a/include/MetroidPrime/CFluidPlaneManager.hpp +++ b/include/MetroidPrime/CFluidPlaneManager.hpp @@ -30,5 +30,6 @@ private: bool x120_; bool x121_; }; +CHECK_SIZEOF(CFluidPlaneManager, 0x124); #endif // _CFLUIDPLANEMANAGER diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index 738e7068..8b2d83b5 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -22,7 +22,9 @@ #include "rstl/auto_ptr.hpp" #include "rstl/list.hpp" +#include "rstl/set.hpp" #include "rstl/map.hpp" +#include "rstl/multimap.hpp" #include "rstl/pair.hpp" #include "rstl/rc_ptr.hpp" #include "rstl/reserved_vector.hpp" @@ -77,6 +79,13 @@ enum EThermalDrawFlag { kTD_Bypass, }; +struct SScriptObjectStream { + // CEntity* x0_obj; + EScriptObjectType x0_type; + u32 x4_position; + u32 x8_length; +}; + struct SOnScreenTex { CAssetId x0_id; CVector2i x4_origin; @@ -268,7 +277,7 @@ private: enum EInitPhase { kIP_LoadWorld, kIP_LoadFirstArea, kIP_Done }; ushort x0_nextFreeIndex; - rstl::reserved_vector< ushort, 1024 > x8_objectIndexArray; + rstl::reserved_vector< ushort, 1024 > x4_objectIndexArray; rstl::reserved_vector< rstl::auto_ptr< CObjectList >, 8 > x808_objectLists; CPlayer* x84c_player; rstl::single_ptr< CWorld > x850_world; @@ -282,10 +291,8 @@ private: rstl::single_ptr< CActorModelParticles > x884_actorModelParticles; uint x888_; CRumbleManager* x88c_rumbleManager; - // TODO - // rstl::multimap< TEditorId, TUniqueId > x890_scriptIdMap; - // rstl::map< TEditorId, SScriptObjectStream > x8a4_loadedScriptObjects; - uchar pad[0x28]; + rstl::multimap< TEditorId, TUniqueId > x890_scriptIdMap; + rstl::map< TEditorId, SScriptObjectStream > x8a4_loadedScriptObjects; rstl::rc_ptr< CPlayerState > x8b8_playerState; rstl::rc_ptr< CScriptMailbox > x8bc_mailbox; rstl::rc_ptr< CMapWorldInfo > x8c0_mapWorldInfo; @@ -307,7 +314,7 @@ private: EGameState x904_gameState; rstl::reserved_vector< FScriptLoader, int(kST_MAX) > x90c_loaderFuncs; EInitPhase xb3c_initPhase; - uchar xb40_pad[0x14]; // rstl::set xb40_uniqueInstanceNames; + rstl::set xb40_uniqueInstanceNames; CFinalInput xb54_finalInput; rstl::reserved_vector< CCameraFilterPass, kCFS_Max > xb84_camFilterPasses; @@ -324,7 +331,8 @@ private: uint xf20_bossStringIdx; float xf24_thermColdScale1; float xf28_thermColdScale2; - CVector2f xf2c_viewportScale; + float xf2c_viewportScaleX; + float xf30_viewportScaleY; EThermalDrawFlag xf34_thermalFlag; TUniqueId xf38_skipCineSpecialFunc; rstl::list< TUniqueId > xf3c_activeFlickerBats; @@ -349,7 +357,7 @@ private: bool xf94_30_fullThreat : 1; void ClearGraveyard(); - static void RendererDrawCallback(void*, void*, int); + static void RendererDrawCallback(const void*, const void*, int); static const bool MemoryAllocatorAllocationFailedCallback(const void*, unsigned int); }; CHECK_SIZEOF(CStateManager, 0xf98) diff --git a/include/MetroidPrime/CStateManagerContainer.hpp b/include/MetroidPrime/CStateManagerContainer.hpp index 2d575ec7..6b6c9cc7 100644 --- a/include/MetroidPrime/CStateManagerContainer.hpp +++ b/include/MetroidPrime/CStateManagerContainer.hpp @@ -31,5 +31,6 @@ private: rstl::reserved_vector< TUniqueId, 20 > xf370_; rstl::reserved_vector< TUniqueId, 20 > xf39c_renderLast; }; +CHECK_SIZEOF(CStateManagerContainer, 0xf3c8); #endif // _CSTATEMANAGERCONTAINER diff --git a/include/MetroidPrime/Cameras/CCameraBlurPass.hpp b/include/MetroidPrime/Cameras/CCameraBlurPass.hpp index 5d734b06..98cf9fe4 100644 --- a/include/MetroidPrime/Cameras/CCameraBlurPass.hpp +++ b/include/MetroidPrime/Cameras/CCameraBlurPass.hpp @@ -33,7 +33,7 @@ public: bool GetNoPersistentCopy() const { return x2d_noPersistentCopy; } private: - rstl::optional_object< TLockedToken< CTexture > > x0_paletteTex; + rstl::optional_object< TCachedToken< CTexture > > x0_paletteTex; EBlurType x10_curType; EBlurType x14_endType; float x18_endValue; diff --git a/include/rstl/list.hpp b/include/rstl/list.hpp index 67698992..3c931929 100644 --- a/include/rstl/list.hpp +++ b/include/rstl/list.hpp @@ -25,16 +25,8 @@ public: , xc_empty_prev(reinterpret_cast< node* >(&xc_empty_prev)) , x10_empty_next(reinterpret_cast< node* >(&xc_empty_prev)) , x14_count(0) {} - ~list() { - node* cur = x4_start; - while (cur != x8_end) { - node* it = cur; - node* next = cur->get_next(); - cur = next; - destroy(it); - x0_allocator.deallocate(it); - } - } + ~list(); + void push_back(const T& val) { do_insert_before(x8_end, val); } void clear() { erase(begin(), end()); @@ -160,6 +152,18 @@ private: int x14_count; }; +template < typename T, typename Alloc> + list::~list() { + node* cur = x4_start; + while (cur != x8_end) { + node* it = cur; + node* next = cur->get_next(); + cur = next; + destroy(it); + x0_allocator.deallocate(it); + } + } + } // namespace rstl #endif // _RSTL_LIST diff --git a/include/rstl/multimap.hpp b/include/rstl/multimap.hpp new file mode 100644 index 00000000..fa1e5241 --- /dev/null +++ b/include/rstl/multimap.hpp @@ -0,0 +1,42 @@ +#ifndef _RSTL_MULTIMAP +#define _RSTL_MULTIMAP + +#include "types.h" + +#include "rstl/pair.hpp" +#include "rstl/red_black_tree.hpp" +#include "rstl/rmemory_allocator.hpp" + +namespace rstl { +template < typename K, typename V, typename Cmp = less< K >, typename Alloc = rmemory_allocator > +class multimap { +public: + typedef pair< K, V > value_type; + +private: + typedef red_black_tree< K, value_type, 1, select1st< value_type >, Cmp, Alloc > rep_type; + +public: + typedef typename rep_type::iterator iterator; + typedef typename rep_type::const_iterator const_iterator; + + iterator insert(const value_type& item) { return inner.insert(item); } + + const_iterator begin() const { return inner.begin(); } + const_iterator end() const { return inner.end(); } + + iterator find(const K& key) { return inner.find(key); } + const_iterator find(const K& key) const { return inner.find(key); } + + void erase(iterator it) { inner.erase(it); } + + rep_type& get_inner() { return inner; } // hack for CWeaponMgr inlining depth +private: + rep_type inner; +}; + +typedef multimap< char, char > unk_multimap; +CHECK_SIZEOF(unk_multimap, 0x14) +} // namespace rstl + +#endif // _RSTL_MULTIMAP diff --git a/include/rstl/red_black_tree.hpp b/include/rstl/red_black_tree.hpp index 929fa317..fbe8de7e 100644 --- a/include/rstl/red_black_tree.hpp +++ b/include/rstl/red_black_tree.hpp @@ -17,6 +17,11 @@ struct select1st< pair< K, V > > { const K& operator()(const pair< K, V >& it) const { return it.first; } }; +template < typename P > +struct identity { + const P& operator()(const P& it) const { return it; } +}; + template < typename T > struct less { bool operator()(const T& a, const T& b) const { return a < b; } diff --git a/include/rstl/reserved_vector.hpp b/include/rstl/reserved_vector.hpp index ed733ce6..8bf62b9f 100644 --- a/include/rstl/reserved_vector.hpp +++ b/include/rstl/reserved_vector.hpp @@ -27,6 +27,7 @@ public: reserved_vector() : x0_count(0) {} explicit reserved_vector(const T& value) : x0_count(N) { uninitialized_fill_n(data(), N, value); } + explicit reserved_vector(int count, const T& value); reserved_vector(const reserved_vector& other) : x0_count(other.x0_count) { uninitialized_copy_n(other.data(), x0_count, data()); } @@ -81,7 +82,20 @@ public: --x0_count; } } + + void resize(int count, const T& item) { + if (size() < count) { + uninitialized_fill_n(end(), count - size(), item); + x0_count = count; + } + } }; + +template < typename T, int N > +reserved_vector< T, N >::reserved_vector(int count, const T& value) : x0_count(count) { + uninitialized_fill_n(data(), count, value); +} + } // namespace rstl #endif // _RSTL_RESERVED_VECTOR diff --git a/include/rstl/set.hpp b/include/rstl/set.hpp new file mode 100644 index 00000000..b9e50be0 --- /dev/null +++ b/include/rstl/set.hpp @@ -0,0 +1,41 @@ +#ifndef _RSTL_SET +#define _RSTL_SET + +#include "types.h" + +#include "rstl/pair.hpp" +#include "rstl/red_black_tree.hpp" +#include "rstl/rmemory_allocator.hpp" + +namespace rstl { +template < typename T, typename Cmp = less< T >, typename Alloc = rmemory_allocator > +class set { +public: + typedef T value_type; + +private: + typedef red_black_tree< T, value_type, 0, identity< T >, Cmp, Alloc > rep_type; + +public: + typedef typename rep_type::iterator iterator; + typedef typename rep_type::const_iterator const_iterator; + + iterator insert(const value_type& item) { return inner.insert(item); } + + const_iterator begin() const { return inner.begin(); } + const_iterator end() const { return inner.end(); } + + iterator find(const T& key) { return inner.find(key); } + const_iterator find(const T& key) const { return inner.find(key); } + + void erase(iterator it) { inner.erase(it); } +private: + rep_type inner; +}; + +typedef set< char, char > unk_set; +CHECK_SIZEOF(unk_set, 0x14) + +} + +#endif // _RSTL_SET diff --git a/src/MetroidPrime/CStateManager.cpp b/src/MetroidPrime/CStateManager.cpp index c0e819b0..5b4cceb2 100644 --- a/src/MetroidPrime/CStateManager.cpp +++ b/src/MetroidPrime/CStateManager.cpp @@ -17,6 +17,7 @@ #include "MetroidPrime/ScriptObjects/CScriptMazeNode.hpp" #include "Collision/CCollisionPrimitive.hpp" +#include "Kyoto/Basics/RAssertDolphin.hpp" #include "Kyoto/Graphics/CLight.hpp" #include "MetaRender/CCubeRenderer.hpp" @@ -25,7 +26,9 @@ CStateManager::CStateManager(const rstl::ncrc_ptr< CScriptMailbox >& mailbox, const rstl::ncrc_ptr< CPlayerState >& playerState, const rstl::ncrc_ptr< CWorldTransManager >& wtMgr, const rstl::ncrc_ptr< CWorldLayerState >& layerState) -: x808_objectLists(rstl::auto_ptr< CObjectList >()) +: x0_nextFreeIndex(0) +, x4_objectIndexArray(0) +, x808_objectLists(rstl::auto_ptr< CObjectList >()) , x86c_stateManagerContainer(new CStateManagerContainer()) @@ -54,8 +57,15 @@ CStateManager::CStateManager(const rstl::ncrc_ptr< CScriptMailbox >& mailbox, , x904_gameState(kGS_Running) , xb3c_initPhase(kIP_LoadWorld) +// based on map, uses the call with the count. +, xb84_camFilterPasses(CCameraFilterPass()) + +// TODO: should not be inlined, but the constructor above is inlined +, xd14_camBlurPasses(kCFS_Max, CCameraBlurPass()) + , xeec_hintIdx(-1) , xef0_hintPeriods(0) +, xef4_pendingScreenTex() , xf08_pauseHudMessage(kInvalidAssetId) , xf0c_escapeTimer(0.0f) @@ -68,7 +78,8 @@ CStateManager::CStateManager(const rstl::ncrc_ptr< CScriptMailbox >& mailbox, , xf24_thermColdScale1(0.0f) , xf28_thermColdScale2(0.0f) -, xf2c_viewportScale(1.f, 1.f) +, xf2c_viewportScaleX(1.f) +, xf30_viewportScaleY(1.f) , xf34_thermalFlag(kTD_Bypass) , xf38_skipCineSpecialFunc(kInvalidUniqueId) @@ -107,9 +118,7 @@ CStateManager::CStateManager(const rstl::ncrc_ptr< CScriptMailbox >& mailbox, gpRender->SetDrawableCallback(RendererDrawCallback, this); CMemory::SetOutOfMemoryCallback(MemoryAllocatorAllocationFailedCallback, this); - for (int i = x90c_loaderFuncs.size(); i < x90c_loaderFuncs.capacity(); ++i) { - x90c_loaderFuncs.push_back(nullptr); - } + x90c_loaderFuncs.resize(x90c_loaderFuncs.capacity(), nullptr); x90c_loaderFuncs[kST_Trigger] = ScriptLoader::LoadTrigger; x90c_loaderFuncs[kST_DamageableTrigger] = ScriptLoader::LoadDamageableTrigger; x90c_loaderFuncs[kST_Actor] = ScriptLoader::LoadActor; @@ -283,6 +292,29 @@ CStateManager::~CStateManager() { CMemory::SetOutOfMemoryCallback(nullptr, nullptr); } +TUniqueId CStateManager::AllocateUniqueId() { + const ushort lastIndex = x0_nextFreeIndex; + ushort ourIndex; + do { + ourIndex = x0_nextFreeIndex; + x0_nextFreeIndex = (ourIndex + 1) & 0x3ff; + if (x0_nextFreeIndex == lastIndex) { + rs_debugger_printf("Object list full!"); + } + } while (ObjectListById(kOL_All).GetObjectByIndex(ourIndex) != nullptr); + + x4_objectIndexArray[ourIndex] = (x4_objectIndexArray[ourIndex] + 1) & 0x3f; + if (TUniqueId(x4_objectIndexArray[ourIndex], ourIndex) == kInvalidUniqueId) { + x4_objectIndexArray[ourIndex] = 0; + } + + return TUniqueId(x4_objectIndexArray[ourIndex], ourIndex); +} + void CStateManager::RemoveObject(TUniqueId id) {} void CStateManager::ClearGraveyard() {} + +void CStateManager::RendererDrawCallback(const void*, const void*, int) {} + +const bool CStateManager::MemoryAllocatorAllocationFailedCallback(const void*, unsigned int) {}