From ec34055dbb44332c13d5fb5202dc7f6ef4db3424 Mon Sep 17 00:00:00 2001 From: Phillip Stephens Date: Thu, 6 Oct 2022 07:24:38 -0700 Subject: [PATCH] More CPlayerGun matches --- asm/MetroidPrime/Player/CPlayerGun.s | 12 +- include/Kyoto/Audio/CSfxManager.hpp | 2 + include/MetroidPrime/Player/CPlayerGun.hpp | 7 +- src/MetroidPrime/Player/CPlayerGun.cpp | 167 +++++++++++++++++++-- 4 files changed, 171 insertions(+), 17 deletions(-) diff --git a/asm/MetroidPrime/Player/CPlayerGun.s b/asm/MetroidPrime/Player/CPlayerGun.s index b9f93c95..2bf1b82e 100644 --- a/asm/MetroidPrime/Player/CPlayerGun.s +++ b/asm/MetroidPrime/Player/CPlayerGun.s @@ -2978,7 +2978,7 @@ lbl_8003CB1C: /* 8003CB2C 00039A8C 38 05 FF FE */ addi r0, r5, -2 /* 8003CB30 00039A90 7C 00 00 34 */ cntlzw r0, r0 /* 8003CB34 00039A94 54 05 D9 7E */ srwi r5, r0, 5 -/* 8003CB38 00039A98 48 00 28 09 */ bl Reset__10CPlayerGunFR13CStateManager +/* 8003CB38 00039A98 48 00 28 09 */ bl Reset__10CPlayerGunFR13CStateManagerb /* 8003CB3C 00039A9C 80 01 00 14 */ lwz r0, 0x14(r1) /* 8003CB40 00039AA0 83 E1 00 0C */ lwz r31, 0xc(r1) /* 8003CB44 00039AA4 83 C1 00 08 */ lwz r30, 8(r1) @@ -5654,7 +5654,7 @@ lbl_8003F100: /* 8003F15C 0003C0BC 7F E3 FB 78 */ mr r3, r31 /* 8003F160 0003C0C0 7F 84 E3 78 */ mr r4, r28 /* 8003F164 0003C0C4 38 A0 00 00 */ li r5, 0 -/* 8003F168 0003C0C8 48 00 01 D9 */ bl Reset__10CPlayerGunFR13CStateManager +/* 8003F168 0003C0C8 48 00 01 D9 */ bl Reset__10CPlayerGunFR13CStateManagerb /* 8003F16C 0003C0CC 57 C0 06 3F */ clrlwi. r0, r30, 0x18 /* 8003F170 0003C0D0 41 82 00 28 */ beq lbl_8003F198 /* 8003F174 0003C0D4 A9 02 C5 F8 */ lha r8, kMaxPriority__11CSfxManager@sda21(r2) @@ -5785,8 +5785,8 @@ lbl_8003F2E0: /* 8003F338 0003C298 38 21 00 20 */ addi r1, r1, 0x20 /* 8003F33C 0003C29C 4E 80 00 20 */ blr -.global Reset__10CPlayerGunFR13CStateManager -Reset__10CPlayerGunFR13CStateManager: +.global Reset__10CPlayerGunFR13CStateManagerb +Reset__10CPlayerGunFR13CStateManagerb: /* 8003F340 0003C2A0 94 21 FF E0 */ stwu r1, -0x20(r1) /* 8003F344 0003C2A4 7C 08 02 A6 */ mflr r0 /* 8003F348 0003C2A8 90 01 00 24 */ stw r0, 0x24(r1) @@ -6056,7 +6056,7 @@ lbl_8003F714: /* 8003F71C 0003C67C 7F C3 F3 78 */ mr r3, r30 /* 8003F720 0003C680 7F E4 FB 78 */ mr r4, r31 /* 8003F724 0003C684 38 A0 00 00 */ li r5, 0 -/* 8003F728 0003C688 4B FF FC 19 */ bl Reset__10CPlayerGunFR13CStateManager +/* 8003F728 0003C688 4B FF FC 19 */ bl Reset__10CPlayerGunFR13CStateManagerb lbl_8003F72C: /* 8003F72C 0003C68C 80 1E 02 E0 */ lwz r0, 0x2e0(r30) /* 8003F730 0003C690 28 00 00 00 */ cmplwi r0, 0 @@ -7113,7 +7113,7 @@ ResetNormal__10CPlayerGunFR13CStateManager: /* 80040638 0003D598 90 01 00 14 */ stw r0, 0x14(r1) /* 8004063C 0003D59C 93 E1 00 0C */ stw r31, 0xc(r1) /* 80040640 0003D5A0 7C 7F 1B 78 */ mr r31, r3 -/* 80040644 0003D5A4 4B FF EC FD */ bl Reset__10CPlayerGunFR13CStateManager +/* 80040644 0003D5A4 4B FF EC FD */ bl Reset__10CPlayerGunFR13CStateManagerb /* 80040648 0003D5A8 88 1F 08 32 */ lbz r0, 0x832(r31) /* 8004064C 0003D5AC 38 60 00 00 */ li r3, 0 /* 80040650 0003D5B0 50 60 1F 38 */ rlwimi r0, r3, 3, 0x1c, 0x1c diff --git a/include/Kyoto/Audio/CSfxManager.hpp b/include/Kyoto/Audio/CSfxManager.hpp index 88cd4c93..b7ed946a 100644 --- a/include/Kyoto/Audio/CSfxManager.hpp +++ b/include/Kyoto/Audio/CSfxManager.hpp @@ -27,6 +27,8 @@ public: static u16 TranslateSFXID(u16); static void PitchBend(CSfxHandle handle, int pitch); + + static CSfxHandle SfxStart(u16 id, u8 vol, u8 pan, bool useAcoustics, s16 prio, bool looped, s32 areaId); }; #endif diff --git a/include/MetroidPrime/Player/CPlayerGun.hpp b/include/MetroidPrime/Player/CPlayerGun.hpp index f914165a..63f9b0ac 100644 --- a/include/MetroidPrime/Player/CPlayerGun.hpp +++ b/include/MetroidPrime/Player/CPlayerGun.hpp @@ -122,7 +122,7 @@ public: void ActivateCombo(CStateManager&); void EnableChargeFx(CPlayerState::EChargeStage, CStateManager&); void UpdateChargeState(float, CStateManager&); - void Reset(CStateManager&); + void Reset(CStateManager& mgr, bool); void ResetCharge(CStateManager&, bool); void ResetBeamParams(CStateManager&, const CPlayerState&, bool); void ChangeWeapon(const CPlayerState&, CStateManager&); @@ -177,6 +177,9 @@ public: static float GetTractorBeamFactor() { return skTractorBeamFactor; } + s32 GetStateFlags() const { return x2f8_stateFlags; } + void SetStateFlags(s32 flags) { x2f8_stateFlags = flags; } + private: class CGunMorph { public: @@ -275,7 +278,7 @@ private: uint x2f0_pressedFireButtonStates; uint x2f4_fireButtonStates; // 0x1: beam mode, 0x2: missile mode, 0x4: missile ready, 0x8: morphing, 0x10: combo fire - uint x2f8_stateFlags; + s32 x2f8_stateFlags; uint x2fc_fidgetAnimBits; uint x300_remainingMissiles; uint x304_; diff --git a/src/MetroidPrime/Player/CPlayerGun.cpp b/src/MetroidPrime/Player/CPlayerGun.cpp index 0570b891..a8df44b8 100644 --- a/src/MetroidPrime/Player/CPlayerGun.cpp +++ b/src/MetroidPrime/Player/CPlayerGun.cpp @@ -7,6 +7,7 @@ #include "MetroidPrime/CWorld.hpp" #include "MetroidPrime/CWorldShadow.hpp" #include "MetroidPrime/Player/CGrappleArm.hpp" +#include "MetroidPrime/Player/CPlayer.hpp" #include "MetroidPrime/Tweaks/CTweakGunRes.hpp" #include "MetroidPrime/Tweaks/CTweakPlayerGun.hpp" #include "MetroidPrime/Weapons/CAuxWeapon.hpp" @@ -18,6 +19,7 @@ #include "MetroidPrime/Weapons/GunController/CGunMotion.hpp" #include "MetroidPrime/Weapons/WeaponTypes.hpp" +#include "Kyoto/Audio/CSfxManager.hpp" #include "Kyoto/Graphics/CModelFlags.hpp" #include "Kyoto/Math/CMath.hpp" #include "Kyoto/Particles/CElementGen.hpp" @@ -354,15 +356,81 @@ void CPlayerGun::Update(float, float, float, CStateManager&) {} void CPlayerGun::ProcessInput(const CFinalInput&, CStateManager&) {} -void CPlayerGun::ProcessChargeState(int, int, CStateManager&, float) {} +void CPlayerGun::ProcessChargeState(int releasedStates, int pressedStates, CStateManager& mgr, + float dt) { + if ((releasedStates & 0x1) != 0) { + ResetCharged(dt, mgr); + return; + } + if ((pressedStates & 0x1) != 0) { + if (x32c_chargePhase == kCP_NotCharging && (pressedStates & 0x1) != 0 && + x348_chargeCooldownTimer == 0.f && x832_28_readyForShot == 1) { + UpdateNormalShotCycle(dt, mgr); + x32c_chargePhase = kCP_ChargeRequested; + } + } else { + const CPlayerState* state = mgr.GetPlayerState(); + if (state->HasPowerUp(CPlayerState::kIT_Missiles) && (pressedStates & 0x2) != 0) { + if (x32c_chargePhase >= kCP_FxGrown) { + if (state->HasPowerUp(skBeamComboArr[size_t(x310_currentBeam)])) + ActivateCombo(mgr); + } else if (x32c_chargePhase == kCP_NotCharging) { + FireSecondary(dt, mgr); + } + } + } +} -void CPlayerGun::ResetNormal(CStateManager&) {} +void CPlayerGun::ResetNormal(CStateManager& mgr) { + Reset(mgr, false); + x832_28_readyForShot = false; +} -void CPlayerGun::ResetCharged(float, CStateManager&) {} +void CPlayerGun::ResetCharged(float dt, CStateManager& mgr) { + if (x832_26_comboFiring == true) { + return; + } -void CPlayerGun::ProcessNormalState(int, int, CStateManager&, float) {} + if (x32c_chargePhase >= kCP_FxGrowing) { + x833_30_canShowAuxMuzzleEffect = false; + UpdateNormalShotCycle(dt, mgr); + x832_24_coolingCharge = true; + CancelCharge(mgr, true); + } else if (x32c_chargePhase != kCP_NotCharging) { + x320_currentAuxBeam = x310_currentBeam; + x833_30_canShowAuxMuzzleEffect = true; + x32c_chargePhase = kCP_ChargeDone; + } + StopChargeSound(mgr); +} -bool CPlayerGun::ExitMissile() { return false; } +void CPlayerGun::ProcessNormalState(int releasedStates, int pressedStates, CStateManager& mgr, + float dt) { + if ((releasedStates & 0x1) != 0) { + ResetNormal(mgr); + return; + } + + if ((pressedStates & 0x1) != 0 && x348_chargeCooldownTimer == 0.f && + x832_28_readyForShot == true) { + UpdateNormalShotCycle(dt, mgr); + return; + } + if ((pressedStates & 0x2) != 0) { + FireSecondary(dt, mgr); + } +} + +bool CPlayerGun::ExitMissile() { + if ((x2f8_stateFlags & 0x1) != 0x1) { + if ((x2f8_stateFlags & 0x10) != 0x10 && x338_nextState != kNS_ExitMissile) { + x338_nextState = kNS_ExitMissile; + PlayAnim(NWeaponTypes::kGAT_FromMissile, false); + } + return false; + } + return true; +} void CPlayerGun::UpdateNormalShotCycle(float, CStateManager&) {} @@ -376,11 +444,76 @@ void CPlayerGun::EnableChargeFx(CPlayerState::EChargeStage, CStateManager&) {} void CPlayerGun::UpdateChargeState(float, CStateManager&) {} -void CPlayerGun::Reset(CStateManager&) {} +void CPlayerGun::Reset(CStateManager& mgr, bool b1) { + x72c_currentBeam->Reset(mgr); + x832_25_chargeEffectVisible = false; + x832_24_coolingCharge = false; + x833_26_ = false; + x348_chargeCooldownTimer = 0.f; + SetGunLightActive(false, mgr); + if ((x2f8_stateFlags & 0x10) != 0x10) { + if (!b1 && (x2f8_stateFlags & 0x2) != 0x2) { + if ((x2f8_stateFlags & 0x8) != 0x8) { + x2f8_stateFlags |= 0x1; + x2f8_stateFlags &= ~0x16; + } + x318_comboAmmoIdx = 0; + x31c_missileMode = kMM_Inactive; + } + } else { + x2f8_stateFlags &= ~0x7; + } +} -void CPlayerGun::ResetCharge(CStateManager&, bool) {} +void CPlayerGun::ResetCharge(CStateManager& mgr, bool resetBeam) { + if (x32c_chargePhase != kCP_NotCharging) + StopChargeSound(mgr); -void CPlayerGun::ResetBeamParams(CStateManager&, const CPlayerState&, bool) {} + if ((x2f8_stateFlags & 0x8) != 0x8 && (x2f8_stateFlags & 0x10) != 0x10) { + bool doResetBeam = + mgr.GetPlayer()->GetMorphballTransitionState() == CPlayer::kMS_Morphed || resetBeam; + if (x832_27_chargeAnimStarted || doResetBeam) + PlayAnim(NWeaponTypes::kGAT_BasePosition, false); + if (doResetBeam) + x72c_currentBeam->EnableSecondaryFx(CGunWeapon::kSFT_None); + if ((x2f8_stateFlags & 0x2) != 0x2 || x330_chargeState != kCS_Normal) { + if ((x2f8_stateFlags & 0x8) != 0x8) { + x2f8_stateFlags |= 0x1; + x2f8_stateFlags &= ~0x16; + } + x318_comboAmmoIdx = 0; + x31c_missileMode = kMM_Inactive; + } + } + + x32c_chargePhase = kCP_NotCharging; + x330_chargeState = kCS_Normal; + x320_currentAuxBeam = x310_currentBeam; + x833_30_canShowAuxMuzzleEffect = true; + x832_27_chargeAnimStarted = false; + x832_26_comboFiring = false; + x344_comboXferTimer = 0.f; +} + +#define SFXwpn_morph_out_wipe 1774 + +void CPlayerGun::ResetBeamParams(CStateManager& mgr, const CPlayerState& playerState, + bool playSelectionSfx) { + StopContinuousBeam(mgr, true); + if (playerState.ItemEnabled(CPlayerState::kIT_ChargeBeam)) { + ResetCharge(mgr, false); + } + const CAnimPlaybackParms parms(skBeamAnimIds[size_t(x314_nextBeam)], -1, 1.f, true); + x6e0_rightHandModel.AnimationData()->SetAnimation(parms, false); + Reset(mgr, false); + if (playSelectionSfx) { + CSfxManager::SfxStart(SFXwpn_morph_out_wipe, 0x7f, 0x40, true, CSfxManager::kMaxPriority, false, + CSfxManager::kAllAreas); + } + x2ec_lastFireButtonStates &= ~0x1; + x320_currentAuxBeam = x310_currentBeam; + x833_30_canShowAuxMuzzleEffect = true; +} void CPlayerGun::ChangeWeapon(const CPlayerState&, CStateManager&) {} @@ -417,7 +550,23 @@ CPlayerGun::CGunMorph::EMorphEvent CPlayerGun::CGunMorph::Update(float, float, f void CPlayerGun::UpdateWeaponFire(float, CPlayerState&, CStateManager&) {} -void CPlayerGun::ResetIdle(CStateManager&) {} +void CPlayerGun::ResetIdle(CStateManager& mgr) { + CFidget::EState fidgetState = x3a4_fidget.GetState(); + x370_gunMotionSpeedMult = 1.f; + x550_camBob.SetState(CPlayerCameraBob::kCBS_GunFireNoBob, mgr); + if (fidgetState != CFidget::kS_NoFidget) { + if (fidgetState == CFidget::kS_Loading) { + UnLoadFidget(); + } + ReturnArmAndGunToDefault(mgr, true); + } + x3a4_fidget.ResetAll(); + ReturnToRestPose(); + if (x324_idleState != kIS_NotIdle) + x324_idleState = kIS_NotIdle; + if (!x740_grappleArm->GetActive()) + x834_26_animPlaying = false; +} void CPlayerGun::UpdateGunIdle(bool, float, float, CStateManager&) {}