mirror of
https://github.com/zeldaret/ss
synced 2026-05-30 08:56:34 -04:00
194 lines
5.8 KiB
C++
194 lines
5.8 KiB
C++
#include "d/snd/d_snd_3d_actor.h"
|
|
|
|
#include "common.h"
|
|
#include "d/a/d_a_player.h"
|
|
#include "d/snd/d_snd_3d_manager.h"
|
|
#include "d/snd/d_snd_checkers.h"
|
|
#include "d/snd/d_snd_mgr.h"
|
|
#include "d/snd/d_snd_player_mgr.h"
|
|
#include "d/snd/d_snd_state_mgr.h"
|
|
#include "nw4r/math/math_types.h"
|
|
|
|
#include <cmath>
|
|
|
|
dSnd3DActor_c::dSnd3DActor_c(dSndSourceParam *pSourceParam, s32 sourceType)
|
|
: nw4r::snd::Sound3DActor(
|
|
dSndPlayerMgr_c::GetInstance()->getSoundArchivePlayerForType(sourceType),
|
|
dSnd3DManager_c::GetInstance()->getManager()
|
|
),
|
|
a_field_0x7D(0),
|
|
mIsDisabled(false),
|
|
mIsDemoActor(false),
|
|
mIsPaused(false),
|
|
a_field_0x84(0.0f),
|
|
a_field_0x88(0.0f),
|
|
a_field_0x8C(0.0f),
|
|
a_field_0x90(INFINITY),
|
|
mDistanceToListener(INFINITY),
|
|
mCameraDirectionDot(0.0f),
|
|
mSpeed(0.0f),
|
|
mpSourceParam(pSourceParam),
|
|
mFlags(0),
|
|
mDistanceToPlayer(INFINITY),
|
|
mFxSend3D(0.0f) {
|
|
resetCachedRelativePositions();
|
|
// Portability hazard
|
|
SetUserParam(reinterpret_cast<u32>(this));
|
|
if (dSndPlayerMgr_c::GetInstance()->shouldUseDemoPlayer(sourceType)) {
|
|
mIsDemoActor = true;
|
|
}
|
|
}
|
|
|
|
void dSnd3DActor_c::setPosition(const nw4r::math::VEC3 &rPosition) {
|
|
SetPosition(rPosition);
|
|
mFxSend3D = dSndStateMgr_c::GetInstance()->getFxSend3D();
|
|
mFlags = 0;
|
|
}
|
|
|
|
void dSnd3DActor_c::resetCachedRelativePositions() {
|
|
mPositionRelativeToPlayer.x = INFINITY;
|
|
mPositionRelativeToPlayer.y = INFINITY;
|
|
mPositionRelativeToPlayer.z = INFINITY;
|
|
|
|
mPositionRelativeToListener.x = INFINITY;
|
|
mPositionRelativeToListener.y = INFINITY;
|
|
mPositionRelativeToListener.z = INFINITY;
|
|
|
|
mPositionTransformedByListener.x = INFINITY;
|
|
mPositionTransformedByListener.y = INFINITY;
|
|
mPositionTransformedByListener.z = INFINITY;
|
|
}
|
|
|
|
void dSnd3DActor_c::setSourceParam(const dSndSourceParam *param) {
|
|
*mpSourceParam = *param;
|
|
}
|
|
|
|
void dSnd3DActor_c::updatePositionRelativeToListener() {
|
|
if (!checkFlag(0x1)) {
|
|
calculatePositionRelativeToListener();
|
|
setFlag(0x1);
|
|
}
|
|
}
|
|
|
|
void dSnd3DActor_c::calculatePositionRelativeToListener() {
|
|
nw4r::math::VEC3Sub(
|
|
&mPositionRelativeToListener, &GetPosition(), &dSnd3DManager_c::GetInstance()->getSndListenerPos()
|
|
);
|
|
}
|
|
|
|
void dSnd3DActor_c::updateDistanceToListener() {
|
|
if (!checkFlag(0x2)) {
|
|
updatePositionRelativeToListener();
|
|
mDistanceToListener = VEC3Len(&mPositionRelativeToListener);
|
|
setFlag(0x2);
|
|
}
|
|
}
|
|
|
|
void dSnd3DActor_c::updatePositionTransformedByListener() {
|
|
if (!checkFlag(0x10)) {
|
|
MTXMultVec(
|
|
dSnd3DManager_c::GetInstance()->getSndListenerMatrix(), GetPosition(), mPositionTransformedByListener
|
|
);
|
|
setFlag(0x10);
|
|
}
|
|
}
|
|
|
|
void dSnd3DActor_c::updateCameraDirectionDot() {
|
|
if (!checkFlag(0x20)) {
|
|
updatePositionRelativeToListener();
|
|
nw4r::math::VEC3 norm;
|
|
VECNormalize(mPositionRelativeToListener, norm);
|
|
mCameraDirectionDot = nw4r::math::VEC3Dot(&norm, &dSnd3DManager_c::GetInstance()->getNrmCameraDirection());
|
|
setFlag(0x20);
|
|
}
|
|
}
|
|
|
|
void dSnd3DActor_c::updatePositionRelativeToCameraTarget() {
|
|
if (!checkFlag(0x4)) {
|
|
calculatePositionRelativeToCameraTarget();
|
|
setFlag(0x4);
|
|
}
|
|
}
|
|
|
|
void dSnd3DActor_c::calculatePositionRelativeToCameraTarget() {
|
|
nw4r::math::VEC3Sub(
|
|
&mPositionRelativeToCameraTarget, &GetPosition(), &dSnd3DManager_c::GetInstance()->getCameraTargetPos()
|
|
);
|
|
}
|
|
|
|
void dSnd3DActor_c::updateDistanceToCameraTarget() {
|
|
if (!checkFlag(0x8)) {
|
|
updatePositionRelativeToCameraTarget();
|
|
mDistanceToCameraTarget = VEC3Len(&mPositionRelativeToCameraTarget);
|
|
setFlag(0x8);
|
|
}
|
|
}
|
|
|
|
void dSnd3DActor_c::updatePositionRelativeToPlayer() {
|
|
if (!checkFlag(0x40)) {
|
|
nw4r::math::VEC3 linkTranslation = dAcPy_c::GetLink()->getCenterTranslation();
|
|
nw4r::math::VEC3 pos = GetPosition();
|
|
nw4r::math::VEC3Sub(&mPositionRelativeToPlayer, &pos, &linkTranslation);
|
|
|
|
setFlag(0x40);
|
|
}
|
|
}
|
|
|
|
const nw4r::math::VEC3 &dSnd3DActor_c::getPositionRelativeToPlayer() {
|
|
updatePositionRelativeToPlayer();
|
|
return mPositionRelativeToPlayer;
|
|
}
|
|
|
|
void dSnd3DActor_c::updateDistanceToPlayer() {
|
|
if (!checkFlag(0x80)) {
|
|
updatePositionRelativeToPlayer();
|
|
nw4r::math::VEC3 linkTranslation = dAcPy_c::GetLink()->getCenterTranslation();
|
|
nw4r::math::VEC3 pos = GetPosition();
|
|
if ((linkTranslation.x == 0.0f && linkTranslation.y == 0.0f && linkTranslation.z == 0.0f) ||
|
|
(pos.x == 0.0f && pos.y == 0.0f && pos.z == 0.0f)) {
|
|
// Don't bother if we received dummy values
|
|
mDistanceToPlayer = INFINITY;
|
|
} else {
|
|
mDistanceToPlayer = nw4r::math::VEC3Len(&mPositionRelativeToPlayer);
|
|
}
|
|
setFlag(0x80);
|
|
}
|
|
}
|
|
|
|
f32 dSnd3DActor_c::getDistanceToPlayer() {
|
|
updateDistanceToPlayer();
|
|
return mDistanceToPlayer;
|
|
}
|
|
|
|
// here are functions that are probably in part copied from nw4r::snd::Sound3DCalculator
|
|
|
|
bool dSnd3DActor_c::hasPlayingSounds() const {
|
|
for (int i = 0; i < ACTOR_PLAYER_COUNT; i++) {
|
|
if (GetPlayingSoundCount(i) > 0) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
bool dSnd3DActor_c::isPlayingSound(u32 id) {
|
|
bool result = false;
|
|
|
|
IsCurrentSoundIdChecker handler(id, &result);
|
|
ForEachSound(handler, false);
|
|
|
|
return result;
|
|
}
|
|
|
|
u32 dSnd3DActor_c::soundLabelToSoundId(const char *soundLabel) const {
|
|
return dSndPlayerMgr_c::GetInstance()->convertLabelStringToSoundId(soundLabel);
|
|
}
|
|
|
|
const char *dSnd3DActor_c::soundIdToSoundLabel(u32 soundId) const {
|
|
if (mIsDemoActor) {
|
|
return dSndPlayerMgr_c::GetInstance()->getDemoArchiveDirectly()->GetSoundLabelString(soundId);
|
|
} else {
|
|
return dSndMgr_c::getSoundLabelString(soundId);
|
|
}
|
|
}
|