mirror of
https://github.com/zeldaret/ss
synced 2026-06-17 07:07:39 -04:00
171 lines
5.1 KiB
C++
171 lines
5.1 KiB
C++
|
|
#include "d/snd/d_snd_source_group.h"
|
|
|
|
#include "common.h"
|
|
#include "d/snd/d_snd_source.h"
|
|
#include "d/snd/d_snd_source_enums.h"
|
|
#include "nw4r/ut/ut_list.h"
|
|
|
|
#include <cmath>
|
|
|
|
extern "C" bool isInStage(const char *stageName);
|
|
|
|
void dSndSourceGroup_c::set(s32 sourceType, const char *name) {
|
|
resetSoundSourceParam();
|
|
bool assignedParam = false;
|
|
|
|
switch (mSourceCategory) {
|
|
case SND_SOURCE_CATEGORY_PLAYER: {
|
|
assignedParam = true;
|
|
mParam.field_0x10 = INFINITY;
|
|
break;
|
|
}
|
|
case SND_SOURCE_CATEGORY_EQUIPMENT:
|
|
if (sourceType == SND_SOURCE_ARROW) {
|
|
assignedParam = true;
|
|
mParam.field_0x00 = 1500.0f;
|
|
mParam.field_0x10 = INFINITY;
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (!assignedParam && (sourceType == SND_SOURCE_KENSEI || sourceType == SND_SOURCE_58)) {
|
|
assignedParam = true;
|
|
mParam.field_0x10 = INFINITY;
|
|
}
|
|
|
|
if (!assignedParam) {
|
|
assignedParam = setParamFromName(name);
|
|
}
|
|
|
|
if (!assignedParam) {
|
|
switch (sourceType) {
|
|
case SND_SOURCE_NPC_NRM: {
|
|
mParam.field_0x00 = 300.0f;
|
|
mParam.field_0x04 = 800.0;
|
|
mParam.field_0x10 = 2200.0;
|
|
break;
|
|
}
|
|
case SND_SOURCE_NPC_48: {
|
|
if (isInStage("F401")) {
|
|
mParam.field_0x00 = 500.0f;
|
|
mParam.field_0x04 = 4000.0;
|
|
} else if (isInStage("F402")) {
|
|
mParam.field_0x00 = 400.0f;
|
|
mParam.field_0x04 = 3500.0;
|
|
} else {
|
|
mParam.field_0x00 = 300.0f;
|
|
mParam.field_0x04 = 800.0;
|
|
mParam.field_0x10 = 2200.0;
|
|
}
|
|
|
|
mParam.field_0x10 = INFINITY;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void dSndSourceGroup_c::resetSoundSourceParam() {
|
|
mParam.reset();
|
|
}
|
|
|
|
dSndSourceGroup_c::dSndSourceGroup_c()
|
|
: mSubtype(0),
|
|
field_0x1C(0),
|
|
field_0x1D(0),
|
|
mName(""),
|
|
field_0x40(0),
|
|
mpCachedClosestSourceToListener(nullptr),
|
|
mpCachedClosestSourceToPlayer(nullptr),
|
|
mCalculatedClosestToListener(false),
|
|
mCalculatedClosestToPlayer(false) {
|
|
// TODO offsetof
|
|
nw4r::ut::List_Init(&mSourceList, 0x138);
|
|
resetSoundSourceParam();
|
|
}
|
|
|
|
dSndSourceGroup_c::~dSndSourceGroup_c() {
|
|
clearList();
|
|
}
|
|
|
|
void dSndSourceGroup_c::calc() {
|
|
// Reset freshness flags, computed on-demand
|
|
mCalculatedClosestToPlayer = false;
|
|
mCalculatedClosestToListener = false;
|
|
}
|
|
|
|
s32 dSndSourceGroup_c::getNumSources() const {
|
|
return nw4r::ut::List_GetSize(&mSourceList);
|
|
}
|
|
|
|
void dSndSourceGroup_c::registerSource(dSoundSource_c *source) {
|
|
if (source != nullptr) {
|
|
nw4r::ut::List_Append(&mSourceList, source);
|
|
}
|
|
}
|
|
|
|
void dSndSourceGroup_c::unregisterSource(dSoundSource_c *source) {
|
|
if (source != nullptr) {
|
|
nw4r::ut::List_Remove(&mSourceList, source);
|
|
}
|
|
}
|
|
|
|
void dSndSourceGroup_c::clearList() {
|
|
dSoundSource_c *source = static_cast<dSoundSource_c *>(nw4r::ut::List_GetFirst(&mSourceList));
|
|
while (source != nullptr) {
|
|
nw4r::ut::List_Remove(&mSourceList, source);
|
|
source = static_cast<dSoundSource_c *>(nw4r::ut::List_GetFirst(&mSourceList));
|
|
}
|
|
}
|
|
|
|
dSoundSource_c *dSndSourceGroup_c::getSourceClosestToListener() {
|
|
if (mCalculatedClosestToListener) {
|
|
return mpCachedClosestSourceToListener;
|
|
}
|
|
|
|
mpCachedClosestSourceToListener = nullptr;
|
|
f32 closest = INFINITY;
|
|
for (dSoundSource_c *source = static_cast<dSoundSource_c *>(nw4r::ut::List_GetFirst(&mSourceList));
|
|
source != nullptr; source = static_cast<dSoundSource_c *>(nw4r::ut::List_GetNext(&mSourceList, source))) {
|
|
if (source->getActorType() != SND_SOURCE_PLAYER_HEAD && source->getActorType() != SND_SOURCE_NPC_48) {
|
|
f32 dist = source->getDistanceToListener();
|
|
if (dist < closest) {
|
|
closest = dist;
|
|
mpCachedClosestSourceToListener = source;
|
|
}
|
|
}
|
|
}
|
|
mCalculatedClosestToListener = true;
|
|
return mpCachedClosestSourceToListener;
|
|
}
|
|
|
|
dSoundSource_c *dSndSourceGroup_c::getSourceClosestToPlayer() {
|
|
if (mCalculatedClosestToPlayer) {
|
|
return mpCachedClosestSourceToPlayer;
|
|
}
|
|
|
|
if ((s32)nw4r::ut::List_GetSize(&mSourceList) <= 1) {
|
|
return static_cast<dSoundSource_c *>(nw4r::ut::List_GetFirst(&mSourceList));
|
|
}
|
|
|
|
mpCachedClosestSourceToPlayer = nullptr;
|
|
f32 closest = INFINITY;
|
|
for (dSoundSource_c *source = static_cast<dSoundSource_c *>(nw4r::ut::List_GetFirst(&mSourceList));
|
|
source != nullptr; source = static_cast<dSoundSource_c *>(nw4r::ut::List_GetNext(&mSourceList, source))) {
|
|
if (source->getActorType() != 1 && source->getActorType() != 48) {
|
|
f32 dist = source->getDistanceToPlayer();
|
|
if (dist < closest) {
|
|
closest = dist;
|
|
mpCachedClosestSourceToPlayer = source;
|
|
}
|
|
}
|
|
}
|
|
mCalculatedClosestToPlayer = true;
|
|
return mpCachedClosestSourceToPlayer;
|
|
}
|
|
|
|
bool dSndSourceGroup_c::setParamFromName(const char*) {
|
|
// TODO
|
|
return false;
|
|
}
|