mirror of
https://github.com/zeldaret/ss
synced 2026-08-09 10:53:09 -04:00
179 lines
4.3 KiB
C++
179 lines
4.3 KiB
C++
#ifndef D_SND_BGM_HARP_DATA_H
|
|
#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
|
|
* is freely strumming. In this case the pitch of the strings
|
|
* is adjusted to match the key of background music through sequence variables.
|
|
* When Link strums the harp, 12 strings can be heard, but it's actually only four
|
|
* notes of the same chord spanning three octaves.
|
|
*
|
|
* I haven't yet investigated all the data, but a typical chord Link might play
|
|
* is Cmaj^7, consisting of C-E-G-B. Link actually plays:
|
|
* 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.
|
|
*/
|
|
|
|
/**
|
|
* Contains a single Seq sound var controlling the pitch of a subset of harp strings
|
|
* Size: 0x02
|
|
*/
|
|
struct dSndBgmDataHarpVar_c {
|
|
dSndBgmDataHarpVar_c() : field_0x00(0), field_0x01(0) {}
|
|
|
|
void reset() {
|
|
field_0x00 = 0;
|
|
field_0x01 = 0;
|
|
}
|
|
|
|
void onFlag() {
|
|
field_0x00 |= 1;
|
|
}
|
|
|
|
bool checkFlag() const {
|
|
return field_0x00 & 1;
|
|
}
|
|
|
|
/* 0x00 */ u8 field_0x00; // flags
|
|
/* 0x01 */ s8 field_0x01; // var
|
|
};
|
|
|
|
/**
|
|
* Contains Seq sound vars for all harp strings, represents a "key" in the bgm music
|
|
* Size: 0x0C
|
|
*/
|
|
class dSndBgmDataHarpVarSetBase_c {
|
|
public:
|
|
dSndBgmDataHarpVarSetBase_c(s32 count);
|
|
~dSndBgmDataHarpVarSetBase_c();
|
|
|
|
void resetVars();
|
|
void addVar(u8 value);
|
|
|
|
s32 getPosition() const {
|
|
return mPosition;
|
|
}
|
|
|
|
void setPosition(s32 position) {
|
|
mPosition = position;
|
|
}
|
|
|
|
s32 getCount() {
|
|
return mCount;
|
|
}
|
|
|
|
s32 getMax() const {
|
|
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;
|
|
}
|
|
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;
|
|
}
|
|
return &mpVars[mCount];
|
|
}
|
|
|
|
private:
|
|
/* 0x00 */ dSndBgmDataHarpVar_c *mpVars;
|
|
/* 0x04 */ s32 mPosition;
|
|
/* 0x08 */ s16 mMax;
|
|
/* 0x0A */ s16 mCount;
|
|
};
|
|
|
|
class dSndBgmDataHarpVarSet_c : public dSndBgmDataHarpVarSetBase_c {
|
|
public:
|
|
dSndBgmDataHarpVarSet_c() : dSndBgmDataHarpVarSetBase_c(4) {}
|
|
|
|
private:
|
|
};
|
|
|
|
/**
|
|
* Contains parsed seq data for harp strings for a single bgm sound
|
|
*/
|
|
class dSndBgmHarpDataBase_c {
|
|
public:
|
|
dSndBgmHarpDataBase_c();
|
|
void resetVars();
|
|
s32 getIdxForPosition(s32 position);
|
|
|
|
dSndBgmDataHarpVarSetBase_c *getUsableVarSet(s32 idx);
|
|
void addVar(s32 position, s32 value, s32 unk);
|
|
void setField_0x08(s32 value);
|
|
|
|
protected:
|
|
dSndBgmDataHarpVarSetBase_c *getVarSet(s32 idx);
|
|
/* 0x00 */ dSndBgmDataHarpVarSetBase_c *mpVarSets;
|
|
/* 0x04 */ s16 mMax;
|
|
/* 0x06 */ s16 mCount;
|
|
/* 0x08 */ s32 field_0x08;
|
|
};
|
|
|
|
class dSndBgmHarpData_c : public dSndBgmHarpDataBase_c {
|
|
public:
|
|
dSndBgmHarpData_c();
|
|
~dSndBgmHarpData_c();
|
|
|
|
/**
|
|
* Writes the Seq sound variables that control the pitch
|
|
* of the individual harp strings.
|
|
*/
|
|
void writeSeqVars(s32 idx);
|
|
|
|
private:
|
|
static const u32 NUM_SETS = 300;
|
|
};
|
|
|
|
#endif
|