I can't believe this function matches

This commit is contained in:
robojumper
2025-07-20 21:36:03 +02:00
parent 339ee576b5
commit ac846aea3e
10 changed files with 194 additions and 13 deletions
+1 -1
View File
@@ -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
+43 -1
View File
@@ -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;
+1 -1
View File
@@ -55,7 +55,7 @@ public:
void onBecomeActive();
bool isBgmBattle() const;
const dSndBgmDataHarpVarSetBase_c *getCurrentHarpVarSet();
dSndBgmDataHarpVarSetBase_c *getCurrentHarpVarSet();
u32 getStrmPlaySamplePosition();
u32 getWavePlaySamplePosition();
+1 -1
View File
@@ -15,7 +15,7 @@ public:
void setPlaySamplePosition(s32 position);
const dSndBgmDataHarpVarSetBase_c *getCurrentVarSet();
dSndBgmDataHarpVarSetBase_c *getCurrentVarSet();
bool isLoaded() const {
return mIsLoaded;
+1 -2
View File
@@ -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
+5 -3
View File
@@ -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
+2
View File
@@ -28,6 +28,8 @@ class dSndBgmSoundHarpMgr_c;
class dSndBgmSeqConfig;
class dSndBgmBattleConfig;
class dSndBgmDataHarpVarSetBase_c;
class dSndHarpSongData_c;
class dSndTagData;
+1 -1
View File
@@ -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();
}
+1 -1
View File
@@ -36,6 +36,6 @@ void dSndBgmSoundHarpMgr_c::setPlaySamplePosition(s32 position) {
}
}
const dSndBgmDataHarpVarSetBase_c *dSndBgmSoundHarpMgr_c::getCurrentVarSet() {
dSndBgmDataHarpVarSetBase_c *dSndBgmSoundHarpMgr_c::getCurrentVarSet() {
return mpCurrVarSet;
}
+138 -2
View File
@@ -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;
}
}
}