From b9ed6c26bda715f2bae11ce6c6e05165072728f8 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sat, 14 Jun 2025 20:56:25 +0200 Subject: [PATCH] d_snd_distant_sound_actor OK --- config/SOUE01/symbols.txt | 36 +++++----- configure.py | 2 +- include/d/snd/d_snd_3d_actor.h | 5 ++ include/d/snd/d_snd_distant_sound_actor.h | 3 + .../d/snd/d_snd_distant_sound_actor_pool.h | 6 +- include/d/snd/d_snd_misc.h | 4 ++ include/d/snd/d_snd_source.h | 52 +++++++++----- include/d/snd/d_snd_source_if.h | 21 +++--- include/nw4r/snd/snd_SoundActor.h | 8 +++ src/d/a/obj/d_a_obj_boomerang.cpp | 2 +- src/d/snd/d_snd_distant_sound_actor.cpp | 13 ++++ src/d/snd/d_snd_distant_sound_actor_pool.cpp | 25 +++++++ src/d/snd/d_snd_source.cpp | 67 ++++++++++++++++++- src/d/snd/d_snd_source_group.cpp | 4 +- src/d/snd/d_snd_source_mgr.cpp | 6 +- 15 files changed, 197 insertions(+), 57 deletions(-) diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index c403e932..326011ed 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -20877,7 +20877,7 @@ resetButtonPressSound__20dSndSmallEffectMgr_cFv = .text:0x8037F0E0; // type:func setButtonPressSound__20dSndSmallEffectMgr_cFP14dSoundSource_c = .text:0x8037F0F0; // type:function size:0x60 fn_8037F150 = .text:0x8037F150; // type:function size:0x6D0 getName__14dSoundSource_cCFv = .text:0x8037F820; // type:function size:0x8 -vt_0x18__14dSoundSource_cFv = .text:0x8037F830; // type:function size:0x8 +getSourceType__14dSoundSource_cCFv = .text:0x8037F830; // type:function size:0x8 fn_8037F840 = .text:0x8037F840; // type:function size:0x74 fn_8037F8C0 = .text:0x8037F8C0; // type:function size:0x78 fn_8037F940 = .text:0x8037F940; // type:function size:0x48 @@ -21034,15 +21034,15 @@ vt_0xE4__14dSoundSource_cFv = .text:0x80385B00; // type:function size:0x4 vt_0xDC__14dSoundSource_cFv = .text:0x80385B10; // type:function size:0x8 vt_0xD4__14dSoundSource_cFv = .text:0x80385B20; // type:function size:0x8 vt_0x54__14dSoundSource_cFv = .text:0x80385B30; // type:function size:0x8 -vt_0x40__14dSoundSource_cFv = .text:0x80385B40; // type:function size:0x8 +stopAllSound__14dSoundSource_cFl = .text:0x80385B40; // type:function size:0x8 vt_0x34__14dSoundSource_cFv = .text:0x80385B50; // type:function size:0x10 vt_0x30__14dSoundSource_cFv = .text:0x80385B60; // type:function size:0x10 vt_0xF8__14dSoundSource_cFv = .text:0x80385B70; // type:function size:0x8 d_s_vt_0x188__14dSoundSource_cFv = .text:0x80385B80; // type:function size:0x4 vt_0x20__14dSoundSource_cFv = .text:0x80385B90; // type:function size:0x4 vt_0x24__14dSoundSource_cFv = .text:0x80385BA0; // type:function size:0x8 -vt_0x1C__14dSoundSource_cFv = .text:0x80385BB0; // type:function size:0x14 -vt_0x14__14dSoundSource_cFv = .text:0x80385BD0; // type:function size:0x14 +isSourceType__14dSoundSource_cCFl = .text:0x80385BB0; // type:function size:0x14 +isCategory__14dSoundSource_cCFl = .text:0x80385BD0; // type:function size:0x14 fn_80385BF0 = .text:0x80385BF0; // type:function size:0xC fn_80385C00 = .text:0x80385C00; // type:function size:0xC fn_80385C10 = .text:0x80385C10; // type:function size:0xC @@ -21142,12 +21142,12 @@ d_s_vt_0x18C__14dSoundSource_cFv = .text:0x80388F20; // type:function size:0x4 hasPlayingSounds__14dSoundSource_cCFv = .text:0x80388F30; // type:function size:0x8 isPlayingSound__14dSoundSource_cFUl = .text:0x80388F40; // type:function size:0x8 isPlayingSound__14dSoundSource_cFPCc = .text:0x80388F50; // type:function size:0x48 -fn_80388FA0 = .text:0x80388FA0; // type:function size:0x14 -fn_80388FC0 = .text:0x80388FC0; // type:function size:0x84 -fn_80389050 = .text:0x80389050; // type:function size:0x68 +initVolumeFade__14dSoundSource_cFv = .text:0x80388FA0; // type:function size:0x14 +setVolumeFade__14dSoundSource_cFfUl = .text:0x80388FC0; // type:function size:0x84 +calcVolumeFade__14dSoundSource_cFv = .text:0x80389050; // type:function size:0x68 vt_0x5C__14dSoundSource_cFv = .text:0x803890C0; // type:function size:0x18 vt_0x58__14dSoundSource_cFv = .text:0x803890E0; // type:function size:0x1C -fn_80389100 = .text:0x80389100; // type:function size:0x60 +isInaudible__14dSoundSource_cFv = .text:0x80389100; // type:function size:0x60 d_s_vt_0x190__14dSoundSource_cFv = .text:0x80389160; // type:function size:0x40 setPause__14dSoundSource_cFbi = .text:0x803891A0; // type:function size:0xB0 startSound__14dSoundSource_cFUl = .text:0x80389250; // type:function size:0x30 @@ -21194,13 +21194,13 @@ d_s_vt_0x1AC__14dSoundSource_cFv = .text:0x8038AE70; // type:function size:0x98 setupSound__14dSoundSource_cFPQ34nw4r3snd11SoundHandleUlPCQ44nw4r3snd14SoundStartable9StartInfoPvb = .text:0x8038AF10; // type:function size:0x254 getBaseSoundVolume__14dSoundSource_cFUlUl = .text:0x8038B170; // type:function size:0x78 startBaseSound__14dSoundSource_cFUlf = .text:0x8038B1F0; // type:function size:0x90 -startBaseSound__14dSoundSource_cFUlPCQ34nw4r4math4VEC3f = .text:0x8038B280; // type:function size:0x94 +startBaseSoundAtPosition__14dSoundSource_cFUlPCQ34nw4r4math4VEC3f = .text:0x8038B280; // type:function size:0x94 d_s_vt_0x1C8__14dSoundSource_cFv = .text:0x8038B320; // type:function size:0x24 onSetupError__14dSoundSource_cFv = .text:0x8038B350; // type:function size:0x30 d_s_vt_0x194__14dSoundSource_cFv = .text:0x8038B380; // type:function size:0x8 -d_vt_0x58__14dSoundSource_cFv = .text:0x8038B390; // type:function size:0x4 +d_vt_0x58__14dSoundSource_cFRQ34nw4r3snd11SoundHandleP13dSndSeSound_cUl = .text:0x8038B390; // type:function size:0x4 d_s_vt_0x1A0__14dSoundSource_cFv = .text:0x8038B3A0; // type:function size:0x8 -d_vt_0x5C__14dSoundSource_cFv = .text:0x8038B3B0; // type:function size:0x4 +d_vt_0x5C__14dSoundSource_cFRQ34nw4r3snd11SoundHandleP13dSndSeSound_cUli = .text:0x8038B3B0; // type:function size:0x4 attachDistantSound__14dSoundSource_cFP23dSndDistantSoundActor_c = .text:0x8038B3C0; // type:function size:0x54 detachDistantSound__14dSoundSource_cFP23dSndDistantSoundActor_c = .text:0x8038B420; // type:function size:0x60 detachAllDistantSounds__14dSoundSource_cFv = .text:0x8038B480; // type:function size:0x74 @@ -21222,7 +21222,7 @@ fn_8038BB10 = .text:0x8038BB10; // type:function size:0x6C fn_8038BB80 = .text:0x8038BB80; // type:function size:0x6C stopSoundHandles__14dSoundSource_cFUll = .text:0x8038BBF0; // type:function size:0x144 vt_0xFC__14dSoundSource_cFv = .text:0x8038BD40; // type:function size:0x20 -vt_0x110__14dSoundSource_cFv = .text:0x8038BD60; // type:function size:0xC +setPolyAttrs__14dSoundSource_cFUcUc = .text:0x8038BD60; // type:function size:0xC d_s_vt_0x1E4__14dSoundSource_cFv = .text:0x8038BD70; // type:function size:0x4 modifySoundId__14dSoundSource_cFUl = .text:0x8038BD80; // type:function size:0xB8 modifySoundId__14dSoundSource_cFUlP14dSoundSource_c = .text:0x8038BE40; // type:function size:0xC4 @@ -21453,15 +21453,15 @@ acquireActor__27dSndDistantSoundActorPool_cFUlPCQ34nw4r4math4VEC3P14dSoundSource addToActiveList__27dSndDistantSoundActorPool_cFP23dSndDistantSoundActor_cUl = .text:0x80393940; // type:function size:0x4C fn_80393990 = .text:0x80393990; // type:function size:0x4C fn_803939E0 = .text:0x803939E0; // type:function size:0x5C -fn_80393A40 = .text:0x80393A40; // type:function size:0xA0 -fn_80393AE0 = .text:0x80393AE0; // type:function size:0xA4 +findActiveActor__27dSndDistantSoundActorPool_cFUlP14dSoundSource_c = .text:0x80393A40; // type:function size:0xA0 +holdSound__27dSndDistantSoundActorPool_cFUlPCQ34nw4r4math4VEC3 = .text:0x80393AE0; // type:function size:0xA4 fn_80393B90 = .text:0x80393B90; // type:function size:0x90 fn_80393C20 = .text:0x80393C20; // type:function size:0x98 fn_80393CC0 = .text:0x80393CC0; // type:function size:0x98 onChangeStage__27dSndDistantSoundActorPool_cFv = .text:0x80393D60; // type:function size:0x60 __sinit_\d_snd_distant_sound_actor_pool_cpp = .text:0x80393DC0; // type:function size:0x34 scope:local __ct__23dSndDistantSoundActor_cFv = .text:0x80393E00; // type:function size:0x74 -getSourceParam__27dSndDistantSoundActorPool_cFv = .text:0x80393E80; // type:function size:0xC +getSourceParam__27dSndDistantSoundActorPool_cFv = .text:0x80393E80; // type:function size:0xC scope:weak initSource__23dSndDistantSoundActor_cFP14dSoundSource_c = .text:0x80393E90; // type:function size:0x54 setSourceDirectly__23dSndDistantSoundActor_cFP14dSoundSource_c = .text:0x80393EF0; // type:function size:0x18 updatePosition__23dSndDistantSoundActor_cFv = .text:0x80393F10; // type:function size:0x28 @@ -21472,9 +21472,9 @@ holdSound__23dSndDistantSoundActor_cFUlRCQ34nw4r4math4VEC3PQ34nw4r3snd11SoundHan loadDefaultParam__23dSndDistantSoundActor_cFv = .text:0x803940B0; // type:function size:0x38 detachFromSource__23dSndDistantSoundActor_cFv = .text:0x803940F0; // type:function size:0x58 setPause__23dSndDistantSoundActor_cFbi = .text:0x80394150; // type:function size:0x6C -fn_803941C0 = .text:0x803941C0; // type:function size:0x10 -fn_803941D0 = .text:0x803941D0; // type:function size:0x24 -@84@__dt__23dSndDistantSoundActor_cFv = .text:0x80394200; // type:function size:0x8 +updateSome3DField__23dSndDistantSoundActor_cFv = .text:0x803941C0; // type:function size:0x10 +d_vt_0x3C__23dSndDistantSoundActor_cFv = .text:0x803941D0; // type:function size:0x24 +@84@__dt__23dSndDistantSoundActor_cFv = .text:0x80394200; // type:function size:0x8 scope:weak __ct__13dSndSeSound_cFv = .text:0x80394210; // type:function size:0xA8 __ct__16UnkSeSoundStructFv = .text:0x803942C0; // type:function size:0x14 scope:weak __dt__16UnkSeSoundStructFv = .text:0x803942E0; // type:function size:0x40 scope:weak diff --git a/configure.py b/configure.py index cd503c5c..a81086b8 100644 --- a/configure.py +++ b/configure.py @@ -770,7 +770,7 @@ config.libs = [ Object(NonMatching, "d/snd/d_snd_source_tg_sound.cpp"), Object(NonMatching, "d/snd/d_snd_mgr_unk_16.cpp"), Object(NonMatching, "d/snd/d_snd_distant_sound_actor_pool.cpp"), - Object(NonMatching, "d/snd/d_snd_distant_sound_actor.cpp"), + Object(Matching, "d/snd/d_snd_distant_sound_actor.cpp"), Object(Matching, "d/snd/d_snd_se_sound.cpp"), Object(Matching, "d/snd/d_snd_se_sound_1.cpp"), Object(Matching, "d/snd/d_snd_se_sound_2.cpp"), diff --git a/include/d/snd/d_snd_3d_actor.h b/include/d/snd/d_snd_3d_actor.h index 436eaeea..7c7ac4ea 100644 --- a/include/d/snd/d_snd_3d_actor.h +++ b/include/d/snd/d_snd_3d_actor.h @@ -79,6 +79,11 @@ public: return mDistanceToListener; } + f32 getDistanceToCameraTarget() { + updateDistanceToCameraTarget(); + return mDistanceToCameraTarget; + } + const dSndSourceParam *getSourceParam() const { return mpSourceParam; } diff --git a/include/d/snd/d_snd_distant_sound_actor.h b/include/d/snd/d_snd_distant_sound_actor.h index 9abe90dd..fe29dfec 100644 --- a/include/d/snd/d_snd_distant_sound_actor.h +++ b/include/d/snd/d_snd_distant_sound_actor.h @@ -20,6 +20,7 @@ class dSndDistantSoundActor_c : public dSnd3DActor_c { public: dSndDistantSoundActor_c(); virtual void setPause(bool flag, int fadeFrames) override; + virtual UNKWORD d_vt_0x3C() override; virtual void d_vt_0x58(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id) override; virtual void d_vt_0x5C(nw4r::snd::SoundHandle &handle, dSndSeSound_c *pSound, u32 id, UNKWORD) override; @@ -57,6 +58,8 @@ public: mUseSourcePosition = true; } + void updateSome3DField(); + private: /* 0x0E4 */ nw4r::ut::Node mPoolLink; // sound actor pool link /* 0x0EC */ nw4r::ut::Node mSourceLink; // sound source link diff --git a/include/d/snd/d_snd_distant_sound_actor_pool.h b/include/d/snd/d_snd_distant_sound_actor_pool.h index 951f5fcd..d7f55a01 100644 --- a/include/d/snd/d_snd_distant_sound_actor_pool.h +++ b/include/d/snd/d_snd_distant_sound_actor_pool.h @@ -15,7 +15,8 @@ SND_DISPOSER_FORWARD_DECL(dSndDistantSoundActorPool_c); /** * A pool for distant sounds actors. Sound sources will borrow * actors from this pool when they want to play a sound - * at a specific position. + * at a specific position. The finisher target sound will + * also play using this pool. */ class dSndDistantSoundActorPool_c { SND_DISPOSER_MEMBERS(dSndDistantSoundActorPool_c); @@ -32,6 +33,9 @@ public: void onChangeStage(); dSndDistantSoundActor_c *acquireActor(u32 soundId, const nw4r::math::VEC3 *position, dSoundSource_c *source); + dSndDistantSoundActor_c *findActiveActor(u32 soundId, dSoundSource_c *source); + + bool holdSound(u32 soundId, const nw4r::math::VEC3 *position); private: void addToActiveList(dSndDistantSoundActor_c *actor, u32 id); diff --git a/include/d/snd/d_snd_misc.h b/include/d/snd/d_snd_misc.h index 3df7709a..fd8ce8d9 100644 --- a/include/d/snd/d_snd_misc.h +++ b/include/d/snd/d_snd_misc.h @@ -19,6 +19,10 @@ struct dSndSourceParam { field_0x10 = value_0x10; } + f32 getField0x10() const { + return field_0x10; + } + /* 0x00 */ f32 field_0x00; /* 0x04 */ f32 field_0x04; /* 0x08 */ f32 field_0x08; diff --git a/include/d/snd/d_snd_source.h b/include/d/snd/d_snd_source.h index ab33d6a6..9c5db0c1 100644 --- a/include/d/snd/d_snd_source.h +++ b/include/d/snd/d_snd_source.h @@ -23,11 +23,12 @@ public: static u32 modifySoundId(u32 baseSoundId, dSoundSource_c *source); u32 getRemoConSoundVariant(u32 soundId) const; s32 getRoomId() const; + bool isInaudible(); // This is where it gets a bit wild and this class starts mixing in overrides between // new virtual functions, which causes the vtable to list these functions in exactly this // order. - virtual const char *getName() const; + virtual const char *getName() const; // 0x17C bool isName(const char *name) const { return !std::strcmp(getName(), name); } @@ -80,16 +81,26 @@ public: // function order. virtual s32 getCategory() const override { return mSourceCategory; - } - virtual const nw4r::math::VEC3 &getListenerPosition() const override; - - virtual bool hasPlayingSounds() const override; // 0x48 - virtual bool isPlayingSound(u32 soundId) override; // 0x4C - virtual bool isPlayingSound(const char *soundId) override; // 0x50 - - virtual bool startSound(u32 soundId) override; // 0x60 - virtual bool startSound(const char *label) override; // 0x70 + } // 0x010 + virtual bool isCategory(s32 category) const override { + return mSourceCategory == category; + } // 0x014 + virtual s32 getSourceType() const override { + return mSourceType; + } // 0x018 + virtual bool isSourceType(s32 type) const override { + return mSourceType == type; + } // 0x01C + virtual const nw4r::math::VEC3 &getListenerPosition() const override; // 0x028 + virtual void stopAllSound(s32 fadeFrames) override { + SoundActor::StopAllSound(fadeFrames); + } // 0x040 + virtual bool hasPlayingSounds() const override; // 0x048 + virtual bool isPlayingSound(u32 soundId) override; // 0x04C + virtual bool isPlayingSound(const char *soundId) override; // 0x050 + virtual bool startSound(u32 soundId) override; // 0x060 + virtual bool startSound(const char *label) override; // 0x070 virtual void stopSounds(u32 soundId, s32 fadeFrames) override; // 0x0A4 virtual void stopSounds(const char *label, s32 fadeFrames) override; // 0x0A8 virtual bool holdSound(u32 soundId) override; // 0x0AC @@ -98,12 +109,12 @@ public: virtual bool isReadyMaybe() override { return false; } // 0x100 - virtual void load(void *data, const char *name) override {} // 0x104 - virtual void setFrame(f32 frame) override {} // 0x108 - virtual void setRate(f32 frame) override {} // 0x10C + virtual void load(void *data, const char *name) override {} // 0x104 + virtual void setFrame(f32 frame) override {} // 0x108 + virtual void setRate(f32 frame) override {} // 0x10C + virtual void setPolyAttrs(u8 polyAttr0, u8 polyAttr1) override; // 0x110 private: - /** * Sound sources can cause other sounds to be started. E.g when * walking, Link will produce a walk sound, but an additional sound @@ -118,7 +129,6 @@ private: dSndDistantSoundActor_c *startBaseSoundAtPosition(u32 baseSoundId, const nw4r::math::VEC3 *position, f32 volume); nw4r::snd::SoundHandle *startBaseSound(u32 baseSoundId, f32 volume); - nw4r::snd::SoundStartable::StartResult onSetupError(); nw4r::snd::SoundStartable::StartResult @@ -146,6 +156,10 @@ private: dSndSeSound1_c *getHandleType1ForSoundHandle(nw4r::snd::SoundHandle *handle); dSndSeSound2_c *getHandleType2ForSoundId(u32 soundId); + void initVolumeFade(); + void setVolumeFade(f32 volume, u32 fadeFrames); + void calcVolumeFade(); + // at 0x00: dSoundSourceIf_c vtable // at 0x04: dSnd3DActor_c sub-object // at 0x58: thunk-vtable @@ -170,10 +184,12 @@ private: /* 0x12C */ nw4r::ut::List mHandleType2List; // node offset 0x4 -> dSndSeSound_c /* 0x138 */ nw4r::ut::Node mGroupLink; // node for list in dSndSourceGroup_c /* 0x140 */ dSndSourceGroup_c *mpOwnerGroup; - /* 0x144 */ u8 _0x144[0x154 - 0x144]; + /* 0x144 */ f32 mVolumeFadeTarget; + /* 0x148 */ f32 mVolumeFadeStepSize; + /* 0x150 */ u8 _0x14C[0x154 - 0x14C]; /* 0x154 */ UNKWORD field_0x154; - /* 0x158 */ s16 field_0x158; - /* 0x15A */ s16 field_0x15A; + /* 0x158 */ s16 mPolyAttr0; + /* 0x15A */ s16 mPolyAttr1; }; #endif diff --git a/include/d/snd/d_snd_source_if.h b/include/d/snd/d_snd_source_if.h index 3d571f7e..9e6812d8 100644 --- a/include/d/snd/d_snd_source_if.h +++ b/include/d/snd/d_snd_source_if.h @@ -13,10 +13,10 @@ public: #define SOUNDSOURCE_VIRTUAL(offset) virtual void vt_##offset() = 0; SOUNDSOURCE_VIRTUAL(0x0C); - virtual s32 getCategory() const = 0; // 0x10 - SOUNDSOURCE_VIRTUAL(0x14); - virtual s32 getActorType() const = 0; - SOUNDSOURCE_VIRTUAL(0x1C); + virtual s32 getCategory() const = 0; // 0x10 + virtual bool isCategory(s32 category) const = 0; // 0x14 + virtual s32 getSourceType() const = 0; // 0x18 + virtual bool isSourceType(s32 type) const = 0; // 0x1C SOUNDSOURCE_VIRTUAL(0x20); SOUNDSOURCE_VIRTUAL(0x24); virtual const nw4r::math::VEC3 &getListenerPosition() const = 0; // 0x28 @@ -25,7 +25,7 @@ public: SOUNDSOURCE_VIRTUAL(0x34); SOUNDSOURCE_VIRTUAL(0x38); SOUNDSOURCE_VIRTUAL(0x3C); - virtual void vt_0x40(s32) = 0; + virtual void stopAllSound(s32 fadeFrames) = 0; // 0x40 SOUNDSOURCE_VIRTUAL(0x44); virtual bool hasPlayingSounds() const = 0; // 0x48 virtual bool isPlayingSound(u32 soundId) = 0; // 0x4C @@ -74,12 +74,11 @@ public: SOUNDSOURCE_VIRTUAL(0xF8); SOUNDSOURCE_VIRTUAL(0xFC); - virtual bool isReadyMaybe() = 0; // 0x100 - virtual void load(void *data, const char *name) = 0; // 0x104 - virtual void setFrame(f32 frame) = 0; // 0x108 - virtual void setRate(f32 frame) = 0; // 0x10C - - SOUNDSOURCE_VIRTUAL(0x110); + virtual bool isReadyMaybe() = 0; // 0x100 + virtual void load(void *data, const char *name) = 0; // 0x104 + virtual void setFrame(f32 frame) = 0; // 0x108 + virtual void setRate(f32 frame) = 0; // 0x10C + virtual void setPolyAttrs(u8 polyAttr0, u8 polyAttr1) = 0; // 0x110 SOUNDSOURCE_VIRTUAL(0x114); SOUNDSOURCE_VIRTUAL(0x118); }; diff --git a/include/nw4r/snd/snd_SoundActor.h b/include/nw4r/snd/snd_SoundActor.h index 044772a7..d8b499f2 100644 --- a/include/nw4r/snd/snd_SoundActor.h +++ b/include/nw4r/snd/snd_SoundActor.h @@ -69,6 +69,14 @@ namespace nw4r { namespace snd void PauseAllSound(bool flag, int fadeFrames); int GetPlayingSoundCount(int playerId) const; + void SetVolume(f32 volume) { + mActorParam.volume = volume; + } + + f32 GetVolume() const { + return mActorParam.volume; + } + // static members public: static int const ACTOR_PLAYER_COUNT = 4; diff --git a/src/d/a/obj/d_a_obj_boomerang.cpp b/src/d/a/obj/d_a_obj_boomerang.cpp index 7cbde76a..eb771ff3 100644 --- a/src/d/a/obj/d_a_obj_boomerang.cpp +++ b/src/d/a/obj/d_a_obj_boomerang.cpp @@ -239,7 +239,7 @@ void dAcBoomerang_c::deleteReady() { deleteCheck(); if (getSoundSource()) { - getSoundSource()->vt_0x40(5); + getSoundSource()->stopAllSound(5); } if (dAcPy_c::GetLink2()) { diff --git a/src/d/snd/d_snd_distant_sound_actor.cpp b/src/d/snd/d_snd_distant_sound_actor.cpp index c7c94d26..8f054e76 100644 --- a/src/d/snd/d_snd_distant_sound_actor.cpp +++ b/src/d/snd/d_snd_distant_sound_actor.cpp @@ -7,6 +7,7 @@ #include "d/snd/d_snd_distant_sound_actor_pool.h" #include "d/snd/d_snd_source.h" #include "d/snd/d_snd_source_enums.h" +#include "d/snd/d_snd_state_mgr.h" dSndDistantSoundActor_c::dSndDistantSoundActor_c() : dSnd3DActor_c(&dSndDistantSoundActorPool_c::GetInstance()->getSourceParam(), SND_SOURCE_DISTANT), @@ -64,6 +65,7 @@ bool dSndDistantSoundActor_c::startSound( } SetPosition(position); + updateSome3DField(); return StartSound(pHandle, soundId); } @@ -105,3 +107,14 @@ void dSndDistantSoundActor_c::setPause(bool flag, int fadeFrames) { mIsPaused = 1; } } + +void dSndDistantSoundActor_c::updateSome3DField() { + a_field_0xE0 = dSndStateMgr_c::GetInstance()->getField_0x49C(); +} + +UNKWORD dSndDistantSoundActor_c::d_vt_0x3C() { + if (mpSoundSource != nullptr) { + return mpSoundSource->d_vt_0x3C(); + } + return 0; +} diff --git a/src/d/snd/d_snd_distant_sound_actor_pool.cpp b/src/d/snd/d_snd_distant_sound_actor_pool.cpp index d8ffa83e..089e84a1 100644 --- a/src/d/snd/d_snd_distant_sound_actor_pool.cpp +++ b/src/d/snd/d_snd_distant_sound_actor_pool.cpp @@ -72,6 +72,31 @@ void dSndDistantSoundActorPool_c::addToActiveList(dSndDistantSoundActor_c *actor actor->setActive(true); } +dSndDistantSoundActor_c *dSndDistantSoundActorPool_c::findActiveActor(u32 soundId, dSoundSource_c *source) { + for (dSndDistantSoundActor_c *it = static_cast(nw4r::ut::List_GetFirst(&mActiveActors)); it != nullptr; it = static_cast(nw4r::ut::List_GetNext(&mActiveActors, it))) { + if (it->isAttachedSource(source) && it->isPlayingSound(soundId)) { + return it; + } + } + + return nullptr; +} + +bool dSndDistantSoundActorPool_c::holdSound(u32 soundId, const nw4r::math::VEC3 *position) { + dSndDistantSoundActor_c *ac = findActiveActor(soundId, nullptr); + if (ac == nullptr) { + ac = acquireActor(soundId, position, nullptr); + if (ac != nullptr) { + ac->updateSome3DField(); + } + } + if (ac != nullptr) { + return ac->holdSound(soundId, *position, nullptr); + } + return false; + +} + void dSndDistantSoundActorPool_c::onChangeStage() { mVec3_c v(INFINITY, INFINITY, INFINITY); for (int i = 0; i < POOL_SIZE; i++) { diff --git a/src/d/snd/d_snd_source.cpp b/src/d/snd/d_snd_source.cpp index d0de9e6c..9a021cc6 100644 --- a/src/d/snd/d_snd_source.cpp +++ b/src/d/snd/d_snd_source.cpp @@ -49,8 +49,8 @@ dSoundSource_c::dSoundSource_c(u8 sourceType, dAcBase_c *actor, const char *name field_0x11C(0), mpOwnerGroup(pOwnerGroup), field_0x154(0), - field_0x158(-1), - field_0x15A(-1) { + mPolyAttr0(-1), + mPolyAttr1(-1) { mSourceCategory = dSndSourceMgr_c::getSourceCategoryForSourceType(sourceType, name); // TODO: Offsetof nw4r::ut::List_Init(&mDistantSoundList, 0xEC); @@ -84,6 +84,64 @@ bool dSoundSource_c::isPlayingSound(const char *soundId) { return isPlayingSound(soundLabelToSoundId(soundId)); } +void dSoundSource_c::initVolumeFade() { + mVolumeFadeTarget = 1.0f; + mVolumeFadeStepSize = 0.0f; +} + +void dSoundSource_c::setVolumeFade(f32 volume, u32 fadeFrames) { + // @bug not actually clamped + (void)nw4r::ut::Clamp(volume, 0.0f, 2.0f); + if (fadeFrames == 0) { + SoundActor::SetVolume(volume); + mVolumeFadeTarget = volume; + mVolumeFadeStepSize = 0.0f; + return; + } + f32 currVolume = SoundActor::GetVolume(); + if (currVolume == volume) { + mVolumeFadeTarget = volume; + mVolumeFadeStepSize = 0.0f; + } else { + mVolumeFadeTarget = volume; + mVolumeFadeStepSize = (volume - currVolume) / fadeFrames; + } +} + +void dSoundSource_c::calcVolumeFade() { + if (mIsPaused) { + return; + } + + if (mVolumeFadeStepSize == 0.0f) { + return; + } + + f32 nextVolume = SoundActor::GetVolume(); + nextVolume += mVolumeFadeStepSize; + if (mVolumeFadeStepSize > 0.0f) { + if (nextVolume >= mVolumeFadeTarget) { + nextVolume = mVolumeFadeTarget; + mVolumeFadeStepSize = 0.0f; + } + } else { + if (nextVolume <= mVolumeFadeTarget) { + nextVolume = mVolumeFadeTarget; + mVolumeFadeStepSize = 0.0f; + } + } + + SoundActor::SetVolume(nextVolume); +} + +bool dSoundSource_c::isInaudible() { + if (field_0x102 != 0) { + return true; + } + + return dSnd3DActor_c::getDistanceToCameraTarget() >= mpSourceParam->getField0x10(); +} + void dSoundSource_c::setPause(bool flag, int fadeFrames) { if (!flag) { PauseAllSound(flag, fadeFrames); @@ -608,6 +666,11 @@ dSndSeSound2_c *dSoundSource_c::getHandleType2ForSoundId(u32 soundId) { return nullptr; } +void dSoundSource_c::setPolyAttrs(u8 polyAttr0, u8 polyAttr1) { + mPolyAttr0 = polyAttr0; + mPolyAttr1 = polyAttr1; +} + void dSoundSource_c::stopSoundHandles(u32 soundId, s32 fadeFrames) { // TODO: Weird declaration order required for regswaps { diff --git a/src/d/snd/d_snd_source_group.cpp b/src/d/snd/d_snd_source_group.cpp index 31b27fb6..fe7fcb33 100644 --- a/src/d/snd/d_snd_source_group.cpp +++ b/src/d/snd/d_snd_source_group.cpp @@ -126,7 +126,7 @@ dSoundSource_c *dSndSourceGroup_c::getSourceClosestToListener() { f32 closest = INFINITY; for (dSoundSource_c *source = static_cast(nw4r::ut::List_GetFirst(&mSourceList)); source != nullptr; source = static_cast(nw4r::ut::List_GetNext(&mSourceList, source))) { - if (source->getActorType() != SND_SOURCE_PLAYER_HEAD && source->getActorType() != SND_SOURCE_NPC_48) { + if (source->getSourceType() != SND_SOURCE_PLAYER_HEAD && source->getSourceType() != SND_SOURCE_NPC_48) { f32 dist = source->getDistanceToListener(); if (dist < closest) { closest = dist; @@ -151,7 +151,7 @@ dSoundSource_c *dSndSourceGroup_c::getSourceClosestToPlayer() { f32 closest = INFINITY; for (dSoundSource_c *source = static_cast(nw4r::ut::List_GetFirst(&mSourceList)); source != nullptr; source = static_cast(nw4r::ut::List_GetNext(&mSourceList, source))) { - if (source->getActorType() != 1 && source->getActorType() != 48) { + if (source->getSourceType() != 1 && source->getSourceType() != 48) { f32 dist = source->getDistanceToPlayer(); if (dist < closest) { closest = dist; diff --git a/src/d/snd/d_snd_source_mgr.cpp b/src/d/snd/d_snd_source_mgr.cpp index fdd0b816..7e175559 100644 --- a/src/d/snd/d_snd_source_mgr.cpp +++ b/src/d/snd/d_snd_source_mgr.cpp @@ -88,13 +88,13 @@ void dSndSourceMgr_c::registerSource(dSoundSource_c *source) { nw4r::ut::List_Append(&mAllSources, source); switch (source->getCategory()) { case SND_SOURCE_CATEGORY_PLAYER: { - if (source->getActorType() == SND_SOURCE_PLAYER && mpPlayerSource == nullptr) { + if (source->getSourceType() == SND_SOURCE_PLAYER && mpPlayerSource == nullptr) { mpPlayerSource = source; } break; } case SND_SOURCE_CATEGORY_EQUIPMENT: { - if (source->getActorType() == SND_SOURCE_BOOMERANG) { + if (source->getSourceType() == SND_SOURCE_BOOMERANG) { mpBoomerangSource = source; } break; @@ -116,7 +116,7 @@ void dSndSourceMgr_c::registerSource(dSoundSource_c *source) { break; } case SND_SOURCE_CATEGORY_NPC: { - if (source->getActorType() == SND_SOURCE_KENSEI) { + if (source->getSourceType() == SND_SOURCE_KENSEI) { mpKenseiSource = source; } break;