From 00c1024f988f3cc52e10951282d900cb152da8a9 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Tue, 2 Sep 2025 14:42:28 -0700 Subject: [PATCH] CArtifactDoll imps --- config/GM8E01_00/symbols.txt | 16 +-- config/GM8E01_01/symbols.txt | 6 +- include/MetroidPrime/CArtifactDoll.hpp | 35 ++++- include/MetroidPrime/CStateManager.hpp | 2 - include/MetroidPrime/Player/CPlayerState.hpp | 4 +- src/MetroidPrime/CArtifactDoll.cpp | 140 +++++++++++++++++++ src/MetroidPrime/Player/CPlayerState.cpp | 2 +- 7 files changed, 186 insertions(+), 19 deletions(-) create mode 100644 src/MetroidPrime/CArtifactDoll.cpp diff --git a/config/GM8E01_00/symbols.txt b/config/GM8E01_00/symbols.txt index 17de0acf..5fc682af 100644 --- a/config/GM8E01_00/symbols.txt +++ b/config/GM8E01_00/symbols.txt @@ -11542,9 +11542,9 @@ __dl__29TOneStatic<15CTweakSlideShow>FPv = .text:0x8029C858; // type:function si GetArtifactHeadScanIndex__13CArtifactDollFUi = .text:0x8029C884; // type:function size:0xB4 scope:global GetArtifactHeadScanFromItemType__13CArtifactDollFQ212CPlayerState9EItemType = .text:0x8029C938; // type:function size:0x30 scope:global Draw__13CArtifactDollFfRC13CStateManagerbUi = .text:0x8029C968; // type:function size:0x494 scope:global -UpdateArtifactHeadScan__13CArtifactDollFRC13CStateManagerf = .text:0x8029CDFC; // type:function size:0xD0 scope:global -CompleteArtifactHeadScan__13CArtifactDollFRC13CStateManager = .text:0x8029CECC; // type:function size:0x28 scope:global -Update__13CArtifactDollFfRC13CStateManager = .text:0x8029CEF4; // type:function size:0xBC scope:global +UpdateArtifactHeadScan__13CArtifactDollFR13CStateManagerf = .text:0x8029CDFC; // type:function size:0xD0 scope:global +CompleteArtifactHeadScan__13CArtifactDollFR13CStateManager = .text:0x8029CECC; // type:function size:0x28 scope:global +Update__13CArtifactDollFfR13CStateManager = .text:0x8029CEF4; // type:function size:0xBC scope:global Touch__13CArtifactDollFv = .text:0x8029CFB0; // type:function size:0x94 scope:global UpdateActorLights__13CArtifactDollFv = .text:0x8029D044; // type:function size:0x2D0 scope:global __dt__13CArtifactDollFv = .text:0x8029D314; // type:function size:0x10C scope:global @@ -17673,9 +17673,9 @@ lbl_803D5C7D = .rodata:0x803D5C7D; // type:object size:0x13 data:string lbl_803D5C90 = .rodata:0x803D5C90; // type:object size:0x15 data:string lbl_803D5CA5 = .rodata:0x803D5CA5; // type:object size:0x18 data:string lbl_803D5CBD = .rodata:0x803D5CBD; // type:object size:0x93 -lbl_803D5D50 = .rodata:0x803D5D50; // type:object size:0x30 data:4byte -lbl_803D5D80 = .rodata:0x803D5D80; // type:object size:0x30 data:4byte -lbl_803D5DB0 = .rodata:0x803D5DB0; // type:object size:0xC data:string +ArtifactPieceModels__27@unnamed@CArtifactDoll_cpp@ = .rodata:0x803D5D50; // type:object size:0x30 data:4byte +ArtifactScanIds__27@unnamed@CArtifactDoll_cpp@ = .rodata:0x803D5D80; // type:object size:0x30 data:4byte +@stringBase0 = .rodata:0x803D5DB0; // type:object size:0xC scope:local data:string_table lbl_803D5DBC = .rodata:0x803D5DBC; // type:object size:0xC data:string lbl_803D5DC8 = .rodata:0x803D5DC8; // type:object size:0xC data:string lbl_803D5DD4 = .rodata:0x803D5DD4; // type:object size:0xC data:string @@ -21804,8 +21804,8 @@ lbl_805A9158 = .sbss:0x805A9158; // type:object size:0x4 data:4byte lbl_805A915C = .sbss:0x805A915C; // type:object size:0x4 data:4byte sNesModule = .sbss:0x805A9160; // type:object size:0x8 scope:global data:4byte lbl_805A9168 = .sbss:0x805A9168; // type:object size:0x8 align:4 data:float -lbl_805A9170 = .sbss:0x805A9170; // type:object size:0x1 data:byte -lbl_805A9174 = .sbss:0x805A9174; // type:object size:0x1 data:byte +skPreColor__13CArtifactDoll = .sbss:0x805A9170; // type:object size:0x4 data:4byte +skPostColor__13CArtifactDoll = .sbss:0x805A9174; // type:object size:0x4 data:4byte lbl_805A9178 = .sbss:0x805A9178; // type:object size:0x8 data:byte gCalledClip = .sbss:0x805A9180; // type:object size:0x4 scope:global data:4byte gRejectedByClip = .sbss:0x805A9184; // type:object size:0x4 scope:global data:4byte diff --git a/config/GM8E01_01/symbols.txt b/config/GM8E01_01/symbols.txt index 1ae0ce78..9baf6bad 100644 --- a/config/GM8E01_01/symbols.txt +++ b/config/GM8E01_01/symbols.txt @@ -11542,9 +11542,9 @@ __dl__29TOneStatic<15CTweakSlideShow>FPv = .text:0x8029C904; // type:function si GetArtifactHeadScanIndex__13CArtifactDollFUi = .text:0x8029C930; // type:function size:0xB4 scope:global GetArtifactHeadScanFromItemType__13CArtifactDollFQ212CPlayerState9EItemType = .text:0x8029C9E4; // type:function size:0x30 scope:global Draw__13CArtifactDollFfRC13CStateManagerbUi = .text:0x8029CA14; // type:function size:0x494 scope:global -UpdateArtifactHeadScan__13CArtifactDollFRC13CStateManagerf = .text:0x8029CEA8; // type:function size:0xD0 scope:global -CompleteArtifactHeadScan__13CArtifactDollFRC13CStateManager = .text:0x8029CF78; // type:function size:0x28 scope:global -Update__13CArtifactDollFfRC13CStateManager = .text:0x8029CFA0; // type:function size:0xBC scope:global +UpdateArtifactHeadScan__13CArtifactDollFR13CStateManagerf = .text:0x8029CEA8; // type:function size:0xD0 scope:global +CompleteArtifactHeadScan__13CArtifactDollFR13CStateManager = .text:0x8029CF78; // type:function size:0x28 scope:global +Update__13CArtifactDollFfR13CStateManager = .text:0x8029CFA0; // type:function size:0xBC scope:global Touch__13CArtifactDollFv = .text:0x8029D05C; // type:function size:0x94 scope:global UpdateActorLights__13CArtifactDollFv = .text:0x8029D0F0; // type:function size:0x2D0 scope:global __dt__13CArtifactDollFv = .text:0x8029D3C0; // type:function size:0x10C scope:global diff --git a/include/MetroidPrime/CArtifactDoll.hpp b/include/MetroidPrime/CArtifactDoll.hpp index ebf59878..525574ec 100644 --- a/include/MetroidPrime/CArtifactDoll.hpp +++ b/include/MetroidPrime/CArtifactDoll.hpp @@ -1,14 +1,43 @@ #ifndef _CARTIFACTDOLL #define _CARTIFACTDOLL -#include "types.h" - +#include "MetroidPrime/CActorLights.hpp" #include "MetroidPrime/Player/CPlayerState.hpp" -#include "MetroidPrime/TGameTypes.hpp" +#include +#include +#include + +#include + +class CModel; class CArtifactDoll { + static const CColor skPreColor; + static const CColor skPostColor; + public: + CArtifactDoll(); + ~CArtifactDoll(); static CAssetId GetArtifactHeadScanFromItemType(CPlayerState::EItemType); + static int GetArtifactHeadScanIndex(CAssetId scanId); + static void UpdateArtifactHeadScan(CStateManager& mgr, const float delta); + + void CompleteArtifactHeadScan(CStateManager& mgr); + void Draw(float alpha, const CStateManager& mgr, const bool inArtifactCategory, + const CAssetId selectedArtifact); + void Update(float dt, CStateManager& mgr); + void Touch(); + bool CheckLoadComplete(); + const bool IsLoaded() const; + +private: + void UpdateActorLights(); + + rstl::vector< CToken > mModels; + rstl::vector< CLight > mLights; + rstl::single_ptr< CActorLights > mActorLights; + float mFader; + bool mIsLoaded : 1; }; #endif // _CARTIFACTDOLL diff --git a/include/MetroidPrime/CStateManager.hpp b/include/MetroidPrime/CStateManager.hpp index e684069a..28ce2410 100644 --- a/include/MetroidPrime/CStateManager.hpp +++ b/include/MetroidPrime/CStateManager.hpp @@ -10,7 +10,6 @@ #include "Kyoto/TOneStatic.hpp" #include "Kyoto/TToken.hpp" - #include "MetroidPrime/CEntityInfo.hpp" #include "MetroidPrime/CObjectList.hpp" #include "MetroidPrime/Cameras/CCameraBlurPass.hpp" @@ -31,7 +30,6 @@ #include "rstl/single_ptr.hpp" #include "rstl/string.hpp" - class CAABox; class CActor; class CActorModelParticles; diff --git a/include/MetroidPrime/Player/CPlayerState.hpp b/include/MetroidPrime/Player/CPlayerState.hpp index dd27618f..59d5de3a 100644 --- a/include/MetroidPrime/Player/CPlayerState.hpp +++ b/include/MetroidPrime/Player/CPlayerState.hpp @@ -118,7 +118,7 @@ public: void UpdateStaticInterference(CStateManager& stateMgr, const float& dt); void IncreaseScanTime(uint time, float val); void SetScanTime(CAssetId res, float time); - float GetScanTime(CAssetId res) const; + const float GetScanTime(CAssetId res) const; bool GetIsVisorTransitioning() const; float GetVisorTransitionFactor() const; void UpdateVisorTransition(float dt); @@ -142,7 +142,7 @@ public: void InitializePowerUp(CPlayerState::EItemType type, int capacity); void SetPowerUp(CPlayerState::EItemType type, int capacity); static bool IsValidScan(CAssetId res); - void SetScanCompletionRateFirst(int rate) { x180_scanCompletionRateFirst = rate; } // name? + void SetScanCompletionRateFirst(int rate) { x180_scanCompletionRateFirst = rate; } // name? void SetScanCompletionRateSecond(int rate) { x184_scanCompletionRateSecond = rate; } // name? void InitializeScanTimes(); diff --git a/src/MetroidPrime/CArtifactDoll.cpp b/src/MetroidPrime/CArtifactDoll.cpp new file mode 100644 index 00000000..f235bd9f --- /dev/null +++ b/src/MetroidPrime/CArtifactDoll.cpp @@ -0,0 +1,140 @@ +#include "MetroidPrime/CArtifactDoll.hpp" +#include "Kyoto/CSimplePool.hpp" +#include "Kyoto/Graphics/CModel.hpp" +#include "Kyoto/Math/CloseEnough.hpp" +#include "Kyoto/SObjectTag.hpp" +#include "Kyoto/TToken.hpp" +#include "MetroidPrime/CStateManager.hpp" +#include "MetroidPrime/Player/CPlayerState.hpp" +#include "rstl/math.hpp" +#include "rstl/rmemory_allocator.hpp" + +const CColor CArtifactDoll::skPreColor((uchar)255, 160, 5, 255); +const CColor CArtifactDoll::skPostColor((uchar)103, 174, 225, 205); + +namespace { +static const char* const ArtifactPieceModels[] = { + "CMDL_Piece1", // Truth + "CMDL_Piece2", // Strength + "CMDL_Piece3", // Elder + "CMDL_Piece4", // Wild + "CMDL_Piece5", // Lifegiver + "CMDL_Piece6", // Warrior + "CMDL_Piece7", // Chozo + "CMDL_Piece8", // Nature + "CMDL_Piece9", // Sun + "CMDL_Piece10", // World + "CMDL_Piece11", // Spirit + "CMDL_Piece12" // Newborn +}; +static const CAssetId ArtifactScanIds[] = { + 0x32C9DDCEu, // Truth + 0xB45DAF60u, // Strength + 0x7F017CC5u, // Elder + 0x62044C7Du, // Wild + 0xA9589FD8u, // Lifegiver + 0x2FCCED76u, // Warrior + 0xE4903ED3u, // Chozo + 0x15C68C06u, // Nature + 0xDE9A5FA3u, // Sun + 0xFBBE9D9Au, // World + 0x30E24E3Fu, // Spirit + 0xB6763C91u // Newborn +}; +}; // namespace + +CArtifactDoll::CArtifactDoll() +: mLights(2, CLight::BuildDirectional(CVector3f::Forward(), CColor(0xFFFFFFFF)), + rstl::rmemory_allocator()) +, mActorLights(rs_new CActorLights(8, CVector3f::Zero(), 4, 4)) +, mFader(0.f) +, mIsLoaded(0) { + + mModels.reserve(12); + for (int i = 0; i < ARRAY_SIZE(ArtifactPieceModels); ++i) { + CToken model = gpSimplePool->GetObj(ArtifactPieceModels[i]); + model.Lock(); + mModels.push_back(model); + } +} + +CArtifactDoll::~CArtifactDoll() {} + +bool CArtifactDoll::CheckLoadComplete() { + if (IsLoaded()) { + return true; + } + + for (rstl::vector< CToken >::iterator it = mModels.begin(); it != mModels.end(); ++it) { + if (!it->IsLoaded()) { + return false; + } + } + mIsLoaded = true; + + return true; +} +const bool CArtifactDoll::IsLoaded() const { return !!mIsLoaded; } +void CArtifactDoll::UpdateActorLights() { + mLights[0] = CLight::BuildDirectional( + (CVector3f::Forward() + (CVector3f::Right() * 0.25f) + (CVector3f::Down() * 0.1f)) + .AsNormalized(), + CColor((uchar)255, 255, 255)); + mLights[1] = CLight::BuildDirectional(-CVector3f::Forward(), CColor((uchar)0, 0, 0)); + mActorLights->BuildFakeLightList(mLights, CColor(0.25f, 0.25f, 0.25f)); +} +void CArtifactDoll::Touch() { + if (!CheckLoadComplete()) { + return; + } + + for (int i = 0; i < mModels.size(); ++i) { + TToken< CModel >(mModels[i])->Touch(0); + } +} + +void CArtifactDoll::Update(float dt, CStateManager& mgr) { + if (!CheckLoadComplete()) { + return; + } + + mFader = rstl::min_val(1.f, mFader + 2.f * dt); + + if (close_enough(mFader, 1.f)) { + UpdateArtifactHeadScan(mgr, 0.5f * dt * 0.5f); + } + UpdateActorLights(); +} +void CArtifactDoll::CompleteArtifactHeadScan(CStateManager& mgr) { + UpdateArtifactHeadScan(mgr, 1.f); +} + +void CArtifactDoll::UpdateArtifactHeadScan(CStateManager& mgr, const float delta) { + for (int i = 0; i < ARRAY_SIZE(ArtifactScanIds); ++i) { + if (mgr.PlayerState()->HasPowerUp(CPlayerState::EItemType(i + CPlayerState::kIT_Truth))) { + const CAssetId id = ArtifactScanIds[i]; + mgr.PlayerState()->SetScanTime( + id, rstl::min_val(1.f, delta + mgr.PlayerState()->GetScanTime(id))); + } + } +} + +void CArtifactDoll::Draw(float alpha, const CStateManager& mgr, const bool inArtifactCategory, + const CAssetId selectedArtifact) {} +CAssetId CArtifactDoll::GetArtifactHeadScanFromItemType(CPlayerState::EItemType item) { + if (item >= CPlayerState::kIT_Truth && item <= CPlayerState::kIT_Newborn) { + int tmp = size_t(item) - CPlayerState::kIT_Truth; + return ArtifactScanIds[tmp]; + } + return kInvalidAssetId; +} + +int CArtifactDoll::GetArtifactHeadScanIndex(CAssetId scanId) { + for (size_t i = 0; i < ARRAY_SIZE(ArtifactScanIds); ++i) { + if (ArtifactScanIds[i] == scanId) { + return int(i); + } + } + + return -1; +} diff --git a/src/MetroidPrime/Player/CPlayerState.cpp b/src/MetroidPrime/Player/CPlayerState.cpp index ed914929..6bd9a854 100644 --- a/src/MetroidPrime/Player/CPlayerState.cpp +++ b/src/MetroidPrime/Player/CPlayerState.cpp @@ -372,7 +372,7 @@ void CPlayerState::InitializeScanTimes() { } } -float CPlayerState::GetScanTime(CAssetId res) const { +const float CPlayerState::GetScanTime(CAssetId res) const { rstl::vector< rstl::pair< CAssetId, float > >::const_iterator it = rstl::find_by_key(x170_scanTimes, res); return it->second;