mirror of https://github.com/AxioDL/metaforce.git
184 lines
6.4 KiB
C++
184 lines
6.4 KiB
C++
#pragma once
|
|
|
|
#include "Runtime/RetroTypes.hpp"
|
|
|
|
#include <zeus/CVector3f.hpp>
|
|
|
|
namespace metaforce {
|
|
class CRandom16;
|
|
class CStateManager;
|
|
|
|
struct SCameraShakePoint {
|
|
friend class CCameraShakeData;
|
|
bool x0_useEnvelope = false;
|
|
float x4_value = 0.f;
|
|
float x8_magnitude = 0.f;
|
|
float xc_attackTime = 0.f;
|
|
float x10_sustainTime = 0.f;
|
|
float x14_duration = 0.f;
|
|
constexpr SCameraShakePoint() noexcept = default;
|
|
constexpr SCameraShakePoint(bool useEnvelope, float attackTime, float sustainTime, float duration,
|
|
float magnitude) noexcept
|
|
: x0_useEnvelope(useEnvelope)
|
|
, x8_magnitude(magnitude)
|
|
, xc_attackTime(attackTime)
|
|
, x10_sustainTime(sustainTime)
|
|
, x14_duration(duration) {}
|
|
[[nodiscard]] constexpr float GetValue() const noexcept { return x0_useEnvelope ? x8_magnitude : x4_value; }
|
|
static SCameraShakePoint LoadCameraShakePoint(CInputStream& in);
|
|
void Update(float curTime);
|
|
};
|
|
|
|
class CCameraShakerComponent {
|
|
friend class CCameraShakeData;
|
|
bool x4_useModulation = false;
|
|
SCameraShakePoint x8_am, x20_fm;
|
|
float x38_value = 0.f;
|
|
|
|
public:
|
|
constexpr CCameraShakerComponent() noexcept = default;
|
|
constexpr CCameraShakerComponent(bool useModulation, const SCameraShakePoint& am,
|
|
const SCameraShakePoint& fm) noexcept
|
|
: x4_useModulation(useModulation), x8_am(am), x20_fm(fm) {}
|
|
static CCameraShakerComponent LoadNewCameraShakerComponent(CInputStream& in);
|
|
void Update(float curTime, float duration, float distAtt);
|
|
[[nodiscard]] constexpr float GetValue() const noexcept { return x38_value; }
|
|
};
|
|
|
|
class CCameraShakeData {
|
|
friend class CCameraManager;
|
|
float x0_duration;
|
|
float x4_curTime = 0.f;
|
|
CCameraShakerComponent x8_shakerX;
|
|
CCameraShakerComponent x44_shakerY;
|
|
CCameraShakerComponent x80_shakerZ;
|
|
u32 xbc_shakerId = 0;
|
|
u32 xc0_flags; // 0x1: positional sfx
|
|
zeus::CVector3f xc4_sfxPos;
|
|
float xd0_sfxDist;
|
|
|
|
public:
|
|
static const CCameraShakeData skChargedShotCameraShakeData;
|
|
|
|
constexpr CCameraShakeData() = default;
|
|
constexpr CCameraShakeData(float duration, float sfxDist, u32 flags, const zeus::CVector3f& sfxPos,
|
|
const CCameraShakerComponent& shaker1, const CCameraShakerComponent& shaker2,
|
|
const CCameraShakerComponent& shaker3) noexcept
|
|
: x0_duration(duration)
|
|
, x8_shakerX(shaker1)
|
|
, x44_shakerY(shaker2)
|
|
, x80_shakerZ(shaker3)
|
|
, xc0_flags(flags)
|
|
, xc4_sfxPos(sfxPos)
|
|
, xd0_sfxDist(sfxDist) {}
|
|
|
|
constexpr CCameraShakeData(float duration, float magnitude) noexcept
|
|
: CCameraShakeData(
|
|
duration, 100.f, 0, zeus::skZero3f, CCameraShakerComponent{}, CCameraShakerComponent{},
|
|
CCameraShakerComponent{true, SCameraShakePoint{false, 0.25f * duration, 0.f, 0.75f * duration, magnitude},
|
|
SCameraShakePoint{true, 0.f, 0.f, 0.5f * duration, 2.f}}) {}
|
|
|
|
explicit CCameraShakeData(CInputStream&);
|
|
|
|
static constexpr CCameraShakeData BuildLandingCameraShakeData(float duration, float magnitude) noexcept {
|
|
return {
|
|
duration,
|
|
100.f,
|
|
0,
|
|
zeus::skZero3f,
|
|
CCameraShakerComponent{
|
|
true,
|
|
SCameraShakePoint(false, 0.15f * duration, 0.f, 0.85f * duration, magnitude),
|
|
SCameraShakePoint(true, 0.f, 0.f, 0.4f * duration, 1.5f),
|
|
},
|
|
CCameraShakerComponent{},
|
|
CCameraShakerComponent{
|
|
true,
|
|
SCameraShakePoint(false, 0.25f * duration, 0.f, 0.75f * duration, magnitude),
|
|
SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 2.f),
|
|
},
|
|
};
|
|
}
|
|
|
|
static constexpr CCameraShakeData BuildProjectileCameraShake(float duration, float magnitude) noexcept {
|
|
return {
|
|
duration,
|
|
100.f,
|
|
0,
|
|
zeus::skZero3f,
|
|
CCameraShakerComponent{
|
|
true,
|
|
SCameraShakePoint(false, 0.f, 0.f, duration, magnitude),
|
|
SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 3.f),
|
|
},
|
|
CCameraShakerComponent{},
|
|
CCameraShakerComponent{},
|
|
};
|
|
}
|
|
|
|
static constexpr CCameraShakeData BuildMissileCameraShake(float duration, float magnitude, float sfxDistance,
|
|
const zeus::CVector3f& sfxPos) noexcept {
|
|
CCameraShakeData ret(duration, magnitude);
|
|
ret.SetSfxPositionAndDistance(sfxPos, sfxDistance);
|
|
return ret;
|
|
}
|
|
|
|
static constexpr CCameraShakeData BuildPhazonCameraShakeData(float duration, float magnitude) noexcept {
|
|
return {
|
|
duration,
|
|
100.f,
|
|
0,
|
|
zeus::skZero3f,
|
|
CCameraShakerComponent{
|
|
true,
|
|
SCameraShakePoint(false, 0.15f * duration, 0.f, 0.25f * duration, magnitude),
|
|
SCameraShakePoint(true, 0.f, 0.f, 0.4f * duration, 0.3f),
|
|
},
|
|
CCameraShakerComponent{},
|
|
CCameraShakerComponent{
|
|
true,
|
|
SCameraShakePoint(false, 0.25f * duration, 0.f, 0.25f * duration, magnitude),
|
|
SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 0.5f),
|
|
},
|
|
};
|
|
}
|
|
|
|
static constexpr CCameraShakeData BuildPatternedExplodeShakeData(float duration, float magnitude) noexcept {
|
|
return {
|
|
duration,
|
|
100.f,
|
|
0,
|
|
zeus::skZero3f,
|
|
CCameraShakerComponent{
|
|
true,
|
|
SCameraShakePoint(false, 0.25f * duration, 0.f, 0.75f * duration, magnitude),
|
|
SCameraShakePoint(true, 0.f, 0.f, 0.5f * duration, 2.0f),
|
|
},
|
|
CCameraShakerComponent{},
|
|
CCameraShakerComponent{},
|
|
};
|
|
}
|
|
|
|
static constexpr CCameraShakeData BuildPatternedExplodeShakeData(const zeus::CVector3f& pos, float duration,
|
|
float magnitude, float distance) noexcept {
|
|
CCameraShakeData shakeData = BuildPatternedExplodeShakeData(duration, magnitude);
|
|
shakeData.SetSfxPositionAndDistance(pos, distance);
|
|
return shakeData;
|
|
}
|
|
|
|
void Update(float dt, CStateManager& mgr);
|
|
zeus::CVector3f GetPoint() const;
|
|
float GetMaxAMComponent() const;
|
|
float GetMaxFMComponent() const;
|
|
void SetShakerId(u32 id) { xbc_shakerId = id; }
|
|
u32 GetShakerId() const { return xbc_shakerId; }
|
|
static CCameraShakeData LoadCameraShakeData(CInputStream& in);
|
|
constexpr void SetSfxPositionAndDistance(const zeus::CVector3f& pos, float sfxDistance) noexcept {
|
|
xc0_flags |= 0x1;
|
|
xc4_sfxPos = pos;
|
|
xd0_sfxDist = sfxDistance;
|
|
}
|
|
};
|
|
|
|
} // namespace metaforce
|