From e65a14744f2254008fd05ebb4b7d63b7c6e21673 Mon Sep 17 00:00:00 2001 From: Henrique Gemignani Passos Lima Date: Sat, 4 Jul 2026 16:24:28 +0300 Subject: [PATCH] Better CPlayerGun::UpdateChargeState --- config/G2ME01/splits.txt | 3 +- config/G2ME01/symbols.txt | 4 +- include/MetroidPrime/Player/CPlayerGun.hpp | 16 +++++++- src/MetroidPrime/Player/CPlayerGun.cpp | 47 ++++++++++++---------- 4 files changed, 43 insertions(+), 27 deletions(-) diff --git a/config/G2ME01/splits.txt b/config/G2ME01/splits.txt index d55ede3..1afabfc 100644 --- a/config/G2ME01/splits.txt +++ b/config/G2ME01/splits.txt @@ -87,7 +87,8 @@ MetroidPrime/CDamageInfo.cpp: MetroidPrime/Player/CPlayerGun.cpp: .text start:0x801C6DF8 end:0x801D2F0C .ctors start:0x803A5578 end:0x803A557C - .sdata2 start:0x8041D11C end:0x8041D124 + .sbss start:0x804192C0 end:0x804192C4 + .sdata2 start:0x8041D11C end:0x8041D18C MetroidPrime/Weapons/CPowerBeam.cpp: .text start:0x801D4FC8 end:0x801D5C70 diff --git a/config/G2ME01/symbols.txt b/config/G2ME01/symbols.txt index 515c777..1b2f478 100644 --- a/config/G2ME01/symbols.txt +++ b/config/G2ME01/symbols.txt @@ -6020,7 +6020,7 @@ fn_8016CB64 = .text:0x8016CB64; // type:function size:0x214 align:4 fn_8016CD78 = .text:0x8016CD78; // type:function size:0x49C fn_8016D214 = .text:0x8016D214; // type:function size:0xA44 align:4 fn_8016DC58 = .text:0x8016DC58; // type:function size:0x24 align:4 -StopRumble__14CRumbleManagerFs = .text:0x8016DC7C; // type:function size:0x30 +HardStopAll__16CRumbleGeneratorFv = .text:0x8016DC7C; // type:function size:0x30 fn_8016DCAC = .text:0x8016DCAC; // type:function size:0x10C align:4 Rumble__14CRumbleManagerFR13CStateManager11ERumbleFxIdf15ERumblePriority = .text:0x8016DDB8; // type:function size:0xE4 fn_8016DE9C = .text:0x8016DE9C; // type:function size:0x60 @@ -20397,7 +20397,7 @@ lbl_804192B0 = .sbss:0x804192B0; // type:object size:0x4 data:4byte lbl_804192B4 = .sbss:0x804192B4; // type:object size:0x4 data:4byte lbl_804192B8 = .sbss:0x804192B8; // type:object size:0x4 data:4byte lbl_804192BC = .sbss:0x804192BC; // type:object size:0x4 data:4byte -lbl_804192C0 = .sbss:0x804192C0; // type:object size:0x4 align:4 data:float +kChargeDtFactor = .sbss:0x804192C0; // type:object size:0x4 align:4 data:float kFactorMultiplierForBeamCombo = .sbss:0x804192C4; // type:object size:0x4 align:4 data:float lbl_804192C8 = .sbss:0x804192C8; // type:object size:0x4 align:4 data:float lbl_804192CC = .sbss:0x804192CC; // type:object size:0x4 data:4byte diff --git a/include/MetroidPrime/Player/CPlayerGun.hpp b/include/MetroidPrime/Player/CPlayerGun.hpp index aa76915..134ee10 100644 --- a/include/MetroidPrime/Player/CPlayerGun.hpp +++ b/include/MetroidPrime/Player/CPlayerGun.hpp @@ -40,6 +40,7 @@ public: CPlayerGun(TUniqueId, int); ~CPlayerGun(); + TUniqueId GetPlayerUniqueId() const { return m_playerUniqueId; } CPlayer* GetPlayer(CStateManager& mgr) const; CPlayer* GetPlayerFromAll(CStateManager& mgr) const; @@ -70,14 +71,25 @@ private: float m_gunHolsterRemTime; char m_pad0[24]; EChargeState m_chargeState; // 0x3a4 - char m_pad1[0x2EC]; // 0x3a8 + int m_gunHolsterState; // 0x3a8 EGunHolsterState + short m_0x3ac; + bool m_0x3ae_b0 : 1; + bool m_0x3ae_b1 : 1; + bool m_0x3ae_b2 : 1; + bool m_0x3ae_b3 : 1; + bool m_0x3ae_b4 : 1; + bool m_0x3ae_b5 : 1; + bool m_0x3ae_b6 : 1; + bool m_0x3ae_b7 : 1; + CTransform4f m_gunWorldXf; // 0x3b0 + char m_pad1[0x2B4]; // 0x3e0 EChargePhase m_chargePhase; // 0x694 ESeekerChargeState m_seekerChargeState; // 0x698 float m_timerRelatedToSeekers; // 0x69c char m_pad2[0xD0]; // 0x6A0 int m_0x770; // 0x770 char m_pad4[0x2b]; // 0x774 - unsigned char m_0x70f; // 0x70f + unsigned char m_0x70f : 1; // 0x70f CSfxHandle m_chargeSfx; // 0x7a0 CSfxHandle m_sfxForShoot; // 0x7a4 short m_chargeRumbleHandle; // 0x7a8 diff --git a/src/MetroidPrime/Player/CPlayerGun.cpp b/src/MetroidPrime/Player/CPlayerGun.cpp index c64a276..fe34ee6 100644 --- a/src/MetroidPrime/Player/CPlayerGun.cpp +++ b/src/MetroidPrime/Player/CPlayerGun.cpp @@ -6,40 +6,43 @@ #include "Kyoto/Audio/CSfxManager.hpp" static const float kFactorMultiplierForBeamCombo = 1.0f / CPlayerState::GetMissileComboChargeFactor(); -static const float kChargeFactor = 1.0f / CPlayerState::GetMissileComboChargeFactor(); +static const float kChargeDtFactor = 1.0f / CPlayerState::GetMissileComboChargeFactor(); void CPlayerGun::UpdateChargeState(float dt, CStateManager& mgr) { CPlayerState* playerState = GetPlayerFromAll(mgr)->GetPlayerState(); - if (m_chargePhase == kCP_AnimAndSfx) { - m_maybeChargeAnim += dt; - if (5.0f <= m_maybeChargeAnim) { - m_maybeChargeAnim = 0.0f; - CRumbleManager* rumbleMgr = mgr.RumbleManager(mgr.MaskUIdNumPlayers(m_playerUniqueId)); - if (m_chargeRumbleHandle == -1) { - rumbleMgr->StopRumble(-1); - m_chargeRumbleHandle = -1; + switch (m_chargePhase) { + case kCP_AnimAndSfx: + m_maybeChargeAnim += dt; + if (m_maybeChargeAnim >= 5.0f) { + m_maybeChargeAnim = 0.0f; + CRumbleManager* rumbleMgr = mgr.RumbleManager(mgr.MaskUIdNumPlayers(GetPlayerUniqueId())); + if (m_chargeRumbleHandle == -1) { + rumbleMgr->HardStopAll(); + m_chargeRumbleHandle = -1; + } + m_chargeRumbleHandle = rumbleMgr->Rumble(mgr, kRFX_PlayerGunCharge, 1.f, kRP_Three); } - m_chargeRumbleHandle = rumbleMgr->Rumble(mgr, kRFX_PlayerGunCharge, 1.f, kRP_Three); - } - } else { - m_maybeChargeAnim = 0.0f; + break; + default: + m_maybeChargeAnim = 0.0f; } - - if (m_chargePhase == kCP_NotCharging) { - if (0.0f < playerState->GetChargeBeamFactor()) { - playerState->IncrementChargeBeamFactor(-dt); - } - } else { - if (m_chargePhase == kCP_Phase_1 && playerState->GetChargeAnimStart() < playerState->GetChargeBeamFactor()) { + + // TODO: probably some sort of weird switch case instead + if (m_chargePhase != kCP_NotCharging) { + if (m_chargePhase == kCP_Phase_1 && playerState->GetChargeAnimStart() > playerState->GetChargeBeamFactor()) { m_chargePhase = kCP_Phase_2; } if (m_chargeSfx && m_seekerChargeState != kSCS_FullyCharged) { - CSfxManager::PitchBend(m_chargeSfx, m_0x70f * 0x40 ? 0 : 0x2000); // FIXME: still wrong + CSfxManager::PitchBend(m_chargeSfx, m_0x3ae_b0 ? 0 : 0x2000); } if (0 < m_chargePhase && m_chargePhase < 4) { - playerState->IncrementChargeBeamFactor(dt * kChargeFactor); + playerState->IncrementChargeBeamFactor(kChargeDtFactor * dt); + } + } else { + if (playerState->GetChargeBeamFactor() > 0.0f) { + playerState->IncrementChargeBeamFactor(-dt); } } }