mirror of https://github.com/AxioDL/metaforce.git
Implement rumble classes
This commit is contained in:
parent
132f2ab007
commit
13a31be23b
|
@ -395,7 +395,7 @@ void CStateManager::UpdateEscapeSequenceTimer(float dt)
|
|||
float factor2 = factor * factor;
|
||||
CCameraShakeData shakeData(1.f, factor2 * 0.2f * x900_activeRandom->Range(0.5f, 1.f));
|
||||
x870_cameraManager->AddCameraShaker(shakeData, true);
|
||||
x88c_rumbleManager->Rumble(*this, ERumbleFxId::Seven, 0.75f, ERumblePriority::One);
|
||||
x88c_rumbleManager->Rumble(*this, ERumbleFxId::EscapeSequenceShake, 0.75f, ERumblePriority::One);
|
||||
g_EscapeShakeCountdown = -12.f * factor2 + 15.f;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -628,7 +628,7 @@ void CCameraManager::UpdateRumble(float dt, CStateManager& mgr)
|
|||
|
||||
if (!x14_shakers.empty() && !xa0_25_rumbling && xa0_24_pendingRumble)
|
||||
{
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Six, 1.f, ERumblePriority::Two);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::CameraShake, 1.f, ERumblePriority::Two);
|
||||
xa0_25_rumbling = true;
|
||||
}
|
||||
|
||||
|
|
|
@ -212,6 +212,27 @@ public:
|
|||
}
|
||||
}
|
||||
}
|
||||
void ControlAllMotors(const EMotorState* states)
|
||||
{
|
||||
if (smashAdapter)
|
||||
{
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
{
|
||||
switch (states[i])
|
||||
{
|
||||
case EMotorState::Stop:
|
||||
smashAdapter->stopRumble(i);
|
||||
break;
|
||||
case EMotorState::Rumble:
|
||||
smashAdapter->startRumble(i);
|
||||
break;
|
||||
case EMotorState::StopHard:
|
||||
smashAdapter->stopRumble(i, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* This is where the game thread enters */
|
||||
void Update(float dt, CArchitectureQueue& queue);
|
||||
|
|
|
@ -1,25 +1,103 @@
|
|||
#include "CRumbleGenerator.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
CRumbleGenerator::CRumbleGenerator()
|
||||
{
|
||||
xf0_24_disabled = false;
|
||||
HardStopAll();
|
||||
}
|
||||
|
||||
void CRumbleGenerator::Update(float)
|
||||
CRumbleGenerator::~CRumbleGenerator()
|
||||
{
|
||||
|
||||
HardStopAll();
|
||||
}
|
||||
|
||||
void CRumbleGenerator::Update(float dt)
|
||||
{
|
||||
if (!xf0_24_disabled)
|
||||
{
|
||||
bool updated = false;
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
{
|
||||
float intensity = x0_voices[i].GetIntensity();
|
||||
if (!x0_voices[i].Update(dt) || intensity <= 0.f)
|
||||
{
|
||||
xc0_periodTime[i] = 0.f;
|
||||
xd0_onTime[i] = 0.f;
|
||||
if (xe0_commandArray[i] != EMotorState::Stop)
|
||||
{
|
||||
xe0_commandArray[i] = EMotorState::Stop;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xc0_periodTime[i] += dt;
|
||||
if (xc0_periodTime[i] >= 1.f / (30.f * intensity))
|
||||
{
|
||||
xc0_periodTime[i] = 0.f;
|
||||
if (xe0_commandArray[i] != EMotorState::Rumble)
|
||||
{
|
||||
xe0_commandArray[i] = EMotorState::Rumble;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
xd0_onTime[i] += dt;
|
||||
if (xd0_onTime[i] >= (1.f / 30.f))
|
||||
{
|
||||
xd0_onTime[i] = 0.f;
|
||||
if (xe0_commandArray[i] != EMotorState::Stop)
|
||||
{
|
||||
xe0_commandArray[i] = EMotorState::Stop;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updated)
|
||||
g_InputGenerator->ControlAllMotors(xe0_commandArray);
|
||||
}
|
||||
}
|
||||
|
||||
static const EMotorState HardStopCommands[] = { EMotorState::StopHard,
|
||||
EMotorState::StopHard,
|
||||
EMotorState::StopHard,
|
||||
EMotorState::StopHard };
|
||||
|
||||
void CRumbleGenerator::HardStopAll()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CRumbleGenerator::Rumble(const SAdsrData& adsr, float, ERumblePriority prio, EIOPort port)
|
||||
for (int i=0 ; i<4 ; ++i)
|
||||
{
|
||||
xc0_periodTime[i] = 0.f;
|
||||
xd0_onTime[i] = 0.f;
|
||||
xe0_commandArray[i] = EMotorState::Stop;
|
||||
x0_voices[i].HardReset();
|
||||
}
|
||||
g_InputGenerator->ControlAllMotors(HardStopCommands);
|
||||
}
|
||||
|
||||
s16 CRumbleGenerator::Rumble(const SAdsrData& adsr, float gain, ERumblePriority prio, EIOPort port)
|
||||
{
|
||||
CRumbleVoice& vox = x0_voices[int(port)];
|
||||
s16 freeChan = vox.GetFreeChannel();
|
||||
if (prio >= vox.GetPriority(freeChan))
|
||||
{
|
||||
xc0_periodTime[int(port)] = 0.f;
|
||||
return vox.Activate(adsr, freeChan, gain, prio);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CRumbleGenerator::Stop(s16 id, EIOPort port)
|
||||
{
|
||||
CRumbleVoice& vox = x0_voices[int(port)];
|
||||
vox.Deactivate(id, false);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -8,11 +8,20 @@ namespace urde
|
|||
{
|
||||
class CRumbleGenerator
|
||||
{
|
||||
CRumbleVoice x0_voices[4];
|
||||
float xc0_periodTime[4];
|
||||
float xd0_onTime[4];
|
||||
EMotorState xe0_commandArray[4];
|
||||
bool xf0_24_disabled : 1;
|
||||
public:
|
||||
CRumbleGenerator();
|
||||
void Update(float);
|
||||
~CRumbleGenerator();
|
||||
void Update(float dt);
|
||||
void HardStopAll();
|
||||
void Rumble(const SAdsrData& adsr, float, ERumblePriority prio, EIOPort port);
|
||||
s16 Rumble(const SAdsrData& adsr, float, ERumblePriority prio, EIOPort port);
|
||||
void Stop(s16 id, EIOPort port);
|
||||
bool IsDisabled() const { return xf0_24_disabled; }
|
||||
void SetDisabled(bool disabled) { xf0_24_disabled = disabled; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,15 +1,29 @@
|
|||
#include "CRumbleManager.hpp"
|
||||
#include "CStateManager.hpp"
|
||||
#include "World/CPlayer.hpp"
|
||||
#include "GameGlobalObjects.hpp"
|
||||
#include "CGameState.hpp"
|
||||
#include "RumbleFxTable.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
void CRumbleManager::SetDisabled(bool disabled)
|
||||
s16 CRumbleManager::Rumble(CStateManager& mgr, const zeus::CVector3f& pos,
|
||||
ERumbleFxId fx, float dist, ERumblePriority priority)
|
||||
{
|
||||
if (disabled)
|
||||
x0_rumbleGenerator.HardStopAll();
|
||||
xf0_24_disabled = disabled;
|
||||
if (zeus::close_enough(dist, 0.f))
|
||||
return -1;
|
||||
zeus::CVector3f delta = mgr.GetPlayer().GetTranslation() - pos;
|
||||
if (delta.magSquared() < dist * dist)
|
||||
return Rumble(mgr, fx, 1.f - delta.magnitude() / dist, priority);
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CRumbleManager::Update(float dt) { x0_rumbleGenerator.Update(dt); }
|
||||
s16 CRumbleManager::Rumble(CStateManager& mgr, ERumbleFxId fx, float gain, ERumblePriority priority)
|
||||
{
|
||||
if (g_GameState->GameOptions().GetIsRumbleEnabled())
|
||||
return x0_rumbleGenerator.Rumble(RumbleFxTable[int(fx)], gain, priority, EIOPort::Zero);
|
||||
return -1;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
#define __URDE_CRUMBLEMANAGER_HPP__
|
||||
|
||||
#include "CRumbleGenerator.hpp"
|
||||
#include "zeus/CVector3f.hpp"
|
||||
|
||||
namespace urde
|
||||
{
|
||||
|
@ -9,15 +10,18 @@ class CStateManager;
|
|||
class CRumbleManager
|
||||
{
|
||||
CRumbleGenerator x0_rumbleGenerator;
|
||||
bool xf0_24_disabled : 1;
|
||||
public:
|
||||
CRumbleManager() { xf0_24_disabled = false; }
|
||||
bool IsDisabled() const { return xf0_24_disabled; }
|
||||
void SetDisabled(bool disabled);
|
||||
void Update(float);
|
||||
void StopRumble(s16) {}
|
||||
void Rumble(CStateManager&, ERumbleFxId, ERumblePriority priority) {}
|
||||
s16 Rumble(CStateManager&, ERumbleFxId, float, ERumblePriority priority) {return 0;}
|
||||
bool IsDisabled() const { return x0_rumbleGenerator.IsDisabled(); }
|
||||
void SetDisabled(bool disabled) { x0_rumbleGenerator.SetDisabled(disabled); }
|
||||
void Update(float dt) { x0_rumbleGenerator.Update(dt); }
|
||||
void StopRumble(s16 id)
|
||||
{
|
||||
if (id == -1)
|
||||
return;
|
||||
x0_rumbleGenerator.Stop(id, EIOPort::Zero);
|
||||
}
|
||||
s16 Rumble(CStateManager& mgr, const zeus::CVector3f& pos, ERumbleFxId fx, float dist, ERumblePriority priority);
|
||||
s16 Rumble(CStateManager& mgr, ERumbleFxId fx, float gain, ERumblePriority priority);
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -2,4 +2,203 @@
|
|||
|
||||
namespace urde
|
||||
{
|
||||
|
||||
CRumbleVoice::CRumbleVoice()
|
||||
{
|
||||
x0_datas.resize(4);
|
||||
x10_deltas.resize(4, SAdsrDelta::Stopped());
|
||||
x20_handleIds.resize(4);
|
||||
}
|
||||
|
||||
s16 CRumbleVoice::CreateRumbleHandle(s16 idx)
|
||||
{
|
||||
++x2e_lastId;
|
||||
if (x2e_lastId == 0)
|
||||
x2e_lastId = 1;
|
||||
x20_handleIds[idx] = x2e_lastId;
|
||||
return (x2e_lastId << 8) | idx;
|
||||
}
|
||||
|
||||
bool CRumbleVoice::OwnsSustained(s16 handle) const
|
||||
{
|
||||
int idx = handle & 0xf;
|
||||
if (idx < 4)
|
||||
return x20_handleIds[idx] == ((handle >> 8) & 0xff);
|
||||
return false;
|
||||
}
|
||||
|
||||
s16 CRumbleVoice::GetFreeChannel() const
|
||||
{
|
||||
for (s16 i=0 ; i<4 ; ++i)
|
||||
if (!((1 << i) & x2c_usedChannels))
|
||||
return i;
|
||||
return false;
|
||||
}
|
||||
|
||||
float CRumbleVoice::GetIntensity() const
|
||||
{
|
||||
return std::min(2.f,
|
||||
std::max(x10_deltas[0].x0_curLevel,
|
||||
std::max(x10_deltas[1].x0_curLevel,
|
||||
std::max(x10_deltas[2].x0_curLevel,
|
||||
x10_deltas[3].x0_curLevel))));
|
||||
}
|
||||
|
||||
bool CRumbleVoice::UpdateChannel(SAdsrDelta& delta, const SAdsrData& data, float dt)
|
||||
{
|
||||
switch (delta.x20_phase)
|
||||
{
|
||||
case SAdsrDelta::EPhase::Queued:
|
||||
if (delta.x4_attackTime < (1.f/30.f))
|
||||
{
|
||||
delta.x4_attackTime += dt;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta.x20_phase = SAdsrDelta::EPhase::Attack;
|
||||
delta.x0_curLevel = 0.f;
|
||||
delta.x4_attackTime = 0.f;
|
||||
}
|
||||
break;
|
||||
case SAdsrDelta::EPhase::Attack:
|
||||
if (delta.x4_attackTime < data.x8_attackDur)
|
||||
{
|
||||
float t = delta.x4_attackTime / data.x8_attackDur;
|
||||
delta.x0_curLevel = t * delta.x14_attackLevel;
|
||||
delta.x4_attackTime += dt;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta.x0_curLevel = delta.x14_attackLevel;
|
||||
delta.x20_phase = SAdsrDelta::EPhase::Decay;
|
||||
}
|
||||
break;
|
||||
case SAdsrDelta::EPhase::Decay:
|
||||
if (data.x18_24_hasSustain)
|
||||
{
|
||||
if (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.x8_decayTime += dt;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta.x0_curLevel = delta.x18_sustainLevel;
|
||||
delta.x20_phase = SAdsrDelta::EPhase::Sustain;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (delta.x8_decayTime < data.xc_decayDur)
|
||||
{
|
||||
float t = delta.x8_decayTime / data.xc_decayDur;
|
||||
delta.x0_curLevel = (1.f - t) * delta.x14_attackLevel;
|
||||
delta.x8_decayTime += dt;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta.x0_curLevel = 0.f;
|
||||
delta.x20_phase = SAdsrDelta::EPhase::Stop;
|
||||
}
|
||||
if (delta.x20_phase != SAdsrDelta::EPhase::Decay)
|
||||
{
|
||||
delta.x20_phase = SAdsrDelta::EPhase::Stop;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SAdsrDelta::EPhase::Release:
|
||||
{
|
||||
float a = data.x18_24_hasSustain ? delta.x18_sustainLevel : 0.f;
|
||||
if (delta.xc_releaseTime < data.x14_releaseDur)
|
||||
{
|
||||
float t = delta.xc_releaseTime / data.x14_releaseDur;
|
||||
delta.x0_curLevel = (1.f - t) * a;
|
||||
delta.xc_releaseTime += dt;
|
||||
}
|
||||
else
|
||||
{
|
||||
delta.x0_curLevel = 0.f;
|
||||
delta.x20_phase = SAdsrDelta::EPhase::Stop;
|
||||
}
|
||||
if (delta.x20_phase != SAdsrDelta::EPhase::Release)
|
||||
{
|
||||
delta.x20_phase = SAdsrDelta::EPhase::Stop;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (data.x18_25_autoRelease)
|
||||
{
|
||||
if (delta.x10_autoReleaseTime < data.x4_autoReleaseDur)
|
||||
delta.x10_autoReleaseTime += dt;
|
||||
else if (delta.x20_phase == SAdsrDelta::EPhase::Sustain)
|
||||
delta.x20_phase = SAdsrDelta::EPhase::Release;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CRumbleVoice::Update(float dt)
|
||||
{
|
||||
if (x2c_usedChannels != 0)
|
||||
{
|
||||
for (s16 i=0 ; i<4 ; ++i)
|
||||
{
|
||||
if ((1 << i) & x2c_usedChannels)
|
||||
{
|
||||
if (UpdateChannel(x10_deltas[i], x0_datas[i], dt))
|
||||
{
|
||||
x2c_usedChannels &= (1 << i);
|
||||
x10_deltas[i] = SAdsrDelta::Stopped();
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void CRumbleVoice::HardReset()
|
||||
{
|
||||
x2c_usedChannels = 0;
|
||||
for (s16 i=0 ; i<4 ; ++i)
|
||||
{
|
||||
x10_deltas[i] = SAdsrDelta::Stopped();
|
||||
x20_handleIds[i] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
s16 CRumbleVoice::Activate(const SAdsrData& data, s16 idx, float gain, ERumblePriority prio)
|
||||
{
|
||||
if (gain > 0.f)
|
||||
{
|
||||
x0_datas[idx] = data;
|
||||
x10_deltas[idx] = SAdsrDelta::Start(prio, !x2c_usedChannels);
|
||||
x10_deltas[idx].x14_attackLevel = gain * x0_datas[idx].x0_attackGain;
|
||||
x10_deltas[idx].x18_sustainLevel = gain * x0_datas[idx].x10_sustainGain;
|
||||
x2c_usedChannels |= 1 << idx;
|
||||
if (data.x18_24_hasSustain)
|
||||
return CreateRumbleHandle(idx);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CRumbleVoice::Deactivate(s16 id, bool b1)
|
||||
{
|
||||
if (id == -1)
|
||||
return;
|
||||
if (OwnsSustained(id))
|
||||
{
|
||||
int handle = (id & 0xf);
|
||||
if (x2c_usedChannels & (1 << handle))
|
||||
x10_deltas[handle].x20_phase = SAdsrDelta::EPhase::Release;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -7,14 +7,14 @@ namespace urde
|
|||
{
|
||||
enum class ERumbleFxId
|
||||
{
|
||||
Six = 6,
|
||||
Seven = 7,
|
||||
Eleven = 11,
|
||||
Twelve = 12,
|
||||
Thirteen = 13,
|
||||
Fourteen = 14,
|
||||
Fifteen = 15,
|
||||
Seventeen = 17
|
||||
CameraShake = 6,
|
||||
EscapeSequenceShake = 7,
|
||||
PlayerBump = 11,
|
||||
PlayerGunCharge = 12,
|
||||
PlayerMissileFire = 13,
|
||||
PlayerGrappleFire = 14,
|
||||
PlayerLand = 15,
|
||||
PlayerGrappleSwoosh = 17
|
||||
};
|
||||
enum class ERumblePriority
|
||||
{
|
||||
|
@ -24,34 +24,28 @@ enum class ERumblePriority
|
|||
Three = 3
|
||||
};
|
||||
|
||||
struct SAdsrData;
|
||||
class CRumbleVoice
|
||||
{
|
||||
public:
|
||||
CRumbleVoice() {}
|
||||
CRumbleVoice(const SAdsrData& data);
|
||||
};
|
||||
|
||||
struct SAdsrData
|
||||
{
|
||||
float x0 = 0.f;
|
||||
float x4 = 0.f;
|
||||
float x8 = 0.f;
|
||||
float xc = 0.f;
|
||||
float x10 = 0.f;
|
||||
float x14 = 0.f;
|
||||
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;
|
||||
union
|
||||
{
|
||||
struct { bool x18_24 : 1; bool x18_25 : 1; };
|
||||
struct { bool x18_24_hasSustain : 1; bool x18_25_autoRelease : 1; };
|
||||
u8 dummy = 0;
|
||||
};
|
||||
|
||||
SAdsrData() = default;
|
||||
SAdsrData(float a, float b, float c, float d, float e, float f, bool g, bool h)
|
||||
: x0(a), x4(b), x8(c), xc(d), x10(e), x14(f)
|
||||
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)
|
||||
{
|
||||
x18_24 = g;
|
||||
x18_25 = h;
|
||||
x18_24_hasSustain = hasSustain;
|
||||
x18_25_autoRelease = autoRelease;
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -60,14 +54,20 @@ struct SAdsrDelta
|
|||
enum class EPhase
|
||||
{
|
||||
Stop,
|
||||
Start,
|
||||
Queued,
|
||||
Attack,
|
||||
Decay,
|
||||
Sustain,
|
||||
Release
|
||||
};
|
||||
|
||||
float x0 = 0.f;
|
||||
float x4 = 0.f;
|
||||
float x8 = 0.f;
|
||||
float xc = 0.f;
|
||||
float x10 = 0.f;
|
||||
float x0_curLevel = 0.f;
|
||||
float x4_attackTime = 0.f;
|
||||
float x8_decayTime = 0.f;
|
||||
float xc_releaseTime = 0.f;
|
||||
float x10_autoReleaseTime = 0.f;
|
||||
float x14_attackLevel;
|
||||
float x18_sustainLevel;
|
||||
ERumblePriority x1c_priority;
|
||||
EPhase x20_phase;
|
||||
|
||||
|
@ -79,7 +79,29 @@ struct SAdsrDelta
|
|||
{}
|
||||
|
||||
static SAdsrDelta Stopped() { return SAdsrDelta(EPhase::Stop); }
|
||||
static SAdsrDelta Start(ERumblePriority priority) { return SAdsrDelta(EPhase::Start, priority); }
|
||||
static SAdsrDelta Start(ERumblePriority priority, bool preQueue)
|
||||
{ return SAdsrDelta(preQueue ? EPhase::Queued : EPhase::Attack, priority); }
|
||||
};
|
||||
|
||||
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; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -5,24 +5,25 @@ namespace urde
|
|||
|
||||
const SAdsrData RumbleFxTable[] =
|
||||
{
|
||||
/* attackGain, autoReleaseDur, attackDur, decayDur, sustainGain, releaseDur, hasSustain, autoRelease */
|
||||
{0.48f, 0.f, 0.3f, 0.125f, 0.1f, 0.5f, false, false},
|
||||
{0.66f, 0.f, 0.11f, 0.175f, 0.42f, 0.375f, false, false},
|
||||
{0.42f, 0.f, 0.1f, 0.225f, 0.225f, 0.f, false, false},
|
||||
{1.5f, 0.f, 0.1f, 0.225f, 1.025f, 0.4f, false, false},
|
||||
{0.786f, 0.f, 0.1f, 0.16f, 0.655f, 0.255f, false, false},
|
||||
{1.2f, 0.f, 0.4f, 0.1f, 1.f, 0.055f, false, false},
|
||||
{1.2f, 0.f, 0.05f, 0.3f, 0.4f, 1.1f, false, false},
|
||||
{1.02f, 0.f, 0.065f, 0.175f, 0.85f, 0.9f, false, false},
|
||||
{1.2f, 0.f, 0.05f, 0.3f, 0.4f, 1.1f, false, false}, // CameraShake
|
||||
{1.02f, 0.f, 0.065f, 0.175f, 0.85f, 0.9f, false, false}, // EscapeSequenceShake
|
||||
{0.48f, 0.f, 0.065f, 0.175f, 0.4f, 0.0f, false, false},
|
||||
{0.72f, 0.f, 0.001f, 0.001f, 0.6f, 0.1f, false, false},
|
||||
{0.24f, 0.f, 0.001f, 0.525f, 0.2f, 0.2f, false, false},
|
||||
{2.4f, 0.f, 0.001f, 0.466f, 0.f, 0.f, false, false},
|
||||
{0.5532f, 0.f, 0.f, 1.345f, 0.f, 1.756f, false, false},
|
||||
{2.4f, 0.f, 0.01f, 0.125f, 0.25f, 0.5f, false, false},
|
||||
{0.84f, 0.f, 0.1f, 0.125f, 0.35f, 1.0f, false, false},
|
||||
{2.4f, 0.f, 0.1f, 0.225f, 0.38f, 0.3f, false, false},
|
||||
{2.4f, 0.f, 0.001f, 0.466f, 0.f, 0.f, false, false}, // PlayerBump
|
||||
{0.5532f, 0.f, 0.f, 1.345f, 0.f, 1.756f, false, false}, // PlayerGunCharge
|
||||
{2.4f, 0.f, 0.01f, 0.125f, 0.25f, 0.5f, false, false}, // PlayerMissileFire
|
||||
{0.84f, 0.f, 0.1f, 0.125f, 0.35f, 1.0f, false, false}, // PlayerGrappleFire
|
||||
{2.4f, 0.f, 0.1f, 0.225f, 0.38f, 0.3f, false, false}, // PlayerLand
|
||||
{0.48f, 0.f, 0.065f, 0.175f, 0.4f, 0.f, false, false},
|
||||
{0.3024f, 0.f, 0.1f, 1.345f, 0.f, 1.756f, false, false},
|
||||
{0.3024f, 0.f, 0.1f, 1.345f, 0.f, 1.756f, false, false}, // PlayerGrappleSwoosh
|
||||
{0.72f, 0.f, 0.01f, 0.01f, 0.6f, 0.1f, false, false},
|
||||
{1.1904f, 0.f, 0.f, 0.125f, 0.683f, 0.5f, true, false},
|
||||
{1.2f, 0.f, 0.01f, 0.621f, 0.f, 0.f, false, false},
|
||||
|
|
|
@ -1647,7 +1647,8 @@ void CFrontEndUI::SOptionsFrontEndFrame::DoMenuSelectionChange(CGuiTableGroup* c
|
|||
if (option.option == EGameOption::Rumble && caller->GetUserSelection() > 0)
|
||||
{
|
||||
x40_rumbleGen.HardStopAll();
|
||||
x40_rumbleGen.Rumble(RumbleFxTable[11], 1.f, ERumblePriority::One, EIOPort::Zero);
|
||||
x40_rumbleGen.Rumble(RumbleFxTable[int(ERumbleFxId::PlayerBump)], 1.f,
|
||||
ERumblePriority::One, EIOPort::Zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -81,6 +81,17 @@ CInventoryScreen::CInventoryScreen(const CStateManager& mgr, CGuiFrame& frame, c
|
|||
playerState.HasPowerUp(CPlayerState::EItemType::GrappleBeam));
|
||||
}
|
||||
|
||||
CInventoryScreen::~CInventoryScreen()
|
||||
{
|
||||
for (int i=0 ; i<5 ; ++i)
|
||||
{
|
||||
xd8_textpane_titles[i]->TextSupport().SetFontColor(zeus::CColor::skWhite);
|
||||
x15c_model_righttitledecos[i]->SetColor(zeus::CColor::skWhite);
|
||||
x144_model_titles[i]->SetColor(zeus::CColor::skWhite);
|
||||
}
|
||||
x8c_model_righthighlight->SetColor(zeus::CColor::skWhite);
|
||||
}
|
||||
|
||||
bool CInventoryScreen::InputDisabled() const
|
||||
{
|
||||
return std::fabs(x19c_samusDoll->GetViewInterpolation()) > 0 || x1a8_state == EState::Leaving;
|
||||
|
|
|
@ -36,6 +36,7 @@ class CInventoryScreen : public CPauseScreenBase
|
|||
public:
|
||||
CInventoryScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg,
|
||||
const CDependencyGroup& suitDgrp, const CDependencyGroup& ballDgrp);
|
||||
~CInventoryScreen();
|
||||
|
||||
bool InputDisabled() const;
|
||||
void TransitioningAway();
|
||||
|
|
|
@ -52,7 +52,6 @@ public:
|
|||
CLogBookScreen(const CStateManager& mgr, CGuiFrame& frame, const CStringTable& pauseStrg);
|
||||
~CLogBookScreen();
|
||||
|
||||
|
||||
bool InputDisabled() const;
|
||||
void TransitioningAway();
|
||||
void Update(float dt, CRandom16& rand, CArchitectureQueue& archQueue);
|
||||
|
|
|
@ -91,7 +91,7 @@ void COptionsScreen::OnEnumChanged(CGuiTableGroup* caller, int oldSel)
|
|||
if (opt == EGameOption::Rumble && caller->GetUserSelection() > 0)
|
||||
{
|
||||
x1a8_rumble.HardStopAll();
|
||||
x1a8_rumble.Rumble(RumbleFxTable[11], 1.f, ERumblePriority::One, EIOPort::Zero);
|
||||
x1a8_rumble.Rumble(RumbleFxTable[int(ERumbleFxId::PlayerBump)], 1.f, ERumblePriority::One, EIOPort::Zero);
|
||||
}
|
||||
|
||||
CPauseScreenBase::UpdateSideTable(caller);
|
||||
|
|
|
@ -87,6 +87,7 @@ void CPauseScreenBase::InitializeFrameGlue()
|
|||
for (int i=0 ; i<5 ; ++i)
|
||||
{
|
||||
xd8_textpane_titles.push_back(static_cast<CGuiTextPane*>(x8_frame.FindWidget(hecl::Format("textpane_title%d", i + 1))));
|
||||
xd8_textpane_titles.back()->TextSupport().SetText(u"");
|
||||
x144_model_titles.push_back(static_cast<CGuiModel*>(x8_frame.FindWidget(hecl::Format("model_title%d", i + 1))));
|
||||
x15c_model_righttitledecos.push_back(static_cast<CGuiModel*>(x8_frame.FindWidget(hecl::Format("model_righttitledeco%d", i + 1))));
|
||||
xa8_textpane_categories.push_back(static_cast<CGuiTextPane*>(x8_frame.FindWidget(hecl::Format("textpane_category%d", i))));
|
||||
|
|
|
@ -313,7 +313,7 @@ void CAuxWeapon::LaunchMissile(float dt, bool underwater, bool charged, CPlayerS
|
|||
}
|
||||
else
|
||||
{
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Thirteen, 0.5f, ERumblePriority::One);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerMissileFire, 0.5f, ERumblePriority::One);
|
||||
}
|
||||
x7c_comboSfx = NWeaponTypes::play_sfx(sfxId, underwater, false, 0.165f);
|
||||
}
|
||||
|
|
|
@ -282,7 +282,7 @@ void CGrappleArm::DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node,
|
|||
x398_grappleHitGen->SetParticleEmission(false);
|
||||
x394_grappleClawGen->SetParticleEmission(true);
|
||||
NWeaponTypes::play_sfx(1526, false, false, -0.15f);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Fourteen, 1.f, ERumblePriority::Three);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerGrappleFire, 1.f, ERumblePriority::Three);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -436,7 +436,7 @@ void CGrappleArm::UpdateSwingAction(float grappleSwingT, float dt, CStateManager
|
|||
x330_swooshSfx = NWeaponTypes::play_sfx(1528, false, false, -0.15f);
|
||||
if (x3b0_rumbleHandle != -1)
|
||||
mgr.GetRumbleManager().StopRumble(x3b0_rumbleHandle);
|
||||
x3b0_rumbleHandle = mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Seventeen, 1.f, ERumblePriority::Three);
|
||||
x3b0_rumbleHandle = mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerGrappleSwoosh, 1.f, ERumblePriority::Three);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1274,7 +1274,7 @@ void CPlayerGun::UpdateChargeState(float dt, CStateManager& mgr)
|
|||
x2e0_chargeSfx = NWeaponTypes::play_sfx(skBeamChargeUpSound[int(x310_currentBeam)],
|
||||
x834_27_underwater, true, 0.165f);
|
||||
if (x830_chargeRumbleHandle == -1)
|
||||
x830_chargeRumbleHandle = mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Twelve, 1.f,
|
||||
x830_chargeRumbleHandle = mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerGunCharge, 1.f,
|
||||
ERumblePriority::Three);
|
||||
x832_27_chargeAnimStarted = true;
|
||||
}
|
||||
|
|
|
@ -1026,7 +1026,7 @@ void CPlayer::TakeDamage(bool significant, const zeus::CVector3f& location,
|
|||
float tmp = x55c_damageAmt / 25.f;
|
||||
if (std::fabs(tmp) > 1.f)
|
||||
tmp = tmp > 0.f ? 1.f : -1.f;
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Eleven, ERumblePriority::One);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerBump, tmp, ERumblePriority::One);
|
||||
}
|
||||
|
||||
if (x2f8_morphBallState != EPlayerMorphBallState::Unmorphed)
|
||||
|
@ -2786,7 +2786,7 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
|
|||
{
|
||||
if (std::fabs(rumbleMag) > 0.8f)
|
||||
rumbleMag = (rumbleMag > 0.f) ? 0.8f : -0.8f;
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Fifteen, rumbleMag, ERumblePriority::One);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerLand, rumbleMag, ERumblePriority::One);
|
||||
}
|
||||
|
||||
x2a0_ = 0.f;
|
||||
|
@ -2805,7 +2805,7 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
|
|||
float rumbleMag = -x138_velocity.z / 110.f * 0.5f;
|
||||
if (std::fabs(rumbleMag) > 0.8f)
|
||||
rumbleMag = (rumbleMag > 0.f) ? 0.8f : -0.8f;
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Fifteen, rumbleMag, ERumblePriority::One);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerLand, rumbleMag, ERumblePriority::One);
|
||||
x2a0_ = 0.f;
|
||||
}
|
||||
if (x138_velocity.z < -30.f)
|
||||
|
@ -2813,7 +2813,7 @@ void CPlayer::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CState
|
|||
float rumbleMag = -x138_velocity.z / 110.f;
|
||||
if (std::fabs(rumbleMag) > 0.8f)
|
||||
rumbleMag = (rumbleMag > 0.f) ? 0.8f : -0.8f;
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Fifteen, rumbleMag, ERumblePriority::One);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerLand, rumbleMag, ERumblePriority::One);
|
||||
x2a0_ = 0.f;
|
||||
}
|
||||
}
|
||||
|
@ -5406,7 +5406,7 @@ void CPlayer::BombJump(const zeus::CVector3f& pos, CStateManager& mgr)
|
|||
{
|
||||
float upVel = std::sqrt(2.f * std::fabs(g_tweakPlayer->GetNormalGravAccel()) *
|
||||
g_tweakPlayer->GetBombJumpRadius());
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Eleven, ERumblePriority::One);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerBump, 0.3f, ERumblePriority::One);
|
||||
x2a0_ = 0.01f;
|
||||
switch (GetSurfaceRestraint())
|
||||
{
|
||||
|
@ -5523,7 +5523,7 @@ void CPlayer::SetMoveState(EPlayerMovementState newState, CStateManager& mgr)
|
|||
{
|
||||
CSfxHandle hnd = CSfxManager::SfxStart(1470, 1.f, 0.f, true, 0x7f, false, kInvalidAreaId);
|
||||
ApplySubmergedPitchBend(hnd);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Eleven, ERumblePriority::One);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerBump, 0.2015f, ERumblePriority::One);
|
||||
x288_startingJumpTimeout = g_tweakPlayer->GetAllowedDoubleJumpTime();
|
||||
x290_minJumpTimeout = g_tweakPlayer->GetAllowedDoubleJumpTime() - g_tweakPlayer->GetMinDoubleJumpTime();
|
||||
x28c_sjTimer = 0.f;
|
||||
|
@ -5870,7 +5870,7 @@ void CPlayer::ComputeDash(const CFinalInput& input, float dt, CStateManager& mgr
|
|||
SetVelocityWR(vel);
|
||||
x778_dashSfx = CSfxManager::SfxStart(1560, 1.f, 0.f, true, 0x7f, false, kInvalidAreaId);
|
||||
ApplySubmergedPitchBend(x778_dashSfx);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::Eleven, ERumblePriority::One);
|
||||
mgr.GetRumbleManager().Rumble(mgr, ERumbleFxId::PlayerBump, 0.24375f, ERumblePriority::One);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit 6c0227fe6917c4997e749fe588f0fbfc62e33214
|
||||
Subproject commit a0754e08b7a524c8e93e4eaf8d267ed2be2ad105
|
2
nod
2
nod
|
@ -1 +1 @@
|
|||
Subproject commit 5197abc131d369af4f66b044242bfe61011f66be
|
||||
Subproject commit bab7aab6fa7a82123f827475c1471f641ed2bf67
|
Loading…
Reference in New Issue