summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-07-09 00:30:48 +0200
committerrobojumper <robojumper@gmail.com>2025-09-13 10:59:42 +0200
commit4f9d63d357dfbdf3f08a7294eb2fbc7ccfe790cf (patch)
tree51b80accf33403078974ee3e65573a94b260923e
parentbb3f0562bd38e7a4d001af0b578be03653faedcf (diff)
d_snd_bgm_sound_battle OK
-rw-r--r--config/SOUE01/symbols.txt12
-rw-r--r--configure.py2
-rw-r--r--include/d/snd/d_snd_bgm_harp_data.h4
-rw-r--r--include/d/snd/d_snd_bgm_mgr.h2
-rw-r--r--include/d/snd/d_snd_bgm_seq_config.h6
-rw-r--r--include/d/snd/d_snd_bgm_sound.h4
-rw-r--r--include/d/snd/d_snd_bgm_sound_battle.h13
-rw-r--r--src/d/snd/d_snd_bgm_mgr.cpp2
-rw-r--r--src/d/snd/d_snd_bgm_mml_parsers.cpp24
-rw-r--r--src/d/snd/d_snd_bgm_sound.cpp38
-rw-r--r--src/d/snd/d_snd_bgm_sound_battle.cpp58
11 files changed, 115 insertions, 50 deletions
diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt
index a76b1ec3..dc814f19 100644
--- a/config/SOUE01/symbols.txt
+++ b/config/SOUE01/symbols.txt
@@ -20755,12 +20755,12 @@ __ct__20dSndBgmBattleSound_cFv = .text:0x8037B4E0; // type:function size:0x58
cancel__20dSndBgmBattleSound_cFv = .text:0x8037B540; // type:function size:0x44
loadSeqConfig__20dSndBgmBattleSound_cFUl = .text:0x8037B590; // type:function size:0x7C
fadeIn__20dSndBgmBattleSound_cFUll = .text:0x8037B610; // type:function size:0xAC
-fn_8037B6C0 = .text:0x8037B6C0; // type:function size:0x18
-fn_8037B6E0 = .text:0x8037B6E0; // type:function size:0x18
-fn_8037B700 = .text:0x8037B700; // type:function size:0xB0
+setTrackGroupMuted__20dSndBgmBattleSound_cFUl = .text:0x8037B6C0; // type:function size:0x18
+setTrackGroupUnmuted__20dSndBgmBattleSound_cFUl = .text:0x8037B6E0; // type:function size:0x18
+startMainBattleLoop__20dSndBgmBattleSound_cFv = .text:0x8037B700; // type:function size:0xB0
calcSeqPlaySamplePosition__20dSndBgmBattleSound_cFv = .text:0x8037B7B0; // type:function size:0x134
-postCalc__20dSndBgmBattleSound_cFv = .text:0x8037B8F0; // type:function size:0x10
-isBattleBgmSound__20dSndBgmBattleSound_cCFv = .text:0x8037B900; // type:function size:0x8
+postCalc__20dSndBgmBattleSound_cFv = .text:0x8037B8F0; // type:function size:0x10 scope:weak
+isBattleBgmSound__20dSndBgmBattleSound_cCFv = .text:0x8037B900; // type:function size:0x8 scope:weak
__ct__21dSndBgmSoundHarpMgr_cFv = .text:0x8037B910; // type:function size:0x54
setSoundId__21dSndBgmSoundHarpMgr_cFUl = .text:0x8037B970; // type:function size:0x8
setLoaded__21dSndBgmSoundHarpMgr_cFv = .text:0x8037B980; // type:function size:0xC
@@ -38040,7 +38040,7 @@ lbl_80549068 = .data:0x80549068; // type:object size:0x10
lbl_80549078 = .data:0x80549078; // type:object size:0x10
lbl_80549088 = .data:0x80549088; // type:object size:0x34
__vt__14dSndBgmSound_c = .data:0x805490BC; // type:object size:0x44
-__vt__20dSndBgmBattleSound_c = .data:0x80549100; // type:object size:0x48
+__vt__20dSndBgmBattleSound_c = .data:0x80549100; // type:object size:0x44
__vt__37SndMgrDisposer<19dSndBgmSeqDataMgr_c> = .data:0x80549148; // type:object size:0xC scope:weak
__vt__18dSndBgmMmlParser_c = .data:0x80549158; // type:object size:0x10
lbl_80549168 = .data:0x80549168; // type:object size:0x10
diff --git a/configure.py b/configure.py
index 7be44e87..d17077eb 100644
--- a/configure.py
+++ b/configure.py
@@ -757,7 +757,7 @@ config.libs = [
Object(NonMatching, "d/snd/d_snd_bgm_sound_callbacks.cpp"),
Object(NonMatching, "d/snd/d_snd_bgm_sound_battle_callbacks.cpp"),
Object(NonMatching, "d/snd/d_snd_bgm_sound.cpp"),
- Object(NonMatching, "d/snd/d_snd_bgm_sound_battle.cpp"),
+ Object(Matching, "d/snd/d_snd_bgm_sound_battle.cpp"),
Object(Matching, "d/snd/d_snd_bgm_sound_harp_mgr.cpp"),
Object(Matching, "d/snd/d_snd_bgm_seq_data_mgr.cpp"),
Object(NonMatching, "d/snd/d_snd_bgm_reverb.cpp"),
diff --git a/include/d/snd/d_snd_bgm_harp_data.h b/include/d/snd/d_snd_bgm_harp_data.h
index b2f9cdd9..fc62f9ab 100644
--- a/include/d/snd/d_snd_bgm_harp_data.h
+++ b/include/d/snd/d_snd_bgm_harp_data.h
@@ -15,6 +15,10 @@
* G3-C4-E4-G4-B4-C5-E5-G5-B5-C6-E6-G6
* B3 is missing, possibly to prevent dissonance at the ends of the scale.
* (Sealed Grounds, before Demise fight, no actual BGM)
+ *
+ * TODO: This deals with slightly more than the harp. It additionally
+ * also deals with the combat hit sounds that also seem to match up in
+ * pitch with the BGM.
*/
/**
diff --git a/include/d/snd/d_snd_bgm_mgr.h b/include/d/snd/d_snd_bgm_mgr.h
index 5a4400be..ff05db51 100644
--- a/include/d/snd/d_snd_bgm_mgr.h
+++ b/include/d/snd/d_snd_bgm_mgr.h
@@ -100,7 +100,7 @@ private:
bool prepareBgmSound(u32 soundId, dSndBgmSound_c *handle, u32 startOffset);
bool startAdditionalBgm(u32 soundId);
- bool playBattleBgm(u32 soundId, bool immediately);
+ bool playBattleBgm(u32 soundId, bool intense);
/** Used to mute other BGM when battle music is playing */
void setBgmHandleIdxVolume(u32 handleIdx, f32 volume, s32 fadeFrames);
diff --git a/include/d/snd/d_snd_bgm_seq_config.h b/include/d/snd/d_snd_bgm_seq_config.h
index b66e9275..a66a8131 100644
--- a/include/d/snd/d_snd_bgm_seq_config.h
+++ b/include/d/snd/d_snd_bgm_seq_config.h
@@ -6,9 +6,9 @@
struct dSndBgmSeqConfig {
/* 0x00 */ u32 soundId;
/* 0x04 */ s32 field_0x04;
- /* 0x08 */ s32 field_0x08;
- /* 0x0C */ u16 field_0x0C;
- /* 0x0E */ u16 field_0x0E;
+ /* 0x08 */ s32 mTimebase;
+ /* 0x0C */ u16 mLoopStart;
+ /* 0x0E */ u16 mLoopEnd;
static const dSndBgmSeqConfig *getConfig(u32 soundId, s32 unkParam);
diff --git a/include/d/snd/d_snd_bgm_sound.h b/include/d/snd/d_snd_bgm_sound.h
index 4e76137c..09403fb7 100644
--- a/include/d/snd/d_snd_bgm_sound.h
+++ b/include/d/snd/d_snd_bgm_sound.h
@@ -77,8 +77,8 @@ protected:
/* 0x108 */ s32 mSeqTempo;
/* 0x10C */ u32 mBgmFlags;
/* 0x110 */ bool mDidRewindPlaySamplePosition;
- /* 0x114 */ s32 field_0x114;
- /* 0x118 */ s32 field_0x118;
+ /* 0x114 */ s32 mBgmVar3;
+ /* 0x118 */ s32 mSeqTimebase;
/* 0x11C */ u32 mPlaySamplePosition;
/* 0x120 */ dSndBgmSoundHarpMgr_c mHarpMgr;
/* 0x140 */ dSndBgmSoundHarpMgr_c *mpHarpMgr;
diff --git a/include/d/snd/d_snd_bgm_sound_battle.h b/include/d/snd/d_snd_bgm_sound_battle.h
index 047832e5..f18fa7be 100644
--- a/include/d/snd/d_snd_bgm_sound_battle.h
+++ b/include/d/snd/d_snd_bgm_sound_battle.h
@@ -20,10 +20,19 @@ public:
virtual void calcSeqPlaySamplePosition() override; // vt 0x3C
virtual void loadCallbacks(u32 soundId) override; // vt 0x40
+ /**
+ * Called when the player is even closer to an enemy.
+ * Adds some more instruments to the battle sound.
+ */
+ bool startMainBattleLoop();
+
private:
+ void setTrackGroupMuted(u32 groupId);
+ void setTrackGroupUnmuted(u32 groupId);
+
/* 0x184 */ const dSndBgmBattleConfig *mpBgmBattleConfig;
- /* 0x188 */ u32 mMuteApplyStateMask;
- /* 0x18C */ u32 mTickRelated;
+ /* 0x188 */ u32 mMuteGroupActiveMask;
+ /* 0x18C */ u32 mPrevTick;
/* 0x190 */ u8 field_0x190;
/* 0x191 */ u8 field_0x191;
};
diff --git a/src/d/snd/d_snd_bgm_mgr.cpp b/src/d/snd/d_snd_bgm_mgr.cpp
index dcfcb3ac..a972531c 100644
--- a/src/d/snd/d_snd_bgm_mgr.cpp
+++ b/src/d/snd/d_snd_bgm_mgr.cpp
@@ -1,7 +1,7 @@
#include "d/snd/d_snd_bgm_mgr.h"
#include "common.h"
-#include "d/snd/d_snd_bgm_sound battle.h"
+#include "d/snd/d_snd_bgm_sound_battle.h"
#include "d/snd/d_snd_bgm_sound.h"
#include "d/snd/d_snd_mgr.h"
#include "d/snd/d_snd_player_mgr.h"
diff --git a/src/d/snd/d_snd_bgm_mml_parsers.cpp b/src/d/snd/d_snd_bgm_mml_parsers.cpp
index e8797706..8e996ed6 100644
--- a/src/d/snd/d_snd_bgm_mml_parsers.cpp
+++ b/src/d/snd/d_snd_bgm_mml_parsers.cpp
@@ -1,9 +1,9 @@
#include "d/snd/d_snd_bgm_mml_parsers.h"
#include "common.h"
-#include "d/snd/d_snd_mgr.h"
-#include "d/snd/d_snd_bgm_sound_harp_mgr.h"
#include "d/snd/d_snd_bgm_seq_data_mgr.h"
+#include "d/snd/d_snd_bgm_sound_harp_mgr.h"
+#include "d/snd/d_snd_mgr.h"
#include "d/snd/d_snd_player_mgr.h"
#include "nw4r/snd/snd_SoundArchive.h"
#include "sized_string.h"
@@ -23,7 +23,8 @@ bool dSndBgmMmlParserHarp_c::parseData(const char *soundLabel, u32 baseSoundId,
SizedString<64> dataLabel;
dataLabel.sprintf("%s%s", dSndBgmSeqDataMgr_c::getDataPrefix(), soundLabel);
u32 dataId = dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(dataLabel);
- if (dataId != -1 && dSndMgr_c::GetInstance()->getArchive()->GetSoundType(dataId) == nw4r::snd::SoundArchive::SOUND_TYPE_SEQ) {
+ if (dataId != -1 &&
+ dSndMgr_c::GetInstance()->getArchive()->GetSoundType(dataId) == nw4r::snd::SoundArchive::SOUND_TYPE_SEQ) {
ok = loadAndParse(dataId, trackMask, true);
if (ok) {
field_0x294->setSoundId(baseSoundId);
@@ -53,22 +54,17 @@ void dSndBgmMmlParserHarp_c::CommandProc(u32 trackNo, int wait, u32 command, s32
}
break;
default:
- if (command == MML_SET_TEMPO) {
- field_0x294->setTempo(commandArg1);
- }
- break;
-
+ if (command == MML_SET_TEMPO) {
+ field_0x294->setTempo(commandArg1);
+ }
+ break;
}
}
void dSndBgmMmlParserHarp_c::NoteOnCommandProc(u32 trackNo, int wait, int key, int velocity, s32 length) const {
// TODO type
switch ((s32)trackNo) {
- case 15:
- field_0x298->addVar(wait, key, velocity);
- break;
- default:
- break;
-
+ case 15: field_0x298->addVar(wait, key, velocity); break;
+ default: break;
}
}
diff --git a/src/d/snd/d_snd_bgm_sound.cpp b/src/d/snd/d_snd_bgm_sound.cpp
index e6e8a78e..60a717bc 100644
--- a/src/d/snd/d_snd_bgm_sound.cpp
+++ b/src/d/snd/d_snd_bgm_sound.cpp
@@ -29,8 +29,8 @@ dSndBgmSound_c::dSndBgmSound_c()
mSeqTempo(-1),
mBgmFlags(0),
mDidRewindPlaySamplePosition(false),
- field_0x114(-1),
- field_0x118(0x180),
+ mBgmVar3(-1),
+ mSeqTimebase(0x180),
mPlaySamplePosition(0),
mpHarpMgr(&mHarpMgr),
mpSeqConfig(nullptr),
@@ -71,9 +71,9 @@ void dSndBgmSound_c::cancel() {
mpSeqConfig = nullptr;
mPlaySamplePosition = 0;
mSeqPlaySamplePosition = -1;
- field_0x114 = -1;
+ mBgmVar3 = -1;
mSeqTempo = -1;
- field_0x118 = 0x180;
+ mSeqTimebase = 0x180;
mHarpMgr.reset();
for (int i = 0; i < 2; i++) {
field_0x14C[i] = 0;
@@ -239,7 +239,7 @@ void dSndBgmSound_c::loadSeqConfig(u32 soundId) {
if (dSndMgr_c::GetInstance()->getArchive()->GetSoundType(soundId) == nw4r::snd::SoundArchive::SOUND_TYPE_SEQ) {
mpSeqConfig = dSndBgmSeqConfig::getConfig(soundId, 1);
if (mpSeqConfig != nullptr) {
- field_0x118 = mpSeqConfig->field_0x08;
+ mSeqTimebase = mpSeqConfig->mTimebase;
}
}
}
@@ -415,27 +415,31 @@ void dSndBgmSound_c::calcSeqPlaySamplePosition() {
nw4r::snd::SeqSoundHandle handle(this);
s32 tick = handle.GetTick();
- field_0x114 = readSeqTrackVariable(3);
- if (field_0x114 >= 0) {
- mSeqPlaySamplePosition = tick % field_0x118;
+ mBgmVar3 = readSeqTrackVariable(3);
+ if (mBgmVar3 >= 0) {
+ // Var >= 0 - seq itself controls play position
+ mSeqPlaySamplePosition = tick % mSeqTimebase;
if (mSeqPlaySamplePosition == 0) {
- field_0x114++;
- if (mpSeqConfig != nullptr && field_0x114 > mpSeqConfig->field_0x0E) {
- field_0x114 = mpSeqConfig->field_0x0C;
+ mBgmVar3++;
+ if (mpSeqConfig != nullptr && mBgmVar3 > mpSeqConfig->mLoopEnd) {
+ mBgmVar3 = mpSeqConfig->mLoopStart;
}
}
- mSeqPlaySamplePosition += field_0x118 * field_0x114;
+ mSeqPlaySamplePosition += mSeqTimebase * mBgmVar3;
} else if (mpSeqConfig != nullptr) {
- if (tick < (mpSeqConfig->field_0x0E + 1) * field_0x118) {
+ if (tick < (mpSeqConfig->mLoopEnd + 1) * mSeqTimebase) {
+ // not looped yet, no adjustment needed
mSeqPlaySamplePosition = tick;
return;
}
- s32 offset = mpSeqConfig->field_0x0C * field_0x118;
+ s32 startOffset = mpSeqConfig->mLoopStart * mSeqTimebase;
- tick -= offset;
- tick = tick % (field_0x118 * (mpSeqConfig->field_0x0E - mpSeqConfig->field_0x0C));
- mSeqPlaySamplePosition = tick + offset;
+ // wrap around loop, making sure to account for start offset
+ tick -= startOffset;
+ tick = tick % (mSeqTimebase * (mpSeqConfig->mLoopEnd - mpSeqConfig->mLoopStart));
+ mSeqPlaySamplePosition = tick + startOffset;
} else {
+ // Fallback, not controlled by seq no config override
mSeqPlaySamplePosition = tick;
}
}
diff --git a/src/d/snd/d_snd_bgm_sound_battle.cpp b/src/d/snd/d_snd_bgm_sound_battle.cpp
index d3b604c5..034fedb1 100644
--- a/src/d/snd/d_snd_bgm_sound_battle.cpp
+++ b/src/d/snd/d_snd_bgm_sound_battle.cpp
@@ -5,14 +5,15 @@
#include "d/snd/d_snd_bgm_sound.h"
#include "d/snd/d_snd_mgr.h"
#include "d/snd/d_snd_wzsound.h"
+#include "nw4r/snd/snd_SeqSoundHandle.h"
dSndBgmBattleSound_c::dSndBgmBattleSound_c()
- : mpBgmBattleConfig(nullptr), mMuteApplyStateMask(0), mTickRelated(0), field_0x190(0), field_0x191(1) {}
+ : mpBgmBattleConfig(nullptr), mMuteGroupActiveMask(0), mPrevTick(0), field_0x190(0), field_0x191(1) {}
void dSndBgmBattleSound_c::cancel() {
dSndBgmSound_c::cancel();
- mMuteApplyStateMask = 0;
- mTickRelated = 0;
+ mMuteGroupActiveMask = 0;
+ mPrevTick = 0;
field_0x190 = 0;
field_0x191 = 1;
}
@@ -44,3 +45,54 @@ void dSndBgmBattleSound_c::fadeIn(u32 id, s32 fadeFrames) {
field_0x191 = 0;
}
}
+
+void dSndBgmBattleSound_c::setTrackGroupMuted(u32 groupId) {
+ mMuteGroupActiveMask |= (1 << groupId);
+}
+
+void dSndBgmBattleSound_c::setTrackGroupUnmuted(u32 groupId) {
+ mMuteGroupActiveMask &= ~(1 << groupId);
+}
+
+bool dSndBgmBattleSound_c::startMainBattleLoop() {
+ if (isPlaying() && readSeqTrackVariable(0) != 1) {
+ // This seq variable allows the seq sound to jump from intro to main loop
+ writeSeqTrackVariable(0, 1);
+ mpSeqConfig = dSndBgmSeqConfig::getConfig(GetId(), 1);
+ return true;
+ }
+
+ return false;
+}
+
+void dSndBgmBattleSound_c::calcSeqPlaySamplePosition() {
+ if (!isSeqSound()) {
+ return;
+ }
+
+ nw4r::snd::SeqSoundHandle handle(this);
+ s32 tick = handle.GetTick();
+ s32 tickDiff = tick - mPrevTick;
+
+ if (tickDiff <= 0) {
+ return;
+ }
+
+ mPrevTick = tick;
+ s32 timeBase = mpSeqConfig != nullptr ? mpSeqConfig->mTimebase : 0x180;
+ mBgmVar3 = readSeqTrackVariable(3);
+ if (mBgmVar3 >= 0) {
+ // Var >= 0 - seq itself controls play position
+ mSeqPlaySamplePosition = tick % mSeqTimebase;
+ mSeqPlaySamplePosition += mSeqTimebase * mBgmVar3;
+ } else if (mpSeqConfig != nullptr) {
+ mSeqPlaySamplePosition += tickDiff;
+ if (mSeqPlaySamplePosition < (mpSeqConfig->mLoopEnd + 1) * timeBase) {
+ // not looped yet, no adjustment needed
+ return;
+ }
+ // looped, simple adjustment - simplified compared to dSndBgmSound_c which always calculates
+ // mSeqPlaySamplePosition freshly. This function instead uses the difference
+ mSeqPlaySamplePosition -= (timeBase * (mpSeqConfig->mLoopEnd - mpSeqConfig->mLoopStart));
+ }
+}