diff --git a/src/SB/Core/x/xSFX.cpp b/src/SB/Core/x/xSFX.cpp index acf1e0a1b..a4fcb046e 100644 --- a/src/SB/Core/x/xSFX.cpp +++ b/src/SB/Core/x/xSFX.cpp @@ -2,18 +2,99 @@ #include "xSnd.h" #include "xEvent.h" +#include "xpkrsvc.h" +#include "xstransvc.h" +#include "zScene.h" +#include "zEntPlayer.h" #include #include -extern xSFX* s_managedEnvSFX[1]; +static xSFX* s_managedEnvSFX[1] = { NULL }; + +static void xSFXUpdate(xSFX* t); +static void xSFXPlay(xSFX* t); +static void xSFXStop(xSFX* t); void xSFXEnvironmentalStreamSceneExit(void) { memset(&s_managedEnvSFX, 0, 4); } -S32 xSFXWillSendDone(xSFX* param_1) +void xSFXUpdateEnvironmentalStreamSounds(xSFX* pSFXList, U32 numSounds) +{ + static xSFX* bestSFX[1]; + static F32 bestDist2[1]; + + for (U32 i = 0; i < numSounds; i++) + { + xSFXUpdate(&pSFXList[i]); + } + + memset(bestSFX, 0, sizeof(bestSFX)); + + for (U32 j = 0; j < numSounds; j++) + { + if (!(pSFXList[j].asset->flagsSFX & 0x200) || !(pSFXList[j].asset->flagsSFX & 0x1000)) + { + continue; + } + + xVec3 playPos; + xSndProcessSoundPos(&pSFXList[j].asset->pos, &playPos); + + xVec3 delta = gSnd.pos - playPos; + + F32 dist = xVec3Length2(&delta); + if (dist > pSFXList[j].cachedOuterDistSquared) + { + break; + } + + if (bestSFX == NULL) + { + *bestSFX = &pSFXList[j]; + *bestDist2 = dist; + } + else if ((*bestSFX)->asset->priority < pSFXList[j].asset->priority) + { + *bestSFX = &pSFXList[j]; + *bestDist2 = dist; + } + else if ((*bestSFX)->asset->priority == pSFXList[j].asset->priority && dist > *bestDist2) + { + *bestSFX = &pSFXList[j]; + *bestDist2 = dist; + } + } + + bool found = false; + if (*s_managedEnvSFX == *bestSFX) + { + *bestSFX = NULL; + found = true; + } + + if (!found && *s_managedEnvSFX != NULL) + { + xSFXStop(*s_managedEnvSFX); + s_managedEnvSFX[0]->id = 0x0; + } + + if (*bestSFX != NULL) + { + if (*s_managedEnvSFX != NULL) + { + *s_managedEnvSFX = *bestSFX; + } + else + { + xSFXPlay(*bestSFX); + } + } +} + +static bool xSFXWillSendDone(xSFX* param_1) { S32 iLink = param_1->linkCount; @@ -25,13 +106,13 @@ S32 xSFXWillSendDone(xSFX* param_1) { if (pLink->srcEvent == 0xbf) { - return 1; + return true; } pLink++; } } - return 0; + return false; } void xSFXInit(void* t, void* asset) @@ -44,7 +125,6 @@ void xSFXInit(xSFX* t, xSFXAsset* asset) { xBaseInit(t, asset); - // S32 xSFXEventCB(xBase* to, xBase* from, U32 toEvent, const F32* toParam, xBase*) t->eventFunc = &xSFXEventCB; t->asset = asset; @@ -61,8 +141,8 @@ void xSFXInit(xSFX* t, xSFXAsset* asset) asset->flagsSFX = asset->flagsSFX | 0x800; } t->sndID = 0; - t->asset->flagsSFX = t->asset->flagsSFX & 0xefff; - t->cachedOuterDistSquared = (t->asset->outerRadius * t->asset->outerRadius); + t->asset->flagsSFX &= (U16) ~0x1000; + t->cachedOuterDistSquared = t->asset->outerRadius * t->asset->outerRadius; } void xSFXSave(xSFX* ent, xSerial* s) @@ -75,29 +155,151 @@ void xSFXLoad(xSFX* ent, xSerial* s) xBaseLoad(ent, s); } -void xSFXReset(xSFX* param_1) +void xSFXReset(xSFX* sfx) +{ + xBaseReset(sfx, sfx->asset); +} + +U32 xSFXConvertFlags(U32 flagsSFX) +{ + U32 flags = 0; + + if (flagsSFX & 4) { + flags |= 0x8000; + } + + return flags; +} + +static void xSFXUpdate(xSFX* t) { - xBaseReset(param_1, param_1->asset); + if ((t->asset->flagsSFX & 0x800) && (t->sndID) && + (!xSndIDIsPlaying(t->sndID))) + { + t->sndID = 0; + t->asset->flagsSFX = t->asset->flagsSFX & 0xefff; + zEntEvent(t, t, 0xbf); + } } -U32 xSFXConvertFlags(U32 param_1) +S32 xSFXEventCB(xBase* to, xBase* from, U32 toEvent, const F32* toParam, xBase* toParamWidget) { - return param_1 & 4 ? 0 : 0x800; + xSFX* t = (xSFX*)from; + + switch (toEvent) + { + case eEventReset: + xSFXReset(t); + break; + case eEventPlay: + t->asset->flagsSFX |= 0x1000; + if (!(t->asset->flagsSFX & 0x200)) + { + xSFXPlay(t); + } + break; + case eEventPlayMaybe: + if (xrand() % 100 >= toParam[0]) + { + t->asset->flagsSFX |= 0x1000; + if (!(t->asset->flagsSFX & 0x200)) + { + xSFXPlay(t); + } + } + break; + case eEventStop: + if (t->sndID != 0) + { + t->asset->flagsSFX &= 0xEFFF; + if (!(t->asset->flagsSFX & 0x200)) + { + xSFXStop(t); + } + } + + break; + case eEventPause: + while (true) + { + } + break; + } + + return 1; } -void xSFXUpdate(xSFX* param_1) +static void xSFXPlay(xSFX* t) { - if ((param_1->asset->flagsSFX & 0x800) && (param_1->sndID) && - (!xSndIDIsPlaying(param_1->sndID))) + st_PKR_ASSET_TOCINFO ainfo; + U32 converted_flags = xSFXConvertFlags(t->asset->flagsSFX); + + if (t->asset->flagsSFX & 0x2) + { + if (t->asset->flagsSFX & 0x8) + { + if (xSTGetAssetInfo(t->asset->attachID, &ainfo) == 0) + { + return; + } + + if (ainfo.typeref->typetag == 'MRKR') + { + t->sndID = xSndPlay3D(t->asset->soundAssetID, 0.77f * ((F32)t->asset->volume / 100.0f), + t->asset->freq * t->asset->freqm, (U32)t->asset->priority, converted_flags, + (const xVec3*)ainfo.mempos, t->asset->innerRadius, + t->asset->outerRadius, SND_CAT_GAME, 0.0f); + } + else + { + xEnt* attach = (xEnt*)zSceneFindObject(t->asset->attachID); + if (!attach) + { + xSTAssetName(t->id); + xSTAssetName(t->asset->attachID); + } + else if (attach->model != NULL) + { + t->sndID = xSndPlay3D(t->asset->soundAssetID, 0.77f * ((F32)t->asset->volume / 100.0f), + t->asset->freq * t->asset->freqm, (U32)t->asset->priority, converted_flags, + attach, t->asset->innerRadius, + t->asset->outerRadius, SND_CAT_GAME, 0.0f); + } + else + { + t->sndID = xSndPlay3D(t->asset->soundAssetID, 0.77f * ((F32)t->asset->volume / 100.0f), + t->asset->freq * t->asset->freqm, (U32)t->asset->priority, converted_flags, + (const xVec3*)&t->asset->pos, t->asset->innerRadius, + t->asset->outerRadius, SND_CAT_GAME, 0.0f); + return; + } + } + } + else + { + t->sndID = xSndPlay3D(t->asset->soundAssetID, 0.77f * ((F32)t->asset->volume / 100.0f), + t->asset->freq * t->asset->freqm, (U32)t->asset->priority, converted_flags, + (const xVec3*)&t->asset->pos, t->asset->innerRadius, + t->asset->outerRadius, SND_CAT_GAME, 0.0f); + } + } + else { - param_1->sndID = 0; - param_1->asset->flagsSFX = param_1->asset->flagsSFX & 0xefff; - zEntEvent(param_1, param_1, 0xbf); + t->sndID = + xSndPlay(t->asset->soundAssetID, 0.77f * (t->asset->volume / 100.0f), t->asset->freq * t->asset->freqm, + (U32)t->asset->priority, converted_flags, 0x0, SND_CAT_GAME, 0.0f); + + if ((t->asset->flagsSFX & 0x400) && t->sndID != 0) + { + zEntPlayer_SNDNotifyPlaying(t->sndID); + } } + + xEnt* ent; } -void xSFXStop(xSFX* param_1) +static void xSFXStop(xSFX* t) { - xSndStop(param_1->sndID); - param_1->sndID = 0; + xSndStop(t->sndID); + t->sndID = 0; } diff --git a/src/SB/Core/x/xSFX.h b/src/SB/Core/x/xSFX.h index 355d8cc8b..723c67903 100644 --- a/src/SB/Core/x/xSFX.h +++ b/src/SB/Core/x/xSFX.h @@ -33,9 +33,10 @@ void xSFXInit(void* t, void* asset); void xSFXInit(xSFX* t, xSFXAsset* asset); void xSFXSave(xSFX* ent, xSerial* s); void xSFXLoad(xSFX* ent, xSerial* s); +void xSFXReset(xSFX* sfx); void xSFXEnvironmentalStreamSceneExit(); void xSFXUpdateEnvironmentalStreamSounds(xSFX* pSFXList, U32 numSounds); -S32 xSFXEventCB(xBase* to, xBase* from, U32 toEvent, const F32* toParam, xBase*); -S32 xSFXWillSendDone(xSFX*); +S32 xSFXEventCB(xBase* to, xBase* from, U32 toEvent, const F32* toParam, xBase* toParamWidget); +U32 xSFXConvertFlags(U32 flagsSFX); #endif diff --git a/src/SB/Game/zEntPlayer.h b/src/SB/Game/zEntPlayer.h index 6acb59330..6279145d9 100644 --- a/src/SB/Game/zEntPlayer.h +++ b/src/SB/Game/zEntPlayer.h @@ -450,6 +450,7 @@ void zEntPlayer_SNDPlayStreamRandom(_tagePlayerStreamSnd player_snd_start, void zEntPlayer_SNDSetVol(_tagePlayerSnd player_snd, F32 new_vol); void zEntPlayer_SNDSetPitch(_tagePlayerSnd player_snd, F32 new_pitch); void zEntPlayer_SNDStop(_tagePlayerSnd player_snd); +void zEntPlayer_SNDNotifyPlaying(U32 id); void zEntPlayerSpeakStop();