d_snd_anim_sound OK

This commit is contained in:
robojumper
2025-06-15 21:22:07 +02:00
parent 6cb7f3bfdc
commit f6e5303ea2
12 changed files with 449 additions and 100 deletions
+73
View File
@@ -0,0 +1,73 @@
#include "d/snd/d_snd_anim_sound.h"
#include "common.h"
#include "d/snd/d_snd_source.h"
#include <cmath>
dSndAnimSound_c::dSndAnimSound_c(dSoundSource_c *source)
: mSound(*source), mpData(nullptr), field_0x94(1.0f), field_0x98(INFINITY), mNeedFrameReset(false) {}
void dSndAnimSound_c::setData(const void *data) {
mDirection = nw4r::snd::AnimSound::FORWARD;
field_0x94 = 1.0f;
if (data == mpData) {
return;
}
mpData = data;
if (mpData != nullptr) {
mNeedFrameReset = true;
mSound.Setup(data);
} else {
mSound.Shutdown();
}
}
void dSndAnimSound_c::setFrame(f32 frame) {
if (mpData == nullptr) {
mSound.Shutdown();
return;
}
if (frame >= mSound.GetAnimDuration()) {
return;
}
if (mNeedFrameReset) {
if (frame <= field_0x98) {
mSound.ResetFrame(0.0f, 0);
} else {
mSound.ResetFrame(frame, 0);
}
mNeedFrameReset = false;
}
mSound.UpdateFrame(frame, mDirection);
}
void dSndAnimSound_c::setRate(f32 rate) {
if (rate < 0.0f) {
mDirection = nw4r::snd::AnimSound::BACKWARD;
} else {
mDirection = nw4r::snd::AnimSound::FORWARD;
}
field_0x94 = rate;
}
void dSndAnimSound_c::resetFrame(f32 frame) {
if (mpData == nullptr || mSound.GetAnimDuration() <= frame) {
return;
}
mNeedFrameReset = false;
mSound.ResetFrame(frame, 0);
}
void dSndAnimSound_c::animCallback(int, s32, const char *, UNKWORD arg, void *userData) {
reinterpret_cast<dSoundSource_c *>(userData)->onAnimSoundEvent(arg);
}
void dSndAnimSound_c::setCallback(dSoundSource_c *source) {
mSound.SetCallback(&animCallback, source);
}
void dSndAnimSound_c::setCallback(nw4r::snd::AnimSound::Callback cb, void *userData) {
mSound.SetCallback(cb, userData);
}
+164
View File
@@ -2,6 +2,7 @@
#include "common.h"
#include "d/snd/d_snd_bgm_mgr.h"
#include "d/snd/d_snd_calc_pitch.h"
#include "d/snd/d_snd_checkers.h"
#include "d/snd/d_snd_control_player_mgr.h"
#include "d/snd/d_snd_distant_sound_actor_pool.h"
@@ -9,6 +10,9 @@
#include "d/snd/d_snd_player_mgr.h"
#include "d/snd/d_snd_source.h"
#include "d/snd/d_snd_source_enums.h"
#include "d/snd/d_snd_source_mgr.h"
#include "d/snd/d_snd_stage_data.h"
#include "d/snd/d_snd_state_mgr.h"
#include "d/snd/d_snd_util.h"
#include "d/snd/d_snd_wzsound.h"
#include "egg/audio/eggAudioRmtSpeakerMgr.h"
@@ -29,6 +33,10 @@ dSndSmallEffectMgr_c::dSndSmallEffectMgr_c()
}
}
void dSndSmallEffectMgr_c::initialize() {
resetButtonPressSound();
}
void dSndSmallEffectMgr_c::calc() {
if (!dSndPlayerMgr_c::GetInstance()->checkFlag(0x4)) {
for (int i = 0; i < NUM_DELAYED_SOUNDS; i++) {
@@ -43,6 +51,72 @@ void dSndSmallEffectMgr_c::calc() {
}
}
void dSndSmallEffectMgr_c::calcTimer() {
if (field_0x10 <= 0) {
return;
}
field_0x10--;
}
void dSndSmallEffectMgr_c::stopAllSound(s32 fadeFrames) {
field_0x10 = fadeFrames;
for (s32 i = dSndPlayerMgr_c::PLAYER_SMALL_IMPORTANT; i <= dSndControlPlayerMgr_c::sPlayerMax; i++) {
dSndControlPlayerMgr_c::GetInstance()->getPlayer1(i)->StopAllSound(fadeFrames);
}
dSndSourceMgr_c::GetInstance()->stopAllSound();
}
void dSndSmallEffectMgr_c::stopAllSoundDemoRelated(s32 fadeFrames) {
field_0x10 = fadeFrames;
if (dSndStateMgr_c::GetInstance()->isInDemo()) {
for (s32 i = dSndPlayerMgr_c::PLAYER_SMALL_NORMAL; i <= dSndControlPlayerMgr_c::sPlayerMax; i++) {
dSndControlPlayerMgr_c::GetInstance()->getPlayer1(i)->StopAllSound(fadeFrames);
}
dSndSourceMgr_c::GetInstance()->stopAllSound();
} else {
dSndControlPlayerMgr_c::GetInstance()
->getPlayer1(dSndPlayerMgr_c::PLAYER_SMALL_NORMAL)
->StopAllSound(fadeFrames);
for (s32 i = dSndPlayerMgr_c::PLAYER_LINK_EQUIPMENT; i <= dSndControlPlayerMgr_c::sPlayerMax; i++) {
if ((u32)i != dSndPlayerMgr_c::PLAYER_AREA) {
dSndControlPlayerMgr_c::GetInstance()->getPlayer1(i)->StopAllSound(fadeFrames);
}
}
dSndSourceMgr_c::GetInstance()->stopAllNonPlayerSound();
}
}
void dSndSmallEffectMgr_c::stopAllSoundExceptEvent(s32 fadeFrames) {
field_0x10 = fadeFrames;
for (u32 i = dSndPlayerMgr_c::PLAYER_SMALL_NORMAL; (s32)i <= dSndControlPlayerMgr_c::sPlayerMax; i++) {
if (i == dSndPlayerMgr_c::PLAYER_LINK_VOICE) {
dSndControlPlayerMgr_c::GetInstance()->getPlayer1(i)->StopAllSound(20);
} else if (i != dSndPlayerMgr_c::PLAYER_EVENT) {
dSndControlPlayerMgr_c::GetInstance()->getPlayer1(i)->StopAllSound(fadeFrames);
}
}
dSndSourceMgr_c::GetInstance()->stopAllSound();
}
void dSndSmallEffectMgr_c::stopAllSoundExceptEffectOrLink(s32 fadeFrames) {
field_0x10 = fadeFrames;
for (s32 i = dSndPlayerMgr_c::PLAYER_LINK_EQUIPMENT; i <= dSndControlPlayerMgr_c::sPlayerMax; i++) {
dSndControlPlayerMgr_c::GetInstance()->getPlayer1(i)->StopAllSound(field_0x10);
}
dSndSourceMgr_c::GetInstance()->stopAllNonPlayerSound();
}
bool dSndSmallEffectMgr_c::playSoundInternalChecked(u32 soundId, nw4r::snd::SoundHandle *pHandle) {
// TODO
return false;
}
bool dSndSmallEffectMgr_c::playSoundInternal(u32 soundId, nw4r::snd::SoundHandle *pHandle) {
// TODO
return false;
}
bool dSndSmallEffectMgr_c::playSound(u32 soundId) {
if (soundId >= SE_S_BUTTON_CALL_L && soundId <= SE_S_PLAY_GUIDE_BUTTON_BLINK) {
soundId = SE_S_BUTTON_CALL_L;
@@ -153,6 +227,11 @@ bool dSndSmallEffectMgr_c::playSoundWithPan(u32 soundId, f32 pan) {
return ok;
}
bool dSndSmallEffectMgr_c::playSoundInternal(u32 soundId) {
// TODO
return false;
}
nw4r::snd::SoundHandle *dSndSmallEffectMgr_c::getHoldSoundHandle(u32 soundId) {
// Find an existing handle holding this sound
for (int i = 0; i < NUM_HOLD_SOUNDS; i++) {
@@ -309,6 +388,91 @@ bool dSndSmallEffectMgr_c::holdDowsingNearestSound() {
return holdSound(SE_S_DOWSING_SOUND_NEAREST, &mDowsingSoundHandle);
}
bool dSndSmallEffectMgr_c::playSirenCountdownSound(s32 timer) {
bool ok = playSoundInternal(SE_S_SIREN_COUNT_DOWN);
if (ok) {
f32 pitch = 1.0f - (timer * 0.01f);
mNormalSound.SetPitch(pitch);
}
return ok;
}
bool dSndSmallEffectMgr_c::playMinigameCountdownSound() {
return playSoundInternal(SE_S_MG_COUNT_DOWN_1);
}
bool dSndSmallEffectMgr_c::playMinigameTimeUpSound(s32 timer) {
return playSoundInternal(timer <= 3 ? SE_S_MG_TIMEUP_COUNT_02 : SE_S_MG_TIMEUP_COUNT_01);
}
bool dSndSmallEffectMgr_c::playMinigameStartSound() {
return playSoundInternal(SE_S_MG_START);
}
bool dSndSmallEffectMgr_c::playMinigameFinishSound() {
dSndBgmMgr_c::GetInstance()->stopAllBgm(10);
return playSoundInternal(SE_S_MG_FINISH);
}
bool dSndSmallEffectMgr_c::playMinigameFinishWhistleSound() {
dSndBgmMgr_c::GetInstance()->stopAllBgm(10);
return playSoundInternal(SE_S_MG_FINISH_WHISTLE);
}
bool dSndSmallEffectMgr_c::playMinigameScoreUpSound(s32 param) {
u32 soundId = SE_S_MG_SCORE_UP;
bool ok;
switch (dSndStateMgr_c::GetInstance()->getStageId_0x044()) {
case SND_STAGE_F019r:
// Bamboo Island
ok = playSoundInternal(SE_S_MG_TAKE_SCORE_UP);
if (ok) {
f32 pitch = pitchScaleForPitchIdx(param);
mNormalSound.SetPitch(pitch);
}
return ok;
case SND_STAGE_F020:
// Sky Field
soundId = dSndMgr_c::GetInstance()->getArchive() != nullptr ? (param >> 1) + SE_S_MG_TAKE_SCORE_UP :
SE_S_MG_DIVING_SCORE_01;
break;
case SND_STAGE_F211:
// Thrill Digger
soundId = SE_S_BE_GET_RUPEE;
break;
case SND_STAGE_F000:
// Skyloft (Pumpkin Archery)
if (param >= 50) {
soundId = SE_S_MG_PUMP_SHOT_SCORE_UP_50;
} else if (param >= 40) {
soundId = SE_S_MG_PUMP_SHOT_SCORE_UP_40;
} else if (param >= 30) {
soundId = SE_S_MG_PUMP_SHOT_SCORE_UP_30;
} else if (param >= 20) {
soundId = SE_S_MG_PUMP_SHOT_SCORE_UP_20;
} else {
soundId = SE_S_MG_PUMP_SHOT_SCORE_UP_10;
}
break;
}
return playSoundInternal(soundId);
}
bool dSndSmallEffectMgr_c::playMinigameScoreDownSound() {
return playSoundInternal(SE_S_MG_SCORE_DOWN);
}
bool dSndSmallEffectMgr_c::playMinigameMusasabiSound(s32 count) {
if (count < 0) {
count = 0;
} else if (count > 10) {
count = 10;
}
return playSoundInternal(
dSndMgr_c::GetInstance()->getArchive() != nullptr ? count + SE_S_MG_MUSASABI_01 : SE_S_MG_MUSASABI_01
);
}
bool dSndSmallEffectMgr_c::playSkbSound(u32 soundId) {
switch (soundId) {
case SE_S_SK_POINT:
+56 -56
View File
@@ -19,11 +19,11 @@ AnimSoundImpl::AnimSoundImpl(SoundStartable &startable, AnimEventPlayer *player,
: mStartable(startable),
mpSounds(player),
mNumSounds(numSounds),
field_0x0C(0.0f),
mCurrentFrame(0.0f),
mIsActive(false),
field_0x19(0),
field_0x1A(0),
field_0x1C(0),
mNeedFrameReset(false),
mNeedTriggerEventsAtCurrentFrame(false),
mCycleCounter(0),
mCallback(NULL),
field_0x28(1.0f) {}
@@ -37,10 +37,10 @@ bool AnimSoundImpl::Setup(const void *data) {
return false;
}
field_0x19 = 1;
mNeedFrameReset = true;
mIsActive = true;
field_0x0C = 0.0f;
field_0x1C = 0;
mCurrentFrame = 0.0f;
mCycleCounter = 0;
return true;
}
@@ -58,10 +58,10 @@ void AnimSoundImpl::Shutdown() {
}
void AnimSoundImpl::ResetFrame(f32 f, int i) {
field_0x0C = f;
field_0x1C = i;
field_0x1A = 1;
field_0x19 = 0;
mCurrentFrame = f;
mCycleCounter = i;
mNeedTriggerEventsAtCurrentFrame = true;
mNeedFrameReset = false;
}
void AnimSoundImpl::UpdateFrame(f32 frame, PlayDirection dir) {
@@ -69,48 +69,48 @@ void AnimSoundImpl::UpdateFrame(f32 frame, PlayDirection dir) {
mpSounds[i].UpdateFrame();
}
if (field_0x19) {
if (mNeedFrameReset) {
if (dir == FORWARD) {
ResetFrame(0.0f, 0);
} else {
u32 duration = mReader.GetAnimDuration();
ResetFrame(duration - 1.0f, 0);
}
field_0x19 = false;
mNeedFrameReset = false;
}
mVariableValue = (frame - field_0x0C) / field_0x28;
mVariableValue = (frame - mCurrentFrame) / field_0x28;
if (dir == FORWARD) {
UpdateForward(frame);
} else {
UpdateBackward(frame);
}
field_0x0C = frame;
field_0x1A = false;
mCurrentFrame = frame;
mNeedTriggerEventsAtCurrentFrame = false;
}
void AnimSoundImpl::UpdateForward(f32 frame) {
s32 duration = std::floorf(field_0x0C);
s32 iFrame = std::floorf(frame);
s32 currFrameFloor = std::floorf(mCurrentFrame);
s32 targetFrame = std::floorf(frame);
if (field_0x1A && field_0x0C == duration) {
duration -= 1;
if (mNeedTriggerEventsAtCurrentFrame && mCurrentFrame == currFrameFloor) {
currFrameFloor -= 1;
}
if (duration == iFrame) {
if (currFrameFloor == targetFrame) {
return;
}
s32 loopFrame = duration + 1;
s32 loopFrame = currFrameFloor + 1;
while (true) {
if (loopFrame == mReader.GetAnimDuration()) {
loopFrame -= mReader.GetAnimDuration();
field_0x1C++;
mCycleCounter++;
}
UpdateOneFrame(loopFrame, FORWARD);
if (loopFrame == iFrame) {
if (loopFrame == targetFrame) {
break;
}
loopFrame++;
@@ -118,35 +118,35 @@ void AnimSoundImpl::UpdateForward(f32 frame) {
}
void AnimSoundImpl::UpdateBackward(f32 frame) {
s32 duration = std::ceilf(field_0x0C);
s32 iFrame = std::ceilf(frame);
s32 currFrameCeil = std::ceilf(mCurrentFrame);
s32 targetFrame = std::ceilf(frame);
if (duration >= mReader.GetAnimDuration()) {
duration -= mReader.GetAnimDuration();
if (currFrameCeil >= mReader.GetAnimDuration()) {
currFrameCeil -= mReader.GetAnimDuration();
}
if (iFrame >= mReader.GetAnimDuration()) {
iFrame -= mReader.GetAnimDuration();
if (targetFrame >= mReader.GetAnimDuration()) {
targetFrame -= mReader.GetAnimDuration();
}
if (field_0x1A && field_0x0C == duration) {
duration += 1;
if (mNeedTriggerEventsAtCurrentFrame && mCurrentFrame == currFrameCeil) {
currFrameCeil += 1;
}
if (duration == iFrame) {
if (currFrameCeil == targetFrame) {
return;
}
s32 loopFrame = duration - 1;
s32 loopFrame = currFrameCeil - 1;
while (true) {
if (loopFrame == -1) {
loopFrame += mReader.GetAnimDuration();
field_0x1C--;
mCycleCounter--;
}
UpdateOneFrame(loopFrame, BACKWARD);
if (loopFrame == iFrame) {
if (loopFrame == targetFrame) {
break;
}
loopFrame--;
@@ -191,7 +191,7 @@ void AnimSoundImpl::UpdateTrigger(const AnimEventRef *ref, s32 frame, PlayDirect
if (ref->mInfo.field_0x00 == frame) {
StopEvent(event);
if (mCallback != NULL) {
(mCallback)(0, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(0, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
StartEvent(event, true);
}
@@ -199,7 +199,7 @@ void AnimSoundImpl::UpdateTrigger(const AnimEventRef *ref, s32 frame, PlayDirect
if (ref->mInfo.field_0x00 == frame) {
StopEvent(event);
if (mCallback != NULL) {
(mCallback)(0, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(0, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
StartEvent(event, true);
}
@@ -213,7 +213,7 @@ void AnimSoundImpl::UpdateTrigger(const AnimEventRef *ref, s32 frame, PlayDirect
if (u == frame) {
if (mCallback != NULL) {
(mCallback)(1, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(1, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
StopEvent(event);
}
@@ -233,11 +233,11 @@ void AnimSoundImpl::UpdateForwardRange(const AnimEventRef *ref, s32 frame) {
if (ref->mInfo.flags & 4) {
if (ref->mInfo.field_0x04 == frame && mCallback != NULL) {
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
if (field_0x1C < ref->mInfo.field_0x09) {
if (mCycleCounter < ref->mInfo.field_0x09) {
HoldEvent(event, true);
} else if (field_0x1C == ref->mInfo.field_0x09) {
} else if (mCycleCounter == ref->mInfo.field_0x09) {
if (frame < ref->mInfo.field_0x04) {
HoldEvent(event, true);
} else {
@@ -246,19 +246,19 @@ void AnimSoundImpl::UpdateForwardRange(const AnimEventRef *ref, s32 frame) {
}
} else if ((ref->mInfo.flags & 2)) {
if (ref->mInfo.field_0x00 == frame && mCallback != NULL) {
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
if (field_0x1C > ref->mInfo.field_0x09) {
if (mCycleCounter > ref->mInfo.field_0x09) {
HoldEvent(event, true);
} else if (field_0x1C == ref->mInfo.field_0x09 && ref->mInfo.field_0x00 <= frame) {
} else if (mCycleCounter == ref->mInfo.field_0x09 && ref->mInfo.field_0x00 <= frame) {
HoldEvent(event, true);
}
} else {
if (ref->mInfo.field_0x00 == frame && mCallback != NULL) {
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
if (ref->mInfo.field_0x04 == frame && mCallback != NULL) {
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
if (ref->mInfo.field_0x00 <= frame && frame < ref->mInfo.field_0x04) {
HoldEvent(event, true);
@@ -281,20 +281,20 @@ void AnimSoundImpl::UpdateBackwardRange(const AnimEventRef *ref, s32 frame) {
if (ref->mInfo.flags & 4) {
if (ref->mInfo.field_0x04 == frame && mCallback != NULL) {
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
if (field_0x1C < ref->mInfo.field_0x09) {
if (mCycleCounter < ref->mInfo.field_0x09) {
HoldEvent(event, true);
} else if (field_0x1C == ref->mInfo.field_0x09 && frame <= ref->mInfo.field_0x04) {
} else if (mCycleCounter == ref->mInfo.field_0x09 && frame <= ref->mInfo.field_0x04) {
HoldEvent(event, true);
}
} else if ((ref->mInfo.flags & 2)) {
if (ref->mInfo.field_0x00 == frame && mCallback != NULL) {
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
if (field_0x1C > ref->mInfo.field_0x09) {
if (mCycleCounter > ref->mInfo.field_0x09) {
HoldEvent(event, true);
} else if (field_0x1C == ref->mInfo.field_0x09) {
} else if (mCycleCounter == ref->mInfo.field_0x09) {
if (ref->mInfo.field_0x00 < frame) {
HoldEvent(event, true);
} else {
@@ -303,10 +303,10 @@ void AnimSoundImpl::UpdateBackwardRange(const AnimEventRef *ref, s32 frame) {
}
} else {
if (ref->mInfo.field_0x00 == frame && mCallback != NULL) {
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(3, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
if (ref->mInfo.field_0x04 == frame && mCallback != NULL) {
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, field_0x24);
(mCallback)(2, frame, event->GetSoundLabel(), event->field_0x1C, mUserData);
}
if (ref->mInfo.field_0x00 < frame && frame <= ref->mInfo.field_0x04) {
HoldEvent(event, true);
@@ -388,7 +388,7 @@ bool AnimSoundImpl::IsPlayableLoopCount(const nw4r::snd::detail::AnimEventFrameI
return true;
}
int i1 = ut::Max((int)ref.field_0x09, 0);
int i2 = ut::Abs(field_0x1C);
int i2 = ut::Abs(mCycleCounter);
if (ref.field_0x0A == 0) {
if (i2 < i1) {
return false;