summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrobojumper <robojumper@gmail.com>2025-07-20 21:36:03 +0200
committerrobojumper <robojumper@gmail.com>2025-09-13 11:10:28 +0200
commitac846aea3e813fb9f03b3d491ccd15ac4646ac7d (patch)
tree57d9af5d3ab8928ed7842b2b16b00123e19edba3
parent339ee576b58abf191ea7d834dc6e1b06c3dea52b (diff)
I can't believe this function matches
-rw-r--r--config/SOUE01/symbols.txt2
-rw-r--r--include/d/snd/d_snd_bgm_harp_data.h44
-rw-r--r--include/d/snd/d_snd_bgm_sound.h2
-rw-r--r--include/d/snd/d_snd_bgm_sound_harp_mgr.h2
-rw-r--r--include/d/snd/d_snd_rng_mgr.h3
-rw-r--r--include/d/snd/d_snd_small_effect_mgr.h8
-rw-r--r--include/d/snd/d_snd_types.h2
-rw-r--r--src/d/snd/d_snd_bgm_sound.cpp2
-rw-r--r--src/d/snd/d_snd_bgm_sound_harp_mgr.cpp2
-rw-r--r--src/d/snd/d_snd_small_effect_mgr.cpp140
10 files changed, 194 insertions, 13 deletions
diff --git a/config/SOUE01/symbols.txt b/config/SOUE01/symbols.txt
index 5a4ac7c9..3a5b3926 100644
--- a/config/SOUE01/symbols.txt
+++ b/config/SOUE01/symbols.txt
@@ -20878,7 +20878,7 @@ setButtonPressSound__20dSndSmallEffectMgr_cFP14dSoundSource_c = .text:0x8037F0F0
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
+setBitsIfAdjacent__20dSndSmallEffectMgr_cFP27dSndBgmDataHarpVarSetBase_cllPUl = .text:0x8037F840; // type:function size:0x74
__dt__35SndMgrDisposer<17dSndHarpSongMgr_c>Fv = .text:0x8037F8C0; // type:function size:0x78
create__35SndMgrDisposer<17dSndHarpSongMgr_c>Fv = .text:0x8037F940; // type:function size:0x48
remove__35SndMgrDisposer<17dSndHarpSongMgr_c>Fv = .text:0x8037F990; // type:function size:0x10
diff --git a/include/d/snd/d_snd_bgm_harp_data.h b/include/d/snd/d_snd_bgm_harp_data.h
index fc62f9ab..3c4cee7f 100644
--- a/include/d/snd/d_snd_bgm_harp_data.h
+++ b/include/d/snd/d_snd_bgm_harp_data.h
@@ -2,6 +2,7 @@
#define D_SND_BGM_HARP_DATA_H
#include "common.h"
+#include "d/snd/d_snd_rng_mgr.h"
/**
* This file deals with the pitch of the Goddess' Harp when Link
@@ -37,6 +38,10 @@ struct dSndBgmDataHarpVar_c {
field_0x00 |= 1;
}
+ bool checkFlag() const {
+ return field_0x00 & 1;
+ }
+
/* 0x00 */ u8 field_0x00; // flags
/* 0x01 */ s8 field_0x01; // var
};
@@ -61,7 +66,7 @@ public:
mPosition = position;
}
- s32 getCount() const {
+ s32 getCount() {
return mCount;
}
@@ -69,6 +74,16 @@ public:
return mMax;
}
+ s32 getNumBitsSet() {
+ s32 numBits = 0;
+ for (int i = 0; i < getCount(); i++) {
+ if (mpVars[i].checkFlag()) {
+ numBits++;
+ }
+ }
+ return numBits;
+ }
+
dSndBgmDataHarpVar_c *getVar(s32 idx) {
if (idx >= getCount()) {
return nullptr;
@@ -76,6 +91,33 @@ public:
return &mpVars[idx];
}
+ s32 getRandomIdx() {
+ return dSndRngMgr_c::GetInstance()->rndIntRange(0, getCount());
+ }
+
+ s32 getRandomIdxWithBitSet() {
+ s32 numBitsSet = getNumBitsSet();
+ s32 idx;
+ if (numBitsSet <= 0) {
+ return 0;
+ } else {
+ idx = dSndRngMgr_c::GetInstance()->rndIntRange(0, getCount());
+ while (true) {
+ if (mpVars[idx].checkFlag()) {
+ return idx;
+ }
+ idx = dSndRngMgr_c::GetInstance()->rndIntRange(0, getCount());
+ }
+ }
+ }
+
+ s32 getVal(s32 idx) {
+ if (idx >= getCount()) {
+ return 0;
+ }
+ return mpVars[idx].field_0x01;
+ }
+
dSndBgmDataHarpVar_c *getUnusedVar() {
if (mCount >= mMax) {
return nullptr;
diff --git a/include/d/snd/d_snd_bgm_sound.h b/include/d/snd/d_snd_bgm_sound.h
index 09403fb7..3d4ccd7b 100644
--- a/include/d/snd/d_snd_bgm_sound.h
+++ b/include/d/snd/d_snd_bgm_sound.h
@@ -55,7 +55,7 @@ public:
void onBecomeActive();
bool isBgmBattle() const;
- const dSndBgmDataHarpVarSetBase_c *getCurrentHarpVarSet();
+ dSndBgmDataHarpVarSetBase_c *getCurrentHarpVarSet();
u32 getStrmPlaySamplePosition();
u32 getWavePlaySamplePosition();
diff --git a/include/d/snd/d_snd_bgm_sound_harp_mgr.h b/include/d/snd/d_snd_bgm_sound_harp_mgr.h
index 16bcdc40..34ed6df2 100644
--- a/include/d/snd/d_snd_bgm_sound_harp_mgr.h
+++ b/include/d/snd/d_snd_bgm_sound_harp_mgr.h
@@ -15,7 +15,7 @@ public:
void setPlaySamplePosition(s32 position);
- const dSndBgmDataHarpVarSetBase_c *getCurrentVarSet();
+ dSndBgmDataHarpVarSetBase_c *getCurrentVarSet();
bool isLoaded() const {
return mIsLoaded;
diff --git a/include/d/snd/d_snd_rng_mgr.h b/include/d/snd/d_snd_rng_mgr.h
index 9ef8adab..64596883 100644
--- a/include/d/snd/d_snd_rng_mgr.h
+++ b/include/d/snd/d_snd_rng_mgr.h
@@ -10,10 +10,9 @@ class dSndRngMgr_c : public dSndRng_c {
public:
SND_DISPOSER_MEMBERS(dSndRngMgr_c)
- u32 rndIntRange(s32 min, s32 max);
-
public:
dSndRngMgr_c() {}
+ u32 rndIntRange(s32 min, s32 max);
};
#endif
diff --git a/include/d/snd/d_snd_small_effect_mgr.h b/include/d/snd/d_snd_small_effect_mgr.h
index 7c6ad9d0..3e55b06a 100644
--- a/include/d/snd/d_snd_small_effect_mgr.h
+++ b/include/d/snd/d_snd_small_effect_mgr.h
@@ -82,6 +82,8 @@ private:
bool isPlayingSound(u32 playerIdx, u32 soundId);
bool isPlayingSound(u32 soundId);
+ void setBitsIfAdjacent(dSndBgmDataHarpVarSetBase_c *set, s32 count, s32 target, u32 *pMask);
+
/**
* Finds a sound handle currently playing the given sound,
* or an idle sound handle,
@@ -100,9 +102,9 @@ private:
/* 0x30 */ s32 mDelayedSoundTimers[NUM_DELAYED_SOUNDS];
/* 0x38 */ u32 mTextboxAdvanceSound;
/* 0x3C */ nw4r::snd::SoundHandle mBattleTuttiHandle;
- /* 0x40 */ u16 field_0x40;
- /* 0x42 */ u16 field_0x42;
- /* 0x44 */ s32 field_0x44;
+ /* 0x40 */ s16 field_0x40;
+ /* 0x42 */ s16 field_0x42;
+ /* 0x44 */ u32 field_0x44;
};
#endif
diff --git a/include/d/snd/d_snd_types.h b/include/d/snd/d_snd_types.h
index c156c7c1..4c835232 100644
--- a/include/d/snd/d_snd_types.h
+++ b/include/d/snd/d_snd_types.h
@@ -28,6 +28,8 @@ class dSndBgmSoundHarpMgr_c;
class dSndBgmSeqConfig;
class dSndBgmBattleConfig;
+class dSndBgmDataHarpVarSetBase_c;
+
class dSndHarpSongData_c;
class dSndTagData;
diff --git a/src/d/snd/d_snd_bgm_sound.cpp b/src/d/snd/d_snd_bgm_sound.cpp
index cfd488a7..2d01949f 100644
--- a/src/d/snd/d_snd_bgm_sound.cpp
+++ b/src/d/snd/d_snd_bgm_sound.cpp
@@ -456,7 +456,7 @@ void dSndBgmSound_c::onBecomeActive() {
spGlobalHarpMgr->resetPrevIdx();
}
-const dSndBgmDataHarpVarSetBase_c *dSndBgmSound_c::getCurrentHarpVarSet() {
+dSndBgmDataHarpVarSetBase_c *dSndBgmSound_c::getCurrentHarpVarSet() {
if (isRunning()) {
return mpHarpMgr->getCurrentVarSet();
}
diff --git a/src/d/snd/d_snd_bgm_sound_harp_mgr.cpp b/src/d/snd/d_snd_bgm_sound_harp_mgr.cpp
index e54a999c..ee376ac9 100644
--- a/src/d/snd/d_snd_bgm_sound_harp_mgr.cpp
+++ b/src/d/snd/d_snd_bgm_sound_harp_mgr.cpp
@@ -36,6 +36,6 @@ void dSndBgmSoundHarpMgr_c::setPlaySamplePosition(s32 position) {
}
}
-const dSndBgmDataHarpVarSetBase_c *dSndBgmSoundHarpMgr_c::getCurrentVarSet() {
+dSndBgmDataHarpVarSetBase_c *dSndBgmSoundHarpMgr_c::getCurrentVarSet() {
return mpCurrVarSet;
}
diff --git a/src/d/snd/d_snd_small_effect_mgr.cpp b/src/d/snd/d_snd_small_effect_mgr.cpp
index 41c89b8e..46a9ffc5 100644
--- a/src/d/snd/d_snd_small_effect_mgr.cpp
+++ b/src/d/snd/d_snd_small_effect_mgr.cpp
@@ -1,7 +1,9 @@
#include "d/snd/d_snd_small_effect_mgr.h"
#include "common.h"
+#include "d/snd/d_snd_bgm_harp_data.h"
#include "d/snd/d_snd_bgm_mgr.h"
+#include "d/snd/d_snd_bgm_sound.h"
#include "d/snd/d_snd_calc_pitch.h"
#include "d/snd/d_snd_checkers.h"
#include "d/snd/d_snd_control_player_mgr.h"
@@ -603,7 +605,141 @@ bool dSndSmallEffectMgr_c::playBattleHitSound(BattleHitSound_e type, dSoundSourc
mBattleTuttiHandle.Stop(5);
}
- // TODO ...
+ dSndBgmSound_c *bgmSound = dSndBgmMgr_c::GetInstance()->getActiveBgmSound();
+ if (bgmSound == nullptr) {
+ return false;
+ }
- return true;
+ dSndBgmDataHarpVarSetBase_c *set = bgmSound->getCurrentHarpVarSet();
+ if (set == nullptr) {
+ return false;
+ }
+
+ bool ok = playSoundInternal(soundId, &mBattleTuttiHandle);
+ if (ok) {
+ nw4r::snd::SeqSoundHandle seqHandle(&mBattleTuttiHandle);
+ if (set->getCount() <= 0) {
+ return true;
+ }
+
+ s32 count = set->getCount();
+ if (count == 1) {
+ field_0x40 = set->getVal(0);
+ field_0x42 = field_0x40;
+ for (int i = 1; i < 4; i++) {
+ seqHandle.WriteVariable(i, field_0x40);
+ }
+ return true;
+ } else {
+ s32 i2 = 0;
+ field_0x44 = 0;
+ s32 varIdx = 0;
+ u32 mask = 0;
+
+ // Pick a var 0
+ if (type == BATTLE_TUTTI_FINISH) {
+ field_0x40 = set->getVal(0);
+ varIdx = 0;
+ } else {
+ s32 numHarpBits = set->getNumBitsSet();
+
+ if (numHarpBits <= 0) {
+ // No bits set, just try and pick a random variable
+ // that's not equal to the one we picked before
+ s32 pick = field_0x40;
+ int i = 0;
+ while (pick == field_0x40) {
+ i++;
+ if (i > 0x14) {
+ break;
+ }
+ varIdx = set->getRandomIdx();
+ pick = set->getVal(varIdx);
+ }
+ field_0x40 = pick;
+ } else if (numHarpBits == 1) {
+ // One bit set, get the value (using a slightly convoluted method
+ // due to inline complexity) without rejecting it when it equals
+ // the previously picked value
+ // TODO - unnecessary reload of count here.
+ varIdx = set->getRandomIdxWithBitSet();
+ field_0x40 = set->getVal(varIdx);
+ } else {
+ // Multiple bits set, just pick a random variable with the bit set
+ // that's not equal to the one we picked before
+ s32 pick = field_0x40;
+ int i = 0;
+ while (pick == field_0x40) {
+ i++;
+ if (i > 0x14) {
+ break;
+ }
+ varIdx = set->getRandomIdxWithBitSet();
+ pick = set->getVal(varIdx);
+ }
+ field_0x40 = pick;
+ }
+ }
+ field_0x44 |= 1 << varIdx;
+ setBitsIfAdjacent(set, count, field_0x40, &mask);
+ seqHandle.WriteVariable(0, field_0x40);
+
+ // Pick a new field_0x42 -> var 1
+ u32 mask5 = 0;
+ s32 value = 0;
+ int i = 0;
+ do {
+ i++;
+ if (i > 0x14) {
+ break;
+ }
+ u32 rndValue = set->getRandomIdx();
+ mask5 = 1 << rndValue;
+ value = set->getVal(rndValue);
+
+ } while ((mask & mask5) || value == field_0x42);
+ field_0x42 = value;
+ field_0x44 |= mask5;
+
+ setBitsIfAdjacent(set, count, field_0x42, &mask);
+ seqHandle.WriteVariable(1, field_0x42);
+
+ // Pick new vars 2 and 3
+ bool b = field_0x40 != field_0x42;
+ s32 seqVarIdx = 2;
+ for (; seqVarIdx < 4; seqVarIdx++) {
+ u32 rndValue = 0;
+ u32 mask5 = 0;
+ int i = 0;
+ do {
+ i++;
+ if (i > 0x14) {
+ break;
+ }
+ rndValue = set->getRandomIdx();
+ mask5 = 1 << rndValue;
+ } while ((mask & mask5) || (seqVarIdx >= 3 && !b && (field_0x44 & mask5)));
+ if (!(field_0x44 & mask5)) {
+ b = true;
+ }
+ s32 nextVal = value = set->getVal(rndValue);
+ setBitsIfAdjacent(set, count, nextVal, &mask);
+ field_0x44 |= mask5;
+ seqHandle.WriteVariable(seqVarIdx, nextVal);
+ }
+ }
+ }
+
+ return ok;
+}
+
+void dSndSmallEffectMgr_c::setBitsIfAdjacent(
+ dSndBgmDataHarpVarSetBase_c *set, s32 count, s32 target, u32 *pMask
+) {
+ for (int i = 0; i < count; i++) {
+ s32 val = set->getVal(i);
+ if (val == target + 1 || val == target - 1) {
+ *pMask |= 1 << i;
+ }
+ }
}