mirror of
https://github.com/ZDoom/Raze.git
synced 2024-12-14 22:51:11 +00:00
0dbf3bbb1e
- Player Control updates - Minor modern types updates - There was removed GDX prefix for all modern stuff # Conflicts: # source/blood/src/aiunicult.cpp # source/blood/src/aiunicult.h # source/blood/src/mapedit.cpp # source/blood/src/player.h # source/blood/src/sfx.h
509 lines
15 KiB
C++
509 lines
15 KiB
C++
//-------------------------------------------------------------------------
|
|
/*
|
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
|
Copyright (C) 2019 Nuke.YKT
|
|
|
|
This file is part of NBlood.
|
|
|
|
NBlood is free software; you can redistribute it and/or
|
|
modify it under the terms of the GNU General Public License version 2
|
|
as published by the Free Software Foundation.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
|
See the GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
*/
|
|
//-------------------------------------------------------------------------
|
|
#include "ns.h" // Must come before everything else!
|
|
|
|
#include <string.h>
|
|
#include "build.h"
|
|
#include "compat.h"
|
|
#include "common_game.h"
|
|
#include "fx_man.h"
|
|
|
|
#include "config.h"
|
|
#include "gameutil.h"
|
|
#include "player.h"
|
|
#include "resource.h"
|
|
#include "sfx.h"
|
|
#include "sound.h"
|
|
#include "trig.h"
|
|
|
|
BEGIN_BLD_NS
|
|
|
|
POINT2D earL, earR, earL0, earR0; // Ear position
|
|
VECTOR2D earVL, earVR; // Ear velocity ?
|
|
int lPhase, rPhase, lVol, rVol, lPitch, rPitch;
|
|
|
|
BONKLE Bonkle[256];
|
|
BONKLE *BonkleCache[256];
|
|
|
|
int nBonkles;
|
|
|
|
void sfxInit(void)
|
|
{
|
|
for (int i = 0; i < 256; i++)
|
|
BonkleCache[i] = &Bonkle[i];
|
|
nBonkles = 0;
|
|
}
|
|
|
|
void sfxTerm()
|
|
{
|
|
}
|
|
|
|
int Vol3d(int angle, int dist)
|
|
{
|
|
return dist - mulscale16(dist, 0x2000 - mulscale30(0x2000, Cos(angle)));
|
|
}
|
|
|
|
void Calc3DValues(BONKLE *pBonkle)
|
|
{
|
|
int dx = pBonkle->at20.x - gMe->pSprite->x;
|
|
int dy = pBonkle->at20.y - gMe->pSprite->y;
|
|
int dz = pBonkle->at20.z - gMe->pSprite->z;
|
|
int angle = getangle(dx, dy);
|
|
dx >>= 4;
|
|
dy >>= 4;
|
|
dz >>= 8;
|
|
int distance = ksqrt(dx*dx + dy * dy + dz * dz);
|
|
distance = ClipLow((distance >> 2) + (distance >> 3), 64);
|
|
int v14, v18;
|
|
v14 = v18 = scale(pBonkle->at1c, 80, distance);
|
|
int sinVal = Sin(angle);
|
|
int cosVal = Cos(angle);
|
|
int v8 = dmulscale30r(cosVal, pBonkle->at20.x - pBonkle->at2c.x, sinVal, pBonkle->at20.y - pBonkle->at2c.y);
|
|
|
|
int distanceL = approxDist(pBonkle->at20.x - earL.x, pBonkle->at20.y - earL.y);
|
|
lVol = Vol3d(angle - (gMe->pSprite->ang - 85), v18);
|
|
int phaseLeft = mulscale16r(distanceL, pBonkle->at3c == 1 ? 4114 : 8228);
|
|
lPitch = scale(pBonkle->at18, dmulscale30r(cosVal, earVL.dx, sinVal, earVL.dy) + 5853, v8 + 5853);
|
|
|
|
int distanceR = approxDist(pBonkle->at20.x - earR.x, pBonkle->at20.y - earR.y);
|
|
rVol = Vol3d(angle - (gMe->pSprite->ang + 85), v14);
|
|
int phaseRight = mulscale16r(distanceR, pBonkle->at3c == 1 ? 4114 : 8228);
|
|
rPitch = scale(pBonkle->at18, dmulscale30r(cosVal, earVR.dx, sinVal, earVR.dy) + 5853, v8 + 5853);
|
|
|
|
int phaseMin = ClipHigh(phaseLeft, phaseRight);
|
|
lPhase = phaseRight - phaseMin;
|
|
rPhase = phaseLeft - phaseMin;
|
|
}
|
|
|
|
void sfxPlay3DSound(int x, int y, int z, int soundId, int nSector)
|
|
{
|
|
if (!SoundEnabled() || soundId < 0) return;
|
|
|
|
DICTNODE *hRes = gSoundRes.Lookup(soundId, "SFX");
|
|
if (!hRes)return;
|
|
|
|
SFX *pEffect = (SFX*)gSoundRes.Load(hRes);
|
|
hRes = gSoundRes.Lookup(pEffect->rawName, "RAW");
|
|
if (!hRes) return;
|
|
|
|
int v1c, v18;
|
|
v1c = v18 = mulscale16(pEffect->pitch, sndGetRate(pEffect->format));
|
|
if (nBonkles >= 256)
|
|
return;
|
|
BONKLE *pBonkle = BonkleCache[nBonkles++];
|
|
pBonkle->at10 = NULL;
|
|
pBonkle->at20.x = x;
|
|
pBonkle->at20.y = y;
|
|
pBonkle->at20.z = z;
|
|
pBonkle->at38 = nSector;
|
|
FindSector(x, y, z, &pBonkle->at38);
|
|
pBonkle->at2c = pBonkle->at20;
|
|
pBonkle->atc = soundId;
|
|
pBonkle->at8 = hRes;
|
|
pBonkle->at1c = pEffect->relVol;
|
|
pBonkle->at18 = v18;
|
|
pBonkle->at3c = pEffect->format;
|
|
int size = hRes->Size();
|
|
char *pData = (char*)gSoundRes.Lock(hRes);
|
|
Calc3DValues(pBonkle);
|
|
int priority = 1;
|
|
if (priority < lVol)
|
|
priority = lVol;
|
|
if (priority < rVol)
|
|
priority = rVol;
|
|
if (snd_doppler)
|
|
{
|
|
MV_Lock();
|
|
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)&pBonkle->at0);
|
|
pBonkle->at4 = FX_PlayRaw(pData + rPhase, size - rPhase, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)&pBonkle->at4);
|
|
MV_Unlock();
|
|
}
|
|
else
|
|
{
|
|
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, v1c, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)&pBonkle->at0);
|
|
pBonkle->at4 = 0;
|
|
}
|
|
}
|
|
|
|
void sfxPlay3DSound(spritetype *pSprite, int soundId, int a3, int a4)
|
|
{
|
|
if (!SoundEnabled())
|
|
return;
|
|
if (!pSprite)
|
|
return;
|
|
if (soundId < 0)
|
|
return;
|
|
DICTNODE *hRes = gSoundRes.Lookup(soundId, "SFX");
|
|
if (!hRes)
|
|
return;
|
|
|
|
SFX *pEffect = (SFX*)gSoundRes.Load(hRes);
|
|
hRes = gSoundRes.Lookup(pEffect->rawName, "RAW");
|
|
if (!hRes)
|
|
return;
|
|
int size = hRes->Size();
|
|
if (size <= 0)
|
|
return;
|
|
int v14;
|
|
v14 = mulscale16(pEffect->pitch, sndGetRate(pEffect->format));
|
|
BONKLE *pBonkle = NULL;
|
|
if (a3 >= 0)
|
|
{
|
|
int i;
|
|
for (i = 0; i < nBonkles; i++)
|
|
{
|
|
pBonkle = BonkleCache[i];
|
|
if (pBonkle->at14 == a3 && (pBonkle->at10 == pSprite || (a4 & 1) != 0))
|
|
{
|
|
if ((a4 & 4) != 0 && pBonkle->at14 == a3)
|
|
return;
|
|
if ((a4 & 2) != 0 && pBonkle->atc == soundId)
|
|
return;
|
|
if (pBonkle->at0 > 0)
|
|
FX_StopSound(pBonkle->at0);
|
|
if (pBonkle->at4 > 0)
|
|
FX_StopSound(pBonkle->at4);
|
|
if (pBonkle->at8)
|
|
{
|
|
gSoundRes.Unlock(pBonkle->at8);
|
|
pBonkle->at8 = NULL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (i == nBonkles)
|
|
{
|
|
if (nBonkles >= 256)
|
|
return;
|
|
pBonkle = BonkleCache[nBonkles++];
|
|
}
|
|
pBonkle->at10 = pSprite;
|
|
pBonkle->at14 = a3;
|
|
}
|
|
else
|
|
{
|
|
if (nBonkles >= 256)
|
|
return;
|
|
pBonkle = BonkleCache[nBonkles++];
|
|
pBonkle->at10 = NULL;
|
|
}
|
|
pBonkle->at20.x = pSprite->x;
|
|
pBonkle->at20.y = pSprite->y;
|
|
pBonkle->at20.z = pSprite->z;
|
|
pBonkle->at38 = pSprite->sectnum;
|
|
pBonkle->at2c = pBonkle->at20;
|
|
pBonkle->atc = soundId;
|
|
pBonkle->at8 = hRes;
|
|
pBonkle->at1c = pEffect->relVol;
|
|
pBonkle->at18 = v14;
|
|
Calc3DValues(pBonkle);
|
|
int priority = 1;
|
|
if (priority < lVol)
|
|
priority = lVol;
|
|
if (priority < rVol)
|
|
priority = rVol;
|
|
int loopStart = pEffect->loopStart;
|
|
int loopEnd = ClipLow(size - 1, 0);
|
|
if (a3 < 0)
|
|
loopStart = -1;
|
|
MV_Lock();
|
|
char *pData = (char*)gSoundRes.Lock(hRes);
|
|
if (loopStart >= 0)
|
|
{
|
|
if (snd_doppler)
|
|
{
|
|
pBonkle->at0 = FX_PlayLoopedRaw(pData + lPhase, size - lPhase, pData + loopStart, pData + loopEnd, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)&pBonkle->at0);
|
|
pBonkle->at4 = FX_PlayLoopedRaw(pData + rPhase, size - rPhase, pData + loopStart, pData + loopEnd, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)&pBonkle->at4);
|
|
}
|
|
else
|
|
{
|
|
pBonkle->at0 = FX_PlayLoopedRaw(pData + lPhase, size - lPhase, pData + loopStart, pData + loopEnd, v14, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)&pBonkle->at0);
|
|
pBonkle->at4 = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pData = (char*)gSoundRes.Lock(pBonkle->at8);
|
|
if (snd_doppler)
|
|
{
|
|
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)&pBonkle->at0);
|
|
pBonkle->at4 = FX_PlayRaw(pData + rPhase, size - rPhase, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)&pBonkle->at4);
|
|
}
|
|
else
|
|
{
|
|
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, v14, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)&pBonkle->at0);
|
|
pBonkle->at4 = 0;
|
|
}
|
|
}
|
|
MV_Unlock();
|
|
}
|
|
|
|
// By NoOne: same as previous, but allows to set custom pitch for sound AND volume. Used by SFX gen now.
|
|
void sfxPlay3DSoundCP(spritetype* pSprite, int soundId, int a3, int a4, int pitch, int volume)
|
|
{
|
|
if (!SoundEnabled() || !pSprite || soundId < 0) return;
|
|
DICTNODE* hRes = gSoundRes.Lookup(soundId, "SFX");
|
|
if (!hRes) return;
|
|
|
|
SFX* pEffect = (SFX*)gSoundRes.Load(hRes);
|
|
hRes = gSoundRes.Lookup(pEffect->rawName, "RAW");
|
|
if (!hRes) return;
|
|
int size = hRes->Size();
|
|
if (size <= 0) return;
|
|
|
|
if (pitch <= 0) pitch = pEffect->pitch;
|
|
else pitch -= Random(pEffect->pitchRange);
|
|
|
|
int v14;
|
|
v14 = mulscale16(pitch, sndGetRate(pEffect->format));
|
|
|
|
BONKLE * pBonkle = NULL;
|
|
if (a3 >= 0)
|
|
{
|
|
int i;
|
|
for (i = 0; i < nBonkles; i++)
|
|
{
|
|
pBonkle = BonkleCache[i];
|
|
if (pBonkle->at14 == a3 && (pBonkle->at10 == pSprite || (a4 & 1) != 0))
|
|
{
|
|
if ((a4 & 4) != 0 && pBonkle->at14 == a3)
|
|
return;
|
|
if ((a4 & 2) != 0 && pBonkle->atc == soundId)
|
|
return;
|
|
if (pBonkle->at0 > 0)
|
|
FX_StopSound(pBonkle->at0);
|
|
if (pBonkle->at4 > 0)
|
|
FX_StopSound(pBonkle->at4);
|
|
if (pBonkle->at8)
|
|
{
|
|
gSoundRes.Unlock(pBonkle->at8);
|
|
pBonkle->at8 = NULL;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
if (i == nBonkles)
|
|
{
|
|
if (nBonkles >= 256)
|
|
return;
|
|
pBonkle = BonkleCache[nBonkles++];
|
|
}
|
|
pBonkle->at10 = pSprite;
|
|
pBonkle->at14 = a3;
|
|
}
|
|
else
|
|
{
|
|
if (nBonkles >= 256)
|
|
return;
|
|
pBonkle = BonkleCache[nBonkles++];
|
|
pBonkle->at10 = NULL;
|
|
}
|
|
pBonkle->at20.x = pSprite->x;
|
|
pBonkle->at20.y = pSprite->y;
|
|
pBonkle->at20.z = pSprite->z;
|
|
pBonkle->at38 = pSprite->sectnum;
|
|
pBonkle->at2c = pBonkle->at20;
|
|
pBonkle->atc = soundId;
|
|
pBonkle->at8 = hRes;
|
|
pBonkle->at1c = ((volume == 0) ? pEffect->relVol : ((volume == -1) ? 0 : ((volume > 255) ? 255 : volume)));
|
|
pBonkle->at18 = v14;
|
|
Calc3DValues(pBonkle);
|
|
int priority = 1;
|
|
if (priority < lVol)
|
|
priority = lVol;
|
|
if (priority < rVol)
|
|
priority = rVol;
|
|
int loopStart = pEffect->loopStart;
|
|
int loopEnd = ClipLow(size - 1, 0);
|
|
if (a3 < 0)
|
|
loopStart = -1;
|
|
MV_Lock();
|
|
char* pData = (char*)gSoundRes.Lock(hRes);
|
|
if (loopStart >= 0)
|
|
{
|
|
if (snd_doppler)
|
|
{
|
|
pBonkle->at0 = FX_PlayLoopedRaw(pData + lPhase, size - lPhase, pData + loopStart, pData + loopEnd, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)& pBonkle->at0);
|
|
pBonkle->at4 = FX_PlayLoopedRaw(pData + rPhase, size - rPhase, pData + loopStart, pData + loopEnd, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)& pBonkle->at4);
|
|
}
|
|
else
|
|
{
|
|
pBonkle->at0 = FX_PlayLoopedRaw(pData + lPhase, size - lPhase, pData + loopStart, pData + loopEnd, v14, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)& pBonkle->at0);
|
|
pBonkle->at4 = 0;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pData = (char*)gSoundRes.Lock(pBonkle->at8);
|
|
if (snd_doppler)
|
|
{
|
|
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, lPitch, 0, lVol, lVol, 0, priority, 1.f, (intptr_t)& pBonkle->at0);
|
|
pBonkle->at4 = FX_PlayRaw(pData + rPhase, size - rPhase, rPitch, 0, rVol, 0, rVol, priority, 1.f, (intptr_t)& pBonkle->at4);
|
|
}
|
|
else
|
|
{
|
|
pBonkle->at0 = FX_PlayRaw(pData + lPhase, size - lPhase, v14, 0, lVol, lVol, rVol, priority, 1.f, (intptr_t)& pBonkle->at0);
|
|
pBonkle->at4 = 0;
|
|
}
|
|
}
|
|
MV_Unlock();
|
|
}
|
|
|
|
|
|
void sfxKill3DSound(spritetype *pSprite, int a2, int a3)
|
|
{
|
|
if (!pSprite)
|
|
return;
|
|
for (int i = nBonkles - 1; i >= 0; i--)
|
|
{
|
|
BONKLE *pBonkle = BonkleCache[i];
|
|
if (pBonkle->at10 == pSprite && (a2 < 0 || a2 == pBonkle->at14) && (a3 < 0 || a3 == pBonkle->atc))
|
|
{
|
|
if (pBonkle->at0 > 0)
|
|
{
|
|
FX_EndLooping(pBonkle->at0);
|
|
FX_StopSound(pBonkle->at0);
|
|
}
|
|
if (pBonkle->at4 > 0)
|
|
{
|
|
FX_EndLooping(pBonkle->at4);
|
|
FX_StopSound(pBonkle->at4);
|
|
}
|
|
if (pBonkle->at8)
|
|
{
|
|
gSoundRes.Unlock(pBonkle->at8);
|
|
pBonkle->at8 = NULL;
|
|
}
|
|
BonkleCache[i] = BonkleCache[--nBonkles];
|
|
BonkleCache[nBonkles] = pBonkle;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sfxKillAllSounds(void)
|
|
{
|
|
for (int i = nBonkles - 1; i >= 0; i--)
|
|
{
|
|
BONKLE *pBonkle = BonkleCache[i];
|
|
if (pBonkle->at0 > 0)
|
|
{
|
|
FX_EndLooping(pBonkle->at0);
|
|
FX_StopSound(pBonkle->at0);
|
|
}
|
|
if (pBonkle->at4 > 0)
|
|
{
|
|
FX_EndLooping(pBonkle->at4);
|
|
FX_StopSound(pBonkle->at4);
|
|
}
|
|
if (pBonkle->at8)
|
|
{
|
|
gSoundRes.Unlock(pBonkle->at8);
|
|
pBonkle->at8 = NULL;
|
|
}
|
|
BonkleCache[i] = BonkleCache[--nBonkles];
|
|
BonkleCache[nBonkles] = pBonkle;
|
|
}
|
|
}
|
|
|
|
void sfxUpdate3DSounds(void)
|
|
{
|
|
int dx = mulscale30(Cos(gMe->pSprite->ang + 512), 43);
|
|
earL0 = earL;
|
|
int dy = mulscale30(Sin(gMe->pSprite->ang + 512), 43);
|
|
earR0 = earR;
|
|
earL.x = gMe->pSprite->x - dx;
|
|
earL.y = gMe->pSprite->y - dy;
|
|
earR.x = gMe->pSprite->x + dx;
|
|
earR.y = gMe->pSprite->y + dy;
|
|
earVL.dx = earL.x - earL0.x;
|
|
earVL.dy = earL.y - earL0.y;
|
|
earVR.dx = earR.x - earR0.x;
|
|
earVR.dy = earR.y - earR0.y;
|
|
for (int i = nBonkles - 1; i >= 0; i--)
|
|
{
|
|
BONKLE *pBonkle = BonkleCache[i];
|
|
if (pBonkle->at0 > 0 || pBonkle->at4 > 0)
|
|
{
|
|
if (!pBonkle->at8)
|
|
continue;
|
|
if (pBonkle->at10)
|
|
{
|
|
pBonkle->at2c = pBonkle->at20;
|
|
pBonkle->at20.x = pBonkle->at10->x;
|
|
pBonkle->at20.y = pBonkle->at10->y;
|
|
pBonkle->at20.z = pBonkle->at10->z;
|
|
pBonkle->at38 = pBonkle->at10->sectnum;
|
|
}
|
|
Calc3DValues(pBonkle);
|
|
MV_Lock();
|
|
if (pBonkle->at0 > 0)
|
|
{
|
|
if (pBonkle->at4 > 0)
|
|
{
|
|
FX_SetPan(pBonkle->at0, lVol, lVol, 0);
|
|
FX_SetFrequency(pBonkle->at0, lPitch);
|
|
}
|
|
else
|
|
FX_SetPan(pBonkle->at0, lVol, lVol, rVol);
|
|
}
|
|
if (pBonkle->at4 > 0)
|
|
{
|
|
FX_SetPan(pBonkle->at4, rVol, 0, rVol);
|
|
FX_SetFrequency(pBonkle->at4, rPitch);
|
|
}
|
|
MV_Unlock();
|
|
}
|
|
else
|
|
{
|
|
gSoundRes.Unlock(pBonkle->at8);
|
|
pBonkle->at8 = NULL;
|
|
BonkleCache[i] = BonkleCache[--nBonkles];
|
|
BonkleCache[nBonkles] = pBonkle;
|
|
}
|
|
}
|
|
}
|
|
|
|
void sfxSetReverb(bool toggle)
|
|
{
|
|
if (toggle)
|
|
{
|
|
FX_SetReverb(128);
|
|
FX_SetReverbDelay(10);
|
|
}
|
|
else
|
|
FX_SetReverb(0);
|
|
}
|
|
|
|
void sfxSetReverb2(bool toggle)
|
|
{
|
|
if (toggle)
|
|
{
|
|
FX_SetReverb(128);
|
|
FX_SetReverbDelay(20);
|
|
}
|
|
else
|
|
FX_SetReverb(0);
|
|
}
|
|
|
|
END_BLD_NS
|