mirror of
https://github.com/ZDoom/Raze.git
synced 2024-12-15 23:20:53 +00:00
e115058cd3
Also, not sure what to do re: map screen. OG seems to keep playing the currently playing track, which seems slightly janky? should we just play track 19? # Conflicts: # source/exhumed/src/cd.cpp # source/exhumed/src/cd.h
1203 lines
27 KiB
C++
1203 lines
27 KiB
C++
//-------------------------------------------------------------------------
|
|
/*
|
|
Copyright (C) 2010-2019 EDuke32 developers and contributors
|
|
Copyright (C) 2019 Nuke.YKT, sirlemonhead
|
|
This file is part of PCExhumed.
|
|
PCExhumed 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"
|
|
#include "compat.h"
|
|
#include "baselayer.h"
|
|
#include "renderlayer.h" // for win_gethwnd()
|
|
#include "build.h"
|
|
#include "cache1d.h"
|
|
#include "fx_man.h"
|
|
#include "keyboard.h"
|
|
#include "control.h"
|
|
#include "engine.h"
|
|
#include "exhumed.h"
|
|
#include "config.h"
|
|
#include "sound.h"
|
|
#include "init.h"
|
|
#include "object.h"
|
|
#include "player.h"
|
|
#include "random.h"
|
|
#include "snake.h"
|
|
#include "trigdat.h"
|
|
#include "sequence.h"
|
|
#include "cd.h"
|
|
|
|
BEGIN_PS_NS
|
|
|
|
#if 0
|
|
extern "C" {
|
|
#include "usrhooks.h"
|
|
#include "music.h"
|
|
#include "multivoc.h"
|
|
#include "fx_man.h"
|
|
#include "midi.h"
|
|
#include "mpu401.h"
|
|
}
|
|
#endif
|
|
|
|
short gMusicVolume = 200;
|
|
short gFXVolume = 200;
|
|
short nSoundsPlaying = 0;
|
|
short nAmbientChannel = -1;
|
|
|
|
short nStopSound;
|
|
short nStoneSound;
|
|
short nSwitchSound;
|
|
|
|
short nLocalEyeSect;
|
|
short nElevSound;
|
|
short nCreepyTimer;
|
|
|
|
const char *SoundFiles[kMaxSoundFiles] =
|
|
{
|
|
"spl_big",
|
|
"spl_smal",
|
|
"bubble_l",
|
|
"grn_drop",
|
|
"p_click",
|
|
"grn_roll",
|
|
"cosprite",
|
|
"m_chant0",
|
|
"anu_icu",
|
|
"item_reg",
|
|
"item_spe", // 10
|
|
"item_key",
|
|
"torch_on", // 12
|
|
"jon_bnst",
|
|
"jon_gasp",
|
|
"jon_land",
|
|
"jon_gags",
|
|
"jon_fall",
|
|
"jon_drwn",
|
|
"jon_air1",
|
|
"jon_glp1", // 20
|
|
"jon_bbwl",
|
|
"jon_pois",
|
|
"amb_ston",
|
|
"cat_icu",
|
|
"bubble_h",
|
|
"set_land",
|
|
"jon_hlnd",
|
|
"jon_laf2",
|
|
"spi_jump",
|
|
"jon_scub", // 30
|
|
"item_use",
|
|
"tr_arrow",
|
|
"swi_foot",
|
|
"swi_ston",
|
|
"swi_wtr1",
|
|
"tr_fire",
|
|
"m_skull5",
|
|
"spi_atak",
|
|
"anu_hit",
|
|
"fishdies", // 40
|
|
"scrp_icu",
|
|
"jon_wade",
|
|
"amb_watr",
|
|
"tele_1",
|
|
"wasp_stg",
|
|
"res",
|
|
"drum4",
|
|
"rex_icu",
|
|
"m_hits_u",
|
|
"q_tail", // 50
|
|
"vatr_mov",
|
|
"jon_hit3",
|
|
"jon_t_2", // 53
|
|
"jon_t_1",
|
|
"jon_t_5",
|
|
"jon_t_6",
|
|
"jon_t_8",
|
|
"jon_t_4",
|
|
"rasprit1",
|
|
"jon_fdie", // 60
|
|
"wijaf1",
|
|
"ship_1",
|
|
"saw_on",
|
|
"ra_on",
|
|
"amb_ston", // 65
|
|
"vatr_stp", // 66
|
|
"mana1",
|
|
"mana2",
|
|
"ammo",
|
|
"pot_pc1", // 70?
|
|
"pot_pc2",
|
|
"weapon",
|
|
"alarm",
|
|
"tick1",
|
|
"scrp_zap", // 75
|
|
"jon_t_3",
|
|
"jon_laf1",
|
|
"blasted",
|
|
"jon_air2" // 79
|
|
};
|
|
|
|
short StaticSound[kMaxSoundFiles];
|
|
|
|
// TODO - temp location. Needs to exist within config file
|
|
//
|
|
// Sound variables
|
|
//
|
|
//int FXDevice;
|
|
//int MusicDevice;
|
|
//int FXVolume;
|
|
//int MusicVolume;
|
|
//int SoundToggle;
|
|
//int MusicToggle;
|
|
//int VoiceToggle;
|
|
//int AmbienceToggle;
|
|
//fx_blaster_config BlasterConfig;
|
|
//int NumVoices;
|
|
//int NumChannels;
|
|
//int NumBits;
|
|
//int MixRate;
|
|
//int32 MidiPort;
|
|
//int ReverseStereo;
|
|
|
|
int nNextFreq;
|
|
int nTotalSoundBytes;
|
|
int nSoundCount;
|
|
short nSwirlyFrames;
|
|
|
|
short nDistTable[256];
|
|
|
|
struct ActiveSound
|
|
{
|
|
/*
|
|
short _0
|
|
short _2
|
|
short _4
|
|
short _6
|
|
byte _7
|
|
|
|
short _10
|
|
short _12
|
|
int _14
|
|
int _18
|
|
int _22;
|
|
int _26
|
|
|
|
int _30; // x val
|
|
int _34; // y val
|
|
int _38; // z val
|
|
short _42
|
|
short _44
|
|
*/
|
|
short f_0;
|
|
short f_2;
|
|
short f_4;
|
|
short f_6;
|
|
short f_8;
|
|
short f_a;
|
|
short f_c;
|
|
int f_e;
|
|
int f_12;
|
|
int f_16;
|
|
int f_1a;
|
|
int f_1e;
|
|
int f_22;
|
|
int f_26;
|
|
short f_2a;
|
|
short f_2c;
|
|
};
|
|
|
|
ActiveSound sActiveSound[kMaxSounds];
|
|
|
|
#if 0
|
|
int AIL_allocate_sample_handle(int);
|
|
int AIL_allocate_sequence_handle(int);
|
|
void AIL_startup(void);
|
|
void AIL_set_preference(int, int);
|
|
int AIL_install_DIG_INI(void);
|
|
int AIL_install_MDI_INI(void);
|
|
void AIL_shutdown(void);
|
|
void AIL_end_sequence(int);
|
|
void AIL_set_sequence_volume(int, int, int);
|
|
void AIL_init_sequence(int, char*, int);
|
|
void AIL_start_sequence(int);
|
|
void AIL_set_sequence_loop_count(int, int);
|
|
void AIL_set_sequence_volume(int, int, int);
|
|
void AIL_set_sample_playback_rate(int, int);
|
|
void AIL_end_sample(int);
|
|
int AIL_sample_status(int);
|
|
void AIL_set_sample_volume(int, int);
|
|
void AIL_set_sample_pan(int, int);
|
|
void AIL_init_sample(int);
|
|
void AIL_set_sample_file(int, char*, int);
|
|
void AIL_start_sample(int);
|
|
void AIL_set_sample_loop_count(int, int);
|
|
int AIL_sample_playback_rate(int);
|
|
char AIL_error[256];
|
|
#endif
|
|
char pMusicBuf[45000];
|
|
char szSoundName[kMaxSounds][kMaxSoundNameLen];
|
|
char *SoundBuf[kMaxSounds];
|
|
int SoundLen[kMaxSounds];
|
|
char SoundLock[kMaxSounds];
|
|
|
|
extern char message_text[80];
|
|
extern short message_timer;
|
|
|
|
int S, dig, mdi, handle;
|
|
int nActiveSounds;
|
|
|
|
short nLocalSectFlags;
|
|
short nLocalChan;
|
|
|
|
uint8_t nPanTable[] = {
|
|
0, 2, 4, 6, 8, 10, 12, 14,
|
|
16, 18, 20, 22, 24, 26, 28, 30,
|
|
32, 34, 36, 38, 40, 42, 44, 46,
|
|
48, 50, 52, 54, 56, 58, 60, 62,
|
|
64, 66, 68, 70, 72, 74, 76, 78,
|
|
80, 82, 84, 86, 88, 90, 92, 94,
|
|
96, 98, 100, 102, 104, 106, 108, 110,
|
|
112, 114, 116, 118, 120, 122, 124, 128,
|
|
128, 128, 128, 128, 128, 128, 128, 128,
|
|
128, 128, 128, 128, 128, 128, 128, 128,
|
|
128, 128, 128, 128, 128, 128, 128, 128,
|
|
128, 128, 128, 128, 128, 128, 128, 128,
|
|
128, 128, 128, 128, 128, 128, 128, 128,
|
|
128, 128, 128, 128, 128, 128, 128, 128,
|
|
128, 128, 128, 128, 128, 128, 128, 128,
|
|
128, 128, 128, 128, 128, 128, 128, 128
|
|
};
|
|
|
|
void CalcASSPan(int nPan, int nVolume, int *pLeft, int *pRight)
|
|
{
|
|
if (nPan < 0)
|
|
nPan = 0;
|
|
else if (nPan > 127)
|
|
nPan = 127;
|
|
|
|
if (nVolume < 0)
|
|
nVolume = 0;
|
|
else if (nVolume > 127)
|
|
nVolume = 127;
|
|
|
|
*pLeft = mulscale6(nPanTable[nPan], nVolume);
|
|
*pRight = mulscale6(nPanTable[127-nPan], nVolume);
|
|
}
|
|
|
|
void ASSCallback(intptr_t num)
|
|
{
|
|
if ((int32_t)num == MUSIC_ID) {
|
|
return;
|
|
}
|
|
|
|
// TODO: add mutex?
|
|
if ((int32_t)num == -1)
|
|
handle = -1;
|
|
else if ((int32_t)num >= 0 && (int32_t)num < kMaxActiveSounds)
|
|
sActiveSound[num].f_e = -1;
|
|
}
|
|
|
|
void CreateDistTable(void)
|
|
{
|
|
int eax = 260;
|
|
|
|
for (int i = 0; i < 256; i++)
|
|
{
|
|
if (eax > 65280)
|
|
{
|
|
nDistTable[i] = 255;
|
|
}
|
|
else
|
|
{
|
|
nDistTable[i] = eax >> 8;
|
|
|
|
eax = (eax * eax) >> 8;
|
|
}
|
|
}
|
|
}
|
|
|
|
void InitSoundInfo(void)
|
|
{
|
|
int i;
|
|
memset(sActiveSound, 255, sizeof(sActiveSound));
|
|
for (i = 0; i < kMaxSounds; i++)
|
|
{
|
|
sActiveSound[i].f_2c = 0;
|
|
sActiveSound[i].f_e = -1;
|
|
}
|
|
nActiveSounds = i;
|
|
|
|
handle = -1;
|
|
}
|
|
|
|
void InitFX(void)
|
|
{
|
|
#ifdef MIXERTYPEWIN
|
|
void* initdata = (void*)win_gethwnd(); // used for DirectSound
|
|
#else
|
|
void* initdata = NULL;
|
|
#endif
|
|
|
|
dig = 0;
|
|
|
|
if (!SoundEnabled())
|
|
return;
|
|
|
|
if (FX_Init(snd_numvoices, snd_numchannels, snd_mixrate, initdata) != FX_Ok)
|
|
{
|
|
Printf("Error initializing sound card!\n");
|
|
initprintf("Error initializing sound card!\n");
|
|
Printf("ERROR: %s\n", FX_ErrorString(FX_Error));
|
|
return;
|
|
}
|
|
|
|
dig = 1;
|
|
|
|
FX_SetCallBack(ASSCallback);
|
|
|
|
CreateDistTable();
|
|
InitSoundInfo();
|
|
|
|
nTotalSoundBytes = 0;
|
|
nSoundCount = 0;
|
|
nCreepyTimer = kCreepyCount;
|
|
|
|
#if 0
|
|
int status = FX_Init(FXDevice, NumVoices, NumChannels, NumBits, MixRate);
|
|
if (status == FX_Ok)
|
|
{
|
|
FX_SetVolume(FXVolume);
|
|
|
|
if (ReverseStereo == 1) {
|
|
FX_SetReverseStereo(!FX_GetReverseStereo());
|
|
}
|
|
}
|
|
|
|
if (status != FX_Ok) {
|
|
// Error("Sound startup error: %s", FX_ErrorString(FX_Error));
|
|
}
|
|
|
|
status = FX_SetCallBack(testcallback);
|
|
|
|
if (status != FX_Ok) {
|
|
// Error("Sound startup error: %s", FX_ErrorString(FX_Error));
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void UnInitFX()
|
|
{
|
|
FX_Shutdown();
|
|
}
|
|
|
|
void InitMusic()
|
|
{
|
|
}
|
|
|
|
void UnInitMusic()
|
|
{
|
|
}
|
|
|
|
void FadeSong()
|
|
{
|
|
}
|
|
|
|
int LoadSong(const char *song)
|
|
{
|
|
UNREFERENCED_PARAMETER(song);
|
|
return 0;
|
|
}
|
|
|
|
int LoadSound(const char *sound)
|
|
{
|
|
if (!dig)
|
|
//return 0;
|
|
return -1;
|
|
int i;
|
|
for (i = 0; i < nSoundCount; i++)
|
|
{
|
|
if (!Bstrncasecmp(szSoundName[i], sound, kMaxSoundNameLen))
|
|
return i;
|
|
}
|
|
|
|
if (i >= kMaxSounds)
|
|
I_Error("Too many sounds being loaded... increase array size\n");
|
|
|
|
strncpy(szSoundName[i], sound, kMaxSoundNameLen);
|
|
|
|
char buffer[32];
|
|
buffer[0] = 0;
|
|
|
|
strncat(buffer, szSoundName[i], kMaxSoundNameLen);
|
|
|
|
char *pzTail = buffer+strlen(buffer);
|
|
while (*pzTail == ' ' && pzTail != buffer)
|
|
*pzTail-- = '\0';
|
|
|
|
strcat(buffer, ".voc");
|
|
|
|
auto hVoc = kopenFileReader(buffer, 0);
|
|
|
|
if (!hVoc.isOpen())
|
|
{
|
|
int nSize = hVoc.GetLength();
|
|
//SoundLock[i] = 255; // crap we don't need.
|
|
SoundLen[i] = nSize;
|
|
cacheAllocateBlock((intptr_t*)&SoundBuf[i], nSize, nullptr);
|
|
if (!SoundBuf[i])
|
|
I_Error("Error allocating buf '%s' to %lld (size=%ld)!\n", buffer, (intptr_t)&SoundBuf[i], nSize);
|
|
|
|
if (hVoc.Read(SoundBuf[i], nSize) != nSize)
|
|
Printf("Error reading '%s'!\n", buffer);
|
|
}
|
|
else
|
|
{
|
|
Printf("Unable to open sound '%s'!\n", buffer);
|
|
SoundBuf[i] = NULL;
|
|
SoundLen[i] = 0;
|
|
//return hVoc;
|
|
return -1;
|
|
}
|
|
nSoundCount++;
|
|
return i;
|
|
}
|
|
|
|
#if 0
|
|
void FreeSounds(void)
|
|
{
|
|
int i;
|
|
for (i = 0; i < nSoundCount; i++)
|
|
free(SoundBuf[i]);
|
|
}
|
|
#endif
|
|
|
|
void LoadFX(void)
|
|
{
|
|
if (!dig)
|
|
return;
|
|
|
|
int i;
|
|
for (i = 0; i < kMaxSoundFiles; i++)
|
|
{
|
|
StaticSound[i] = LoadSound(SoundFiles[i]);
|
|
if (StaticSound[i] < 0)
|
|
I_Error("error loading static sound #%d ('%.8s')\n", i, SoundFiles[i]);
|
|
}
|
|
}
|
|
|
|
void GetSpriteSoundPitch(short nSector, int *pVolume, int *pPitch)
|
|
{
|
|
if (nSector < 0)
|
|
return;
|
|
if ((SectFlag[nSector]^nLocalSectFlags) & kSectUnderwater)
|
|
{
|
|
*pVolume >>= 1;
|
|
*pPitch -= 1200;
|
|
}
|
|
}
|
|
|
|
void BendAmbientSound(void)
|
|
{
|
|
if (nAmbientChannel < 0)
|
|
return;
|
|
ActiveSound *pASound = &sActiveSound[nAmbientChannel];
|
|
//AIL_set_sample_playback_rate(pASound->f_e, nDronePitch+11000);
|
|
if (pASound->f_e > -1)
|
|
FX_SetFrequency(pASound->f_e, nDronePitch+11000);
|
|
}
|
|
|
|
short PlayFXAtXYZ(unsigned short ax, int x, int y, int z, int nSector);
|
|
|
|
void CheckAmbience(short nSector)
|
|
{
|
|
if (SectSound[nSector] != -1)
|
|
{
|
|
short nSector2 = SectSoundSect[nSector];
|
|
walltype *pWall = &wall[sector[nSector2].wallptr];
|
|
if (nAmbientChannel < 0)
|
|
{
|
|
PlayFXAtXYZ(SectSound[nSector]|0x4000, pWall->x, pWall->y, sector[nSector2].floorz, nSector);
|
|
return;
|
|
}
|
|
ActiveSound *pASound = &sActiveSound[nAmbientChannel];
|
|
if (nSector == nSector2)
|
|
{
|
|
spritetype *pSprite = &sprite[PlayerList[0].nSprite];
|
|
pASound->f_1e = pSprite->x;
|
|
pASound->f_22 = pSprite->y;
|
|
pASound->f_26 = pSprite->z;
|
|
}
|
|
else
|
|
{
|
|
pASound->f_1e = pWall->x;
|
|
pASound->f_22 = pWall->y;
|
|
pASound->f_26 = sector[nSector2].floorz;
|
|
}
|
|
}
|
|
else if (nAmbientChannel != -1)
|
|
{
|
|
if (sActiveSound[nAmbientChannel].f_e > -1)
|
|
FX_StopSound(sActiveSound[nAmbientChannel].f_e);
|
|
sActiveSound[nAmbientChannel].f_e = -1;
|
|
nAmbientChannel = -1;
|
|
}
|
|
}
|
|
|
|
int GetDistFromDXDY(int dx, int dy)
|
|
{
|
|
int nSqr = dx*dx+dy*dy;
|
|
return (nSqr>>3)-(nSqr>>5);
|
|
}
|
|
|
|
#if 0
|
|
void MuteSounds(void)
|
|
{
|
|
if (!dig)
|
|
return;
|
|
|
|
int i;
|
|
ActiveSound *pASound = sActiveSound;
|
|
pASound++;
|
|
for (i = 1; i < kMaxActiveSounds; i++, pASound++)
|
|
{
|
|
if (pASound->f_e > -1 && FX_SoundActive(pASound->f_e))
|
|
FX_SetPan(pASound->f_e, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
void SetChanPan(int nSound, int nPan)
|
|
{
|
|
AIL_set_sample_pan(sActiveSound[nSound].f_e, nPan);
|
|
}
|
|
#endif
|
|
|
|
void SoundBigEntrance(void)
|
|
{
|
|
StopAllSounds();
|
|
ActiveSound *pASound = sActiveSound;
|
|
for (int i = 0; i < 4; i++, pASound++)
|
|
{
|
|
#if 0
|
|
AIL_init_sample(pASound->f_e);
|
|
short nPitch = i*512-1200;
|
|
pASound->f_16 = nPitch;
|
|
AIL_set_sample_playback_rate(pASound->f_e, 11000+nPitch);
|
|
AIL_set_sample_file(pASound->f_e, SoundBuf[12], -1);
|
|
AIL_set_sample_volume(pASound->f_e, 200);
|
|
AIL_set_sample_pan(pASound->f_e, 63-(i&1)*127);
|
|
AIL_start_sample(pASound->f_e);
|
|
#endif
|
|
short nPitch = i*512-1200;
|
|
pASound->f_16 = nPitch;
|
|
int nLeft, nRight;
|
|
CalcASSPan(63-(i&1)*127, 200, &nLeft, &nRight);
|
|
if (pASound->f_e >= 0)
|
|
FX_StopSound(pASound->f_e);
|
|
pASound->f_e = FX_Play(SoundBuf[kSoundTorchOn], SoundLen[kSoundTorchOn], -1, 0, 0, max(nLeft, nRight), nLeft, nRight, 0, fix16_one, i);
|
|
if (pASound->f_e > -1)
|
|
FX_SetFrequency(pASound->f_e, 11000+nPitch);
|
|
}
|
|
}
|
|
|
|
void StartSwirly(int nActiveSound)
|
|
{
|
|
ActiveSound *pASound = &sActiveSound[nActiveSound];
|
|
pASound->f_6 &= 0x7ff;
|
|
|
|
//AIL_init_sample(pASound->f_e);
|
|
short nPitch = nNextFreq-RandomSize(9);
|
|
pASound->f_16 = nPitch;
|
|
nNextFreq = 25000-RandomSize(10)*6;
|
|
if (nNextFreq > 32000)
|
|
nNextFreq = 32000;
|
|
|
|
//AIL_set_sample_file(pASound->f_e, SoundBuf[StaticSound[kSound67]], -1);
|
|
|
|
int nVolume = nSwirlyFrames+1;
|
|
if (nVolume >= 220)
|
|
nVolume = 220;
|
|
|
|
pASound->f_4 = nVolume;
|
|
|
|
int nPan = pASound->f_6&127;
|
|
int nLeft, nRight;
|
|
CalcASSPan(nPan, nVolume, &nLeft, &nRight);
|
|
if (pASound->f_e >= 0)
|
|
FX_StopSound(pASound->f_e);
|
|
pASound->f_e = FX_Play(SoundBuf[StaticSound[kSound67]], SoundLen[StaticSound[kSound67]], -1, 0, 0, max(nLeft, nRight), nLeft, nRight, 0, fix16_one, nActiveSound);
|
|
if (pASound->f_e > -1)
|
|
FX_SetFrequency(pASound->f_e, nPitch);
|
|
|
|
#if 0
|
|
AIL_set_sample_volume(pASound->f_e, nVolume);
|
|
AIL_set_sample_playback_rate(pASound->f_e, nPitch);
|
|
AIL_set_sample_loop_count(pASound->f_e, 1);
|
|
AIL_set_sample_pan(pASound->f_e, pASound->f_6);
|
|
AIL_start_sample(pASound->f_e);
|
|
#endif
|
|
}
|
|
|
|
void StartSwirlies()
|
|
{
|
|
StopAllSounds();
|
|
|
|
nNextFreq = 19000;
|
|
nSwirlyFrames = 0;
|
|
|
|
for (int i = 1; i <= 4; i++)
|
|
StartSwirly(i);
|
|
}
|
|
|
|
void UpdateSwirlies()
|
|
{
|
|
nSwirlyFrames++;
|
|
ActiveSound* pASound = sActiveSound;
|
|
pASound++;
|
|
for (int i = 1; i <= 4; i++, pASound++)
|
|
{
|
|
if (pASound->f_e < 0 || !FX_SoundActive(pASound->f_e))
|
|
StartSwirly(i);
|
|
if (pASound->f_e >= 0)
|
|
{
|
|
int nLeft, nRight;
|
|
int nPan = 64+(Sin((int)totalclock<<(4+i))>>8);
|
|
CalcASSPan(nPan, pASound->f_4, &nLeft, &nRight);
|
|
MV_SetPan(pASound->f_e, max(nLeft, nRight), nLeft, nRight);
|
|
}
|
|
//AIL_set_sample_pan(pASound->f_e, 64+(Sin((int)totalclock<<(4+i))>>8));
|
|
}
|
|
}
|
|
|
|
void UpdateSounds()
|
|
{
|
|
if (!dig || nFreeze)
|
|
return;
|
|
|
|
nLocalSectFlags = SectFlag[nPlayerViewSect[nLocalPlayer]];
|
|
spritetype *pSprite = &sprite[PlayerList[nLocalPlayer].nSprite];
|
|
int x, y;
|
|
short ang;
|
|
if (nSnakeCam > -1)
|
|
{
|
|
Snake *pSnake = &SnakeList[nSnakeCam];
|
|
spritetype *pSnakeSprite = &sprite[pSnake->nSprites[0]];
|
|
x = pSnakeSprite->x;
|
|
y = pSnakeSprite->y;
|
|
ang = pSnakeSprite->ang;
|
|
}
|
|
else
|
|
{
|
|
x = initx;
|
|
y = inity;
|
|
ang = inita;
|
|
}
|
|
ActiveSound* pASound = sActiveSound;
|
|
pASound++;
|
|
for (int i = 1; i < kMaxActiveSounds; i++, pASound++)
|
|
{
|
|
if (pASound->f_e >= 0 && FX_SoundActive(pASound->f_e))
|
|
{
|
|
short nSoundSprite = pASound->f_0;
|
|
int dx, dy;
|
|
if (nSoundSprite < 0)
|
|
{
|
|
dx = x-pASound->f_1e;
|
|
dy = y-pASound->f_22;
|
|
}
|
|
else
|
|
{
|
|
dx = x-sprite[nSoundSprite].x;
|
|
dy = y-sprite[nSoundSprite].y;
|
|
}
|
|
|
|
dx >>= 8;
|
|
dy >>= 8;
|
|
|
|
short nSoundAng;
|
|
if ((dx|dy) == 0)
|
|
nSoundAng = 0;
|
|
else
|
|
nSoundAng = AngleDelta(GetMyAngle(dx, dy), ang, 1024);
|
|
|
|
int nDist = GetDistFromDXDY(dx, dy);
|
|
if (nDist >= 255)
|
|
{
|
|
FX_StopSound(pASound->f_e);
|
|
if (pASound->f_a&0x4000)
|
|
nAmbientChannel = -1;
|
|
return;
|
|
}
|
|
|
|
int nVolume = gFXVolume+10-(Sin(nDist<<1)>>6);
|
|
if (nVolume < 0)
|
|
nVolume = 0;
|
|
if (nVolume > 255)
|
|
nVolume = 255;
|
|
|
|
int nPitch = pASound->f_16;
|
|
short nSoundSect;
|
|
if (nSoundSprite >= 0)
|
|
{
|
|
if (nSoundSprite == nLocalSpr)
|
|
nSoundSect = nPlayerViewSect[nLocalPlayer];
|
|
else
|
|
nSoundSect = sprite[nSoundSprite].sectnum;
|
|
}
|
|
else
|
|
nSoundSect = pASound->f_2a;
|
|
|
|
GetSpriteSoundPitch(nSoundSect, &nVolume, &nPitch);
|
|
|
|
if (pASound->f_12 != nPitch)
|
|
pASound->f_12 = nPitch;
|
|
|
|
if (nVolume != pASound->f_4 || nSoundAng != pASound->f_6)
|
|
{
|
|
int nLeft, nRight;
|
|
int nPan = 63+(Sin(nSoundAng+1023)>>8);
|
|
CalcASSPan(nPan, nVolume, &nLeft, &nRight);
|
|
FX_SetPan(pASound->f_e, nVolume, nLeft, nRight);
|
|
|
|
if (nPitch < 0)
|
|
FX_SetFrequency(pASound->f_e, 7000);
|
|
|
|
pASound->f_4 = nVolume;
|
|
pASound->f_6 = nSoundAng;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void UpdateCreepySounds()
|
|
{
|
|
if (levelnum == 20 || nFreeze)
|
|
return;
|
|
spritetype *pSprite = &sprite[PlayerList[nLocalPlayer].nSprite];
|
|
nCreepyTimer--;
|
|
if (nCreepyTimer <= 0)
|
|
{
|
|
if (nCreaturesLeft > 0 && !(SectFlag[nPlayerViewSect[nLocalPlayer]]&0x2000))
|
|
{
|
|
int vsi = seq_GetFrameSound(SeqOffsets[kSeqCreepy], totalmoves%SeqSize[SeqOffsets[kSeqCreepy]]);
|
|
if (vsi >= 0 && (vsi&0x1ff) < kMaxSounds)
|
|
{
|
|
int vdx = (totalmoves+32)&31;
|
|
if (totalmoves & 1)
|
|
vdx = -vdx;
|
|
int vax = (totalmoves+32)&63;
|
|
if (totalmoves & 2)
|
|
vax = -vax;
|
|
|
|
PlayFXAtXYZ(vsi, pSprite->x+vdx, pSprite->y+vax, pSprite->z, pSprite->sectnum);
|
|
}
|
|
}
|
|
nCreepyTimer = kCreepyCount;
|
|
}
|
|
}
|
|
|
|
int LocalSoundPlaying(void)
|
|
{
|
|
if (!dig)
|
|
return 0;
|
|
|
|
return sActiveSound[nLocalChan].f_e >= 0 && FX_SoundActive(sActiveSound[nLocalChan].f_e);
|
|
}
|
|
|
|
int GetLocalSound(void)
|
|
{
|
|
if (LocalSoundPlaying() == -1)
|
|
return -1;
|
|
|
|
return sActiveSound[nLocalChan].f_2&0x1ff;
|
|
}
|
|
|
|
void UpdateLocalSound(void)
|
|
{
|
|
if (!dig)
|
|
return;
|
|
|
|
if (sActiveSound[nLocalChan].f_e >= 0)
|
|
FX_SetPan(sActiveSound[nLocalChan].f_e, gFXVolume, gFXVolume, gFXVolume);
|
|
}
|
|
|
|
void StopLocalSound(void)
|
|
{
|
|
if (!dig)
|
|
return;
|
|
|
|
if (nLocalChan == nAmbientChannel)
|
|
nAmbientChannel = -1;
|
|
|
|
if (LocalSoundPlaying())
|
|
FX_StopSound(sActiveSound[nLocalChan].f_e);
|
|
}
|
|
|
|
void SetLocalChan(int nChannel)
|
|
{
|
|
nLocalChan = nChannel;
|
|
}
|
|
|
|
void PlaySound(int nSound)
|
|
{
|
|
if (!dig)
|
|
return;
|
|
|
|
if (nSound < 0 || nSound >= kMaxSounds || !SoundBuf[nSound])
|
|
{
|
|
initprintf("PlaySound: Invalid sound nSound == %i\n", nSound);
|
|
return;
|
|
}
|
|
|
|
int bLoop = SoundBuf[nSound][26] == 6;
|
|
|
|
if (handle >= 0)
|
|
FX_StopSound(handle);
|
|
|
|
handle = FX_Play(SoundBuf[nSound], SoundLen[nSound], bLoop ? 0 : -1, 0, 0, gFXVolume, gFXVolume, gFXVolume, 0, fix16_one, -1);
|
|
|
|
#if 0
|
|
AIL_init_sample(handle);
|
|
AIL_set_sample_file(handle, SoundBuf[nSound], -1);
|
|
AIL_set_sample_volume(handle, gFXVolume>>1);
|
|
|
|
if (SoundBuf[nSound][26] == 6)
|
|
AIL_set_sample_loop_count(handle, 0);
|
|
|
|
AIL_start_sample(handle);
|
|
#endif
|
|
}
|
|
|
|
void PlayLocalSound(short nSound, short nRate)
|
|
{
|
|
if (!dig)
|
|
return;
|
|
|
|
if (nSound < 0 || nSound >= kMaxSounds || !SoundBuf[nSound])
|
|
{
|
|
initprintf("PlayLocalSound: Invalid sound nSound == %i, nRate == %i\n", nSound, nRate);
|
|
return;
|
|
}
|
|
|
|
if (nLocalChan == nAmbientChannel)
|
|
nAmbientChannel = -1;
|
|
|
|
int bLoop = SoundBuf[nSound][26] == 6;
|
|
|
|
ActiveSound* pASound = &sActiveSound[nLocalChan];
|
|
if (pASound->f_e >= 0)
|
|
FX_StopSound(pASound->f_e);
|
|
|
|
pASound->f_e = FX_Play(SoundBuf[nSound], SoundLen[nSound], bLoop ? 0 : -1, 0, 0, gFXVolume, gFXVolume, gFXVolume, 0, fix16_one, nLocalChan);
|
|
|
|
if (nRate)
|
|
{
|
|
int nFreq = 0;
|
|
FX_GetFrequency(pASound->f_e, &nFreq);
|
|
FX_SetFrequency(pASound->f_e, nFreq+nRate);
|
|
}
|
|
#if 0
|
|
AIL_init_sample(pASound->f_e);
|
|
AIL_set_sample_file(pASound->f_e, SoundBuf[nSound], -1);
|
|
AIL_set_sample_volume(pASound->f_e, gFXVolume>>1);
|
|
|
|
if (nRate)
|
|
AIL_set_sample_playback_rate(pASound->f_e, AIL_sample_playback_rate(pASound->f_e)+nRate);
|
|
|
|
if (SoundBuf[nSound][26] == 6)
|
|
AIL_set_sample_loop_count(pASound->f_e, 0);
|
|
|
|
AIL_start_sample(pASound->f_e);
|
|
#endif
|
|
pASound->f_2 = nSound;
|
|
SetLocalChan(0);
|
|
}
|
|
|
|
void PlayTitleSound(void)
|
|
{
|
|
PlayLocalSound(StaticSound[kSound10], 0);
|
|
}
|
|
|
|
void PlayLogoSound(void)
|
|
{
|
|
PlayLocalSound(StaticSound[kSound28], 7000);
|
|
}
|
|
|
|
void PlayGameOverSound(void)
|
|
{
|
|
PlayLocalSound(StaticSound[kSound28], 0);
|
|
}
|
|
|
|
int soundx, soundy, soundz;
|
|
short soundsect;
|
|
|
|
short PlayFX2(unsigned short nSound, short nSprite)
|
|
{
|
|
if (!dig)
|
|
return -1;
|
|
|
|
if ((nSound&0x1ff) >= kMaxSounds || !SoundBuf[(nSound&0x1ff)])
|
|
{
|
|
initprintf("PlayFX2: Invalid sound nSound == %i, nSprite == %i\n", nSound, nSprite);
|
|
return -1;
|
|
}
|
|
|
|
nLocalSectFlags = SectFlag[nPlayerViewSect[nLocalPlayer]];
|
|
short v1c;
|
|
short vcx;
|
|
if (nSprite < 0)
|
|
{
|
|
vcx = 0;
|
|
v1c = 0;
|
|
}
|
|
else
|
|
{
|
|
v1c = nSprite&0x2000;
|
|
vcx = nSprite&0x4000;
|
|
nSprite &= 0xfff;
|
|
soundx = sprite[nSprite].x;
|
|
soundy = sprite[nSprite].y;
|
|
soundz = sprite[nSprite].z;
|
|
}
|
|
int dx, dy;
|
|
|
|
dx = initx-soundx;
|
|
dy = inity-soundy;
|
|
|
|
dx >>= 8; dy >>= 8;
|
|
|
|
short nSoundAng;
|
|
if ((dx|dy) == 0)
|
|
nSoundAng = 0;
|
|
else
|
|
nSoundAng = AngleDelta(GetMyAngle(dx, dy), inita, 1024);
|
|
|
|
int nDist = GetDistFromDXDY(dx, dy);
|
|
if (nDist >= 255)
|
|
{
|
|
if ((int16_t)nSound > -1)
|
|
StopSpriteSound(nSound);
|
|
return -1;
|
|
}
|
|
|
|
int nVolume;
|
|
|
|
if (!v1c)
|
|
{
|
|
nVolume = gFXVolume+10-(Sin(nDist<<1)>>6)-10;
|
|
if (nVolume <= 0)
|
|
{
|
|
if ((int16_t)nSound > -1)
|
|
StopSpriteSound(nSound);
|
|
return -1;
|
|
}
|
|
if (nVolume > 255)
|
|
nVolume = 255;
|
|
}
|
|
else
|
|
nVolume = gFXVolume;
|
|
|
|
short vc = nSound & (~0x1ff);
|
|
short v4 = nSound & 0x2000;
|
|
short v8 = nSound & 0x1000;
|
|
short v14 = nSound & 0x4000;
|
|
short v10 = (nSound&0xe00)>>9;
|
|
int v2c = 0x7fffffff;
|
|
ActiveSound* v38 = NULL;
|
|
ActiveSound* v28 = NULL;
|
|
ActiveSound* vdi = NULL;
|
|
nSound &= 0x1ff;
|
|
|
|
short v20;
|
|
|
|
if (v8 || v14)
|
|
v20 = 1000;
|
|
else if (nSprite != -1 && vcx)
|
|
v20 = 2000;
|
|
else
|
|
v20 = 0;
|
|
ActiveSound* pASound = sActiveSound;
|
|
pASound++;
|
|
for (int i = 1; i < kMaxActiveSounds; i++, pASound++)
|
|
{
|
|
if (pASound->f_e < 0 || !FX_SoundActive(pASound->f_e))
|
|
vdi = pASound;
|
|
else if (v20 >= pASound->f_c)
|
|
{
|
|
if (v2c > pASound->f_1a && pASound->f_c <= v20)
|
|
{
|
|
v28 = pASound;
|
|
v2c = pASound->f_1a;
|
|
}
|
|
if (!v8)
|
|
{
|
|
if (nSound == pASound->f_2)
|
|
{
|
|
if (v4 == 0 && nSprite == pASound->f_0)
|
|
return -1;
|
|
if (v20 >= pASound->f_c)
|
|
v38 = pASound;
|
|
}
|
|
else if (nSprite == pASound->f_0)
|
|
{
|
|
if (v4 || nSound != pASound->f_2)
|
|
{
|
|
vdi = pASound;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!vdi)
|
|
{
|
|
if (v38)
|
|
vdi = v38;
|
|
else if (v28)
|
|
vdi = v28;
|
|
}
|
|
|
|
if (vdi->f_e >= 0 && FX_SoundActive(vdi->f_e))
|
|
{
|
|
FX_StopSound(vdi->f_e);
|
|
if (vdi->f_2c == nAmbientChannel)
|
|
nAmbientChannel = -1;
|
|
}
|
|
|
|
int nPitch;
|
|
if (v10)
|
|
nPitch = -(totalmoves&((1<<v10)-1))*16;
|
|
else
|
|
nPitch = 0;
|
|
|
|
if (vdi)
|
|
{
|
|
vdi->f_16 = nPitch;
|
|
vdi->f_8 = nVolume;
|
|
if (nSprite < 0)
|
|
{
|
|
vdi->f_1e = soundx;
|
|
vdi->f_22 = soundy;
|
|
vdi->f_2a = soundsect;
|
|
}
|
|
GetSpriteSoundPitch(soundsect, &nVolume, &nPitch);
|
|
vdi->f_12 = nPitch;
|
|
vdi->f_4 = nVolume;
|
|
vdi->f_6 = nSoundAng;
|
|
vdi->f_0 = nSprite;
|
|
vdi->f_2 = nSound;
|
|
vdi->f_1a = (int)totalclock;
|
|
vdi->f_c = v20;
|
|
vdi->f_a = vc;
|
|
short nPan = 63+(Sin(nSoundAng+1023)>>8);
|
|
int nLeft, nRight;
|
|
|
|
int bLoop = SoundBuf[nSound][26] == 6;
|
|
|
|
CalcASSPan(nPan, nVolume>>1, &nLeft, &nRight);
|
|
|
|
vdi->f_e = FX_Play(SoundBuf[nSound], SoundLen[nSound], bLoop ? 0 : -1, 0, 0, max(nLeft, nRight), nLeft, nRight, 0, fix16_one, vdi-sActiveSound);
|
|
|
|
if (nPitch)
|
|
{
|
|
int nFreq = 0;
|
|
FX_GetFrequency(vdi->f_e, &nFreq);
|
|
FX_SetFrequency(vdi->f_e, nFreq+nPitch);
|
|
}
|
|
#if 0
|
|
AIL_init_sample(vdi->f_e);
|
|
AIL_set_sample_file(vdi->f_e, SoundBuf[nSound], -1);
|
|
AIL_set_sample_pan(vdi->f_e, nPan);
|
|
AIL_set_sample_volume(vdi->f_e, nVolume>>1);
|
|
|
|
if (SoundBuf[nSound][26] == 6)
|
|
AIL_set_sample_loop_count(vdi->f_e, 0);
|
|
|
|
if (nPitch)
|
|
AIL_set_sample_playback_rate(vdi->f_e, AIL_sample_playback_rate(vdi->f_e)+nPitch);
|
|
|
|
AIL_start_sample(vdi->f_e);
|
|
#endif
|
|
if (v14)
|
|
nAmbientChannel = v14;
|
|
|
|
// Nuke: added nSprite >= 0 check
|
|
if (nSprite != nLocalSpr && nSprite >= 0 && (sprite[nSprite].cstat&257))
|
|
nCreepyTimer = kCreepyCount;
|
|
|
|
return v14;
|
|
}
|
|
return -1;
|
|
}
|
|
|
|
short PlayFXAtXYZ(unsigned short ax, int x, int y, int z, int nSector)
|
|
{
|
|
soundx = x;
|
|
soundy = y;
|
|
soundz = z;
|
|
soundsect = nSector&0x3fff;
|
|
short nSnd = PlayFX2(ax, -1);
|
|
if (nSnd > -1 && (nSector&0x4000))
|
|
sActiveSound[nSnd].f_c = 2000;
|
|
return nSnd;
|
|
}
|
|
|
|
short D3PlayFX(unsigned short nSound, short nVal)
|
|
{
|
|
return PlayFX2(nSound, nVal);
|
|
}
|
|
|
|
void StopSpriteSound(short nSprite)
|
|
{
|
|
if (!dig)
|
|
return;
|
|
|
|
for (int i = 0; i < kMaxActiveSounds; i++)
|
|
{
|
|
if (sActiveSound[i].f_e >= 0 && FX_SoundActive(sActiveSound[i].f_e) && nSprite == sActiveSound[i].f_0)
|
|
{
|
|
FX_StopSound(sActiveSound[i].f_e);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void StopAllSounds(void)
|
|
{
|
|
if (!dig)
|
|
return;
|
|
|
|
for (int i = 0; i < kMaxActiveSounds; i++)
|
|
{
|
|
if (sActiveSound[i].f_e >= 0)
|
|
FX_StopSound(sActiveSound[i].f_e);
|
|
// AIL_end_sample(sActiveSound[i].f_e);
|
|
}
|
|
|
|
nSoundsPlaying = 0;
|
|
nAmbientChannel = -1;
|
|
}
|
|
|
|
#if 0
|
|
void Lock(void)
|
|
{
|
|
AIL_lock();
|
|
}
|
|
|
|
void Unlock(void)
|
|
{
|
|
AIL_unlock();
|
|
}
|
|
|
|
#endif
|
|
END_PS_NS
|