diff --git a/config/SOUE01/splits.txt b/config/SOUE01/splits.txt index 72bc4f64..ce9bc24e 100644 --- a/config/SOUE01/splits.txt +++ b/config/SOUE01/splits.txt @@ -2781,13 +2781,16 @@ d/snd/d_snd_source.cpp: .sbss start:0x80575DB0 end:0x80575DC0 .sdata2 start:0x8057DCB0 end:0x8057DCD0 -d/snd/d_snd_source_link_body.cpp: +d/snd/d_snd_source_player.cpp: .text start:0x8038C410 end:0x8038D548 align:16 - .data start:0x8054AAE8 end:0x8054AFC0 + .data start:0x8054AAE8 end:0x8054AF18 + .sdata start:0x80574718 end:0x80574758 + .sdata2 start:0x8057DCD0 end:0x8057DD08 -d/snd/d_snd_source_link_head.cpp: +d/snd/d_snd_source_player_head.cpp: .text start:0x8038D550 end:0x8038DD08 align:16 - .data start:0x8054AFC0 end:0x8054B1B8 + .data start:0x8054AF18 end:0x8054B1B8 + .sdata2 start:0x8057DD08 end:0x8057DD48 d/snd/d_snd_source_enemy.cpp: .text start:0x8038DD10 end:0x8038E858 align:16 @@ -2913,12 +2916,14 @@ d/snd/d_snd_sound_tgsound_callbacks.cpp: .text start:0x80399000 end:0x8039942C align:16 .sdata start:0x805748E8 end:0x805748F0 -d/snd/d_snd_mgr_unk_17.cpp: +d/snd/d_snd_rng_link_voice.cpp: .text start:0x80399430 end:0x80399574 align:16 + .rodata start:0x804F3E38 end:0x804F42F8 .data start:0x8054D740 end:0x8054D760 d/snd/d_snd_fi_vocal_mgr.cpp: .text start:0x80399580 end:0x80399A3C align:16 + .rodata start:0x804F42F8 end:0x804F4778 .data start:0x8054D760 end:0x8054D7A8 .sbss start:0x80575DE0 end:0x80575DE8 @@ -2931,8 +2936,12 @@ d/snd/d_snd_rng_mgr.cpp: .data start:0x8054D7B8 end:0x8054D7D0 .sbss start:0x80575DE8 end:0x80575DF0 -d/snd/d_snd_mgr_unk_11.cpp: - .text start:0x80399D60 end:0x8039A344 align:16 +d/snd/d_snd_rng_id.cpp: + .text start:0x80399D60 end:0x8039A204 align:16 + .data start:0x8054D7D0 end:0x8054D7E0 + +d/snd/d_snd_rng_id_if.cpp: + .text start:0x8039A210 end:0x8039A344 align:16 d/snd/d_snd_file_mgr.cpp: .text start:0x8039A350 end:0x8039A848 align:16 @@ -2942,6 +2951,7 @@ d/snd/d_snd_file_mgr.cpp: d/snd/d_snd_calc_pitch.cpp: .text start:0x8039A850 end:0x8039A960 align:16 + .rodata start:0x804F4778 end:0x804F4F00 revolution/kpr/kpr_lib.c: .text start:0x8039A960 end:0x8039AF7C align:16 diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt index 3ddf7de7..a54fff63 100644 --- a/config/SOUE01/symbols.txt +++ b/config/SOUE01/symbols.txt @@ -2462,7 +2462,7 @@ fn_8005BAC0 = .text:0x8005BAC0; // type:function size:0x10 fn_8005BAD0 = .text:0x8005BAD0; // type:function size:0x10 fn_8005BAE0 = .text:0x8005BAE0; // type:function size:0xC IsLinkOutOfStamina = .text:0x8005BAF0; // type:function size:0x14 -fn_8005BB10 = .text:0x8005BB10; // type:function size:0x8 +getStamina__17daPlayerActBase_cFv = .text:0x8005BB10; // type:function size:0x8 getBoatActorIfRiding = .text:0x8005BB20; // type:function size:0x24 getRidingActor__17daPlayerActBase_cFv = .text:0x8005BB50; // type:function size:0x8 AcNpcTke__setRefInLinkToCall = .text:0x8005BB60; // type:function size:0xC @@ -21264,27 +21264,27 @@ fn_8038D520 = .text:0x8038D520; // type:function size:0x8 fn_8038D530 = .text:0x8038D530; // type:function size:0x8 fn_8038D540 = .text:0x8038D540; // type:function size:0x8 __ct__22dSndSourcePlayerHead_cFlP9dAcBase_cPCcP17dSndSourceGroup_c = .text:0x8038D550; // type:function size:0x7C -fn_8038D5D0 = .text:0x8038D5D0; // type:function size:0x40 -fn_8038D610 = .text:0x8038D610; // type:function size:0x40 +__dt__18dSndRngLinkVoice_cFv = .text:0x8038D5D0; // type:function size:0x40 +__dt__11dSndRngId_cFv = .text:0x8038D610; // type:function size:0x40 __dt__9dSndRng_cFv = .text:0x8038D650; // type:function size:0x40 -fn_8038D690 = .text:0x8038D690; // type:function size:0x74 -fn_8038D710 = .text:0x8038D710; // type:function size:0x8 -actuallyPlaysLinkSound = .text:0x8038D720; // type:function size:0x334 -fn_8038DA60 = .text:0x8038DA60; // type:function size:0x14 -fn_8038DA80 = .text:0x8038DA80; // type:function size:0x58 -fn_8038DAE0 = .text:0x8038DAE0; // type:function size:0x8 -fn_8038DAF0 = .text:0x8038DAF0; // type:function size:0x6C -fn_8038DB60 = .text:0x8038DB60; // type:function size:0x48 -fn_8038DBB0 = .text:0x8038DBB0; // type:function size:0x54 -fn_8038DC10 = .text:0x8038DC10; // type:function size:0x8 -fn_8038DC20 = .text:0x8038DC20; // type:function size:0x8 -fn_8038DC30 = .text:0x8038DC30; // type:function size:0x4 -fn_8038DC40 = .text:0x8038DC40; // type:function size:0x8 -fn_8038DC50 = .text:0x8038DC50; // type:function size:0x80 -fn_8038DCD0 = .text:0x8038DCD0; // type:function size:0x8 -fn_8038DCE0 = .text:0x8038DCE0; // type:function size:0x8 -fn_8038DCF0 = .text:0x8038DCF0; // type:function size:0x8 -fn_8038DD00 = .text:0x8038DD00; // type:function size:0x8 +configureVoiceRngs__22dSndSourcePlayerHead_cFv = .text:0x8038D690; // type:function size:0x74 +d_vt_0x3C__22dSndSourcePlayerHead_cFv = .text:0x8038D710; // type:function size:0x8 +startVoiceLine__22dSndSourcePlayerHead_cFUl = .text:0x8038D720; // type:function size:0x334 +isPlayingActionSound__22dSndSourcePlayerHead_cCFv = .text:0x8038DA60; // type:function size:0x14 +startVoiceSoundInternal__22dSndSourcePlayerHead_cFUl = .text:0x8038DA80; // type:function size:0x58 +d_vt_0x30__22dSndSourcePlayerHead_cFv = .text:0x8038DAE0; // type:function size:0x8 +isCurrentActionSound__22dSndSourcePlayerHead_cCFUl = .text:0x8038DAF0; // type:function size:0x6C +stopCurrentActionSound__22dSndSourcePlayerHead_cFv = .text:0x8038DB60; // type:function size:0x48 +stopActionSound__22dSndSourcePlayerHead_cFUl = .text:0x8038DBB0; // type:function size:0x54 +startVoiceLine__22dSndSourcePlayerHead_cFPCc = .text:0x8038DC10; // type:function size:0x8 +vt_1F0__22dSndSourcePlayerHead_cFv = .text:0x8038DC20; // type:function size:0x8 +preCalc__22dSndSourcePlayerHead_cFv = .text:0x8038DC30; // type:function size:0x4 +overrideStartSoundId__22dSndSourcePlayerHead_cFUl = .text:0x8038DC40; // type:function size:0x8 +__dt__22dSndSourcePlayerHead_cFv = .text:0x8038DC50; // type:function size:0x80 +@88@__dt__22dSndSourcePlayerHead_cFv = .text:0x8038DCD0; // type:function size:0x8 +@4@d_vt_0x3C__22dSndSourcePlayerHead_cFv = .text:0x8038DCE0; // type:function size:0x8 +@4@d_vt_0x30__22dSndSourcePlayerHead_cFv = .text:0x8038DCF0; // type:function size:0x8 +@4@__dt__22dSndSourcePlayerHead_cFv = .text:0x8038DD00; // type:function size:0x8 __ct__17dSndSourceEnemy_cFlP9dAcBase_cPCcP17dSndSourceGroup_c = .text:0x8038DD10; // type:function size:0x94 __dt__17dSndSourceEnemy_cFv = .text:0x8038DDB0; // type:function size:0x7C shutdown__17dSndSourceEnemy_cFv = .text:0x8038DE30; // type:function size:0x34 @@ -21607,10 +21607,10 @@ fn_80399180 = .text:0x80399180; // type:function size:0xB0 fn_80399230 = .text:0x80399230; // type:function size:0xA0 fn_803992D0 = .text:0x803992D0; // type:function size:0xA8 postSetupSound__19dSndSourceTgSound_cFUlUlP13dSndSeSound_c = .text:0x80399380; // type:function size:0xAC -fn_80399430 = .text:0x80399430; // type:function size:0x3C -fn_80399470 = .text:0x80399470; // type:function size:0x6C -fn_803994E0 = .text:0x803994E0; // type:function size:0x78 -fn_80399560 = .text:0x80399560; // type:function size:0x14 +__ct__18dSndRngLinkVoice_cFv = .text:0x80399430; // type:function size:0x3C +configure__18dSndRngLinkVoice_cFPC19dSndLinkVoiceConfigP22dSndSourcePlayerHead_c = .text:0x80399470; // type:function size:0x6C +handleId__18dSndRngLinkVoice_cFUl = .text:0x803994E0; // type:function size:0x78 +getConfig__18dSndRngLinkVoice_cFl = .text:0x80399560; // type:function size:0x14 __dt__34SndMgrDisposer<16dSndFiVocalMgr_c>Fv = .text:0x80399580; // type:function size:0x78 create__34SndMgrDisposer<16dSndFiVocalMgr_c>Fv = .text:0x80399600; // type:function size:0x48 remove__34SndMgrDisposer<16dSndFiVocalMgr_c>Fv = .text:0x80399650; // type:function size:0x10 @@ -21628,19 +21628,19 @@ create__30SndMgrDisposer<12dSndRngMgr_c>Fv = .text:0x80399C20; // type:function remove__30SndMgrDisposer<12dSndRngMgr_c>Fv = .text:0x80399CB0; // type:function size:0x10 scope:weak rndIntRange__12dSndRngMgr_cFll = .text:0x80399CC0; // type:function size:0x34 __dt__12dSndRngMgr_cFv = .text:0x80399D00; // type:function size:0x5C scope:weak -fn_80399D60 = .text:0x80399D60; // type:function size:0x44 -fn_80399DB0 = .text:0x80399DB0; // type:function size:0x34 -fn_80399DF0 = .text:0x80399DF0; // type:function size:0x15C -fn_80399F50 = .text:0x80399F50; // type:function size:0xAC -fn_8039A000 = .text:0x8039A000; // type:function size:0x54 -fn_8039A060 = .text:0x8039A060; // type:function size:0xC4 -fn_8039A130 = .text:0x8039A130; // type:function size:0xB4 -fn_8039A1F0 = .text:0x8039A1F0; // type:function size:0x10 -fn_8039A200 = .text:0x8039A200; // type:function size:0x4 -fn_8039A210 = .text:0x8039A210; // type:function size:0x44 -fn_8039A260 = .text:0x8039A260; // type:function size:0x44 -fn_8039A2B0 = .text:0x8039A2B0; // type:function size:0x44 -fn_8039A300 = .text:0x8039A300; // type:function size:0x44 +__ct__11dSndRngId_cFv = .text:0x80399D60; // type:function size:0x44 +configure__11dSndRngId_cFUlUlUc = .text:0x80399DB0; // type:function size:0x34 +rndIdNoReuse__11dSndRngId_cFv = .text:0x80399DF0; // type:function size:0x15C +nextIdNoReuse__11dSndRngId_cFv = .text:0x80399F50; // type:function size:0xAC +rndId__11dSndRngId_cFv = .text:0x8039A000; // type:function size:0x54 +rndIdNotSame__11dSndRngId_cFv = .text:0x8039A060; // type:function size:0xC4 +markPicked__11dSndRngId_cFUlb = .text:0x8039A130; // type:function size:0xB4 +resetPicked__11dSndRngId_cFv = .text:0x8039A1F0; // type:function size:0x10 +rndInt__11dSndRngId_cFl = .text:0x8039A200; // type:function size:0x4 +doNextIdNoReuse__13dSndRngIdIf_cFv = .text:0x8039A210; // type:function size:0x44 +doRndId__13dSndRngIdIf_cFv = .text:0x8039A260; // type:function size:0x44 +doRndIdNoReuse__13dSndRngIdIf_cFv = .text:0x8039A2B0; // type:function size:0x44 +doRndIdNotSame__13dSndRngIdIf_cFv = .text:0x8039A300; // type:function size:0x44 __dt__15dSndFileManagerFv = .text:0x8039A350; // type:function size:0x40 scope:weak create__15dSndFileManagerFPQ34nw4r3snd12SoundArchivePQ34nw4r3snd9SoundHeap = .text:0x8039A390; // type:function size:0xB0 clearGlob__15dSndFileManagerFv = .text:0x8039A440; // type:function size:0x40 @@ -38074,7 +38074,7 @@ __vt__16dSoundSourceIf_c = .data:0x8054A9C8; // type:object size:0x11C scope:wea lbl_8054AAE8 = .data:0x8054AAE8; // type:object size:0x38 lbl_8054AB20 = .data:0x8054AB20; // type:object size:0x3F8 jumptable_8054AF18 = .data:0x8054AF18; // type:object size:0xA8 scope:local -lbl_8054AFC0 = .data:0x8054AFC0; // type:object size:0x1F8 +__vt__22dSndSourcePlayerHead_c = .data:0x8054AFC0; // type:object size:0x1F8 lbl_8054B1B8 = .data:0x8054B1B8; // type:object size:0xC lbl_8054B1C4 = .data:0x8054B1C4; // type:object size:0xC __vt__22dSndSourceEnemyMulti_c = .data:0x8054B1D0; // type:object size:0x1EC @@ -38117,14 +38117,14 @@ lbl_8054D520 = .data:0x8054D520; // type:object size:0x10 data:string lbl_8054D530 = .data:0x8054D530; // type:object size:0x10 __vt__15dSndSourceNpc_c = .data:0x8054D540; // type:object size:0x1F0 lbl_8054D730 = .data:0x8054D730; // type:object size:0x10 -lbl_8054D740 = .data:0x8054D740; // type:object size:0x20 +__vt__18dSndRngLinkVoice_c = .data:0x8054D740; // type:object size:0x20 lbl_8054D760 = .data:0x8054D760; // type:object size:0xC jumptable_8054D76C = .data:0x8054D76C; // type:object size:0x30 scope:local __vt__34SndMgrDisposer<16dSndFiVocalMgr_c> = .data:0x8054D79C; // type:object size:0xC __vt__9dSndRng_c = .data:0x8054D7A8; // type:object size:0x10 __vt__12dSndRngMgr_c = .data:0x8054D7B8; // type:object size:0xC scope:weak __vt__30SndMgrDisposer<12dSndRngMgr_c> = .data:0x8054D7C4; // type:object size:0xC scope:weak -lbl_8054D7D0 = .data:0x8054D7D0; // type:object size:0x10 +__vt__11dSndRngId_c = .data:0x8054D7D0; // type:object size:0xC scope:weak __vt__15dSndFileManager = .data:0x8054D7E0; // type:object size:0x30 lbl_8054D810 = .data:0x8054D810; // type:object size:0x48 lbl_8054D858 = .data:0x8054D858; // type:object size:0xA data:string diff --git a/configure.py b/configure.py index e8f43b36..6c000cfd 100644 --- a/configure.py +++ b/configure.py @@ -772,8 +772,8 @@ config.libs = [ Object(NonMatching, "d/snd/d_snd_source_mgr.cpp"), Object(NonMatching, "d/snd/d_snd_source_group.cpp"), Object(Matching, "d/snd/d_snd_source.cpp"), - Object(NonMatching, "d/snd/d_snd_source_link_body.cpp"), - Object(NonMatching, "d/snd/d_snd_source_link_head.cpp"), + Object(NonMatching, "d/snd/d_snd_source_player.cpp"), + Object(NonMatching, "d/snd/d_snd_source_player_head.cpp"), Object(NonMatching, "d/snd/d_snd_source_enemy.cpp"), Object(Matching, "d/snd/d_snd_source_obj.cpp"), Object(Matching, "d/snd/d_snd_source_obj_clef.cpp"), @@ -799,12 +799,12 @@ config.libs = [ Object(NonMatching, "d/snd/d_snd_sound_npc_callbacks.cpp"), Object(NonMatching, "d/snd/d_snd_sound_npc_2_callbacks.cpp"), Object(NonMatching, "d/snd/d_snd_sound_tgsound_callbacks.cpp"), - Object(NonMatching, "d/snd/d_snd_mgr_unk_17.cpp"), + Object(NonMatching, "d/snd/d_snd_rng_link_voice.cpp"), Object(NonMatching, "d/snd/d_snd_fi_vocal_mgr.cpp"), Object(NonMatching, "d/snd/d_snd_rng.cpp"), Object(Matching, "d/snd/d_snd_rng_mgr.cpp"), - # more rng related - Object(NonMatching, "d/snd/d_snd_mgr_unk_11.cpp"), + Object(Matching, "d/snd/d_snd_rng_id.cpp"), + Object(Matching, "d/snd/d_snd_rng_id_if.cpp"), Object(Matching, "d/snd/d_snd_file_mgr.cpp"), Object(NonMatching, "d/snd/d_snd_calc_pitch.cpp"), ], diff --git a/include/d/d_player_act.h b/include/d/d_player_act.h index 4e8b4b49..1f618598 100644 --- a/include/d/d_player_act.h +++ b/include/d/d_player_act.h @@ -631,6 +631,9 @@ public: static mAng fn_8005BAA0(); static void updateCurrentSword(); + static bool isOutOfStamina(); + static f32 getStamina(); + static s32 getCurrentSwordType(); static const char *getSwordName(s32); static s32 getCurrentlyEquippedShieldType(); diff --git a/include/d/snd/d_snd_rng_id.h b/include/d/snd/d_snd_rng_id.h new file mode 100644 index 00000000..ac068194 --- /dev/null +++ b/include/d/snd/d_snd_rng_id.h @@ -0,0 +1,32 @@ +#ifndef D_SND_RNG_ID_H +#define D_SND_RNG_ID_H + +#include "d/snd/d_snd_rng.h" + +/** A class for picking sound ID variants at random without repeats. */ +class dSndRngId_c : public dSndRng_c { +public: + dSndRngId_c(); + + void configure(u32 start, u32 end, u8 genChance); + + u32 rndIdNoReuse(); + u32 nextIdNoReuse(); + u32 rndId(); + u32 rndIdNotSame(); + void markPicked(u32 id, bool allowReset); + +private: + void resetPicked(); + u32 rndInt(s32 max); + + /* 0x18 */ u32 mBaseId; + /* 0x1C */ u32 mLastPicked; + /* 0x20 */ u32 mPickedMask; + /* 0x24 */ s16 mPickedNum; + /* 0x26 */ u8 mRange; + /* 0x27 */ u8 mGenChance; + /* 0x28 */ bool mIsConfigured; +}; + +#endif diff --git a/include/d/snd/d_snd_rng_id_if.h b/include/d/snd/d_snd_rng_id_if.h new file mode 100644 index 00000000..94198f5e --- /dev/null +++ b/include/d/snd/d_snd_rng_id_if.h @@ -0,0 +1,17 @@ +#ifndef D_SND_RNG_ID_IF_H +#define D_SND_RNG_ID_IF_H + +#include "d/snd/d_snd_rng_id.h" + +/** A class for picking sound ID variants at random without repeats. */ +class dSndRngIdIf_c : protected dSndRngId_c { +public: + /* 0x0C */ virtual bool doNextIdNoReuse(); + /* 0x10 */ virtual bool doRndId(); + /* 0x14 */ virtual bool doRndIdNoReuse(); + /* 0x18 */ virtual bool doRndIdNotSame(); + + /* 0x1C */ virtual bool handleId(u32 id) = 0; +}; + +#endif diff --git a/include/d/snd/d_snd_rng_link_voice.h b/include/d/snd/d_snd_rng_link_voice.h new file mode 100644 index 00000000..8292bd64 --- /dev/null +++ b/include/d/snd/d_snd_rng_link_voice.h @@ -0,0 +1,188 @@ +#ifndef D_SND_RNG_LINK_VOICE_H +#define D_SND_RNG_LINK_VOICE_H + +#include "d/snd/d_snd_rng_id_if.h" +#include "d/snd/d_snd_types.h" + +struct dSndLinkVoiceConfig; + +enum dSndLinkVoice_e { + /* 0x00 */ SND_LV_PRACTICE_S, + /* 0x01 */ SND_LV_PRACTICE_M, + /* 0x02 */ SND_LV_PRACTICE_L, + /* 0x03 */ SND_LV_PRACTICE_KAITEN_M, + /* 0x04 */ SND_LV_ATTACK_S, + /* 0x05 */ SND_LV_ATTACK_M, + /* 0x06 */ SND_LV_ATTACK_L, + /* 0x07 */ SND_LV_SAVE_POWER, + /* 0x08 */ SND_LV_ATTACK_KAITEN_M, + /* 0x09 */ SND_LV_NOTICE, + /* 0x0A */ SND_LV_PRACTICE_SHIELD, + /* 0x0B */ SND_LV_ATTACK_SHIELD, + /* 0x0C */ SND_LV_ATTACK_SHIELD_GJ, + /* 0x0D */ SND_LV_SHELD_GUARD, + /* 0x0E */ SND_LV_SHELD_DOWN, + /* 0x0F */ SND_LV_SHELD_BREAK, + /* 0x10 */ SND_LV_ATTACK_DOWN, + /* 0x11 */ SND_LV_DAMAGE_S, + /* 0x12 */ SND_LV_DAMAGE_L, + /* 0x13 */ SND_LV_DAMAGE_FIRE_S, + /* 0x14 */ SND_LV_DAMAGE_FIRE_L, + /* 0x15 */ SND_LV_DAMAGE_ELEC_S, + /* 0x16 */ SND_LV_DAMAGE_ELEC_L, + /* 0x17 */ SND_LV_STRUGGLE_S, + /* 0x18 */ SND_LV_STRUGGLE_L, + /* 0x19 */ SND_LV_GROAN, + /* 0x1A */ SND_LV_ESCAPE, + /* 0x1B */ SND_LV_DAMAGE_MAGMA, + /* 0x1C */ SND_LV_DAMAGE_QUICKSAND, + /* 0x1D */ SND_LV_DIE_L, + /* 0x1E */ SND_LV_DIE_S, + /* 0x1F */ SND_LV_DIE_WATER, + /* 0x20 */ SND_LV_RESTART, + /* 0x21 */ SND_LV_STAND_UP, + /* 0x22 */ SND_LV_PHEW_1, + /* 0x23 */ SND_LV_TIRED_S_1, + /* 0x24 */ SND_LV_TIRED_S_2, + /* 0x25 */ SND_LV_TIRED_M, + /* 0x26 */ SND_LV_TIRED_L, + /* 0x27 */ SND_LV_CLIMB_TIRED_S_1, + /* 0x28 */ SND_LV_CLIMB_TIRED_S_2, + /* 0x29 */ SND_LV_CLIMB_TIRED_M, + /* 0x2A */ SND_LV_CLIMB_TIRED_L, + /* 0x2B */ SND_LV_LIFT_TIRED_S_1, + /* 0x2C */ SND_LV_LIFT_TIRED_S_2, + /* 0x2D */ SND_LV_LIFT_TIRED_M, + /* 0x2E */ SND_LV_LIFT_TIRED_L, + /* 0x2F */ SND_LV_TIRED_RECOVER, + /* 0x30 */ SND_LV_TIRED_RECOVER_S, + /* 0x31 */ SND_LV_TIRED_RECOVER_M, + /* 0x32 */ SND_LV_TIRED_RECOVER_L, + /* 0x33 */ SND_LV_TIRED_EMPTY, + /* 0x34 */ SND_LV_PHEW_2, + /* 0x35 */ SND_LV_JUMP_S, + /* 0x36 */ SND_LV_JUMP_M, + /* 0x37 */ SND_LV_JUMP_L, + /* 0x38 */ SND_LV_SHOOT_START, + /* 0x39 */ SND_LV_SHOOT_SLOPE, + /* 0x3A */ SND_LV_RUN_UP, + /* 0x3B */ SND_LV_GRAB, + /* 0x3C */ SND_LV_CLIMB_STEP, + /* 0x3D */ SND_LV_HUNG, + /* 0x3E */ SND_LV_JUMP_IVY, + /* 0x3F */ SND_LV_BACKFLIP, + /* 0x40 */ SND_LV_ZENTEN, + /* 0x41 */ SND_LV_ZENTEN_CLASH, + /* 0x42 */ SND_LV_ZENTEN_UP, + /* 0x43 */ SND_LV_FALLING_HIGH, + /* 0x44 */ SND_LV_DAMAGE_FALL, + /* 0x45 */ SND_LV_SKYDIVE, + /* 0x46 */ SND_LV_RIDE_BIRD, + /* 0x47 */ SND_LV_BLAST, + /* 0x48 */ SND_LV_WIND_FLY, + /* 0x49 */ SND_LV_BALANCE_BALL, + /* 0x4A */ SND_LV_SLIDE_START, + /* 0x4B */ SND_LV_CLIMB_ROPE, + /* 0x4C */ SND_LV_SWING_ROPE, + /* 0x4D */ SND_LV_JUMP_ROPE, + /* 0x4E */ SND_LV_STOP_ROPE, + /* 0x4F */ SND_LV_SHAKE_ROPE, + /* 0x50 */ SND_LV_FOOT_MISS, + /* 0x51 */ SND_LV_BREATH, + /* 0x52 */ SND_LV_TAKE_BREATH, + /* 0x53 */ SND_LV_GET_AIR, + /* 0x54 */ SND_LV_DOLPHIN_JUMP, + /* 0x55 */ SND_LV_LIFT_S, + /* 0x56 */ SND_LV_THROW_S, + /* 0x57 */ SND_LV_LIFT_L, + /* 0x58 */ SND_LV_THROW_L, + /* 0x59 */ SND_LV_PUSH_M, + /* 0x5A */ SND_LV_DIG_GLOVE, + /* 0x5B */ SND_LV_SWING_S, + /* 0x5C */ SND_LV_DRINK, + /* 0x5D */ SND_LV_DRINK_FIN, + /* 0x5E */ SND_LV_CLIMB_WALL, + /* 0x5F */ SND_LV_JUMPON_LIFT, + /* 0x60 */ SND_LV_GET_SURPRISND, + /* 0x61 */ SND_LV_FLOATAWAY, + /* 0x62 */ SND_LV_CANNON_JUMP, + /* 0x63 */ SND_LV_FIRE, + /* 0x64 */ SND_LV_LOOK_BODY, + /* 0x65 */ SND_LV_QUICKWATER, + /* 0x66 */ SND_LV_DANGER_ROCK, + /* 0x67 */ SND_LV_PULL_SWORD, + /* 0x68 */ SND_LV_WHIP_BACK, + /* 0x69 */ SND_LV_SW_PUSH, + /* 0x6A */ SND_LV_SW_REJECT, + /* 0x6B */ SND_LV_JUMP_DIVEWATER, + /* 0x6C */ SND_LV_DAMAGE_WATER_M, + /* 0x6D */ SND_LV_DAMAGE_WATER_S, + /* 0x6E */ SND_LV_DAMAGE_ELEC_W, + /* 0x6F */ SND_LV_STRUGGLE_W, + /* 0x70 */ SND_LV_GROAN_W, + /* 0x71 */ SND_LV_ESCAPE_W, + /* 0x72 */ SND_LV_BREATH_TIRED_S_1, + /* 0x73 */ SND_LV_BREATH_TIRED_S_2, + /* 0x74 */ SND_LV_BREATH_TIRED_M, + /* 0x75 */ SND_LV_BREATH_TIRED_L, + /* 0x76 */ SND_LV_LIE_UP, + /* 0x77 */ SND_LV_PRACTICE_PUNCH, + /* 0x78 */ SND_LV_ATTACK_PUNCH, + /* 0x79 */ SND_LV_SURPRISND_S, + /* 0x7A */ SND_LV_SHUTTER_OPEN, + /* 0x7B */ SND_LV_BIRDRACE_REACH, + /* 0x7C */ SND_LV_ATTACK_A, + /* 0x7D */ SND_LV_BADSMELL_TIRED_S_1, + /* 0x7E */ SND_LV_BADSMELL_TIRED_S_2, + /* 0x7F */ SND_LV_BADSMELL_TIRED_M, + /* 0x80 */ SND_LV_BADSMELL_TIRED_L, + /* 0x81 */ SND_LV_GIRA_SWORD_REJECT, + /* 0x82 */ SND_LV_GIRA_SWORD_PULL, + /* 0x83 */ SND_LV_GIRA_GRAPPLE, + /* 0x84 */ SND_LV_SWORD_SIREN_IN, + /* 0x85 */ SND_LV_APPEAR_SURPRISND, + /* 0x86 */ SND_LV_EXIT_SURPRISND, + /* 0x87 */ SND_LV_BIRD_DAMAGE, + /* 0x88 */ SND_LV_BIRD_SPIN, + /* 0x89 */ SND_LV_BIRD_ATTACK, + /* 0x8A */ SND_LV_TRUCK_JUMP, + /* 0x8B */ SND_LV_TRUCK_IN, + /* 0x8C */ SND_LV_TRUCK_BRAKE, + /* 0x8D */ SND_LV_DAMAGE_MUTEKI_S, + /* 0x8E */ SND_LV_DAMAGE_MUTEKI_L, + /* 0x8F */ SND_LV_DAMAGE_MUTEKI_W_S, + /* 0x90 */ SND_LV_DAMAGE_MUTEKI_W_L, + /* 0x91 */ SND_LV_RECOVER_WATER, + /* 0x92 */ SND_LV_SPIN_WATER, + /* 0x93 */ SND_LV_SHOCKED, + /* 0x94 */ SND_LV_LIGHT_SURPRISND, + /* 0x95 */ SND_LV_QUIETLY_S, + /* 0x96 */ SND_LV_QUIETLY_M, + /* 0x97 */ SND_LV_DAMAGE_L_1, + /* 0x98 */ SND_LV_MAX +}; + +class dSndRngLinkVoice_c : public dSndRngIdIf_c { +public: + dSndRngLinkVoice_c(); + + void configure(const dSndLinkVoiceConfig *config, dSndSourcePlayerHead_c *source); + static const dSndLinkVoiceConfig *getConfig(s32 idx); + + /* 0x1C */ bool handleId(u32 id) override; + + s32 getPriority() const { + return mPriority; + } + + bool getPriorityTiebreaker() const { + return mPriorityTiebreaker; + } + +private: + /* 0x2C */ dSndSourcePlayerHead_c *mpSource; + /* 0x30 */ s32 mPriority; + /* 0x34 */ bool mPriorityTiebreaker; +}; + +#endif diff --git a/include/d/snd/d_snd_source_player_head.h b/include/d/snd/d_snd_source_player_head.h index 2307c7b3..e221595c 100644 --- a/include/d/snd/d_snd_source_player_head.h +++ b/include/d/snd/d_snd_source_player_head.h @@ -1,13 +1,69 @@ #ifndef D_SND_SOURCE_PLAYER_HEAD_H #define D_SND_SOURCE_PLAYER_HEAD_H +#include "common.h" +#include "d/snd/d_snd_rng_link_voice.h" #include "d/snd/d_snd_source.h" +#include "nw4r/snd/snd_SoundHandle.h" class dSndSourcePlayerHead_c : public dSoundSource_c { public: dSndSourcePlayerHead_c(s32 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup); - /* 0x15C */ u8 _0x15C[0x22B0 - 0x15C]; + bool startVoiceSoundInternal(u32 id); + + /* 0x0D4 */ virtual bool startVoiceLine(u32 id) override; + + /* 0x0E0 */ virtual void stopCurrentActionSound() override { + mSoundHandle.Stop(2); + field_0x22A0 = SND_LV_MAX; + } + /* 0x0E4 */ virtual void stopActionSound(u32 id) override { + if (isCurrentActionSound(id)) { + stopCurrentActionSound(); + } + } + /* 0x0E8 */ virtual bool isPlayingActionSound() const override { + return mSoundHandle.IsAttachedSound(); + } + /* 0x0EC */ virtual bool isCurrentActionSound(u32 id) const override { + return isPlayingActionSound() && id == mLastPlayedSound; + } + + // TODO - some of these might not be inlines. It's probably possible to implement them + // as not inlines in the source file for the correct order, but maybe when we figure out how + // to fix the order in d_snd_source_mgr we might also be able to fix it here that way. + + /* 0x0D8 */ virtual bool startVoiceLine(const char *label) override { + return false; + } + + /* 0x184 */ virtual void preCalc() override {} + + /* 0x194 */ virtual u32 overrideStartSoundId(u32 soundId) override { + return soundId; + } + + /* 0x1EC */ virtual bool d_vt_0x30() override { + return false; + } + + /* 0x1F0 */ virtual bool vt_1F0() { + return false; + } + + /* 0x1F4 */ virtual UNKWORD d_vt_0x3C() override { + return 1; + } + +private: + void configureVoiceRngs(); + + /* 0x015C */ u8 _0x015C[0x0160 - 0x015C]; + /* 0x0160 */ dSndRngLinkVoice_c mLinkVoiceRngs[SND_LV_MAX]; + /* 0x22A0 */ u32 field_0x22A0; + /* 0x22A4 */ s32 mLastPlayedSound; + /* 0x22A8 */ nw4r::snd::SoundHandle mSoundHandle; }; #endif diff --git a/include/d/snd/d_snd_types.h b/include/d/snd/d_snd_types.h index 2edec499..85632917 100644 --- a/include/d/snd/d_snd_types.h +++ b/include/d/snd/d_snd_types.h @@ -8,8 +8,10 @@ class dSoundSource_c; class dSndSourceGroup_c; class dSndDistantSoundActor_c; + class dSndSourceEnemy_c; class dSndSourceHarpRelated_c; +class dSndSourcePlayerHead_c; class dSndSound_c; diff --git a/src/d/snd/d_snd_harp_song_data.cpp b/src/d/snd/d_snd_harp_song_data.cpp index b5ad90c6..5ea89fe5 100644 --- a/src/d/snd/d_snd_harp_song_data.cpp +++ b/src/d/snd/d_snd_harp_song_data.cpp @@ -2,8 +2,9 @@ #include "common.h" #include "d/snd/d_snd_fi_vocal_mgr.h" +#include "d/snd/d_snd_wzsound.h" -const s32 dSndHarpSongData_c::sNumHarpSongs = 6; +const s32 dSndHarpSongData_c::sNumHarpSongs = LABEL_HARP_TONE_RAW_END - LABEL_HARP_TONE_RAW_START - 1; static const f32 sUnkSongVals[] = { 40.0f, 40.0f, diff --git a/src/d/snd/d_snd_rng_id.cpp b/src/d/snd/d_snd_rng_id.cpp new file mode 100644 index 00000000..dab77371 --- /dev/null +++ b/src/d/snd/d_snd_rng_id.cpp @@ -0,0 +1,152 @@ +#include "d/snd/d_snd_rng_id.h" + +dSndRngId_c::dSndRngId_c() : mIsConfigured(false) {} + +void dSndRngId_c::configure(u32 start, u32 end, u8 genChance) { + mBaseId = start; + mLastPicked = -1; + mPickedMask = 0; + mPickedNum = 0; + mRange = end - start + 1; + mGenChance = genChance; + mIsConfigured = true; +} + + +u32 dSndRngId_c::rndIdNoReuse() { + if (mPickedNum >= mRange) { + return -1; + } + + if (!rndBool(mGenChance)) { + return -1; + } + + u32 result = mLastPicked; + + if (mRange == 1) { + // only one possible ID + return mBaseId; + } else if (mRange == 2) { + // not alternating like below + result = mBaseId + rndInt(2); + } else { + int remaining = mRange - mPickedNum; + if (remaining == 1) { + // find the single last remaining ID + for (int i = 0; i < mRange; i++) { + if (((1 << i) & ~mPickedMask) != 0) { + result = mBaseId + i; + } + } + + } else { + while (mLastPicked == result) { + // pick a remaining ID and find it + int pick = rndInt(remaining); + int j = 0; + for (int i = 0; i < mRange; i++) { + if (((1 << i) & ~mPickedMask) != 0) { + if (j == pick) { + result = mBaseId + i; + } + j++; + } + } + } + } + } + + return result; +} + +u32 dSndRngId_c::nextIdNoReuse() { + if (mPickedNum >= mRange) { + return -1; + } + + if (!rndBool(mGenChance)) { + return -1; + } + + if (mRange == 1) { + // only one possible ID + return mBaseId; + } + + for (int i = 0; i < mRange; i++) { + if (((1 << i) & ~mPickedMask) != 0) { + return mBaseId + i; + } + } + + return -1; +} + +u32 dSndRngId_c::rndId() { + if (!rndBool(mGenChance)) { + return -1; + } + return mBaseId + rndInt(mRange); +} + +u32 dSndRngId_c::rndIdNotSame() { + if (!rndBool(mGenChance)) { + return -1; + } + + u32 last = mLastPicked; + if (mRange == 1) { + // we have to reuse if we only have one ID to pick from + return mBaseId; + } + + u32 result = mLastPicked; + + if (mRange == 2) { + if (last == -1) { + // we haven't generated an ID yet, so pick one of the two at random + result = mBaseId + rndInt(2); + } else { + // we have generated an ID before, so pick the other one now + if (last == mBaseId) { + result = mBaseId + 1; + } else { + result = mBaseId; + } + } + } else { + while (mLastPicked == result) { + result = mBaseId + rndInt(mRange); + } + } + + + return result; +} + +void dSndRngId_c::markPicked(u32 id, bool allowReset) { + if (id != -1 && id >= mBaseId && id < mBaseId + mRange) { + if (mRange >= 2) { + u32 bit = 1 << (id - mBaseId); + if (!(mPickedMask & bit)) { + mPickedMask |= bit; + mPickedNum++; + } + + if (allowReset && mPickedNum >= mRange) { + resetPicked(); + } + mLastPicked = id; + } + } +} + +void dSndRngId_c::resetPicked() { + mPickedMask = 0; + mPickedNum = 0; +} + +u32 dSndRngId_c::rndInt(s32 max) { + return dSndRng_c::rndInt(max); +} diff --git a/src/d/snd/d_snd_rng_id_if.cpp b/src/d/snd/d_snd_rng_id_if.cpp new file mode 100644 index 00000000..7fdf103e --- /dev/null +++ b/src/d/snd/d_snd_rng_id_if.cpp @@ -0,0 +1,17 @@ +#include "d/snd/d_snd_rng_id_if.h" + +bool dSndRngIdIf_c::doNextIdNoReuse() { + return handleId(nextIdNoReuse()); +} + +bool dSndRngIdIf_c::doRndId() { + return handleId(rndId()); +} + +bool dSndRngIdIf_c::doRndIdNoReuse() { + return handleId(rndIdNoReuse()); +} + +bool dSndRngIdIf_c::doRndIdNotSame() { + return handleId(rndIdNotSame()); +} diff --git a/src/d/snd/d_snd_rng_link_voice.cpp b/src/d/snd/d_snd_rng_link_voice.cpp new file mode 100644 index 00000000..058486f8 --- /dev/null +++ b/src/d/snd/d_snd_rng_link_voice.cpp @@ -0,0 +1,346 @@ +#include "d/snd/d_snd_rng_link_voice.h" + +#include "common.h" +#include "d/snd/d_snd_rng_id.h" +#include "d/snd/d_snd_source_player_head.h" +#include "d/snd/d_snd_wzsound.h" + +struct dSndLinkVoiceConfig { + /* 0x00 */ u16 begin; + /* 0x02 */ u16 end; + /* 0x04 */ s16 mGenChance; + /* 0x06 */ s8 priority; + /* 0x07 */ bool priorityTiebreaker; +}; + +static const dSndLinkVoiceConfig sLinkVoiceConfig[] = { + /* SND_LV_PRACTICE_S*/ + { SE_LV_PRACTICE_S_01, SE_LV_PRACTICE_S_ff, 70, 9, false}, + /* SND_LV_PRACTICE_M*/ + { SE_LV_PRACTICE_M_01, SE_LV_PRACTICE_M_ff, 100, 10, false}, + /* SND_LV_PRACTICE_L*/ + { SE_LV_PRACTICE_L_01, SE_LV_PRACTICE_L_ff, 100, 10, false}, + /* SND_LV_PRACTICE_KAITEN_M*/ + {SE_LV_PRACTICE_KAITEN_M_01, SE_LV_PRACTICE_KAITEN_M_ff, 100, 11, false}, + /* SND_LV_ATTACK_S*/ + { SE_LV_ATTACK_S_01, SE_LV_ATTACK_S_ff, 100, 10, false}, + /* SND_LV_ATTACK_M*/ + { SE_LV_ATTACK_M_01, SE_LV_ATTACK_M_ff, 100, 10, false}, + /* SND_LV_ATTACK_L*/ + { SE_LV_ATTACK_L_01, SE_LV_ATTACK_L_ff, 100, 10, false}, + /* SND_LV_SAVE_POWER*/ + { SE_LV_SAVE_POWER_01, SE_LV_SAVE_POWER_ff, 100, 0, false}, + /* SND_LV_ATTACK_KAITEN_M*/ + { SE_LV_ATTACK_KAITEN_M_01, SE_LV_ATTACK_KAITEN_M_ff, 100, 11, false}, + /* SND_LV_NOTICE*/ + { SE_LV_NOTICE_01, SE_LV_NOTICE_ff, 100, 0, false}, + /* SND_LV_PRACTICE_SHIELD*/ + { SE_LV_PRACTICE_SHIELD_01, SE_LV_PRACTICE_SHIELD_ff, 100, 8, false}, + /* SND_LV_ATTACK_SHIELD*/ + { SE_LV_ATTACK_SHIELD_01, SE_LV_ATTACK_SHIELD_ff, 100, 8, false}, + /* SND_LV_ATTACK_SHIELD_GJ*/ + { SE_LV_ATTACK_SHIELD_GJ_01, SE_LV_ATTACK_SHIELD_GJ_ff, 100, 9, false}, + /* SND_LV_SHELD_GUARD*/ + { SE_LV_SHELD_GUARD_01, SE_LV_SHELD_GUARD_ff, 100, 8, false}, + /* SND_LV_SHELD_DOWN*/ + { SE_LV_SHELD_DOWN_01, SE_LV_SHELD_DOWN_ff, 100, 15, false}, + /* SND_LV_SHELD_BREAK*/ + { SE_LV_SHELD_BREAK_01, SE_LV_SHELD_BREAK_ff, 100, 16, false}, + /* SND_LV_ATTACK_DOWN*/ + { SE_LV_ATTACK_DOWN_01, SE_LV_ATTACK_DOWN_ff, 100, 16, false}, + /* SND_LV_DAMAGE_S*/ + { SE_LV_DAMAGE_S_01, SE_LV_DAMAGE_S_ff, 100, 15, false}, + /* SND_LV_DAMAGE_L*/ + { SE_LV_DAMAGE_L_01, SE_LV_DAMAGE_L_ff, 100, 16, false}, + /* SND_LV_DAMAGE_FIRE_S*/ + { SE_LV_DAMAGE_FIRE_S_01, SE_LV_DAMAGE_FIRE_S_ff, 100, 15, false}, + /* SND_LV_DAMAGE_FIRE_L*/ + { SE_LV_DAMAGE_FIRE_L_01, SE_LV_DAMAGE_FIRE_L_ff, 100, 16, false}, + /* SND_LV_DAMAGE_ELEC_S*/ + { SE_LV_DAMAGE_ELEC_S_01, SE_LV_DAMAGE_ELEC_S_ff, 100, 15, false}, + /* SND_LV_DAMAGE_ELEC_L*/ + { SE_LV_DAMAGE_ELEC_L_01, SE_LV_DAMAGE_ELEC_L_ff, 100, 15, false}, + /* SND_LV_STRUGGLE_S*/ + { SE_LV_STRUGGLE_S_01, SE_LV_STRUGGLE_S_ff, 100, 14, false}, + /* SND_LV_STRUGGLE_L*/ + { SE_LV_STRUGGLE_L_01, SE_LV_STRUGGLE_L_ff, 100, 14, false}, + /* SND_LV_GROAN*/ + { SE_LV_GROAN_01, SE_LV_GROAN_ff, 100, 246, false}, + /* SND_LV_ESCAPE*/ + { SE_LV_ESCAPE_01, SE_LV_ESCAPE_ff, 100, 15, true}, + /* SND_LV_DAMAGE_MAGMA*/ + { SE_LV_DAMAGE_MAGMA_01, SE_LV_DAMAGE_MAGMA_ff, 100, 17, false}, + /* SND_LV_DAMAGE_QUICKSAND*/ + { SE_LV_DAMAGE_QUICKSAND_01, SE_LV_DAMAGE_QUICKSAND_ff, 100, 17, false}, + /* SND_LV_DIE_L*/ + { SE_LV_DIE_L_01, SE_LV_DIE_L_ff, 100, 100, true}, + /* SND_LV_DIE_S*/ + { SE_LV_DIE_S_01, SE_LV_DIE_S_ff, 100, 100, true}, + /* SND_LV_DIE_WATER*/ + { SE_LV_DIE_WATER_01, SE_LV_DIE_WATER_ff, 100, 100, true}, + /* SND_LV_RESTART*/ + { SE_LV_RESTART_01, SE_LV_RESTART_ff, 100, 100, true}, + /* SND_LV_STAND_UP*/ + { SE_LV_STAND_UP_01, SE_LV_STAND_UP_ff, 100, 0, false}, + /* SND_LV_PHEW*/ + { SE_LV_PHEW_01, SE_LV_PHEW_ff, 100, 0, false}, + /* SND_LV_TIRED_S*/ + { SE_LV_TIRED_S_01, SE_LV_TIRED_S_ff, 100, 254, true}, + /* SND_LV_TIRED_S*/ + { SE_LV_TIRED_S_01, SE_LV_TIRED_S_ff, 100, 254, true}, + /* SND_LV_TIRED_M*/ + { SE_LV_TIRED_M_01, SE_LV_TIRED_M_ff, 100, 254, true}, + /* SND_LV_TIRED_L*/ + { SE_LV_TIRED_L_01, SE_LV_TIRED_L_ff, 100, 254, true}, + /* SND_LV_CLIMB_TIRED_S*/ + { SE_LV_CLIMB_TIRED_S_01, SE_LV_CLIMB_TIRED_S_ff, 60, 254, false}, + /* SND_LV_CLIMB_TIRED_S*/ + { SE_LV_CLIMB_TIRED_S_01, SE_LV_CLIMB_TIRED_S_ff, 60, 254, false}, + /* SND_LV_CLIMB_TIRED_M*/ + { SE_LV_CLIMB_TIRED_M_01, SE_LV_CLIMB_TIRED_M_ff, 60, 254, false}, + /* SND_LV_CLIMB_TIRED_L*/ + { SE_LV_CLIMB_TIRED_L_01, SE_LV_CLIMB_TIRED_L_ff, 100, 254, false}, + /* SND_LV_LIFT_TIRED_S*/ + { SE_LV_LIFT_TIRED_S_01, SE_LV_LIFT_TIRED_S_ff, 60, 254, false}, + /* SND_LV_LIFT_TIRED_S*/ + { SE_LV_LIFT_TIRED_S_01, SE_LV_LIFT_TIRED_S_ff, 60, 254, false}, + /* SND_LV_LIFT_TIRED_M*/ + { SE_LV_LIFT_TIRED_M_01, SE_LV_LIFT_TIRED_M_ff, 60, 254, false}, + /* SND_LV_LIFT_TIRED_L*/ + { SE_LV_LIFT_TIRED_L_01, SE_LV_LIFT_TIRED_L_ff, 100, 254, false}, + /* SND_LV_TIRED_RECOVER*/ + { SE_LV_TIRED_RECOVER_01, SE_LV_TIRED_RECOVER_ff, 100, 254, true}, + /* SND_LV_TIRED_RECOVER_S*/ + { SE_LV_TIRED_RECOVER_S_01, SE_LV_TIRED_RECOVER_S_ff, 100, 254, true}, + /* SND_LV_TIRED_RECOVER_M*/ + { SE_LV_TIRED_RECOVER_M_01, SE_LV_TIRED_RECOVER_M_ff, 100, 254, true}, + /* SND_LV_TIRED_RECOVER_L*/ + { SE_LV_TIRED_RECOVER_L_01, SE_LV_TIRED_RECOVER_L_ff, 100, 254, true}, + /* SND_LV_TIRED_EMPTY*/ + { SE_LV_TIRED_EMPTY_01, SE_LV_TIRED_EMPTY_ff, 100, 1, true}, + /* SND_LV_PHEW*/ + { SE_LV_PHEW_01, SE_LV_PHEW_ff, 100, 1, true}, + /* SND_LV_JUMP_S*/ + { SE_LV_JUMP_S_01, SE_LV_JUMP_S_ff, 100, 8, false}, + /* SND_LV_JUMP_M*/ + { SE_LV_JUMP_M_01, SE_LV_JUMP_M_ff, 100, 8, false}, + /* SND_LV_JUMP_L*/ + { SE_LV_JUMP_L_01, SE_LV_JUMP_L_ff, 100, 8, false}, + /* SND_LV_SHOOT_START*/ + { SE_LV_SHOOT_START_01, SE_LV_SHOOT_START_ff, 100, 255, false}, + /* SND_LV_SHOOT_SLOPE*/ + { SE_LV_SHOOT_SLOPE_01, SE_LV_SHOOT_SLOPE_ff, 100, 255, false}, + /* SND_LV_RUN_UP*/ + { SE_LV_RUN_UP_01, SE_LV_RUN_UP_ff, 100, 255, false}, + /* SND_LV_GRAB*/ + { SE_LV_GRAB_01, SE_LV_GRAB_ff, 100, 0, false}, + /* SND_LV_CLIMB_STEP*/ + { SE_LV_CLIMB_STEP_01, SE_LV_CLIMB_STEP_ff, 100, 1, false}, + /* SND_LV_HUNG*/ + { SE_LV_HUNG_01, SE_LV_HUNG_ff, 100, 0, false}, + /* SND_LV_JUMP_IVY*/ + { SE_LV_JUMP_IVY_01, SE_LV_JUMP_IVY_ff, 100, 0, true}, + /* SND_LV_BACKFLIP*/ + { SE_LV_BACKFLIP_01, SE_LV_BACKFLIP_ff, 70, 0, false}, + /* SND_LV_ZENTEN*/ + { SE_LV_ZENTEN_01, SE_LV_ZENTEN_ff, 100, 0, false}, + /* SND_LV_ZENTEN_CLASH*/ + { SE_LV_ZENTEN_CLASH_01, SE_LV_ZENTEN_CLASH_ff, 100, 14, false}, + /* SND_LV_ZENTEN_UP*/ + { SE_LV_ZENTEN_UP_01, SE_LV_ZENTEN_UP_ff, 100, 247, true}, + /* SND_LV_FALLING_HIGH*/ + { SE_LV_FALLING_HIGH_01, SE_LV_FALLING_HIGH_ff, 100, 15, true}, + /* SND_LV_DAMAGE_FALL*/ + { SE_LV_DAMAGE_FALL_01, SE_LV_DAMAGE_FALL_ff, 100, 15, true}, + /* SND_LV_SKYDIVE*/ + { SE_LV_SKYDIVE_01, SE_LV_SKYDIVE_ff, 100, 0, false}, + /* SND_LV_RIDE_BIRD*/ + { SE_LV_RIDE_BIRD_01, SE_LV_RIDE_BIRD_ff, 100, 0, true}, + /* SND_LV_BLAST*/ + { SE_LV_BLAST_01, SE_LV_BLAST_ff, 100, 0, false}, + /* SND_LV_WIND_FLY*/ + { SE_LV_WIND_FLY_01, SE_LV_WIND_FLY_ff, 100, 0, false}, + /* SND_LV_BALANCE_BALL*/ + { SE_LV_BALANCE_BALL_01, SE_LV_BALANCE_BALL_ff, 100, 0, false}, + /* SND_LV_SLIDE_START*/ + { SE_LV_SLIDE_START_01, SE_LV_SLIDE_START_ff, 100, 255, false}, + /* SND_LV_CLIMB_ROPE*/ + { SE_LV_CLIMB_ROPE_01, SE_LV_CLIMB_ROPE_ff, 60, 0, false}, + /* SND_LV_SWING_ROPE*/ + { SE_LV_SWING_ROPE_01, SE_LV_SWING_ROPE_ff, 100, 0, false}, + /* SND_LV_JUMP_ROPE*/ + { SE_LV_JUMP_ROPE_01, SE_LV_JUMP_ROPE_ff, 100, 0, false}, + /* SND_LV_STOP_ROPE*/ + { SE_LV_STOP_ROPE_01, SE_LV_STOP_ROPE_ff, 100, 0, false}, + /* SND_LV_SHAKE_ROPE*/ + { SE_LV_SHAKE_ROPE_01, SE_LV_SHAKE_ROPE_ff, 100, 0, false}, + /* SND_LV_FOOT_MISS*/ + { SE_LV_FOOT_MISS_01, SE_LV_FOOT_MISS_ff, 100, 0, false}, + /* SND_LV_BREATH*/ + { SE_LV_BREATH_01, SE_LV_BREATH_ff, 100, 0, false}, + /* SND_LV_TAKE_BREATH*/ + { SE_LV_TAKE_BREATH_01, SE_LV_TAKE_BREATH_ff, 100, 0, false}, + /* SND_LV_GET_AIR*/ + { SE_LV_GET_AIR_01, SE_LV_GET_AIR_ff, 100, 0, false}, + /* SND_LV_DOLPHIN_JUMP*/ + { SE_LV_DOLPHIN_JUMP_01, SE_LV_DOLPHIN_JUMP_ff, 100, 0, false}, + /* SND_LV_LIFT_S*/ + { SE_LV_LIFT_S_01, SE_LV_LIFT_S_ff, 100, 0, false}, + /* SND_LV_THROW_S*/ + { SE_LV_THROW_S_01, SE_LV_THROW_S_ff, 100, 0, false}, + /* SND_LV_LIFT_L*/ + { SE_LV_LIFT_L_01, SE_LV_LIFT_L_ff, 100, 0, false}, + /* SND_LV_THROW_L*/ + { SE_LV_THROW_L_01, SE_LV_THROW_L_ff, 100, 0, false}, + /* SND_LV_PUSH_M*/ + { SE_LV_PUSH_M_01, SE_LV_PUSH_M_ff, 100, 0, false}, + /* SND_LV_DIG_GLOVE*/ + { SE_LV_DIG_GLOVE_01, SE_LV_DIG_GLOVE_ff, 100, 0, false}, + /* SND_LV_SWING_S*/ + { SE_LV_SWING_S_01, SE_LV_SWING_S_ff, 100, 0, false}, + /* SND_LV_DRINK*/ + { SE_LV_DRINK_01, SE_LV_DRINK_ff, 100, 0, false}, + /* SND_LV_DRINK_FIN*/ + { SE_LV_DRINK_FIN_01, SE_LV_DRINK_FIN_ff, 100, 255, false}, + /* SND_LV_CLIMB_WALL*/ + { SE_LV_CLIMB_WALL_01, SE_LV_CLIMB_WALL_ff, 60, 254, false}, + /* SND_LV_JUMPON_LIFT*/ + { SE_LV_JUMPON_LIFT_01, SE_LV_JUMPON_LIFT_ff, 100, 0, false}, + /* SND_LV_GET_SURPRISND*/ + { SE_LV_GET_SURPRISE_01, SE_LV_GET_SURPRISE_ff, 100, 0, false}, + /* SND_LV_FLOATAWAY*/ + { SE_LV_FLOATAWAY_01, SE_LV_FLOATAWAY_ff, 100, 0, false}, + /* SND_LV_CANNON_JUMP*/ + { SE_LV_CANNON_JUMP_01, SE_LV_CANNON_JUMP_ff, 100, 0, false}, + /* SND_LV_FIRE*/ + { SE_LV_FIRE_01, SE_LV_FIRE_ff, 100, 0, false}, + /* SND_LV_LOOK_BODY*/ + { SE_LV_LOOK_BODY_01, SE_LV_LOOK_BODY_ff, 100, 0, false}, + /* SND_LV_QUICKWATER*/ + { SE_LV_QUICKWATER_01, SE_LV_QUICKWATER_ff, 60, 0, false}, + /* SND_LV_DANGER_ROCK*/ + { SE_LV_DANGER_ROCK_01, SE_LV_DANGER_ROCK_ff, 100, 0, false}, + /* SND_LV_PULL_SWORD*/ + { SE_LV_PULL_SWORD_01, SE_LV_PULL_SWORD_ff, 100, 0, false}, + /* SND_LV_WHIP_BACK*/ + { SE_LV_WHIP_BACK_01, SE_LV_WHIP_BACK_ff, 100, 0, false}, + /* SND_LV_SW_PUSH*/ + { SE_LV_SW_PUSH_01, SE_LV_SW_PUSH_ff, 100, 0, false}, + /* SND_LV_SW_REJECT*/ + { SE_LV_SW_REJECT_01, SE_LV_SW_REJECT_ff, 100, 0, false}, + /* SND_LV_JUMP_DIVEWATER*/ + { SE_LV_JUMP_DIVEWATER_01, SE_LV_JUMP_DIVEWATER_ff, 100, 0, false}, + /* SND_LV_DAMAGE_WATER_M*/ + { SE_LV_DAMAGE_WATER_M_01, SE_LV_DAMAGE_WATER_M_ff, 100, 16, false}, + /* SND_LV_DAMAGE_WATER_S*/ + { SE_LV_DAMAGE_WATER_S_01, SE_LV_DAMAGE_WATER_S_ff, 100, 15, false}, + /* SND_LV_DAMAGE_ELEC_W*/ + { SE_LV_DAMAGE_ELEC_W_01, SE_LV_DAMAGE_ELEC_W_ff, 100, 15, false}, + /* SND_LV_STRUGGLE_W*/ + { SE_LV_STRUGGLE_W_01, SE_LV_STRUGGLE_W_ff, 100, 0, false}, + /* SND_LV_GROAN_W*/ + { SE_LV_GROAN_W_01, SE_LV_GROAN_W_ff, 100, 0, false}, + /* SND_LV_ESCAPE_W*/ + { SE_LV_ESCAPE_W_01, SE_LV_ESCAPE_W_ff, 100, 0, false}, + /* SND_LV_BREATH_TIRED_S*/ + { SE_LV_BREATH_TIRED_S_01, SE_LV_BREATH_TIRED_S_ff, 100, 254, false}, + /* SND_LV_BREATH_TIRED_S*/ + { SE_LV_BREATH_TIRED_S_01, SE_LV_BREATH_TIRED_S_ff, 30, 254, false}, + /* SND_LV_BREATH_TIRED_M*/ + { SE_LV_BREATH_TIRED_M_01, SE_LV_BREATH_TIRED_M_ff, 60, 254, false}, + /* SND_LV_BREATH_TIRED_L*/ + { SE_LV_BREATH_TIRED_L_01, SE_LV_BREATH_TIRED_L_ff, 100, 254, false}, + /* SND_LV_LIE_UP*/ + { SE_LV_LIE_UP_01, SE_LV_LIE_UP_ff, 100, 0, false}, + /* SND_LV_PRACTICE_PUNCH*/ + { SE_LV_PRACTICE_PUNCH_01, SE_LV_PRACTICE_PUNCH_ff, 100, 0, false}, + /* SND_LV_ATTACK_PUNCH*/ + { SE_LV_ATTACK_PUNCH_01, SE_LV_ATTACK_PUNCH_ff, 100, 0, false}, + /* SND_LV_SURPRISND_S*/ + { SE_LV_SURPRISE_S_01, SE_LV_SURPRISE_S_ff, 100, 0, false}, + /* SND_LV_SHUTTER_OPEN*/ + { SE_LV_SHUTTER_OPEN_01, SE_LV_SHUTTER_OPEN_ff, 100, 0, false}, + /* SND_LV_BIRDRACE_REACH*/ + { SE_LV_BIRDRACE_REACH_01, SE_LV_BIRDRACE_REACH_ff, 100, 10, false}, + /* SND_LV_ATTACK_A*/ + { SE_LV_ATTACK_A_01, SE_LV_ATTACK_A_ff, 100, 0, false}, + /* SND_LV_BADSMELL_TIRED_S*/ + { SE_LV_BADSMELL_TIRED_S_01, SE_LV_BADSMELL_TIRED_S_ff, 100, 254, false}, + /* SND_LV_BADSMELL_TIRED_S*/ + { SE_LV_BADSMELL_TIRED_S_01, SE_LV_BADSMELL_TIRED_S_ff, 50, 254, false}, + /* SND_LV_BADSMELL_TIRED_M*/ + { SE_LV_BADSMELL_TIRED_M_01, SE_LV_BADSMELL_TIRED_M_ff, 60, 254, false}, + /* SND_LV_BADSMELL_TIRED_L*/ + { SE_LV_BADSMELL_TIRED_L_01, SE_LV_BADSMELL_TIRED_L_ff, 100, 254, false}, + /* SND_LV_GIRA_SWORD_REJECT*/ + {SE_LV_GIRA_SWORD_REJECT_01, SE_LV_GIRA_SWORD_REJECT_ff, 100, 0, false}, + /* SND_LV_GIRA_SWORD_PULL*/ + { SE_LV_GIRA_SWORD_PULL_01, SE_LV_GIRA_SWORD_PULL_ff, 100, 0, false}, + /* SND_LV_GIRA_GRAPPLE*/ + { SE_LV_GIRA_GRAPPLE_01, SE_LV_GIRA_GRAPPLE_ff, 100, 0, false}, + /* SND_LV_SWORD_SIREN_IN*/ + { SE_LV_SWORD_SIREN_IN_01, SE_LV_SWORD_SIREN_IN_ff, 100, 0, false}, + /* SND_LV_APPEAR_SURPRISND*/ + { SE_LV_APPEAR_SURPRISE_01, SE_LV_APPEAR_SURPRISE_ff, 100, 0, false}, + /* SND_LV_EXIT_SURPRISND*/ + { SE_LV_EXIT_SURPRISE_01, SE_LV_EXIT_SURPRISE_ff, 100, 0, false}, + /* SND_LV_BIRD_DAMAGE*/ + { SE_LV_BIRD_DAMAGE_01, SE_LV_BIRD_DAMAGE_ff, 100, 15, false}, + /* SND_LV_BIRD_SPIN*/ + { SE_LV_BIRD_SPIN_01, SE_LV_BIRD_SPIN_ff, 100, 10, false}, + /* SND_LV_BIRD_ATTACK*/ + { SE_LV_BIRD_ATTACK_01, SE_LV_BIRD_ATTACK_ff, 100, 9, false}, + /* SND_LV_TRUCK_JUMP*/ + { SE_LV_TRUCK_JUMP_01, SE_LV_TRUCK_JUMP_ff, 100, 0, false}, + /* SND_LV_TRUCK_IN*/ + { SE_LV_TRUCK_IN_01, SE_LV_TRUCK_IN_ff, 100, 0, false}, + /* SND_LV_TRUCK_BRAKE*/ + { SE_LV_TRUCK_BRAKE_01, SE_LV_TRUCK_BRAKE_ff, 100, 0, false}, + /* SND_LV_DAMAGE_MUTEKI_S*/ + { SE_LV_DAMAGE_MUTEKI_S_01, SE_LV_DAMAGE_MUTEKI_S_ff, 100, 15, false}, + /* SND_LV_DAMAGE_MUTEKI_L*/ + { SE_LV_DAMAGE_MUTEKI_L_01, SE_LV_DAMAGE_MUTEKI_L_ff, 100, 15, false}, + /* SND_LV_DAMAGE_MUTEKI_W_S*/ + {SE_LV_DAMAGE_MUTEKI_W_S_01, SE_LV_DAMAGE_MUTEKI_W_S_ff, 100, 15, false}, + /* SND_LV_DAMAGE_MUTEKI_W_L*/ + {SE_LV_DAMAGE_MUTEKI_W_L_01, SE_LV_DAMAGE_MUTEKI_W_L_ff, 100, 15, false}, + /* SND_LV_RECOVER_WATER*/ + { SE_LV_RECOVER_WATER_01, SE_LV_RECOVER_WATER_ff, 100, 100, true}, + /* SND_LV_SPIN_WATER*/ + { SE_LV_SPIN_WATER_01, SE_LV_SPIN_WATER_ff, 100, 8, false}, + /* SND_LV_SHOCKED*/ + { SE_LV_SHOCKED_01, SE_LV_SHOCKED_ff, 100, 14, false}, + /* SND_LV_LIGHT_SURPRISND*/ + { SE_LV_LIGHT_SURPRISE_01, SE_LV_LIGHT_SURPRISE_ff, 100, 0, false}, + /* SND_LV_QUIETLY_S*/ + { SE_LV_QUIETLY_S_01, SE_LV_QUIETLY_S_ff, 60, 0, false}, + /* SND_LV_QUIETLY_M*/ + { SE_LV_QUIETLY_M_01, SE_LV_QUIETLY_M_ff, 60, 0, false}, + /* SND_LV_DAMAGE_L*/ + { SE_LV_DAMAGE_L_01, SE_LV_DAMAGE_L_ff, 100, 17, false}, +}; + +dSndRngLinkVoice_c::dSndRngLinkVoice_c() {} + +void dSndRngLinkVoice_c::configure(const dSndLinkVoiceConfig *config, dSndSourcePlayerHead_c *source) { + dSndRngId_c::configure(config->begin, config->end, config->mGenChance); + mPriority = config->priority; + mPriorityTiebreaker = config->priorityTiebreaker; + mpSource = source; +} + +bool dSndRngLinkVoice_c::handleId(u32 id) { + if (mpSource == nullptr) { + return false; + } + + bool ok = mpSource->startVoiceSoundInternal(id); + if (ok) { + markPicked(id, true); + } + return ok; +} + +const dSndLinkVoiceConfig *dSndRngLinkVoice_c::getConfig(s32 idx) { + return &sLinkVoiceConfig[idx]; +} diff --git a/src/d/snd/d_snd_source_player_head.cpp b/src/d/snd/d_snd_source_player_head.cpp new file mode 100644 index 00000000..ef077563 --- /dev/null +++ b/src/d/snd/d_snd_source_player_head.cpp @@ -0,0 +1,166 @@ +#include "d/snd/d_snd_source_player_head.h" + +#include "common.h" +#include "d/d_player_act.h" +#include "d/snd/d_snd_rng_link_voice.h" +#include "d/snd/d_snd_wzsound.h" + +dSndSourcePlayerHead_c::dSndSourcePlayerHead_c( + s32 sourceType, dAcBase_c *ac, const char *name, dSndSourceGroup_c *pOwnerGroup +) + : dSoundSource_c(sourceType, ac, name, pOwnerGroup) { + configureVoiceRngs(); +} + +void dSndSourcePlayerHead_c::configureVoiceRngs() { + field_0x22A0 = SND_LV_MAX; + mLastPlayedSound = SND_LV_MAX; + + for (int i = 0; i < SND_LV_MAX; i++) { + mLinkVoiceRngs[i].configure(dSndRngLinkVoice_c::getConfig(i), this); + } +} + +bool dSndSourcePlayerHead_c::startVoiceLine(u32 id) { + // id might be a sound ID, or it might be the ID of one of our RNGs + if (id > LABEL_LV_START && id < LABEL_LV_END) { + return startVoiceSoundInternal(id); + } + + if (id >= SND_LV_MAX) { + return false; + } + + if (checkFlag(1)) { + switch (id) { + case SND_LV_JUMP_S: + case SND_LV_SHOOT_START: + case SND_LV_SHOOT_SLOPE: + case SND_LV_RUN_UP: + case SND_LV_CLIMB_STEP: + case SND_LV_BACKFLIP: + case SND_LV_CLIMB_WALL: { + id = SND_LV_QUIETLY_S; + break; + } + case SND_LV_JUMP_M: + case SND_LV_JUMP_L: + case SND_LV_ZENTEN: { + id = SND_LV_QUIETLY_M; + break; + } + case SND_LV_GRAB: + case SND_LV_HUNG: { + return false; + } + } + } + + f32 stamina = daPlayerActBase_c::getStamina(); + switch (id) { + case SND_LV_TIRED_S_1: { + if (stamina < 0.25) { + id = SND_LV_TIRED_L; + } else if (stamina < 0.5) { + id = SND_LV_TIRED_M; + } else if (stamina < 0.8) { + id = SND_LV_TIRED_S_2; + } else { + return false; + } + break; + } + case SND_LV_CLIMB_TIRED_S_1: { + if (stamina < 0.125) { + id = SND_LV_CLIMB_TIRED_L; + } else if (stamina < 0.375) { + id = SND_LV_CLIMB_TIRED_M; + } else { + return false; + } + break; + } + case SND_LV_LIFT_TIRED_S_1: { + if (stamina < 0.125) { + id = SND_LV_LIFT_TIRED_L; + } else if (stamina < 0.375) { + id = SND_LV_LIFT_TIRED_M; + } else { + return false; + } + break; + } + case SND_LV_TIRED_RECOVER: { + if (stamina > 0.75) { + id = SND_LV_TIRED_RECOVER_S; + } else if (stamina > 0.5) { + id = SND_LV_TIRED_RECOVER_M; + } else if (stamina > 0.375) { + id = SND_LV_TIRED_RECOVER_L; + } + break; + } + + case SND_LV_BREATH_TIRED_S_1: { + if (stamina <= 0.0f) { + id = SND_LV_BREATH_TIRED_L; + } else if (stamina < 0.125) { + id = SND_LV_BREATH_TIRED_M; + } else if (stamina < 0.25) { + id = SND_LV_BREATH_TIRED_S_2; + } else { + return false; + } + break; + } + + case SND_LV_BADSMELL_TIRED_S_1: { + if (stamina < 0.125) { + id = SND_LV_BADSMELL_TIRED_L; + } else if (stamina < 0.375) { + id = SND_LV_BADSMELL_TIRED_M; + } else if (stamina < 0.99) { + id = SND_LV_BADSMELL_TIRED_S_2; + } else { + return false; + } + break; + } + + case SND_LV_DIE_WATER: + case SND_LV_DAMAGE_WATER_M: + case SND_LV_DAMAGE_WATER_S: + case SND_LV_DAMAGE_ELEC_W: startSound(SE_L_WATER_AIR_OUT); break; + } + + if (mLastPlayedSound != SND_LV_MAX && isPlayingActionSound()) { + s32 oldPriority = mLinkVoiceRngs[mLastPlayedSound].getPriority(); + s32 newPriority = mLinkVoiceRngs[id].getPriority(); + + if (oldPriority > newPriority) { + return false; + } + + if (oldPriority == newPriority && !mLinkVoiceRngs[id].getPriorityTiebreaker()) { + return false; + } + } + + field_0x22A0 = id; + bool ok = mLinkVoiceRngs[id].doRndIdNoReuse(); + if (ok) { + mLastPlayedSound = id; + } + + return ok; +} + +bool dSndSourcePlayerHead_c::startVoiceSoundInternal(u32 id) { + bool ok = false; + // @bug shouldn't this be > and < ? + if (id >= LABEL_LV_START && id <= LABEL_LV_END) { + ok = startSound(id, &mSoundHandle) != nullptr; + field_0x22A0 = SND_LV_MAX; + } + return ok; +}