diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 4ef4740f..f08cfacf 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2367,6 +2367,7 @@ d/snd/d_snd_3d_engine.cpp: d/snd/d_snd_sound.cpp: .text start:0x8035C3F0 end:0x8035DA88 align:16 + .data start:0x80548730 end:0x80548758 .sdata2 start:0x8057D368 end:0x8057D380 d/snd/d_snd_player_mgr.cpp: diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 143697b6..948f6ada 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -208,7 +208,7 @@ fn_80008A00 = .text:0x80008A00; // type:function size:0x24 fn_80008A30 = .text:0x80008A30; // type:function size:0x1C0 fn_80008BF0 = .text:0x80008BF0; // type:function size:0xE4 fn_80008CE0 = .text:0x80008CE0; // type:function size:0x134 -getSoundArchivePlayer = .text:0x80008E20; // type:function size:0xC +getPlayer__9dSndMgr_cFv = .text:0x80008E20; // type:function size:0xC fn_80008E30 = .text:0x80008E30; // type:function size:0x58 fn_80008E90 = .text:0x80008E90; // type:function size:0x58 fn_80008EF0 = .text:0x80008EF0; // type:function size:0xA4 @@ -19882,42 +19882,42 @@ fn_8035C1C0 = .text:0x8035C1C0; // type:function size:0xDC fn_8035C2A0 = .text:0x8035C2A0; // type:function size:0x110 __dt__14dSnd3DEngine_cFv = .text:0x8035C3B0; // type:function size:0x40 __ct__11dSndSound_cFv = .text:0x8035C3F0; // type:function size:0x2F8 -__ct__32dSndControlSoundSeqTrackVolume_cFv = .text:0x8035C6F0; // type:function size:0x44 -__ct__33dSndControlSoundStrmTrackVolume_cFv = .text:0x8035C740; // type:function size:0x44 -__dt__32dSndControlSoundSeqTrackVolume_cFv = .text:0x8035C790; // type:function size:0x40 -__dt__33dSndControlSoundStrmTrackVolume_cFv = .text:0x8035C7D0; // type:function size:0x40 +__ct__32dSndControlSoundSeqTrackVolume_cFv = .text:0x8035C6F0; // type:function size:0x44 scope:weak +__ct__33dSndControlSoundStrmTrackVolume_cFv = .text:0x8035C740; // type:function size:0x44 scope:weak +__dt__32dSndControlSoundSeqTrackVolume_cFv = .text:0x8035C790; // type:function size:0x40 scope:weak +__dt__33dSndControlSoundStrmTrackVolume_cFv = .text:0x8035C7D0; // type:function size:0x40 scope:weak __dt__11dSndSound_cFv = .text:0x8035C810; // type:function size:0xA0 -fn_8035C8B0 = .text:0x8035C8B0; // type:function size:0x84 -reset__11dSndSound_cFv = .text:0x8035C940; // type:function size:0xE8 -fn_8035CA30 = .text:0x8035CA30; // type:function size:0xD8 -fadeIn__11dSndSound_cFUli = .text:0x8035CB10; // type:function size:0x6C -fn_8035CB80 = .text:0x8035CB80; // type:function size:0xD4 -fn_8035CC60 = .text:0x8035CC60; // type:function size:0xCC +cancel__11dSndSound_cFv = .text:0x8035C8B0; // type:function size:0x84 +resetControls__11dSndSound_cFv = .text:0x8035C940; // type:function size:0xE8 +executeCtrls__11dSndSound_cFv = .text:0x8035CA30; // type:function size:0xD8 +fadeIn__11dSndSound_cFUll = .text:0x8035CB10; // type:function size:0x6C +stop__11dSndSound_cFl = .text:0x8035CB80; // type:function size:0xD4 +pause__11dSndSound_cFbl = .text:0x8035CC60; // type:function size:0xCC isStrmSound__11dSndSound_cFv = .text:0x8035CD30; // type:function size:0x58 isWaveSound__11dSndSound_cFv = .text:0x8035CD90; // type:function size:0x58 isSeqSound__11dSndSound_cFv = .text:0x8035CDF0; // type:function size:0x58 -fn_8035CE50 = .text:0x8035CE50; // type:function size:0x28 -fn_8035CE80 = .text:0x8035CE80; // type:function size:0x28 +linkCtrl__11dSndSound_cFP18dSndControlSound_c = .text:0x8035CE50; // type:function size:0x28 +unlinkCtrl__11dSndSound_cFP18dSndControlSound_c = .text:0x8035CE80; // type:function size:0x28 readSeqTrackVariable__11dSndSound_cFi = .text:0x8035CEB0; // type:function size:0x84 writeSeqTrackVariable__11dSndSound_cFis = .text:0x8035CF40; // type:function size:0x78 -fn_8035CFC0 = .text:0x8035CFC0; // type:function size:0x90 -fn_8035D050 = .text:0x8035D050; // type:function size:0x1C +setControlValue__11dSndSound_cFP18dSndControlSound_cfl = .text:0x8035CFC0; // type:function size:0x90 +setVolume__11dSndSound_cFfl = .text:0x8035D050; // type:function size:0x1C setPitchRelated__11dSndSound_cFfl = .text:0x8035D070; // type:function size:0x1C -fn_8035D090 = .text:0x8035D090; // type:function size:0x1C +setLinearPitch__11dSndSound_cFfl = .text:0x8035D090; // type:function size:0x1C resetTrackVolumes__11dSndSound_cFv = .text:0x8035D0B0; // type:function size:0xE8 -fn_8035D1A0 = .text:0x8035D1A0; // type:function size:0x114 -fn_8035D2C0 = .text:0x8035D2C0; // type:function size:0xC0 -fn_8035D380 = .text:0x8035D380; // type:function size:0xA0 -fn_8035D420 = .text:0x8035D420; // type:function size:0xA0 -fn_8035D4C0 = .text:0x8035D4C0; // type:function size:0xB8 -fn_8035D580 = .text:0x8035D580; // type:function size:0xB8 -fn_8035D640 = .text:0x8035D640; // type:function size:0x24 -fn_8035D670 = .text:0x8035D670; // type:function size:0x60 +setTrackVolume__11dSndSound_cFUlfl = .text:0x8035D1A0; // type:function size:0x114 +setStrmTrackVolume__11dSndSound_cFUlfl = .text:0x8035D2C0; // type:function size:0xC0 +setSingleSeqTrackVolume__11dSndSound_cFUsfl = .text:0x8035D380; // type:function size:0xA0 +setSingleStrmTrackVolume__11dSndSound_cFUsfl = .text:0x8035D420; // type:function size:0xA0 +setEachSeqTrackVolume__11dSndSound_cFUlf = .text:0x8035D4C0; // type:function size:0xB8 +setEachStrmTrackVolume__11dSndSound_cFUlf = .text:0x8035D580; // type:function size:0xB8 +getCurrentStrmTrackVolume__11dSndSound_cCFUl = .text:0x8035D640; // type:function size:0x24 +setSeqTempoRatio__11dSndSound_cFfl = .text:0x8035D670; // type:function size:0x60 setSeqTrackMute__11dSndSound_cFUlQ34nw4r3snd7SeqMute = .text:0x8035D6D0; // type:function size:0x78 -fn_8035D750 = .text:0x8035D750; // type:function size:0x1E8 -fn_8035D940 = .text:0x8035D940; // type:function size:0x58 -fn_8035D9A0 = .text:0x8035D9A0; // type:function size:0x68 -stop__11dSndSound_cFv = .text:0x8035DA10; // type:function size:0x4C +prepareSound__11dSndSound_cFUlUl = .text:0x8035D750; // type:function size:0x1E8 +prepareSound__11dSndSound_cFPCcUl = .text:0x8035D940; // type:function size:0x58 +onPreparing__11dSndSound_cFUlUl = .text:0x8035D9A0; // type:function size:0x68 +forceStop__11dSndSound_cFv = .text:0x8035DA10; // type:function size:0x4C configure__13dSndControl_cFfff = .text:0x8035DA60; // type:function size:0x28 getSoundArchivePath__15dSndPlayerMgr_cFv = .text:0x8035DA90; // type:function size:0xC __dt__33SndMgrDisposer<15dSndPlayerMgr_c>Fv = .text:0x8035DAA0; // type:function size:0x78 @@ -20390,7 +20390,7 @@ apply__23dSndControlSoundPitch_cFP11dSndSound_c = .text:0x8036C230; // type:func __ct__29dSndControlSoundPitchLinear_cFv = .text:0x8036C250; // type:function size:0x48 set__29dSndControlSoundPitchLinear_cFfl = .text:0x8036C2A0; // type:function size:0x70 apply__29dSndControlSoundPitchLinear_cFP11dSndSound_c = .text:0x8036C310; // type:function size:0x3C -apply__36dSndControlSoundSeqTrackTempoRatio_cFP11dSndSound_c = .text:0x8036C350; // type:function size:0x4C +apply__31dSndControlSoundSeqTempoRatio_cFP11dSndSound_c = .text:0x8036C350; // type:function size:0x4C apply__32dSndControlSoundSeqTrackVolume_cFP11dSndSound_c = .text:0x8036C3A0; // type:function size:0x50 apply__33dSndControlSoundStrmTrackVolume_cFP11dSndSound_c = .text:0x8036C3F0; // type:function size:0x54 __ct__29dSndControlPlayerVolumeBase_cFv = .text:0x8036C450; // type:function size:0x48 @@ -37698,7 +37698,7 @@ lbl_80548B38 = .data:0x80548B38; // type:object size:0x10 lbl_80548B48 = .data:0x80548B48; // type:object size:0x30 __vt__33dSndControlSoundStrmTrackVolume_c = .data:0x80548B78; // type:object size:0x20 __vt__32dSndControlSoundSeqTrackVolume_c = .data:0x80548B98; // type:object size:0x20 -__vt__36dSndControlSoundSeqTrackTempoRatio_c = .data:0x80548BB8; // type:object size:0x20 +__vt__31dSndControlSoundSeqTempoRatio_c = .data:0x80548BB8; // type:object size:0x20 __vt__29dSndControlSoundPitchLinear_c = .data:0x80548BD8; // type:object size:0x20 __vt__23dSndControlSoundPitch_c = .data:0x80548BF8; // type:object size:0x20 __vt__24dSndControlSoundVolume_c = .data:0x80548C18; // type:object size:0x20 @@ -48372,11 +48372,11 @@ lbl_8057D358 = .sdata2:0x8057D358; // type:object size:0x4 align:4 data:float lbl_8057D35C = .sdata2:0x8057D35C; // type:object size:0x4 align:4 data:float lbl_8057D360 = .sdata2:0x8057D360; // type:object size:0x4 align:4 data:float lbl_8057D364 = .sdata2:0x8057D364; // type:object size:0x4 align:4 data:float -lbl_8057D368 = .sdata2:0x8057D368; // type:object size:0x4 align:4 data:float -lbl_8057D36C = .sdata2:0x8057D36C; // type:object size:0x4 align:4 data:float -lbl_8057D370 = .sdata2:0x8057D370; // type:object size:0x4 align:4 data:float -lbl_8057D374 = .sdata2:0x8057D374; // type:object size:0x4 align:4 data:float -lbl_8057D378 = .sdata2:0x8057D378; // type:object size:0x4 align:4 data:float +@7826 = .sdata2:0x8057D368; // type:object size:0x4 scope:local align:4 data:float +@7827 = .sdata2:0x8057D36C; // type:object size:0x4 scope:local align:4 data:float +@7828 = .sdata2:0x8057D370; // type:object size:0x4 scope:local align:4 data:float +@7829 = .sdata2:0x8057D374; // type:object size:0x4 scope:local align:4 data:float +@7830 = .sdata2:0x8057D378; // type:object size:0x4 scope:local align:4 data:float lbl_8057D380 = .sdata2:0x8057D380; // type:object size:0x4 align:4 data:float lbl_8057D384 = .sdata2:0x8057D384; // type:object size:0x4 align:4 data:float lbl_8057D388 = .sdata2:0x8057D388; // type:object size:0x4 align:4 data:float diff --git a/configure.py b/configure.py index ec055e44..7c231437 100644 --- a/configure.py +++ b/configure.py @@ -706,7 +706,7 @@ config.libs = [ Object(Matching, "d/snd/d_snd_actor.cpp"), Object(NonMatching, "d/snd/d_snd_3d_actor.cpp"), Object(NonMatching, "d/snd/d_snd_3d_engine.cpp"), - Object(NonMatching, "d/snd/d_snd_sound.cpp"), + Object(Matching, "d/snd/d_snd_sound.cpp"), Object(NonMatching, "d/snd/d_snd_player_mgr.cpp"), Object(NonMatching, "d/snd/mgr/d_snd_mgr_unk1.cpp"), Object(Matching, "d/snd/d_snd_3d_manager.cpp"), diff --git a/include/d/snd/d_snd_sound.h b/include/d/snd/d_snd_sound.h index 3f4f9fd9..da12e39e 100644 --- a/include/d/snd/d_snd_sound.h +++ b/include/d/snd/d_snd_sound.h @@ -4,6 +4,7 @@ #include "common.h" #include "nw4r/snd/snd_SeqTrack.h" #include "nw4r/snd/snd_SoundHandle.h" +#include "nw4r/snd/snd_SoundStartable.h" #include "nw4r/ut/ut_list.h" class dSndSound_c; @@ -42,6 +43,10 @@ public: return mCurrValue; } + bool isFinished() const { + return mTimer >= mDuration; + } + protected: /* 0x04 */ f32 mResetValue; /* 0x08 */ f32 mMax; @@ -90,9 +95,9 @@ private: /* 0x30 */ dSndControlSound_c *mpOtherControl; }; -class dSndControlSoundSeqTrackTempoRatio_c : public dSndControlSound_c { +class dSndControlSoundSeqTempoRatio_c : public dSndControlSound_c { public: - dSndControlSoundSeqTrackTempoRatio_c() : dSndControlSound_c(1.0f, 0.25f, 4.0f) {} + dSndControlSoundSeqTempoRatio_c() : dSndControlSound_c(1.0f, 0.25f, 4.0f) {} virtual void apply(dSndSound_c *pHandle) override; }; @@ -127,18 +132,36 @@ public: dSndSound_c(); ~dSndSound_c(); - virtual void vt_0x08(); // 0x08 - virtual void vt_0x0C(); // 0x0C - virtual void fadeIn(u32 id, int fadeFrames); // 0x10 + virtual void cancel(); // 0x08 + virtual void executeCtrls(); // 0x0C + virtual void fadeIn(u32 id, s32 fadeFrames); // 0x10 + virtual nw4r::snd::SoundStartable::StartResult prepareSound(u32 soundId, u32 startOffset); // 0x14 + virtual nw4r::snd::SoundStartable::StartResult prepareSound(const char *label, u32 startOffset); // 0x18 + virtual void onPreparing(u32 soundId, u32 startOffset); // 0x1C + virtual void stop(s32 fadeFrames); // 0x20 + virtual void pause(bool pauseFlag, s32 fadeFrames); // 0x24 bool isStrmSound(); bool isWaveSound(); bool isSeqSound(); - void setPitchRelated(f32 pitch, s32 frames); + f32 getCurrentStrmTrackVolume(u32 index) const; + void setVolume(f32 volume, s32 frames); + void setPitchRelated(f32 pitch, s32 frames); + void setLinearPitch(f32 pitch, s32 frames); + void setTrackVolume(u32 trackFlags, f32 volume, s32 frames); + void setStrmTrackVolume(u32 trackFlags, f32 volume, s32 frames); + void setSingleSeqTrackVolume(u16 index, f32 volume, s32 frames); + void setSingleStrmTrackVolume(u16 index, f32 volume, s32 frames); + + // why f32 frames? + void setEachSeqTrackVolume(u32 trackFlags, f32 frames); + void setEachStrmTrackVolume(u32 trackFlags, f32 frames); + + void setSeqTempoRatio(f32 ratio, s32 frames); void setSeqTrackMute(u32 trackFlags, nw4r::snd::SeqMute mute); - void stop(); + void forceStop(); s16 readSeqTrackVariable(int varNo); void writeSeqTrackVariable(int varNo, s16 value); @@ -147,22 +170,51 @@ public: void unlinkCtrl(dSndControlSound_c *); private: - void reset(); + bool cannotStart() const { + return mIsRunning && !mIsFadingOut && IsAttachedSound(); + } + + bool isRunning() const { + return mIsRunning && IsAttachedSound(); + } + + bool isPreparing() const { + return mIsPreparing && !mIsRunning; + } + + bool canCancel() const { + return mIsRunning || mIsPreparing || IsAttachedSound(); + } + + bool isPreparingSoundId(u32 soundId) const { + bool ret = mIsPreparing; + if (ret) { + ret = !mIsRunning; + } + if (ret) { + ret = GetId() == soundId; + } + return ret; + } + + void resetControls(); void resetTrackVolumes(); + void setControlValue(dSndControlSound_c *ctrl, f32 value, s32 frames); + /* 0x08 */ u8 _0x08[0x10 - 0x08]; - /* 0x10 */ UNKWORD field_0x10; - /* 0x14 */ u8 field_0x14; - /* 0x15 */ u8 field_0x15; - /* 0x16 */ u8 field_0x16; - /* 0x17 */ u8 field_0x17; + /* 0x10 */ u32 mPrevStartOffset; + /* 0x14 */ bool mIsPreparing; + /* 0x15 */ bool mPauseFlag; + /* 0x16 */ bool mIsRunning; + /* 0x17 */ bool mIsFadingOut; /* 0x18 */ dSndControlSoundVolume_c mCtrlVolume; /* 0x48 */ dSndControlSoundPitch_c mCtrlPitch; - /* 0x78 */ dSndControlSoundPitchLinear_c mCtrlUnk; + /* 0x78 */ dSndControlSoundPitchLinear_c mLinearPitch; /* 0xAC */ dSndControlSoundSeqTrackVolume_c *mpCtrlSeqTrackVolume; /* 0xB0 */ dSndControlSoundStrmTrackVolume_c *mpCtrlStrmTrackVolume; - /* 0xB4 */ dSndControlSoundSeqTrackTempoRatio_c mpCtrlSeqTrackTempoRatio; + /* 0xB4 */ dSndControlSoundSeqTempoRatio_c mpCtrlSeqTempoRatio; /* 0xE4 */ nw4r::ut::List mList; }; diff --git a/include/nw4r/snd/snd_SoundHandle.h b/include/nw4r/snd/snd_SoundHandle.h index e8d1a3c0..5c969c1c 100644 --- a/include/nw4r/snd/snd_SoundHandle.h +++ b/include/nw4r/snd/snd_SoundHandle.h @@ -50,9 +50,14 @@ namespace nw4r { namespace snd mSound->SetPitch(volume); } - void Stop() { + void Stop(int fadeFrames) { if (IsAttachedSound()) - mSound->Stop(0); + mSound->Stop(fadeFrames); + } + + void Pause(bool flag, int fadeFrames) { + if (IsAttachedSound()) + mSound->Pause(flag, fadeFrames); } bool IsPause() const { diff --git a/include/nw4r/snd/snd_SoundStartable.h b/include/nw4r/snd/snd_SoundStartable.h index c672c7f3..86d62ec6 100644 --- a/include/nw4r/snd/snd_SoundStartable.h +++ b/include/nw4r/snd/snd_SoundStartable.h @@ -54,6 +54,7 @@ namespace nw4r { namespace snd // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x27291 struct StartInfo { + StartInfo() : enableFlag(0) {} // enums public: enum EnableFlag @@ -76,6 +77,7 @@ namespace nw4r { namespace snd // [R89JEL]:/bin/RVL/Debug/mainD.elf:.debug::0x27208 struct SeqSoundInfo { + SeqSoundInfo() : seqDataAddress(NULL), startLocationLabel(NULL) {} void *seqDataAddress; // size 0x04, offset 0x00 char const *startLocationLabel; // size 0x04, offset 0x04 }; // size 0x08 diff --git a/include/toBeSorted/music_mgrs.h b/include/toBeSorted/music_mgrs.h index aad42969..4a38e498 100644 --- a/include/toBeSorted/music_mgrs.h +++ b/include/toBeSorted/music_mgrs.h @@ -5,6 +5,9 @@ #include "d/snd/d_snd_player_mgr.h" class dSndPlayerMgr_c; +class dSndSound_c; + +// A lot of these names are and were guesses that are probably wrong in a lot of ways. #define BGM_MGR (dSndPlayerMgr_c::GetInstance()) extern "C" void fn_8035E000(); @@ -24,7 +27,7 @@ extern "C" void fn_80365D20(void *); extern "C" void fn_803624F0(void *); extern "C" void fn_80364FD0(void *, s32); extern "C" bool fn_80364DA0(void *); -extern "C" void fn_80364D00(void*, s32); +extern "C" void fn_80364D00(void *, s32); extern "C" void *ENEMY_BGM_RELATED_MGR; extern "C" void fn_80384570(void *, bool); @@ -37,5 +40,8 @@ extern "C" bool fn_803720E0(void *, u32); extern "C" bool fn_80372070(void *, u32); extern "C" bool fn_803734C0(void *, u32); extern "C" bool fn_80373550(void *, u32); +extern "C" void fn_80372920(void *); +extern "C" void fn_803738B0(void *, dSndSound_c *sound); +extern "C" void fn_80373900(void *, dSndSound_c *sound); #endif diff --git a/src/d/snd/d_snd_control_sound.cpp b/src/d/snd/d_snd_control_sound.cpp index cdffeaf1..aaef106f 100644 --- a/src/d/snd/d_snd_control_sound.cpp +++ b/src/d/snd/d_snd_control_sound.cpp @@ -84,7 +84,7 @@ void dSndControlSoundPitchLinear_c::apply(dSndSound_c *pHandle) { pHandle->setPitchRelated(pitchScaleForPitchIdxTenths(mCurrValue), 0); } -void dSndControlSoundSeqTrackTempoRatio_c::apply(dSndSound_c *sound) { +void dSndControlSoundSeqTempoRatio_c::apply(dSndSound_c *sound) { nw4r::snd::SeqSoundHandle handle(sound); handle.SetTempoRatio(mCurrValue); } diff --git a/src/d/snd/d_snd_sound.cpp b/src/d/snd/d_snd_sound.cpp index 03d3b20d..aa441136 100644 --- a/src/d/snd/d_snd_sound.cpp +++ b/src/d/snd/d_snd_sound.cpp @@ -2,11 +2,15 @@ #include "common.h" #include "d/snd/d_snd_mgr.h" +#include "d/snd/d_snd_player_mgr.h" #include "nw4r/snd/snd_SeqSoundHandle.h" #include "nw4r/snd/snd_SoundArchive.h" +#include "nw4r/snd/snd_SoundStartable.h" #include "nw4r/ut/ut_list.h" +#include "toBeSorted/music_mgrs.h" -dSndSound_c::dSndSound_c() : field_0x10(0), field_0x14(0), field_0x15(0), field_0x16(0), field_0x17(0) { +dSndSound_c::dSndSound_c() + : mPrevStartOffset(0), mIsPreparing(false), mPauseFlag(false), mIsRunning(false), mIsFadingOut(false) { nw4r::ut::List_Init(&mList, 0x24); mpCtrlSeqTrackVolume = new dSndControlSoundSeqTrackVolume_c[16](); @@ -20,8 +24,8 @@ dSndSound_c::dSndSound_c() : field_0x10(0), field_0x14(0), field_0x15(0), field_ mpCtrlStrmTrackVolume[i].setMask(1 << i); } - mCtrlUnk.setControl(&mCtrlPitch); - reset(); + mLinearPitch.setControl(&mCtrlPitch); + resetControls(); } dSndSound_c::~dSndSound_c() { @@ -33,26 +37,82 @@ dSndSound_c::~dSndSound_c() { } } -void dSndSound_c::reset() { +void dSndSound_c::cancel() { + if (canCancel()) { + resetControls(); + mIsRunning = false; + mIsFadingOut = false; + mIsPreparing = false; + mPrevStartOffset = 0; + fn_80373900(FANFARE_SOUND_MGR, this); + } +} + +void dSndSound_c::resetControls() { mCtrlVolume.reset(); mCtrlVolume.apply(this); mCtrlPitch.reset(); mCtrlPitch.apply(this); - mCtrlUnk.reset(); - mCtrlUnk.apply(this); - mpCtrlSeqTrackTempoRatio.reset(); - mpCtrlSeqTrackTempoRatio.apply(this); - field_0x15 = 0; + mLinearPitch.reset(); + mLinearPitch.apply(this); + mpCtrlSeqTempoRatio.reset(); + mpCtrlSeqTempoRatio.apply(this); + mPauseFlag = 0; resetTrackVolumes(); } -void dSndSound_c::fadeIn(u32 id, int fadeFrames) { +void dSndSound_c::executeCtrls() { + if (mIsRunning && !IsAttachedSound()) { + cancel(); + } + + dSndControlSound_c *next; + dSndControlSound_c *iter = static_cast(nw4r::ut::List_GetNext(&mList, nullptr)); + while (iter != nullptr) { + next = static_cast(nw4r::ut::List_GetNext(&mList, iter)); + iter->calc(); + iter->apply(this); + if (iter->isFinished()) { + unlinkCtrl(iter); + } + iter = next; + } +} + +void dSndSound_c::fadeIn(u32 id, s32 fadeFrames) { if (id != -1) { if (fadeFrames != 0) { FadeIn(fadeFrames); } - vt_0x08(); - field_0x16 = 1; + cancel(); + mIsRunning = true; + } +} + +void dSndSound_c::stop(s32 fadeFrames) { + if (isRunning()) { + Stop(fadeFrames); + + if (fadeFrames != 0) { + mIsFadingOut = true; + } else { + cancel(); + } + } else { + if (!isPreparing()) { + cancel(); + } + } +} + +void dSndSound_c::pause(bool pauseFlag, s32 fadeFrames) { + if (!IsAttachedSound()) { + return; + } + + if ((pauseFlag && !IsPause()) || (!pauseFlag && IsPause())) { + Pause(pauseFlag, fadeFrames); + mPauseFlag = pauseFlag; } } @@ -77,6 +137,28 @@ bool dSndSound_c::isSeqSound() { return dSndMgr_c::GetInstance()->getArchive()->GetSoundType(GetId()) == nw4r::snd::SoundArchive::SOUND_TYPE_SEQ; } +void dSndSound_c::linkCtrl(dSndControlSound_c *ctrl) { + if (ctrl == nullptr) { + return; + } + if (ctrl->isLinked()) { + return; + } + ctrl->setLinked(true); + nw4r::ut::List_Append(&mList, ctrl); +} + +void dSndSound_c::unlinkCtrl(dSndControlSound_c *ctrl) { + if (ctrl == nullptr) { + return; + } + if (!ctrl->isLinked()) { + return; + } + ctrl->setLinked(false); + nw4r::ut::List_Remove(&mList, ctrl); +} + s16 dSndSound_c::readSeqTrackVariable(int varNo) { if (!isSeqSound()) { return -1; @@ -95,6 +177,36 @@ void dSndSound_c::writeSeqTrackVariable(int varNo, s16 value) { handle.WriteVariable(varNo, value); } +void dSndSound_c::setControlValue(dSndControlSound_c *ctrl, f32 value, s32 frames) { + ctrl->set(value, frames); + + if (ctrl->isFinished()) { + unlinkCtrl(ctrl); + } else { + linkCtrl(ctrl); + } + + ctrl->apply(this); +} + +void dSndSound_c::setVolume(f32 volume, s32 frames) { + if (IsAttachedSound()) { + setControlValue(&mCtrlVolume, volume, frames); + } +} + +void dSndSound_c::setPitchRelated(f32 pitch, s32 frames) { + if (IsAttachedSound()) { + setControlValue(&mCtrlPitch, pitch, frames); + } +} + +void dSndSound_c::setLinearPitch(f32 pitch, s32 frames) { + if (IsAttachedSound()) { + setControlValue(&mLinearPitch, pitch, frames); + } +} + void dSndSound_c::resetTrackVolumes() { if (mpCtrlSeqTrackVolume != nullptr) { for (int i = 0; i < 16; i++) { @@ -111,6 +223,99 @@ void dSndSound_c::resetTrackVolumes() { } } +void dSndSound_c::setTrackVolume(u32 trackFlags, f32 volume, s32 frames) { + if (trackFlags != 0 && IsAttachedSound()) { + switch (dSndMgr_c::GetInstance()->getArchive()->GetSoundType(GetId())) { + case nw4r::snd::SoundArchive::SOUND_TYPE_SEQ: { + for (int i = 0; i < 16; i++) { + if ((trackFlags & (u16)(1 << i)) != 0) { + setControlValue(&mpCtrlSeqTrackVolume[i], volume, frames); + } + } + break; + } + case nw4r::snd::SoundArchive::SOUND_TYPE_STRM: { + for (int i = 0; i < 3; i++) { + if ((trackFlags & (u16)(1 << i)) != 0) { + setControlValue(&mpCtrlStrmTrackVolume[i], volume, frames); + } + } + } + default: break; + } + } +} + +void dSndSound_c::setStrmTrackVolume(u32 trackFlags, f32 volume, s32 frames) { + if (trackFlags != 0 && IsAttachedSound()) { + switch (dSndMgr_c::GetInstance()->getArchive()->GetSoundType(GetId())) { + case nw4r::snd::SoundArchive::SOUND_TYPE_STRM: { + for (int i = 0; i < 3; i++) { + if ((trackFlags & (u16)(1 << i)) != 0) { + setControlValue(&mpCtrlStrmTrackVolume[i], volume, frames); + } + } + } + default: break; + } + } +} + +void dSndSound_c::setSingleSeqTrackVolume(u16 index, f32 volume, s32 frames) { + if (IsAttachedSound() && index < 16) { + switch (dSndMgr_c::GetInstance()->getArchive()->GetSoundType(GetId())) { + case nw4r::snd::SoundArchive::SOUND_TYPE_SEQ: { + setControlValue(&mpCtrlSeqTrackVolume[index], volume, frames); + } + default: break; + } + } +} + +void dSndSound_c::setSingleStrmTrackVolume(u16 index, f32 volume, s32 frames) { + if (IsAttachedSound() && index < 3) { + switch (dSndMgr_c::GetInstance()->getArchive()->GetSoundType(GetId())) { + case nw4r::snd::SoundArchive::SOUND_TYPE_STRM: { + setControlValue(&mpCtrlStrmTrackVolume[index], volume, frames); + } + default: break; + } + } +} + +void dSndSound_c::setEachSeqTrackVolume(u32 trackFlags, f32 frames) { + for (int i = 0; i < 16; i++) { + if ((trackFlags & (u16)(1 << i)) != 0) { + setSingleSeqTrackVolume(i, 1.0f, (u32)frames); + } else { + setSingleSeqTrackVolume(i, 0.0f, (u32)frames); + } + } +} + +void dSndSound_c::setEachStrmTrackVolume(u32 trackFlags, f32 frames) { + for (int i = 0; i < 3; i++) { + if ((trackFlags & (u16)(1 << i)) != 0) { + setSingleStrmTrackVolume(i, 1.0f, (u32)frames); + } else { + setSingleStrmTrackVolume(i, 0.0f, (u32)frames); + } + } +} + +f32 dSndSound_c::getCurrentStrmTrackVolume(u32 index) const { + if (index >= 3) { + return 0.0f; + } + return mpCtrlStrmTrackVolume[index].getCurrentValue(); +} + +void dSndSound_c::setSeqTempoRatio(f32 ratio, s32 frames) { + if (isSeqSound()) { + setControlValue(&mpCtrlSeqTempoRatio, ratio, frames); + } +} + void dSndSound_c::setSeqTrackMute(u32 trackFlags, nw4r::snd::SeqMute mute) { if (isSeqSound()) { nw4r::snd::SeqSoundHandle handle(this); @@ -118,9 +323,65 @@ void dSndSound_c::setSeqTrackMute(u32 trackFlags, nw4r::snd::SeqMute mute) { } } -void dSndSound_c::stop() { - vt_0x08(); - Stop(); +nw4r::snd::SoundStartable::StartResult dSndSound_c::prepareSound(u32 soundId, u32 startOffset) { + if (soundId == -1) { + return nw4r::snd::SoundStartable::START_ERR_USER; + } + + if (cannotStart()) { + return nw4r::snd::SoundStartable::START_ERR_USER; + } + + if (isPreparingSoundId(soundId)) { + if (mPrevStartOffset == startOffset) { + return nw4r::snd::SoundStartable::START_ERR_USER; + } + forceStop(); + } else { + if (isPreparing()) { + forceStop(); + } else { + fn_80372920(FANFARE_SOUND_MGR); + } + } + + nw4r::snd::SoundStartable::StartResult res; + if (startOffset == 0) { + res = dSndMgr_c::GetInstance()->getPlayer()->detail_PrepareSound(this, soundId, nullptr); + } else { + nw4r::snd::SoundStartable::StartInfo info; + info.enableFlag |= nw4r::snd::SoundStartable::StartInfo::ENABLE_START_OFFSET; + info.startOffsetType = nw4r::snd::SoundStartable::StartInfo::START_OFFSET_TYPE_MILLISEC; + info.startOffset = startOffset; + res = dSndMgr_c::GetInstance()->getPlayer()->detail_PrepareSound(this, soundId, &info); + } + + if (res == nw4r::snd::SoundStartable::START_SUCCESS) { + onPreparing(soundId, startOffset); + } else { + cancel(); + } + + return res; +} + +nw4r::snd::SoundStartable::StartResult dSndSound_c::prepareSound(const char *label, u32 startOffset) { + u32 id = dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(label); + return prepareSound(id, startOffset); +} + +void dSndSound_c::onPreparing(u32 soundId, u32 startOffset) { + if (soundId != -1) { + cancel(); + mPrevStartOffset = startOffset; + mIsPreparing = true; + fn_803738B0(FANFARE_SOUND_MGR, this); + } +} + +void dSndSound_c::forceStop() { + cancel(); + Stop(0); } // Might be a separate file diff --git a/src/nw4r/snd/snd_AnimSound.cpp b/src/nw4r/snd/snd_AnimSound.cpp index 0ba0b144..91f80368 100644 --- a/src/nw4r/snd/snd_AnimSound.cpp +++ b/src/nw4r/snd/snd_AnimSound.cpp @@ -48,7 +48,7 @@ void AnimSoundImpl::Shutdown() { if (mIsActive) { for (int i = 0; i < mNumSounds; i++) { if (mpSounds[i].GetHandle()->IsAttachedSound() && mpSounds[i].IsRunning()) { - mpSounds[i].GetHandle()->Stop(); + mpSounds[i].GetHandle()->Stop(0); } } @@ -437,7 +437,7 @@ AnimEventPlayer::AnimEventPlayer() : mpEvent(NULL), mIsRunning(false) {} AnimEventPlayer::~AnimEventPlayer() { if (mHandle.IsAttachedSound() && IsRunning()) { - mHandle.Stop(); + mHandle.Stop(0); } }