1
0
Fork 0
mirror of https://github.com/galaxyhaxz/devilution synced 2025-02-23 12:44:54 +00:00
devilution/2020_03_31/Source/effects.cpp

432 lines
7.1 KiB
C++
Raw Normal View History

2020-11-28 18:24:54 -06:00
#include "diablo.h"
#include "../3rdParty/Storm/Source/storm.h"
int sfxdelay; // weak
int sfxdnum;
HANDLE sghStream;
TSFX *sgpStreamSFX;
const char monster_action_sounds[] = { 'a', 'h', 'd', 's' }; // idb
/* data */
TSFX sgSFX[NUM_SFX] =
{
#include "Data/xl_sfx.cpp"
};
BOOL effect_is_playing(int nSFX)
{
TSFX *pSFX;
/// ASSERT: assert(nSFX < NUM_SFX);
pSFX = &sgSFX[nSFX];
if(pSFX->pSnd != NULL) {
return snd_playing(pSFX->pSnd);
}
if(pSFX->bFlags & 1) {
return pSFX == sgpStreamSFX;
}
return FALSE;
}
void stream_stop()
{
if(sghStream != NULL) {
SFileDdaEnd(sghStream);
SFileCloseFile(sghStream);
sghStream = NULL;
sgpStreamSFX = NULL;
}
}
static void stream_play(TSFX *pSFX, long lVolume, long lPan)
{
BOOL bSuccess;
/// ASSERT: assert(pSFX);
/// ASSERT: assert(pSFX->bFlags & sfx_STREAM);
stream_stop();
lVolume += sound_get_or_set_sound_volume(1);
if(lVolume < VOLUME_MIN) {
return;
}
if(lVolume > VOLUME_MAX) {
lVolume = VOLUME_MAX;
}
#ifdef _DEBUG
SFileEnableDirectAccess(FALSE);
#endif
bSuccess = SFileOpenFile(pSFX->pszName, &sghStream);
#ifdef _DEBUG
SFileEnableDirectAccess(TRUE);
#endif
if(!bSuccess) {
sghStream = NULL;
return;
}
if(!SFileDdaBeginEx(sghStream, 0x40000, 0, 0, lVolume, lPan, 0)) {
stream_stop();
return;
}
sgpStreamSFX = pSFX;
}
static void stream_update()
{
DWORD dwStart, dwEnd;
if(sghStream == NULL) {
return;
}
if(!SFileDdaGetPos(sghStream, &dwStart, &dwEnd)) {
return;
}
if(dwStart < dwEnd) {
return;
}
stream_stop();
}
static void sfx_stop()
{
int i;
TSFX *pSFX;
pSFX = sgSFX;
i = NUM_SFX;
while(i--) {
if(pSFX->pSnd != NULL) {
snd_stop_snd(pSFX->pSnd);
}
pSFX++;
}
}
void InitMonsterSND(int monst)
{
int mtype, mode, nr;
TSnd *pSnd;
char *pszFile;
char szName[MAX_PATH];
if(!gbSndInited) {
return;
}
mtype = Monsters[monst].mtype;
for(mode = 0; mode < 4; mode++) {
if(monster_action_sounds[mode] == 's' && !monsterdata[mtype].snd_special) {
continue;
}
for(nr = 0; nr < 2; nr++) {
sprintf(szName, monsterdata[mtype].sndfile, monster_action_sounds[mode], nr + 1);
pszFile = (char *)DiabloAllocPtr(strlen(szName) + 1);
strcpy(pszFile, szName);
pSnd = sound_file_load(pszFile);
Monsters[monst].Snds[mode][nr] = pSnd;
if(pSnd == NULL) {
MemFreeDbg(pszFile);
}
}
}
}
void FreeMonsterSnd()
{
int mi, mode, nr;
TSnd *pSnd;
char *pszFile;
for(mi = 0; mi < nummtypes; mi++) {
for(mode = 0; mode < 4; mode++) {
for(nr = 0; nr < 2; nr++) {
pSnd = Monsters[mi].Snds[mode][nr];
if(pSnd == NULL) {
continue;
}
Monsters[mi].Snds[mode][nr] = NULL;
pszFile = pSnd->sound_path;
pSnd->sound_path = NULL;
sound_file_cleanup(pSnd);
MemFreeDbg(pszFile);
}
}
}
}
static BOOL calc_snd_position(int x, int y, long *plVolume, long *plPan)
{
long volume, pan;
x -= plr[myplr].WorldX;
y -= plr[myplr].WorldY;
pan = x - y;
*plPan = pan << 8;
if(abs(*plPan) > 6400) {
return FALSE;
}
volume = abs(x) > abs(y) ? abs(x) : abs(y);
*plVolume = volume << 6;
if(*plVolume >= 6400) {
return FALSE;
}
*plVolume = -*plVolume;
return TRUE;
}
static void PlaySFX_priv(TSFX *pSFX, BOOL loc, int x, int y)
{
long lPan, lVolume;
if(plr[myplr].pLvlLoad != 0 && gbMaxPlayers != 1) {
return;
}
if(!gbSndInited || !gbSoundOn) {
return;
}
if(gbBufferMsgs != 0) {
return;
}
if(!(pSFX->bFlags & 3) && pSFX->pSnd != NULL && snd_playing(pSFX->pSnd)) {
return;
}
lPan = 0;
lVolume = 0;
if(loc && !calc_snd_position(x, y, &lVolume, &lPan)) {
return;
}
if(pSFX->bFlags & 1) {
stream_play(pSFX, lVolume, lPan);
} else {
if(pSFX->pSnd == NULL) {
pSFX->pSnd = sound_file_load(pSFX->pszName);
}
if(pSFX->pSnd != NULL) {
snd_play_snd(pSFX->pSnd, lVolume, lPan);
}
}
}
void PlayEffect(int i, int mode)
{
int mi, nr;
long lPan, lVolume;
TSnd *pSnd;
if(plr[myplr].pLvlLoad != 0) {
return;
}
nr = random(164, 2);
if(!gbSndInited || !gbSoundOn) {
return;
}
if(gbBufferMsgs != 0) {
return;
}
mi = monster[i]._mMTidx;
pSnd = Monsters[mi].Snds[mode][nr];
if(pSnd == NULL) {
#ifdef _DEBUG
app_fatal("Monster sound problem\n:%s playing %i", Monsters[mi].MData->mName, mode);
#endif
return;
}
if(snd_playing(pSnd)) {
return;
}
if(!calc_snd_position(monster[i]._mx, monster[i]._my, &lVolume, &lPan)) {
return;
}
snd_play_snd(pSnd, lVolume, lPan);
}
static int RndSFX(int psfx)
{
int nRand;
if(psfx == PS_WARR69) {
nRand = 2;
} else if(psfx == PS_WARR14) {
nRand = 3;
} else if(psfx == PS_WARR15) {
nRand = 3;
} else if(psfx == PS_WARR16) {
nRand = 3;
} else if(psfx == PS_MAGE69) {
nRand = 2;
} else if(psfx == PS_ROGUE69) {
nRand = 2;
} else if(psfx == PS_SWING) {
nRand = 2;
} else if(psfx == LS_ACID) {
nRand = 2;
} else if(psfx == IS_FMAG) {
nRand = 2;
} else if(psfx == IS_MAGIC) {
nRand = 2;
} else if(psfx == IS_BHIT) {
nRand = 2;
} else if(psfx == PS_WARR2) {
nRand = 3;
} else {
return psfx;
}
return random(165, nRand) + psfx;
}
void PlaySFX(int psfx)
{
psfx = RndSFX(psfx);
/// ASSERT: assert(psfx < NUM_SFX);
PlaySFX_priv(&sgSFX[psfx], FALSE, 0, 0);
}
void PlaySfxLoc(int psfx, int x, int y)
{
psfx = RndSFX(psfx);
/// ASSERT: assert(psfx < NUM_SFX);
if(psfx >= PS_WALK1 && psfx <= PS_WALK4 && sgSFX[psfx].pSnd != NULL) {
sgSFX[psfx].pSnd->start_tc = 0;
}
PlaySFX_priv(&sgSFX[psfx], TRUE, x, y);
}
void sound_stop()
{
int mi, mode, nr;
snd_update(TRUE);
stream_stop();
sfx_stop();
for(mi = 0; mi < nummtypes; mi++) {
for(mode = 0; mode < 4; mode++) {
for(nr = 0; nr < 2; nr++) {
snd_stop_snd(Monsters[mi].Snds[mode][nr]);
}
}
}
}
void sound_update()
{
if(!gbSndInited) {
return;
}
snd_update(FALSE);
stream_update();
}
void effects_cleanup_sfx()
{
int i;
sound_stop();
for(i = 0; (DWORD)i < NUM_SFX; i++) {
if(sgSFX[i].pSnd == NULL) {
continue;
}
sound_file_cleanup(sgSFX[i].pSnd);
sgSFX[i].pSnd = NULL;
}
}
static void priv_sound_init(BYTE bLoadMask)
{
BYTE pc;
int i;
if(!gbSndInited) {
return;
}
pc = bLoadMask & (0x20 | 0x10 | 0x40);
bLoadMask ^= pc;
for(i = 0; (DWORD)i < NUM_SFX; i++) {
if(sgSFX[i].pSnd != NULL) {
continue;
}
if(sgSFX[i].bFlags & 1) {
continue;
}
if(bLoadMask != 0 && !(sgSFX[i].bFlags & bLoadMask)) {
continue;
}
if(sgSFX[i].bFlags & (0x20 | 0x10 | 0x40) && !(sgSFX[i].bFlags & pc)) {
continue;
}
sgSFX[i].pSnd = sound_file_load(sgSFX[i].pszName);
}
}
void sound_init()
{
BYTE bLoadMask;
bLoadMask = 0;
if(gbMaxPlayers > 1) {
bLoadMask = 0x20 | 0x10 | 0x40;
} else {
if(plr[myplr]._pClass == PC_WARRIOR) {
bLoadMask = 0x20;
} else if(plr[myplr]._pClass == PC_ROGUE) {
bLoadMask = 0x10;
} else if(plr[myplr]._pClass == PC_SORCERER) {
bLoadMask = 0x40;
} else {
app_fatal("effects:1");
}
}
priv_sound_init(bLoadMask);
}
void ui_sound_init()
{
priv_sound_init(4);
}
void __stdcall effects_play_sound(const char *pszFile)
{
int i;
if(!gbSndInited || !gbSoundOn) {
return;
}
for(i = 0; (DWORD)i < NUM_SFX; i++) {
if(_strcmpi(sgSFX[i].pszName, pszFile) == 0 && sgSFX[i].pSnd != NULL) {
if(!snd_playing(sgSFX[i].pSnd)) {
snd_play_snd(sgSFX[i].pSnd, 0, 0);
}
return;
}
}
}