metaforce/Runtime/Input/CRumbleVoice.hpp

113 lines
2.9 KiB
C++
Raw Normal View History

2018-10-07 03:42:33 +00:00
#pragma once
2016-02-21 06:34:42 +00:00
#include "RetroTypes.hpp"
2016-03-04 23:04:53 +00:00
namespace urde
2016-02-21 06:34:42 +00:00
{
enum class ERumbleFxId
{
Zero = 0,
One = 1,
2018-01-26 09:48:42 +00:00
CameraShake = 6,
EscapeSequenceShake = 7,
PlayerBump = 11,
PlayerGunCharge = 12,
PlayerMissileFire = 13,
PlayerGrappleFire = 14,
PlayerLand = 15,
PlayerGrappleSwoosh = 17,
Twenty = 20,
TwentyOne = 21,
TwentyTwo = 22,
TwentyThree = 23
2016-02-21 06:34:42 +00:00
};
enum class ERumblePriority
{
None = 0,
One = 1,
2017-09-02 04:06:05 +00:00
Two = 2,
Three = 3
2016-02-21 06:34:42 +00:00
};
struct SAdsrData
{
2018-01-26 09:48:42 +00:00
float x0_attackGain = 0.f;
float x4_autoReleaseDur = 0.f;
float x8_attackDur = 0.f;
float xc_decayDur = 0.f;
float x10_sustainGain = 0.f;
float x14_releaseDur = 0.f;
2016-02-21 06:34:42 +00:00
union
{
2018-01-26 09:48:42 +00:00
struct { bool x18_24_hasSustain : 1; bool x18_25_autoRelease : 1; };
2016-02-21 06:34:42 +00:00
u8 dummy = 0;
};
SAdsrData() = default;
2018-01-26 09:48:42 +00:00
SAdsrData(float attackGain, float autoReleaseDur, float attackDur, float decayDur,
float sustainGain, float releaseDur, bool hasSustain, bool autoRelease)
: x0_attackGain(attackGain), x4_autoReleaseDur(autoReleaseDur), x8_attackDur(attackDur),
xc_decayDur(decayDur), x10_sustainGain(sustainGain), x14_releaseDur(releaseDur)
2016-02-21 06:34:42 +00:00
{
2018-01-26 09:48:42 +00:00
x18_24_hasSustain = hasSustain;
x18_25_autoRelease = autoRelease;
2016-02-21 06:34:42 +00:00
}
};
struct SAdsrDelta
{
enum class EPhase
{
Stop,
2018-01-26 19:46:35 +00:00
PrePulse,
2018-01-26 09:48:42 +00:00
Attack,
Decay,
Sustain,
Release
2016-02-21 06:34:42 +00:00
};
2018-01-26 19:46:35 +00:00
float x0_curIntensity = 0.f;
2018-01-26 09:48:42 +00:00
float x4_attackTime = 0.f;
float x8_decayTime = 0.f;
float xc_releaseTime = 0.f;
float x10_autoReleaseTime = 0.f;
2018-01-26 19:46:35 +00:00
float x14_attackIntensity;
float x18_sustainIntensity;
2016-02-21 06:34:42 +00:00
ERumblePriority x1c_priority;
2018-01-26 09:48:42 +00:00
EPhase x20_phase;
2016-02-21 06:34:42 +00:00
SAdsrDelta(EPhase phase, ERumblePriority priority)
2018-01-26 19:46:35 +00:00
: x0_curIntensity(phase == EPhase::PrePulse ? 2.f : 0.f), x1c_priority(priority), x20_phase(phase)
2016-02-21 06:34:42 +00:00
{}
SAdsrDelta(EPhase phase)
: x1c_priority(ERumblePriority::None), x20_phase(phase)
{}
static SAdsrDelta Stopped() { return SAdsrDelta(EPhase::Stop); }
2018-01-27 08:34:46 +00:00
static SAdsrDelta Start(ERumblePriority priority, bool prePulse)
{ return SAdsrDelta(prePulse ? EPhase::PrePulse : EPhase::Attack, priority); }
2018-01-26 09:48:42 +00:00
};
class CRumbleVoice
{
std::vector<SAdsrData> x0_datas;
std::vector<SAdsrDelta> x10_deltas;
rstl::reserved_vector<s16, 4> x20_handleIds;
s16 x2c_usedChannels = 0;
u8 x2e_lastId = 0;
bool UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float dt);
public:
CRumbleVoice();
s16 CreateRumbleHandle(s16 idx);
bool OwnsSustained(s16 id) const;
s16 GetFreeChannel() const;
float GetIntensity() const;
bool Update(float dt);
void HardReset();
s16 Activate(const SAdsrData& data, s16 idx, float gain, ERumblePriority prio);
void Deactivate(s16 id, bool b1);
ERumblePriority GetPriority(s16 idx) const { return x10_deltas[idx].x1c_priority; }
2016-02-21 06:34:42 +00:00
};
}