mirror of https://github.com/AxioDL/metaforce.git
Ensure rumble pre-pulse
This commit is contained in:
parent
13a31be23b
commit
6f7cd14836
|
@ -15,8 +15,26 @@ CRumbleGenerator::~CRumbleGenerator()
|
||||||
HardStopAll();
|
HardStopAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define PWM_MONITOR 0
|
||||||
|
#if PWM_MONITOR
|
||||||
|
static bool b_tp = false;
|
||||||
|
static std::chrono::steady_clock::time_point s_tp;
|
||||||
|
#endif
|
||||||
|
|
||||||
void CRumbleGenerator::Update(float dt)
|
void CRumbleGenerator::Update(float dt)
|
||||||
{
|
{
|
||||||
|
#if PWM_MONITOR
|
||||||
|
std::chrono::milliseconds::rep ms = 0;
|
||||||
|
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
|
||||||
|
if (!b_tp)
|
||||||
|
{
|
||||||
|
b_tp = true;
|
||||||
|
s_tp = now;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ms = std::chrono::duration_cast<std::chrono::milliseconds>(now - s_tp).count();
|
||||||
|
#endif
|
||||||
|
|
||||||
if (!xf0_24_disabled)
|
if (!xf0_24_disabled)
|
||||||
{
|
{
|
||||||
bool updated = false;
|
bool updated = false;
|
||||||
|
@ -29,6 +47,10 @@ void CRumbleGenerator::Update(float dt)
|
||||||
xd0_onTime[i] = 0.f;
|
xd0_onTime[i] = 0.f;
|
||||||
if (xe0_commandArray[i] != EMotorState::Stop)
|
if (xe0_commandArray[i] != EMotorState::Stop)
|
||||||
{
|
{
|
||||||
|
#if PWM_MONITOR
|
||||||
|
s_tp = now;
|
||||||
|
printf("%lldms ON\n", ms);
|
||||||
|
#endif
|
||||||
xe0_commandArray[i] = EMotorState::Stop;
|
xe0_commandArray[i] = EMotorState::Stop;
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
|
@ -41,6 +63,10 @@ void CRumbleGenerator::Update(float dt)
|
||||||
xc0_periodTime[i] = 0.f;
|
xc0_periodTime[i] = 0.f;
|
||||||
if (xe0_commandArray[i] != EMotorState::Rumble)
|
if (xe0_commandArray[i] != EMotorState::Rumble)
|
||||||
{
|
{
|
||||||
|
#if PWM_MONITOR
|
||||||
|
s_tp = now;
|
||||||
|
printf("%lldms Off\n", ms);
|
||||||
|
#endif
|
||||||
xe0_commandArray[i] = EMotorState::Rumble;
|
xe0_commandArray[i] = EMotorState::Rumble;
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
|
@ -53,6 +79,10 @@ void CRumbleGenerator::Update(float dt)
|
||||||
xd0_onTime[i] = 0.f;
|
xd0_onTime[i] = 0.f;
|
||||||
if (xe0_commandArray[i] != EMotorState::Stop)
|
if (xe0_commandArray[i] != EMotorState::Stop)
|
||||||
{
|
{
|
||||||
|
#if PWM_MONITOR
|
||||||
|
s_tp = now;
|
||||||
|
printf("%lldms ON\n", ms);
|
||||||
|
#endif
|
||||||
xe0_commandArray[i] = EMotorState::Stop;
|
xe0_commandArray[i] = EMotorState::Stop;
|
||||||
updated = true;
|
updated = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,17 +38,17 @@ s16 CRumbleVoice::GetFreeChannel() const
|
||||||
float CRumbleVoice::GetIntensity() const
|
float CRumbleVoice::GetIntensity() const
|
||||||
{
|
{
|
||||||
return std::min(2.f,
|
return std::min(2.f,
|
||||||
std::max(x10_deltas[0].x0_curLevel,
|
std::max(x10_deltas[0].x0_curIntensity,
|
||||||
std::max(x10_deltas[1].x0_curLevel,
|
std::max(x10_deltas[1].x0_curIntensity,
|
||||||
std::max(x10_deltas[2].x0_curLevel,
|
std::max(x10_deltas[2].x0_curIntensity,
|
||||||
x10_deltas[3].x0_curLevel))));
|
x10_deltas[3].x0_curIntensity))));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float dt)
|
bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float dt)
|
||||||
{
|
{
|
||||||
switch (delta.x20_phase)
|
switch (delta.x20_phase)
|
||||||
{
|
{
|
||||||
case SAdsrDelta::EPhase::Queued:
|
case SAdsrDelta::EPhase::PrePulse:
|
||||||
if (delta.x4_attackTime < (1.f/30.f))
|
if (delta.x4_attackTime < (1.f/30.f))
|
||||||
{
|
{
|
||||||
delta.x4_attackTime += dt;
|
delta.x4_attackTime += dt;
|
||||||
|
@ -56,7 +56,7 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delta.x20_phase = SAdsrDelta::EPhase::Attack;
|
delta.x20_phase = SAdsrDelta::EPhase::Attack;
|
||||||
delta.x0_curLevel = 0.f;
|
delta.x0_curIntensity = 0.f;
|
||||||
delta.x4_attackTime = 0.f;
|
delta.x4_attackTime = 0.f;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -64,12 +64,12 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
|
||||||
if (delta.x4_attackTime < data.x8_attackDur)
|
if (delta.x4_attackTime < data.x8_attackDur)
|
||||||
{
|
{
|
||||||
float t = delta.x4_attackTime / data.x8_attackDur;
|
float t = delta.x4_attackTime / data.x8_attackDur;
|
||||||
delta.x0_curLevel = t * delta.x14_attackLevel;
|
delta.x0_curIntensity = t * delta.x14_attackIntensity;
|
||||||
delta.x4_attackTime += dt;
|
delta.x4_attackTime += dt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delta.x0_curLevel = delta.x14_attackLevel;
|
delta.x0_curIntensity = delta.x14_attackIntensity;
|
||||||
delta.x20_phase = SAdsrDelta::EPhase::Decay;
|
delta.x20_phase = SAdsrDelta::EPhase::Decay;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -79,12 +79,12 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
|
||||||
if (delta.x8_decayTime < data.xc_decayDur)
|
if (delta.x8_decayTime < data.xc_decayDur)
|
||||||
{
|
{
|
||||||
float t = delta.x8_decayTime / data.xc_decayDur;
|
float t = delta.x8_decayTime / data.xc_decayDur;
|
||||||
delta.x0_curLevel = (1.f - t) * delta.x14_attackLevel + t * delta.x18_sustainLevel;
|
delta.x0_curIntensity = (1.f - t) * delta.x14_attackIntensity + t * delta.x18_sustainIntensity;
|
||||||
delta.x8_decayTime += dt;
|
delta.x8_decayTime += dt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delta.x0_curLevel = delta.x18_sustainLevel;
|
delta.x0_curIntensity = delta.x18_sustainIntensity;
|
||||||
delta.x20_phase = SAdsrDelta::EPhase::Sustain;
|
delta.x20_phase = SAdsrDelta::EPhase::Sustain;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -93,12 +93,12 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
|
||||||
if (delta.x8_decayTime < data.xc_decayDur)
|
if (delta.x8_decayTime < data.xc_decayDur)
|
||||||
{
|
{
|
||||||
float t = delta.x8_decayTime / data.xc_decayDur;
|
float t = delta.x8_decayTime / data.xc_decayDur;
|
||||||
delta.x0_curLevel = (1.f - t) * delta.x14_attackLevel;
|
delta.x0_curIntensity = (1.f - t) * delta.x14_attackIntensity;
|
||||||
delta.x8_decayTime += dt;
|
delta.x8_decayTime += dt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delta.x0_curLevel = 0.f;
|
delta.x0_curIntensity = 0.f;
|
||||||
delta.x20_phase = SAdsrDelta::EPhase::Stop;
|
delta.x20_phase = SAdsrDelta::EPhase::Stop;
|
||||||
}
|
}
|
||||||
if (delta.x20_phase != SAdsrDelta::EPhase::Decay)
|
if (delta.x20_phase != SAdsrDelta::EPhase::Decay)
|
||||||
|
@ -110,16 +110,16 @@ bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float
|
||||||
break;
|
break;
|
||||||
case SAdsrDelta::EPhase::Release:
|
case SAdsrDelta::EPhase::Release:
|
||||||
{
|
{
|
||||||
float a = data.x18_24_hasSustain ? delta.x18_sustainLevel : 0.f;
|
float a = data.x18_24_hasSustain ? delta.x18_sustainIntensity : 0.f;
|
||||||
if (delta.xc_releaseTime < data.x14_releaseDur)
|
if (delta.xc_releaseTime < data.x14_releaseDur)
|
||||||
{
|
{
|
||||||
float t = delta.xc_releaseTime / data.x14_releaseDur;
|
float t = delta.xc_releaseTime / data.x14_releaseDur;
|
||||||
delta.x0_curLevel = (1.f - t) * a;
|
delta.x0_curIntensity = (1.f - t) * a;
|
||||||
delta.xc_releaseTime += dt;
|
delta.xc_releaseTime += dt;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
delta.x0_curLevel = 0.f;
|
delta.x0_curIntensity = 0.f;
|
||||||
delta.x20_phase = SAdsrDelta::EPhase::Stop;
|
delta.x20_phase = SAdsrDelta::EPhase::Stop;
|
||||||
}
|
}
|
||||||
if (delta.x20_phase != SAdsrDelta::EPhase::Release)
|
if (delta.x20_phase != SAdsrDelta::EPhase::Release)
|
||||||
|
@ -154,7 +154,7 @@ bool CRumbleVoice::Update(float dt)
|
||||||
{
|
{
|
||||||
if (UpdateChannel(x10_deltas[i], x0_datas[i], dt))
|
if (UpdateChannel(x10_deltas[i], x0_datas[i], dt))
|
||||||
{
|
{
|
||||||
x2c_usedChannels &= (1 << i);
|
x2c_usedChannels &= ~(1 << i);
|
||||||
x10_deltas[i] = SAdsrDelta::Stopped();
|
x10_deltas[i] = SAdsrDelta::Stopped();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,8 +180,8 @@ s16 CRumbleVoice::Activate(const SAdsrData& data, s16 idx, float gain, ERumblePr
|
||||||
{
|
{
|
||||||
x0_datas[idx] = data;
|
x0_datas[idx] = data;
|
||||||
x10_deltas[idx] = SAdsrDelta::Start(prio, !x2c_usedChannels);
|
x10_deltas[idx] = SAdsrDelta::Start(prio, !x2c_usedChannels);
|
||||||
x10_deltas[idx].x14_attackLevel = gain * x0_datas[idx].x0_attackGain;
|
x10_deltas[idx].x14_attackIntensity = gain * x0_datas[idx].x0_attackGain;
|
||||||
x10_deltas[idx].x18_sustainLevel = gain * x0_datas[idx].x10_sustainGain;
|
x10_deltas[idx].x18_sustainIntensity = gain * x0_datas[idx].x10_sustainGain;
|
||||||
x2c_usedChannels |= 1 << idx;
|
x2c_usedChannels |= 1 << idx;
|
||||||
if (data.x18_24_hasSustain)
|
if (data.x18_24_hasSustain)
|
||||||
return CreateRumbleHandle(idx);
|
return CreateRumbleHandle(idx);
|
||||||
|
|
|
@ -54,25 +54,25 @@ struct SAdsrDelta
|
||||||
enum class EPhase
|
enum class EPhase
|
||||||
{
|
{
|
||||||
Stop,
|
Stop,
|
||||||
Queued,
|
PrePulse,
|
||||||
Attack,
|
Attack,
|
||||||
Decay,
|
Decay,
|
||||||
Sustain,
|
Sustain,
|
||||||
Release
|
Release
|
||||||
};
|
};
|
||||||
|
|
||||||
float x0_curLevel = 0.f;
|
float x0_curIntensity = 0.f;
|
||||||
float x4_attackTime = 0.f;
|
float x4_attackTime = 0.f;
|
||||||
float x8_decayTime = 0.f;
|
float x8_decayTime = 0.f;
|
||||||
float xc_releaseTime = 0.f;
|
float xc_releaseTime = 0.f;
|
||||||
float x10_autoReleaseTime = 0.f;
|
float x10_autoReleaseTime = 0.f;
|
||||||
float x14_attackLevel;
|
float x14_attackIntensity;
|
||||||
float x18_sustainLevel;
|
float x18_sustainIntensity;
|
||||||
ERumblePriority x1c_priority;
|
ERumblePriority x1c_priority;
|
||||||
EPhase x20_phase;
|
EPhase x20_phase;
|
||||||
|
|
||||||
SAdsrDelta(EPhase phase, ERumblePriority priority)
|
SAdsrDelta(EPhase phase, ERumblePriority priority)
|
||||||
: x1c_priority(priority), x20_phase(phase)
|
: x0_curIntensity(phase == EPhase::PrePulse ? 2.f : 0.f), x1c_priority(priority), x20_phase(phase)
|
||||||
{}
|
{}
|
||||||
SAdsrDelta(EPhase phase)
|
SAdsrDelta(EPhase phase)
|
||||||
: x1c_priority(ERumblePriority::None), x20_phase(phase)
|
: x1c_priority(ERumblePriority::None), x20_phase(phase)
|
||||||
|
@ -80,7 +80,7 @@ struct SAdsrDelta
|
||||||
|
|
||||||
static SAdsrDelta Stopped() { return SAdsrDelta(EPhase::Stop); }
|
static SAdsrDelta Stopped() { return SAdsrDelta(EPhase::Stop); }
|
||||||
static SAdsrDelta Start(ERumblePriority priority, bool preQueue)
|
static SAdsrDelta Start(ERumblePriority priority, bool preQueue)
|
||||||
{ return SAdsrDelta(preQueue ? EPhase::Queued : EPhase::Attack, priority); }
|
{ return SAdsrDelta(preQueue ? EPhase::PrePulse : EPhase::Attack, priority); }
|
||||||
};
|
};
|
||||||
|
|
||||||
class CRumbleVoice
|
class CRumbleVoice
|
||||||
|
|
Loading…
Reference in New Issue