mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-12-16 17:37:02 +00:00
Match and link CRumbleGenerator, nearly match CRumbleVoice
This commit is contained in:
81
src/Kyoto/Input/CRumbleGenerator.cpp
Normal file
81
src/Kyoto/Input/CRumbleGenerator.cpp
Normal file
@@ -0,0 +1,81 @@
|
||||
#include "Kyoto/Input/CRumbleGenerator.hpp"
|
||||
|
||||
const EMotorState CRumbleGenerator::kStopAll[4] = {
|
||||
kMS_StopHard,
|
||||
kMS_StopHard,
|
||||
kMS_StopHard,
|
||||
kMS_StopHard,
|
||||
};
|
||||
|
||||
CRumbleGenerator::CRumbleGenerator() : xf0_24_disabled(false) { HardStopAll(); }
|
||||
|
||||
CRumbleGenerator::~CRumbleGenerator() { HardStopAll(); }
|
||||
|
||||
short CRumbleGenerator::Rumble(const SAdsrData& adsr, float gain, ERumblePriority prio,
|
||||
EIOPort port) {
|
||||
ushort freeChan = x0_voices[port].GetFreeChannel();
|
||||
if (prio >= x0_voices[port].GetPriority(freeChan)) {
|
||||
xc0_periodTime[port] = 0.f;
|
||||
xd0_onTime[port] = 0.f;
|
||||
return x0_voices[port].Activate(adsr, freeChan, gain, prio);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void CRumbleGenerator::Update(float dt) {
|
||||
if (!xf0_24_disabled) {
|
||||
bool updated = false;
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
const 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] != kMS_Stop) {
|
||||
xe0_commandArray[i] = kMS_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] != kMS_Rumble) {
|
||||
xe0_commandArray[i] = kMS_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] != kMS_Stop) {
|
||||
xe0_commandArray[i] = kMS_Stop;
|
||||
updated = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (updated) {
|
||||
PADControlAllMotors(reinterpret_cast< const u32* >(xe0_commandArray));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CRumbleGenerator::HardStopAll() {
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
xc0_periodTime[i] = 0.f;
|
||||
xd0_onTime[i] = 0.f;
|
||||
xe0_commandArray[i] = kMS_Stop;
|
||||
x0_voices[i].HardReset();
|
||||
}
|
||||
|
||||
PADControlAllMotors(reinterpret_cast< const u32* >(kStopAll));
|
||||
}
|
||||
|
||||
void CRumbleGenerator::SetDisabled(const bool disabled) {
|
||||
if (disabled) {
|
||||
HardStopAll();
|
||||
}
|
||||
|
||||
xf0_24_disabled = disabled;
|
||||
}
|
||||
@@ -22,14 +22,13 @@ short CRumbleVoice::Activate(const SAdsrData& data, ushort idx, float gain, ERum
|
||||
}
|
||||
|
||||
void CRumbleVoice::Deactivate(short id, bool b1) {
|
||||
if (id == -1)
|
||||
return;
|
||||
if (OwnsSustained(id)) {
|
||||
return;
|
||||
} else if (x2c_usedChannels & (1 << (id & 0xf))) {
|
||||
x10_deltas[(id & 0xf)].x20_phase = SAdsrDelta::kP_Release;
|
||||
if (id == -1 || !OwnsSustained(id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (x2c_usedChannels & (1 << GetChannelId(id))) {
|
||||
x10_deltas[GetChannelId(id)].x20_phase = SAdsrDelta::kP_Release;
|
||||
}
|
||||
}
|
||||
|
||||
void CRumbleVoice::HardReset() {
|
||||
@@ -130,14 +129,15 @@ bool CRumbleVoice::Update(float dt) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint CRumbleVoice::GetFreeChannel() const {
|
||||
ushort CRumbleVoice::GetFreeChannel() const {
|
||||
for (ushort i = 0; i < 4; ++i) {
|
||||
if ((x2c_usedChannels & (1 << i)) == 0) {
|
||||
return i;
|
||||
return (ushort)i;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
float CRumbleVoice::GetIntensity() const {
|
||||
float ret = x10_deltas[0].x0_curIntensity;
|
||||
if (ret < x10_deltas[1].x0_curIntensity) {
|
||||
@@ -158,17 +158,20 @@ float CRumbleVoice::GetIntensity() const {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool CRumbleVoice::OwnsSustained(short handle) const {
|
||||
ushort idx = (((ushort)handle >> 8) & 0xff);
|
||||
if (idx < 4)
|
||||
return x20_handleIds[idx] == (idx & 0xf);
|
||||
return false;
|
||||
const ushort i = GetChannelId(handle);
|
||||
const uint owner = GetOwnerId(handle);
|
||||
return i < 4 ? x20_handleIds[i] == owner : false;
|
||||
}
|
||||
|
||||
/* TODO: Fake matched, find real solution */
|
||||
short CRumbleVoice::CreateRumbleHandle(ushort idx) {
|
||||
++x2e_lastId;
|
||||
if (x2e_lastId == 0)
|
||||
x2e_lastId = 1;
|
||||
x20_handleIds[idx] = x2e_lastId;
|
||||
return ((x2e_lastId << 8) | idx) & 0xFFFF;
|
||||
u16 x = idx;
|
||||
u16* h = &x20_handleIds[x];
|
||||
*h = x2e_lastId;
|
||||
return ((x2e_lastId << 8) | x) & 0xFFFF;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user