A little bit

This commit is contained in:
robojumper
2025-06-15 00:24:13 +02:00
parent d3d5b57363
commit 7d333a8d8e
11 changed files with 193 additions and 36 deletions
+6 -6
View File
@@ -20477,7 +20477,7 @@ fn_803706E0 = .text:0x803706E0; // type:function size:0x24
fn_80370710 = .text:0x80370710; // type:function size:0x64
beginBgmBattleRoom__12dSndBgmMgr_cFv = .text:0x80370780; // type:function size:0x54
endBgmBattleRoom__12dSndBgmMgr_cFv = .text:0x803707E0; // type:function size:0x60
fn_80370840 = .text:0x80370840; // type:function size:0x78
isPlayingAnyBattleMusic__12dSndBgmMgr_cFv = .text:0x80370840; // type:function size:0x78
fn_803708C0 = .text:0x803708C0; // type:function size:0x34
fn_80370900 = .text:0x80370900; // type:function size:0xA0
fn_803709A0 = .text:0x803709A0; // type:function size:0xA8
@@ -20834,7 +20834,7 @@ remove__38SndMgrDisposer<20dSndSmallEffectMgr_c>Fv = .text:0x8037D8D0; // type:f
__ct__20dSndSmallEffectMgr_cFv = .text:0x8037D8E0; // type:function size:0x9C
__ct__Q34nw4r3snd11SoundHandleFv = .text:0x8037D980; // type:function size:0xC
fn_8037D990 = .text:0x8037D990; // type:function size:0x4
fn_8037D9A0 = .text:0x8037D9A0; // type:function size:0xA0
calc__20dSndSmallEffectMgr_cFv = .text:0x8037D9A0; // type:function size:0xA0
fn_8037DA40 = .text:0x8037DA40; // type:function size:0x18
fn_8037DA60 = .text:0x8037DA60; // type:function size:0x70
fn_8037DAD0 = .text:0x8037DAD0; // type:function size:0xDC
@@ -20846,9 +20846,9 @@ playSound__20dSndSmallEffectMgr_cFUl = .text:0x8037DED0; // type:function size:0
playSoundWithPan__20dSndSmallEffectMgr_cFUlf = .text:0x8037E1A0; // type:function size:0x90
fn_8037E230 = .text:0x8037E230; // type:function size:0xEC
playSoundInternal__20dSndSmallEffectMgr_cFUl = .text:0x8037E320; // type:function size:0x78
fn_8037E3A0 = .text:0x8037E3A0; // type:function size:0x158
getHoldSoundHandle__20dSndSmallEffectMgr_cFUl = .text:0x8037E3A0; // type:function size:0x158
fn_8037E500 = .text:0x8037E500; // type:function size:0x58
playSoundWithPitch__20dSndSmallEffectMgr_cFUlf = .text:0x8037E560; // type:function size:0xBC
holdSoundWithPitch__20dSndSmallEffectMgr_cFUlf = .text:0x8037E560; // type:function size:0xBC
fn_8037E620 = .text:0x8037E620; // type:function size:0xDC
fn_8037E700 = .text:0x8037E700; // type:function size:0x8
fn_8037E710 = .text:0x8037E710; // type:function size:0x8
@@ -20865,7 +20865,7 @@ fn_8037EAD0 = .text:0x8037EAD0; // type:function size:0x40
fn_8037EB10 = .text:0x8037EB10; // type:function size:0x11C
fn_8037EC30 = .text:0x8037EC30; // type:function size:0x8
fn_8037EC40 = .text:0x8037EC40; // type:function size:0x3C
fn_8037EC80 = .text:0x8037EC80; // type:function size:0xB0
playSkbSound__20dSndSmallEffectMgr_cFUl = .text:0x8037EC80; // type:function size:0xB0
fn_8037ED30 = .text:0x8037ED30; // type:function size:0x68
stopSounds__20dSndSmallEffectMgr_cFUlUll = .text:0x8037EDA0; // type:function size:0xA0
__cl__12SoundStopperFRQ34nw4r3snd11SoundHandle = .text:0x8037EE40; // type:function size:0x3C
@@ -20875,7 +20875,7 @@ isPlayingSound__20dSndSmallEffectMgr_cFUl = .text:0x8037EFA0; // type:function s
playButtonPressSoundWhenAdvancingTextBoxes__20dSndSmallEffectMgr_cFf = .text:0x8037F020; // type:function size:0xB4
resetButtonPressSound__20dSndSmallEffectMgr_cFv = .text:0x8037F0E0; // type:function size:0xC
setButtonPressSound__20dSndSmallEffectMgr_cFP14dSoundSource_c = .text:0x8037F0F0; // type:function size:0x60
fn_8037F150 = .text:0x8037F150; // type:function size:0x6D0
playBattleHitSound__20dSndSmallEffectMgr_cFQ220dSndSmallEffectMgr_c16BattleHitSound_eP14dSoundSource_c = .text:0x8037F150; // type:function size:0x6D0
getName__14dSoundSource_cCFv = .text:0x8037F820; // type:function size:0x8
getSourceType__14dSoundSource_cCFv = .text:0x8037F830; // type:function size:0x8
fn_8037F840 = .text:0x8037F840; // type:function size:0x74
+2
View File
@@ -64,6 +64,8 @@ public:
/** Runs when the fight is over, no matter how you started it */
bool endBgmBattleRoom();
bool isPlayingAnyBattleMusic();
private:
bool stopBgmSound(dSndBgmSound_c *sound, s32 fadeFrames);
void checkForPrepareStoppedBgmSound(u32 stoppedSoundId);
+32 -10
View File
@@ -15,18 +15,37 @@ SND_DISPOSER_FORWARD_DECL(dSndSmallEffectMgr_c);
class dSndSmallEffectMgr_c {
SND_DISPOSER_MEMBERS(dSndSmallEffectMgr_c)
static const s32 NUM_DELAYED_SOUNDS = 2;
static const s32 NUM_HOLD_SOUNDS = 3;
public:
enum BattleHitSound_e {
BATTLE_TUTTI_NORMAL = 0,
BATTLE_TUTTI_TURN = 1,
BATTLE_TUTTI_JUMP = 2,
BATTLE_TUTTI_FINISH = 3,
BATTLE_TUTTI_GUARDJUST = 5,
};
dSndSmallEffectMgr_c();
void calc();
bool playSound(u32 soundId);
// used for clawshots cursor, pan depends on where on the screen
// your cursor is when it activates
bool playSoundWithPan(u32 soundId, f32 pan);
void playSoundWithPitch(u32 soundId, f32 pitch);
void holdSoundWithPitch(u32 soundId, f32 pitch);
bool playSkbSound(u32 soundId);
bool playButtonPressSoundWhenAdvancingTextBoxes(f32);
void resetButtonPressSound();
void setButtonPressSound(dSoundSource_c *source);
void playSound(u32 soundId, nw4r::snd::SoundHandle *handle);
bool playBattleHitSound(BattleHitSound_e type, dSoundSource_c *source);
private:
bool playSoundInternal(u32 soundId);
void stopSounds(u32 playerIdx, u32 soundId, s32 fadeFrames);
@@ -34,20 +53,23 @@ private:
bool isPlayingSound(u32 playerIdx, u32 soundId);
bool isPlayingSound(u32 soundId);
/* 0x10 */ nw4r::snd::SoundHandle mHandle1;
/**
* Finds a sound handle currently playing the given sound,
* or an idle sound handle,
* or stops a lower-priority sound if needed and possible.
*/
nw4r::snd::SoundHandle *getHoldSoundHandle(u32 soundId);
/* 0x10 */ s32 field_0x10;
// used for most sounds
/* 0x14 */ nw4r::snd::SoundHandle mNormalSound;
/* 0x18 */ nw4r::snd::SoundHandle mHandle3;
// apparently used for shield gauge sounds, but maybe not given
// that the callers appear unreachable
/* 0x1C */ nw4r::snd::SoundHandle mShieldGaugeHandles[3];
/* 0x1C */ nw4r::snd::SoundHandle mHoldSoundHandles[NUM_HOLD_SOUNDS];
/* 0x28 */ s32 field_0x28;
/* 0x2C */ s32 field_0x2C;
/* 0x30 */ s32 field_0x30;
/* 0x34 */ s32 field_0x34;
/* 0x28 */ u32 mDelayedSoundIds[NUM_DELAYED_SOUNDS];
/* 0x30 */ s32 mDelayedSoundTimers[NUM_DELAYED_SOUNDS];
/* 0x38 */ u32 mTextboxAdvanceSound;
/* 0x3C */ nw4r::snd::SoundHandle mHandle4;
/* 0x3C */ nw4r::snd::SoundHandle mBattleTuttiHandle;
/* 0x40 */ u16 field_0x40;
/* 0x42 */ u16 field_0x42;
/* 0x44 */ s32 field_0x44;
+3 -6
View File
@@ -10,8 +10,6 @@
#include "nw4r/snd/snd_SoundStartable.h"
#include "nw4r/ut/ut_list.h"
#include <cstring>
/** Manages sound relating to a particular actor. */
/** Size: probably 0x15C */
class dSoundSource_c : public dSoundSourceIf_c, public dSnd3DActor_c {
@@ -28,10 +26,9 @@ public:
// 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; // 0x17C
bool isName(const char *name) const {
return !std::strcmp(getName(), name);
}
virtual const char *getName() const {
return mpName;
} // 0x17C
virtual void d_s_vt_0x180();
virtual void d_s_vt_0x184();
virtual void d_s_vt_0x188();
+1
View File
@@ -33,6 +33,7 @@ enum SoundSourceType_e {
SND_SOURCE_TIME_STONE = 37,
SND_SOURCE_CLEF = 38,
SND_SOURCE_SHUTTER = 39,
SND_SOURCE_OBJECT_40 = 40,
SND_SOURCE_OBJECT_42 = 42,
// 43-52: Npc (4)
+6
View File
@@ -4,6 +4,12 @@
#include "common.h"
#include "egg/core/eggDisposer.h"
#include <cstring>
inline bool streq(const char *left, const char *right) {
return !std::strcmp(left, right);
}
// This setup is only inferred. d/snd uses it all over the place.
// This works for dSndPlayerMgr_c, which has a vtable of its own but the Disposer at offset 0.
// It also works for the factory at 0x80399c20, which calls a base class ctor,
+6
View File
@@ -36,6 +36,12 @@ namespace nw4r { namespace snd
void DetachSound();
u32 GetTick() const {
if (IsAttachedSound())
return mSound->GetTick();
return 0;
}
void WriteVariable(int varNo, s16 value) {
if (IsAttachedSound())
mSound->WriteVariable(varNo, value);
+2 -2
View File
@@ -181,13 +181,13 @@ bool dLytMeterShieldGauge_c::execute() {
if (mCurrentDurability >= mMaxDurability) {
if (field_0x31E) {
// Unreachable?
dSndSmallEffectMgr_c::GetInstance()->playSoundWithPitch(SE_S_GAUGE_SHIELD_UP_LV, 1.0f);
dSndSmallEffectMgr_c::GetInstance()->holdSoundWithPitch(SE_S_GAUGE_SHIELD_UP_LV, 1.0f);
}
dSndSmallEffectMgr_c::GetInstance()->playSound(SE_S_GAUGE_SHIELD_UP_MAX);
} else {
if (field_0x31E) {
// Unreachable?
dSndSmallEffectMgr_c::GetInstance()->playSoundWithPitch(
dSndSmallEffectMgr_c::GetInstance()->holdSoundWithPitch(
SE_S_GAUGE_SHIELD_UP_LV, mCurrentDurability / mMaxDurability
);
}
+133 -7
View File
@@ -1,11 +1,13 @@
#include "d/snd/d_snd_small_effect_mgr.h"
#include "common.h"
#include "d/snd/d_snd_bgm_mgr.h"
#include "d/snd/d_snd_checkers.h"
#include "d/snd/d_snd_control_player_mgr.h"
#include "d/snd/d_snd_mgr.h"
#include "d/snd/d_snd_player_mgr.h"
#include "d/snd/d_snd_source.h"
#include "d/snd/d_snd_source_if.h"
#include "d/snd/d_snd_source_enums.h"
#include "d/snd/d_snd_util.h"
#include "d/snd/d_snd_wzsound.h"
#include "nw4r/snd/snd_SeqSoundHandle.h"
@@ -14,12 +16,26 @@
SND_DISPOSER_DEFINE(dSndSmallEffectMgr_c)
dSndSmallEffectMgr_c::dSndSmallEffectMgr_c() : mTextboxAdvanceSound(-1), field_0x40(0), field_0x42(0), field_0x44(0) {
// probably arrays
field_0x28 = -1;
field_0x30 = 0;
field_0x2C = -1;
field_0x34 = 0;
dSndSmallEffectMgr_c::dSndSmallEffectMgr_c()
: field_0x10(0), mTextboxAdvanceSound(-1), field_0x40(0), field_0x42(0), field_0x44(0) {
for (int i = 0; i < NUM_DELAYED_SOUNDS; i++) {
mDelayedSoundIds[i] = -1;
mDelayedSoundTimers[i] = 0;
}
}
void dSndSmallEffectMgr_c::calc() {
if (!dSndPlayerMgr_c::GetInstance()->checkFlag(0x4)) {
for (int i = 0; i < NUM_DELAYED_SOUNDS; i++) {
if (mDelayedSoundIds[i] != -1) {
mDelayedSoundTimers[i]--;
if (mDelayedSoundTimers[i] <= 0) {
playSound(mDelayedSoundIds[i], nullptr);
mDelayedSoundIds[i] = -1;
}
}
}
}
}
bool dSndSmallEffectMgr_c::playSound(u32 soundId) {
@@ -132,6 +148,57 @@ bool dSndSmallEffectMgr_c::playSoundWithPan(u32 soundId, f32 pan) {
return ok;
}
nw4r::snd::SoundHandle *dSndSmallEffectMgr_c::getHoldSoundHandle(u32 soundId) {
// Find an existing handle holding this sound
for (int i = 0; i < NUM_HOLD_SOUNDS; i++) {
nw4r::snd::SoundHandle *h = &mHoldSoundHandles[i];
if (h->GetId() == soundId) {
return h;
}
}
// Find a free handle
for (int i = 0; i < NUM_HOLD_SOUNDS; i++) {
nw4r::snd::SoundHandle *h = &mHoldSoundHandles[i];
if (!h->IsAttachedSound()) {
return h;
}
}
// Drop a lower-priority sound
nw4r::snd::SoundHandle *least = nullptr;
nw4r::snd::SoundArchive::SoundInfo info;
dSndMgr_c::GetInstance()->getArchive()->ReadSoundInfo(soundId, &info);
s32 newPriority = info.playerPriority;
for (int i = 0; i < NUM_HOLD_SOUNDS; i++) {
nw4r::snd::SoundHandle *h = &mHoldSoundHandles[i];
dSndMgr_c::GetInstance()->getArchive()->ReadSoundInfo(h->GetId(), &info);
if (info.playerPriority < newPriority) {
newPriority = info.playerPriority;
least = h;
}
}
return least;
}
bool dSndSmallEffectMgr_c::playSkbSound(u32 soundId) {
switch (soundId) {
case SE_S_SK_POINT:
case SE_S_SK_INPUT:
if (isPlayingSound(SE_S_SK_INPUT_DECIDE)) {
return false;
}
break;
case SE_S_SK_INPUT_DECIDE:
stopSounds(dSndPlayerMgr_c::PLAYER_SMALL_NORMAL, SE_S_SK_POINT, 0);
stopSounds(dSndPlayerMgr_c::PLAYER_SMALL_NORMAL, SE_S_SK_INPUT, 0);
break;
case SE_S_SK_DELETE_ERROR: stopSounds(dSndPlayerMgr_c::PLAYER_SMALL_NORMAL, SE_S_SK_INPUT, 0); break;
}
return playSound(soundId);
}
void dSndSmallEffectMgr_c::stopSounds(u32 playerIdx, u32 soundId, s32 fadeFrames) {
SoundStopper stopper(soundId, fadeFrames);
dSndControlPlayerMgr_c::GetInstance()->getPlayer1(playerIdx)->ForEachSound(stopper, false);
@@ -191,3 +258,62 @@ void dSndSmallEffectMgr_c::setButtonPressSound(dSoundSource_c *source) {
}
}
}
bool dSndSmallEffectMgr_c::playBattleHitSound(BattleHitSound_e type, dSoundSource_c *source) {
// if we're not in battle, don't play any of the hit effects
if (!dSndBgmMgr_c::GetInstance()->isPlayingAnyBattleMusic()) {
return false;
}
if (source != nullptr) {
const char *name = source->getName();
s32 sourceType = source->getSourceType();
if (sourceType == SND_SOURCE_OBJECT_40) {
return false;
}
switch (type) {
case BATTLE_TUTTI_GUARDJUST:
if (sourceType >= SND_SOURCE_BULLET) {
// Do not play battle effects for countering bullets
return false;
}
break;
case BATTLE_TUTTI_FINISH:
if (streq(name, "BLasBos")) {
// Do not play finish effect for finishing Demise
return false;
}
break;
default: break;
}
}
u32 soundId = BGM_BATTLE_TUTTI;
switch (type) {
case BATTLE_TUTTI_TURN: soundId = BGM_BATTLE_TUTTI_TURN; break;
case BATTLE_TUTTI_JUMP: soundId = BGM_BATTLE_TUTTI_JUMP; break;
case BATTLE_TUTTI_FINISH: soundId = BGM_BATTLE_TUTTI_FINISH; break;
case BATTLE_TUTTI_GUARDJUST: soundId = BGM_BATTLE_TUTTI_GUARDJUST; break;
default: break;
}
if (mBattleTuttiHandle.IsAttachedSound()) {
u32 alreadyPlayingSound = mBattleTuttiHandle.GetId();
// BGM_BATTLE_TUTTI_ sounds are ordered by priority apparently
if (alreadyPlayingSound > soundId) {
return false;
}
if (alreadyPlayingSound == BGM_BATTLE_TUTTI) {
nw4r::snd::SeqSoundHandle handle(&mBattleTuttiHandle);
// Do not allow stopping BGM_BATTLE_TUTTI too early
if ((s32)handle.GetTick() < 12) {
return false;
}
}
mBattleTuttiHandle.Stop(5);
}
// TODO ...
return true;
}
+2 -1
View File
@@ -3,6 +3,7 @@
#include "common.h"
#include "d/snd/d_snd_source.h"
#include "d/snd/d_snd_source_enums.h"
#include "d/snd/d_snd_util.h"
#include "nw4r/ut/ut_list.h"
#include <cmath>
@@ -110,7 +111,7 @@ void dSndSourceMgr_c::registerSource(dSoundSource_c *source) {
break;
}
case SND_SOURCE_CATEGORY_OBJECT: {
if (source->isName("TBoat") && mpTBoatSource == nullptr) {
if (streq(source->getName(), "TBoat") && mpTBoatSource == nullptr) {
mpTBoatSource = source;
}
break;
-4
View File
@@ -84,10 +84,6 @@ void dSndStateMgr_c::setup(EGG::Heap *pHeap) {
resetStageName();
}
inline bool streq(const char *stageName, const char *name) {
return !std::strcmp(stageName, name);
}
void dSndStateMgr_c::onStageOrLayerUpdate() {
if (dSndPlayerMgr_c::GetInstance()->checkFlag(dSndPlayerMgr_c::MGR_UNK_0x80)) {
dSndPlayerMgr_c::GetInstance()->stopAllSound();