14 Jun 2008

This commit is contained in:
g-cont 2008-06-14 00:00:00 +04:00 committed by Alibek Omarov
parent 89f509dccd
commit bee955e12f
21 changed files with 325 additions and 727 deletions

View File

@ -19,7 +19,7 @@ int FindMiptex( char *name )
if (!stricmp(name, textureref[i].texname))
return i;
}
if( nummiptex == MAX_MAP_TEXTURES ) Sys_Error ("MAX_MAP_TEXTURES");
if( nummiptex == MAX_MAP_TEXTURES ) Sys_Break("MAX_MAP_TEXTURES limit exceeds\n");
// register texture
strcpy (textureref[i].texname, name );

View File

@ -71,5 +71,5 @@ if exist vsound\vsound.plg del /f /q vsound\vsound.plg
echo Build succeeded!
echo Please wait. Xash is now loading
cd D:\Xash3D\
quake.exe -log -game tmpQuArK -debug -dev 3 +map start
quake.exe -log -game tmpQuArK -debug -dev 3 +map walk_test
:done

View File

@ -241,6 +241,10 @@ void Field_CompleteCommand( field_t *field )
{
result = Cmd_GetMapList(Cmd_Argv(1), filename, MAX_STRING );
}
else if(!stricmp(Cmd_Argv(0), "play" ) || !stricmp(Cmd_Argv(0), "\\play" ))
{
result = Cmd_GetSoundList(Cmd_Argv(1), filename, MAX_STRING );
}
else if(!stricmp(Cmd_Argv(0), "playdemo" ) || !stricmp(Cmd_Argv(0), "\\playdemo" ))
{
result = Cmd_GetDemoList(Cmd_Argv(1), filename, MAX_STRING );

View File

@ -198,11 +198,6 @@ void CL_Drop (void)
CL_Disconnect();
}
float CL_GetTime( void )
{
return cl.time;
}
/*
=======================
CL_SendConnectPacket

View File

@ -365,7 +365,7 @@ void CL_PrepRefresh( void )
// set sky textures and speed
SCR_UpdateScreen();
rotate = atof(cl.configstrings[CS_SKYROTATE]);
rotate = com.atof(cl.configstrings[CS_SKYROTATE]);
com.atov( axis, cl.configstrings[CS_SKYAXIS], 3 );
re->SetSky( cl.configstrings[CS_SKY], rotate, axis);
Cvar_SetValue("scr_loading", 100.0f ); // all done

View File

@ -1866,6 +1866,51 @@ bool Cmd_GetMovieList (const char *s, char *completedname, int length )
return true;
}
/*
=====================================
Cmd_GetSoundList
Prints or complete sound filename
=====================================
*/
bool Cmd_GetSoundList (const char *s, char *completedname, int length )
{
search_t *t;
string matchbuf;
int i, numsounds;
t = FS_Search(va("sound/%s*.wav", s ), true);
if(!t) return false;
FS_FileBase(t->filenames[0], matchbuf );
if(completedname && length) com.strncpy( completedname, matchbuf, length );
if(t->numfilenames == 1) return true;
for(i = 0, numsounds = 0; i < t->numfilenames; i++)
{
const char *ext = FS_FileExtension( t->filenames[i] );
if( com.stricmp(ext, "wav" )) continue;
FS_FileBase(t->filenames[i], matchbuf );
Msg("%16s\n", matchbuf );
numsounds++;
}
Msg("\n^3 %i sounds found.\n", numsounds );
Mem_Free(t);
// cut shortestMatch to the amount common with s
if(completedname && length)
{
for( i = 0; matchbuf[i]; i++ )
{
if(com.tolower(completedname[i]) != com.tolower(matchbuf[i]))
completedname[i] = 0;
}
}
return true;
}
/*
============
Cmd_WriteVariables

View File

@ -372,7 +372,6 @@ void SV_Transform( sv_edict_t *ed, matrix4x3 transform );
int CL_PMpointcontents( vec3_t point );
void CL_AddLoopingSounds( void );
void CL_RegisterSounds( void );
float CL_GetTime( void );
void CL_Drop( void );
char *Info_ValueForKey( char *s, char *key );
void Info_RemoveKey( char *s, char *key );
@ -383,10 +382,11 @@ void Cmd_ForwardToServer( void ); // client callback
char *Cvar_Userinfo( void );
char *Cvar_Serverinfo( void );
void Cmd_WriteVariables( file_t *f );
bool Cmd_GetMapList (const char *s, char *completedname, int length );
bool Cmd_GetFontList (const char *s, char *completedname, int length );
bool Cmd_GetMapList(const char *s, char *completedname, int length );
bool Cmd_GetFontList(const char *s, char *completedname, int length );
bool Cmd_GetDemoList(const char *s, char *completedname, int length );
bool Cmd_GetMovieList(const char *s, char *completedname, int length);
bool Cmd_GetMovieList(const char *s, char *completedname, int length );
bool Cmd_GetSoundList(const char *s, char *completedname, int length );
void Sys_Error( const char *msg, ... );
void Sys_SendKeyEvents( void );

View File

@ -203,7 +203,6 @@ void Host_InitSound( void )
si.GetSoundSpatialization = CL_GetEntitySoundSpatialization;
si.PointContents = CL_PMpointcontents;
si.AddLoopingSounds = CL_AddLoopingSounds;
si.GetClientTime = CL_GetTime;
Sys_LoadLibrary( &vsound_dll );

View File

@ -197,16 +197,16 @@ typedef enum
*/
// per-level limits
#define MAX_ENTITIES 128
#define MAX_DLIGHTS 32
#define MAX_ENTITIES 512 // refdef ents
#define MAX_DLIGHTS 64
#define MAX_CLIENTS 256 // absolute limit
#define MAX_PARTICLES 4096
#define MAX_PARTICLES 512
#define MAX_LIGHTSTYLES 256
#define MAX_SOUNDS 256 // so they cannot be blindly increased
#define MAX_SOUNDS 512 // so they cannot be blindly increased
#define MAX_IMAGES 256 // hud graphics
#define MAX_DECALS 256 // various decals
#define MAX_ITEMS 512 // player items
#define MAX_GENERAL (MAX_CLIENTS*2) // general config strings
#define MAX_ITEMS 128 // player items
#define MAX_GENERAL (MAX_CLIENTS * 2) // general config strings
// config strings are a general means of communication from
// the server to all connected clients.

View File

@ -81,7 +81,7 @@ void SV_SetMinMaxSize (edict_t *e, float *min, float *max, bool rotate)
int i;
for (i = 0; i < 3; i++)
if (min[i] > max[i])
if( min[i] > max[i] )
PRVM_ERROR("SV_SetMinMaxSize: backwards mins/maxs");
// set derived values
@ -1439,8 +1439,9 @@ void PF_sound( void )
VM_Warning("SV_StartSound: channel must be in range 0-7\n");
return;
}
sound_idx = SV_SoundIndex( sample );
channel |= CHAN_RELIABLE|CHAN_NO_PHS_ADD;
sound_idx = SV_SoundIndex( sample );
SV_StartSound (NULL, entity, channel, sound_idx, volume / 255.0f, attenuation, 0 );
}

View File

@ -164,7 +164,7 @@ void _MSG_Send (msgtype_t to, vec3_t origin, edict_t *ent, const char *filename,
int leafnum = 0, cluster = 0;
int area1 = 0, area2 = 0;
int j, numclients = maxclients->value;
client_state_t *client, *current = svs.clients;
client_state_t *client, *current = svs.clients;
bool reliable = false;
/*if(origin == NULL || ent == NULL)

View File

@ -187,9 +187,9 @@ cvar_t *Cvar_Get( const char *var_name, const char *var_value, int flags, const
Mem_Free( var->reset_string );
var->reset_string = copystring( var_value );
}
else if ( var_value[0] && strcmp( var->reset_string, var_value ))
else if ( var_value[0] && com_strcmp( var->reset_string, var_value ))
{
MsgDev(D_WARN, "cvar \"%s\" given initial values: \"%s\" and \"%s\"\n", var_name, var->reset_string, var_value );
MsgDev(D_NOTE, "cvar \"%s\" given initial values: \"%s\" and \"%s\"\n", var_name, var->reset_string, var_value );
}
// if we have a latched string, take that value now

View File

@ -591,7 +591,7 @@ typedef struct vsound_imp_s
void (*GetSoundSpatialization)( int entnum, vec3_t origin, vec3_t velocity );
int (*PointContents)( vec3_t point );
void (*AddLoopingSounds)( void );
float (*GetClientTime)( void );
} vsound_imp_t;
// this is the only function actually exported at the linker level

View File

@ -18,10 +18,6 @@ int numgltextures;
byte intensitytable[256];
cvar_t *gl_maxsize;
byte *r_imagepool;
byte *imagebuffer;
int imagebufsize;
byte *uploadbuffer;
int uploadbufsize;
bool use_gl_extension = false;
cvar_t *intensity;
uint d_8to24table[256];
@ -47,6 +43,8 @@ typedef struct
int flags;
byte *pal;
byte *source;
byte *scaled;
} pixformat_desc_t;
static pixformat_desc_t image_desc;
@ -143,9 +141,6 @@ void R_SetPixelFormat( int width, int height, int depth )
// NOTE: size of current miplevel or cubemap side, not total (filesize - sizeof(header))
image_desc.SizeOfFile = R_GetImageSize( BlockSize, width, height, depth, image_desc.bpp, image_desc.BitsCount / 8);
if (image_desc.width * image_desc.height > imagebufsize / 4) // warning
MsgWarn("R_SetPixelFormat: image too big [%i*%i]\n", image_desc.width, image_desc.height);
}
/*
@ -161,7 +156,8 @@ bool R_GetPixelFormat( rgbdata_t *pic, imagetype_t type )
size_t mipsize, totalsize = 0;
if(!pic || !pic->buffer) return false;
Mem_EmptyPool( r_imagepool ); // flush buffers
memset( &image_desc, 0, sizeof(image_desc));
for(i = 0; i < PF_TOTALCOUNT; i++)
{
@ -231,6 +227,9 @@ bool R_GetPixelFormat( rgbdata_t *pic, imagetype_t type )
use_gl_extension = true;
else use_gl_extension = false;
image_desc.source = Mem_Alloc( r_imagepool, s * 4 ); // source buffer
image_desc.scaled = Mem_Alloc( r_imagepool, w * h * 4 ); // scaled buffer
if(image_desc.flags & IMAGE_CUBEMAP)
totalsize *= 6;
@ -315,27 +314,19 @@ void R_InitTextures( void )
gl_maxsize = Cvar_Get( "gl_maxsize", "4096", CVAR_ARCHIVE );
qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &texsize); // merge value
if (gl_maxsize->integer != texsize) Cvar_SetValue ("gl_maxsize", texsize );
if(texsize < 2048) imagebufsize = 2048*2048*4;
else imagebufsize = texsize * texsize * 4;
uploadbufsize = texsize * texsize * 4;
// create intermediate & upload image buffer
imagebuffer = Mem_Alloc( r_imagepool, imagebufsize );
uploadbuffer = Mem_Alloc( r_imagepool, uploadbufsize );
if( gl_maxsize->integer != texsize ) Cvar_SetValue( "gl_maxsize", texsize );
registration_sequence = 1;
// init intensity conversions
intensity = Cvar_Get ("intensity", "2", 0 );
if ( intensity->value <= 1 ) Cvar_SetValue( "intensity", 1 );
if( intensity->value <= 1 ) Cvar_SetValue( "intensity", 1 );
gl_state.inverse_intensity = 1 / intensity->value;
for (i = 0; i < 256; i++)
{
j = i * intensity->value;
intensitytable[i] = bound(0, j, 255);
intensitytable[i] = bound( 0, j, 255 );
}
R_GetPalette();
}
@ -347,8 +338,8 @@ void R_RoundImageDimensions( int *scaled_width, int *scaled_height )
for( width = 1; width < *scaled_width; width <<= 1 );
for( height = 1; height < *scaled_height; height <<= 1 );
*scaled_width = bound(1, width, gl_maxsize->integer );
*scaled_height = bound(1, height, gl_maxsize->integer );
*scaled_width = bound( 1, width, gl_maxsize->integer );
*scaled_height = bound( 1, height, gl_maxsize->integer );
}
bool R_ResampleTexture (uint *in, int inwidth, int inheight, uint *out, int outwidth, int outheight)
@ -451,10 +442,10 @@ bool qrsCompressedTexImage2D( uint target, int level, int internalformat, uint w
uint bits, bitmask, Offset;
int scaled_width, scaled_height;
word sAlpha, sColor0, sColor1;
byte *fin, *fout = imagebuffer;
byte *fin, *fout = image_desc.source;
byte alphas[8], *alpha, *alphamask;
int w, h, x, y, z, i, j, k, Select;
uint *scaled = (unsigned *)uploadbuffer;
uint *scaled = (uint *)image_desc.scaled;
bool has_alpha = false;
int samples;
@ -790,8 +781,8 @@ bool qrsDecompressedTexImage2D( uint target, int level, int internalformat, uint
byte *fin;
int i, p, samples;
int scaled_width, scaled_height;
uint *scaled = (uint *)uploadbuffer;
byte *fout = imagebuffer;
uint *scaled = (uint *)image_desc.scaled;
byte *fout = image_desc.source;
bool noalpha = true;
if (!data) return false;
@ -853,8 +844,7 @@ bool qrsDecompressedTexImage2D( uint target, int level, int internalformat, uint
case PF_ABGR_64:
case PF_RGBA_32:
case PF_RGBA_GN:
// nothing to process
fout = fin;
fout = fin; // nothing to process
break;
default:
MsgDev(D_WARN, "qrsDecompressedTexImage2D: invalid compression type: %s\n", PFDesc[internalformat].name );
@ -902,8 +892,8 @@ bool qrsDecompressImageARGB( uint target, int level, int internalformat, uint wi
uint ReadI = 0, TempBpp;
uint RedL, RedR, GreenL, GreenR, BlueL, BlueR, AlphaL, AlphaR;
uint r_bitmask, g_bitmask, b_bitmask, a_bitmask;
uint *scaled = (unsigned *)uploadbuffer;
byte *fin, *fout = imagebuffer;
uint *scaled = (unsigned *)image_desc.scaled;
byte *fin, *fout = image_desc.source;
bool has_alpha = false;
int scaled_width, scaled_height;
int i, w, h, samples;

View File

@ -23,7 +23,9 @@ fopen
1. Сделать OpenAL совместимый движок OK
2. Поддержка OGG Vorbis OK
3. Сделать поддержку loop звуков OK
4.
4. registration_sequence OK
5. óïîðÿäî÷èòü ïåðåìåííûå OK
6.
Физика игрока:
1. Убрать отскоки от стен

View File

@ -8,9 +8,8 @@
#define MAX_SFX 4096
static sfx_t s_knownSfx[MAX_SFX];
static int s_numSfx = 0;
#define SFX_HASHSIZE 128
static sfx_t *sfxHash[SFX_HASHSIZE];
int s_registration_sequence = 0;
bool s_registering = false;
/*
=================
@ -47,9 +46,7 @@ void S_SoundList_f( void )
if( sfx->name[0] == '#' ) Msg("%s", &sfx->name[1]);
else Msg("sound/%s", sfx->name);
if( sfx->default_snd ) Msg(" (DEFAULTED)\n");
else Msg("\n");
Msg( "\n" );
}
else
{
@ -59,8 +56,8 @@ void S_SoundList_f( void )
}
Msg("-------------------------------------------\n");
Msg("%i total samples\n", samples);
Msg("%i total sounds\n", s_numSfx);
Msg("%i total samples\n", samples );
Msg("%i total sounds\n", s_numSfx );
Msg("\n");
}
@ -162,7 +159,7 @@ S_LoadWAV
static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
{
byte *buffer, *out;
int length;
int length, samples;
buffer = FS_LoadFile( name, &length );
if( !buffer ) return false;
@ -216,7 +213,33 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
return false;
}
// Find data chunk
// get cue chunk
S_FindChunk("cue ");
if( iff_dataPtr )
{
iff_dataPtr += 32;
info->loopstart = S_GetLittleLong();
Msg("found 'cue '\n" );
// if the next chunk is a LIST chunk, look for a cue length marker
S_FindNextChunk("LIST");
if( iff_dataPtr )
{
if(!com.strncmp ((const char *)iff_dataPtr + 28, "mark", 4))
{
// this is not a proper parse, but it works with CoolEdit...
iff_dataPtr += 24;
info->samples = info->loopstart + S_GetLittleLong(); // samples in loop
Msg("loopstart = %d, samples %d\n", info->loopstart, info->samples );
}
}
}
else
{
info->loopstart = -1;
info->samples = 0;
}
// find data chunk
S_FindChunk("data");
if( !iff_dataPtr )
{
@ -226,7 +249,17 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
}
iff_dataPtr += 4;
info->samples = S_GetLittleLong() / info->width;
samples = S_GetLittleLong() / info->width;
if( info->samples )
{
if( samples < info->samples )
{
MsgDev( D_ERROR, "S_LoadWAV: %s has a bad loop length\n", name );
return false;
}
}
else info->samples = samples;
if( info->samples <= 0 )
{
@ -268,8 +301,9 @@ static void S_UploadSound( byte *data, int width, int channels, sfx_t *sfx )
}
// upload the sound
palGenBuffers(1, &sfx->bufferNum);
palGenBuffers( 1, &sfx->bufferNum );
palBufferData( sfx->bufferNum, sfx->format, data, size, sfx->rate );
S_CheckForErrors();
}
/*
@ -288,8 +322,19 @@ static void S_CreateDefaultSound( byte **wav, wavinfo_t *info )
info->samples = 11025;
*wav = out = Z_Malloc( info->samples * info->width );
for( i = 0; i < info->samples; i++ )
((short *)out)[i] = sin(i * 0.1f) * 20000;
if( s_check_errors->integer )
{
// create 1 kHz tone as default sound
for( i = 0; i < info->samples; i++ )
((short *)out)[i] = sin(i * 0.1f) * 20000;
}
else
{
// create silent sound
for( i = 0; i < info->samples; i++ )
((short *)out)[i] = i;
}
}
/*
@ -314,19 +359,20 @@ bool S_LoadSound( sfx_t *sfx )
if(!S_LoadWAV(name, &data, &info))
{
sfx->default_snd = true;
MsgWarn( "couldn't find sound '%s', using default...\n", name );
sfx->default_sound = true;
MsgDev(D_WARN, "couldn't load %s\n", sfx->name );
S_CreateDefaultSound( &data, &info );
info.loopstart = -1;
}
// load it in
sfx->loaded = true;
sfx->loopstart = info.loopstart;
sfx->samples = info.samples;
sfx->rate = info.rate;
S_UploadSound( data, info.width, info.channels, sfx );
Mem_Free(data);
sfx->loaded = true;
Mem_Free( data );
return true;
}
@ -334,29 +380,6 @@ bool S_LoadSound( sfx_t *sfx )
// =======================================================================
// Load a sound
// =======================================================================
/*
================
return a hash value for the sfx name
================
*/
static long S_HashSFXName( const char *name )
{
int i = 0;
long hash = 0;
char letter;
while( name[i] != '\0' )
{
letter = com.tolower(name[i]);
if (letter =='.') break; // don't include extension
if (letter =='\\') letter = '/'; // damn path names
hash += (long)(letter)*(i+119);
i++;
}
hash &= (SFX_HASHSIZE-1);
return hash;
}
/*
=================
S_FindSound
@ -364,53 +387,47 @@ S_FindSound
*/
sfx_t *S_FindSound( const char *name )
{
int i, hash;
sfx_t *sfx;
int i;
if( !name || !name[0] )
{
MsgWarn("S_FindSound: empty name\n");
return NULL;
}
if( !name || !name[0] ) return NULL;
if( com.strlen(name) >= MAX_STRING )
{
MsgWarn("S_FindSound: sound name too long: %s", name);
MsgDev( D_ERROR, "S_FindSound: sound name too long: %s", name );
return NULL;
}
hash = S_HashSFXName(name);
sfx = sfxHash[hash];
// see if already loaded
while( sfx )
{
if (!stricmp(sfx->name, name))
return sfx;
sfx = sfx->nextHash;
}
// find a free sfx slot
for (i = 0; i < s_numSfx; i++)
{
if(!s_knownSfx[i].name[0])
break;
}
if (i == s_numSfx)
{
if (s_numSfx == MAX_SFX)
for( i = 0; i < s_numSfx; i++ )
{
sfx = &s_knownSfx[i];
if( !sfx->name[0] ) continue;
if( !com.strcmp( name, sfx->name ))
{
MsgWarn("S_FindName: MAX_SFX limit exceeded\n");
// prolonge registration
sfx->registration_sequence = s_registration_sequence;
return sfx;
}
}
// find a free sfx slot spot
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++)
{
if(!sfx->name[0]) break; // free spot
}
if( i == s_numSfx )
{
if( s_numSfx == MAX_SFX )
{
MsgWarn("S_FindName: MAX_SFX limit exceeded\n" );
return NULL;
}
s_numSfx++;
}
sfx = &s_knownSfx[i];
memset (sfx, 0, sizeof(*sfx));
strcpy (sfx->name, name);
sfx->nextHash = sfxHash[hash];
sfxHash[hash] = sfx;
memset( sfx, 0, sizeof(*sfx));
com.strncpy( sfx->name, name, MAX_STRING );
sfx->registration_sequence = s_registration_sequence;
return sfx;
}
@ -422,6 +439,8 @@ S_BeginRegistration
*/
void S_BeginRegistration( void )
{
s_registration_sequence++;
s_registering = true;
}
/*
@ -431,6 +450,29 @@ S_EndRegistration
*/
void S_EndRegistration( void )
{
sfx_t *sfx;
int i;
// free any sounds not from this registration sequence
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
{
if( !sfx->name[0] ) continue;
if( sfx->registration_sequence != s_registration_sequence )
{
// don't need this sound
palDeleteBuffers( 1, &sfx->bufferNum );
sfx->name[0] = '\0'; // free spot
sfx->loaded = false;
}
}
// load everything in
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
{
if( !sfx->name[0] )continue;
S_LoadSound( sfx );
}
s_registering = false;
}
/*
@ -446,9 +488,11 @@ sound_t S_RegisterSound( const char *name )
return 0;
sfx = S_FindSound( name );
S_LoadSound( sfx );
if( !sfx ) return 0;
sfx->registration_sequence = s_registration_sequence;
if( !s_registering ) S_LoadSound( sfx );
return sfx - s_knownSfx;
}
@ -469,22 +513,20 @@ sfx_t *S_GetSfxByHandle( sound_t handle )
*/
void S_FreeSounds( void )
{
sfx_t *sfx;
int i;
int i;
// Stop all sounds
// stop all sounds
S_StopAllSounds();
// Free all sounds
// free all sounds
for (i = 0; i < s_numSfx; i++)
{
sfx = &s_knownSfx[i];
if( !sfx->loaded ) continue;
palDeleteBuffers(1, &sfx->bufferNum);
}
memset( sfxHash, 0, sizeof(sfx_t *)*SFX_HASHSIZE);
memset( s_knownSfx, 0, sizeof(s_knownSfx));
s_numSfx = 0;
}

View File

@ -1,454 +0,0 @@
//=======================================================================
// Copyright XashXT Group 2007 ©
// s_load.c - sound managment
//=======================================================================
#include "sound.h"
#define SFX_HASHSIZE 256
#define MAX_SFX 1024
static sfx_t *s_sfxHash[SFX_HASHSIZE];
static sfx_t *s_sfx[MAX_SFX];
static int s_numSfx;
/*
=================
S_SoundList_f
=================
*/
void S_SoundList_f( void )
{
sfx_t *sfx;
int i, samples = 0;
Msg("\n");
Msg(" -samples -hz-- -format- -name--------\n");
for( i = 0; i < s_numSfx; i++ )
{
sfx = s_sfx[i];
Msg("%4i: ", i);
if( sfx->loaded )
{
samples += sfx->samples;
Msg("%8i ", sfx->samples);
Msg("%5i ", sfx->rate);
switch( sfx->format )
{
case AL_FORMAT_STEREO16: Msg("STEREO16 "); break;
case AL_FORMAT_STEREO8: Msg("STEREO8 "); break;
case AL_FORMAT_MONO16: Msg("MONO16 "); break;
case AL_FORMAT_MONO8: Msg("MONO8 "); break;
default: Msg("???????? "); break;
}
if( sfx->name[0] == '#' ) Msg("%s", &sfx->name[1]);
else Msg("sound/%s", sfx->name);
if( sfx->default_snd ) Msg(" (DEFAULTED)\n");
else Msg("\n");
}
else
{
if( sfx->name[0] == '*' ) Msg(" placeholder %s\n", sfx->name);
else Msg(" not loaded %s\n", sfx->name);
}
}
Msg("-------------------------------------------\n");
Msg("%i total samples\n", samples);
Msg("%i total sounds\n", s_numSfx);
Msg("\n");
}
/*
=======================================================================
WAV LOADING
=======================================================================
*/
static byte *iff_data;
static byte *iff_dataPtr;
static byte *iff_end;
static byte *iff_lastChunk;
static int iff_chunkLen;
/*
=================
S_GetLittleShort
=================
*/
static short S_GetLittleShort( void )
{
short val = 0;
val += (*(iff_dataPtr+0) << 0);
val += (*(iff_dataPtr+1) << 8);
iff_dataPtr += 2;
return val;
}
/*
=================
S_GetLittleLong
=================
*/
static int S_GetLittleLong( void )
{
int val = 0;
val += (*(iff_dataPtr+0) << 0);
val += (*(iff_dataPtr+1) << 8);
val += (*(iff_dataPtr+2) << 16);
val += (*(iff_dataPtr+3) << 24);
iff_dataPtr += 4;
return val;
}
/*
=================
S_FindNextChunk
=================
*/
static void S_FindNextChunk( const char *name )
{
while( 1 )
{
iff_dataPtr = iff_lastChunk;
if( iff_dataPtr >= iff_end )
{
// didn't find the chunk
iff_dataPtr = NULL;
return;
}
iff_dataPtr += 4;
iff_chunkLen = S_GetLittleLong();
if (iff_chunkLen < 0)
{
iff_dataPtr = NULL;
return;
}
iff_dataPtr -= 8;
iff_lastChunk = iff_dataPtr + 8 + ((iff_chunkLen + 1) & ~1);
if(!com.strncmp( iff_dataPtr, name, 4 ))
return;
}
}
/*
=================
S_FindChunk
=================
*/
static void S_FindChunk( const char *name )
{
iff_lastChunk = iff_data;
S_FindNextChunk( name );
}
/*
=================
S_LoadWAV
=================
*/
static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
{
byte *buffer, *out;
int length;
buffer = FS_LoadFile( name, &length );
if( !buffer ) return false;
iff_data = buffer;
iff_end = buffer + length;
// dind "RIFF" chunk
S_FindChunk( "RIFF" );
if(!(iff_dataPtr && !com.strncmp(iff_dataPtr+8, "WAVE", 4)))
{
MsgDev( D_WARN, "S_LoadWAV: missing 'RIFF/WAVE' chunks (%s)\n", name );
Mem_Free( buffer );
return false;
}
// get "fmt " chunk
iff_data = iff_dataPtr + 12;
S_FindChunk("fmt ");
if( !iff_dataPtr )
{
MsgDev( D_WARN, "S_LoadWAV: missing 'fmt ' chunk (%s)\n", name );
Mem_Free( buffer );
return false;
}
iff_dataPtr += 8;
if( S_GetLittleShort() != 1 )
{
MsgDev( D_WARN, "S_LoadWAV: microsoft PCM format only (%s)\n", name );
Mem_Free( buffer );
return false;
}
info->channels = S_GetLittleShort();
if( info->channels != 1 )
{
MsgDev( D_WARN, "S_LoadWAV: only mono WAV files supported (%s)\n", name );
Mem_Free( buffer );
return false;
}
info->rate = S_GetLittleLong();
iff_dataPtr += 4+2;
info->width = S_GetLittleShort() / 8;
if( info->width != 1 && info->width != 2 )
{
MsgDev( D_WARN, "S_LoadWAV: only 8 and 16 bit WAV files supported (%s)\n", name );
Mem_Free( buffer );
return false;
}
// Find data chunk
S_FindChunk("data");
if( !iff_dataPtr )
{
MsgDev( D_WARN, "S_LoadWAV: missing 'data' chunk (%s)\n", name );
Mem_Free( buffer );
return false;
}
iff_dataPtr += 4;
info->samples = S_GetLittleLong() / info->width;
if( info->samples <= 0 )
{
MsgDev( D_WARN, "S_LoadWAV: file with 0 samples (%s)\n", name);
Mem_Free( buffer );
return false;
}
// Load the data
*wav = out = Z_Malloc( info->samples * info->width );
Mem_Copy( out, buffer + (iff_dataPtr - buffer), info->samples * info->width );
Mem_Free( buffer );
return true;
}
/*
=================
S_UploadSound
=================
*/
static void S_UploadSound( byte *data, int width, int channels, sfx_t *sfx )
{
int size;
// calculate buffer size
size = sfx->samples * width * channels;
// Set buffer format
if( width == 2 )
{
if( channels == 2 ) sfx->format = AL_FORMAT_STEREO16;
else sfx->format = AL_FORMAT_MONO16;
}
else
{
if( channels == 2 ) sfx->format = AL_FORMAT_STEREO8;
else sfx->format = AL_FORMAT_MONO8;
}
// upload the sound
palGenBuffers(1, &sfx->bufferNum);
palBufferData(sfx->bufferNum, sfx->format, data, size, sfx->rate);
}
/*
=================
S_CreateDefaultSound
=================
*/
static void S_CreateDefaultSound( byte **wav, wavinfo_t *info )
{
byte *out;
int i;
info->rate = 22050;
info->width = 2;
info->channels = 1;
info->samples = 11025;
*wav = out = Z_Malloc( info->samples * info->width );
for( i = 0; i < info->samples; i++ )
((short *)out)[i] = sin(i * 0.1f) * 20000;
}
/*
=================
S_LoadSound
=================
*/
bool S_LoadSound( sfx_t *sfx )
{
string name;
byte *data;
wavinfo_t info;
if( !sfx ) return false;
if( sfx->name[0] == '*' ) return false;
if( sfx->loaded ) return true; // see if still in memory
// load it from disk
if( sfx->name[0] == '#' )
com.snprintf( name, sizeof(name), "%s", &sfx->name[1]);
else com.snprintf( name, sizeof(name), "sound/%s", sfx->name );
if(!S_LoadWAV(name, &data, &info))
{
sfx->default_snd = true;
MsgWarn( "couldn't find sound '%s', using default...\n", name );
S_CreateDefaultSound( &data, &info );
}
// load it in
sfx->loaded = true;
sfx->samples = info.samples;
sfx->rate = info.rate;
S_UploadSound( data, info.width, info.channels, sfx );
Mem_Free(data);
return true;
}
/*
=================
S_FindSound
=================
*/
sfx_t *S_FindSound( const char *name )
{
sfx_t *sfx;
uint hashKey;
if( !name || !name[0] )
{
MsgWarn("S_FindSound: empty name\n");
return NULL;
}
if( com.strlen(name) >= MAX_STRING )
{
MsgWarn("S_FindSound: sound name too long: %s", name);
return NULL;
}
hashKey = Com_HashKey(name, SFX_HASHSIZE);
for( sfx = s_sfxHash[hashKey]; sfx; sfx = sfx->nextHash )
{
if (!com.stricmp( sfx->name, name ))
return sfx;
}
// Create a new sfx_t
if( s_numSfx == MAX_SFX )
{
MsgWarn("S_FindSound: MAX_SFX limit exceeded\n");
return NULL;
}
s_sfx[s_numSfx++] = sfx = Z_Malloc(sizeof(sfx_t));
// fill it in
com.strncpy( sfx->name, name, sizeof(sfx->name));
// add to hash table
sfx->nextHash = s_sfxHash[hashKey];
s_sfxHash[hashKey] = sfx;
return sfx;
}
/*
=====================
S_BeginRegistration
=====================
*/
void S_BeginRegistration( void )
{
}
/*
=====================
S_EndRegistration
=====================
*/
void S_EndRegistration( void )
{
}
/*
=================
S_RegisterSound
=================
*/
sound_t S_RegisterSound( const char *name )
{
sfx_t *sfx;
if(!al_state.initialized)
return 0;
sfx = S_FindSound( name );
S_LoadSound( sfx );
if( !sfx ) return 0;
return sfx - *s_sfx;
}
sfx_t *S_GetSfxByHandle( sound_t handle )
{
if( handle < 0 || handle >= s_numSfx )
{
MsgWarn("S_GetSfxByHandle: handle %i out of range (%i)\n", handle, s_numSfx );
return NULL;
}
return s_sfx[handle];
}
/*
=================
S_FreeSounds
=================
*/
void S_FreeSounds( void )
{
sfx_t *sfx;
int i;
// Stop all sounds
S_StopAllSounds();
// Free all sounds
for (i = 0; i < s_numSfx; i++){
sfx = s_sfx[i];
palDeleteBuffers(1, &sfx->bufferNum);
Mem_Free(sfx);
}
memset( s_sfxHash, 0, sizeof(s_sfxHash));
memset( s_sfx, 0, sizeof(s_sfx));
s_numSfx = 0;
}

View File

@ -5,66 +5,43 @@
#include "sound.h"
cvar_t *s_initSound;
cvar_t *s_show;
cvar_t *s_alDevice;
cvar_t *s_allowExtensions;
cvar_t *s_soundfx;
cvar_t *s_ignoreALErrors;
cvar_t *s_masterVolume;
cvar_t *s_sfxVolume;
cvar_t *s_musicVolume;
cvar_t *s_minDistance;
cvar_t *s_maxDistance;
cvar_t *s_rolloffFactor;
cvar_t *s_dopplerFactor;
cvar_t *s_dopplerVelocity;
#define MAX_PLAYSOUNDS 128
#define MAX_CHANNELS 64
static playSound_t s_playSounds[MAX_PLAYSOUNDS];
static playSound_t s_freePlaySounds;
static playSound_t s_pendingPlaySounds;
static channel_t s_channels[MAX_CHANNELS];
static int s_numChannels;
static listener_t s_listener;
static int s_frameCount;
static channel_t s_channels[MAX_CHANNELS];
static listener_t s_listener;
const guid_t DSPROPSETID_EAX20_ListenerProperties = {0x306a6a8, 0xb224, 0x11d2, {0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22}};
const guid_t DSPROPSETID_EAX20_BufferProperties = {0x306a6a7, 0xb224, 0x11d2, {0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22}};
cvar_t *s_initSound;
cvar_t *s_show;
cvar_t *s_alDriver;
cvar_t *host_sound;
cvar_t *s_alDevice;
cvar_t *s_allowExtensions;
cvar_t *s_ext_eax;
cvar_t *s_ignoreALErrors;
cvar_t *s_masterVolume;
cvar_t *s_sfxVolume;
cvar_t *s_musicVolume;
cvar_t *s_soundfx;
cvar_t *s_check_errors;
cvar_t *s_volume; // master volume
cvar_t *s_musicvolume; // background track volume
cvar_t *s_minDistance;
cvar_t *s_maxDistance;
cvar_t *s_rolloffFactor;
cvar_t *s_dopplerFactor;
cvar_t *s_dopplerVelocity;
/*
=================
S_CheckForErrors
=================
*/
static void S_CheckForErrors( void )
void S_CheckForErrors( void )
{
int err;
char *str;
if( !s_check_errors->integer )
return;
if((err = palGetError()) == AL_NO_ERROR)
return;
@ -154,7 +131,23 @@ static void S_PlayChannel( channel_t *ch, sfx_t *sfx )
palSourcei(ch->sourceNum, AL_BUFFER, sfx->bufferNum);
palSourcei(ch->sourceNum, AL_LOOPING, ch->loopsound);
palSourcei(ch->sourceNum, AL_SOURCE_RELATIVE, false);
palSourcePlay(ch->sourceNum);
if( sfx->loopstart > -1 )
{
if( sfx->loopfirst )
{
sfx->loopfirst = false;
Msg( "loopsound playing at first\n" );
palSourcei( ch->sourceNum, AL_SAMPLE_OFFSET, 0 );
}
else
{
Msg( "loopsound playing loop from %d\n", sfx->loopstart );
palSourcei( ch->sourceNum, AL_SAMPLE_OFFSET, sfx->loopstart );
}
}
else palSourcei( ch->sourceNum, AL_SAMPLE_OFFSET, 0 );
palSourcePlay( ch->sourceNum );
}
/*
@ -210,7 +203,7 @@ static void S_SpatializeChannel( channel_t *ch )
palSourcef( ch->sourceNum, AL_MAX_DISTANCE, s_maxDistance->value );
// update volume and rolloff factor
palSourcef( ch->sourceNum, AL_GAIN, s_sfxVolume->value * ch->volume );
palSourcef( ch->sourceNum, AL_GAIN, ch->volume );
palSourcef( ch->sourceNum, AL_ROLLOFF_FACTOR, s_rolloffFactor->value );
}
@ -226,7 +219,7 @@ channel_t *S_PickChannel( int entnum, int entChannel )
channel_t *ch;
int i;
int firstToDie = -1;
int oldestTime = si.GetClientTime();
int oldestTime = Sys_DoubleTime();
if( entnum < 0 || entChannel < 0 )
Host_Error( "S_PickChannel: entnum or entChannel less than 0" );
@ -269,7 +262,7 @@ channel_t *S_PickChannel( int entnum, int entChannel )
ch->entnum = entnum;
ch->entchannel = entChannel;
ch->startTime = si.GetClientTime();
ch->startTime = Sys_DoubleTime();
// Make sure this channel is stopped
palSourceStop(ch->sourceNum);
@ -298,7 +291,7 @@ bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn )
sfx = S_GetSfxByHandle( handle );
// default looped sound it's terrible :)
if( !sfx || !sfx->loaded || sfx->default_snd )
if( !sfx || !sfx->loaded || sfx->default_sound )
return false;
// if this entity is already playing the same sound effect on an
@ -391,11 +384,15 @@ static void S_IssuePlaySounds( void )
{
ps = s_pendingPlaySounds.next;
if(ps == &s_pendingPlaySounds)
{
Msg("no more pending playsounds\n");
break; // no more pending playSounds
if( ps->beginTime > si.GetClientTime())
}
if( ps->beginTime > Sys_DoubleTime())
{
Msg("no more pending playsounds\n");
break; // No more pending playSounds this frame
}
// pick a channel and start the sound effect
ch = S_PickChannel( ps->entnum, ps->entchannel );
if(!ch)
@ -405,8 +402,12 @@ static void S_IssuePlaySounds( void )
S_FreePlaySound( ps );
continue;
}
// check for looping sounds with "cue " marker
if( ps->sfx->loopstart > -1 )
{
ps->sfx->loopfirst = true;
}
ch->loopsound = false;
ch->fixedPosition = ps->fixedPosition;
VectorCopy( ps->position, ch->position );
ch->volume = ps->volume;
@ -419,6 +420,16 @@ static void S_IssuePlaySounds( void )
// free the playSound
S_FreePlaySound( ps );
if( S_ChannelState( ch ) == AL_STOPPED )
{
if( ch->sfx->loopstart > -1 )
{
Msg("playing %s again form offset %d\n", ch->sfx->name, ch->sfx->loopstart );
S_PlayChannel( ch, ch->sfx );
}
}
}
}
@ -438,10 +449,9 @@ void S_StartSound( const vec3_t position, int entnum, int entChannel, sound_t ha
if(!al_state.initialized )
return;
sfx = S_GetSfxByHandle( handle );
if( !sfx ) return;
Msg("CL_StartSound %s ( entnum %d, channel %d)\n", sfx->name, entnum, entChannel );
// Make sure the sound is loaded
if(!S_LoadSound(sfx)) return;
@ -453,7 +463,6 @@ void S_StartSound( const vec3_t position, int entnum, int entChannel, sound_t ha
else MsgDev( D_ERROR, "dropped sound \"sound/%s\"\n", sfx->name );
return;
}
ps->sfx = sfx;
ps->entnum = entnum;
ps->entchannel = entChannel;
@ -467,7 +476,7 @@ void S_StartSound( const vec3_t position, int entnum, int entChannel, sound_t ha
ps->volume = volume;
ps->attenuation = attenuation;
ps->beginTime = si.GetClientTime();
ps->beginTime = Sys_DoubleTime();
// Sort into the pending playSounds list
for( sort = s_pendingPlaySounds.next; sort != &s_pendingPlaySounds&& sort->beginTime < ps->beginTime; sort = sort->next );
@ -493,7 +502,7 @@ bool S_StartLocalSound( const char *name )
return false;
sfxHandle = S_RegisterSound( name );
S_StartSound( NULL, al_state.clientnum, 0, sfxHandle, 1.0f, ATTN_NONE );
S_StartSound( NULL, al_state.clientnum, CHAN_BODY, sfxHandle, 1.0f, ATTN_NONE );
return true;
}
@ -589,7 +598,7 @@ void S_Update( int clientnum, const vec3_t position, const vec3_t velocity, cons
palListenerfv(AL_POSITION, s_listener.position);
palListenerfv(AL_VELOCITY, s_listener.velocity);
palListenerfv(AL_ORIENTATION, s_listener.orientation);
palListenerf(AL_GAIN, (al_state.active) ? s_masterVolume->value : 0.0f );
palListenerf(AL_GAIN, (al_state.active) ? s_volume->value : 0.0f );
// Set state
palDistanceModel( AL_INVERSE_DISTANCE_CLAMPED );
@ -636,8 +645,7 @@ void S_Update( int clientnum, const vec3_t position, const vec3_t velocity, cons
}
// check for errors
if(!s_ignoreALErrors->integer)
S_CheckForErrors();
S_CheckForErrors();
}
/*
@ -655,7 +663,7 @@ void S_Activate( bool active )
return;
al_state.active = active;
if( active ) palListenerf( AL_GAIN, s_masterVolume->value );
if( active ) palListenerf( AL_GAIN, s_volume->value );
else palListenerf( AL_GAIN, 0.0 );
}
@ -739,14 +747,12 @@ void S_SoundInfo_f( void )
*/
void S_Init( void *hInst )
{
s_initSound = Cvar_Get("s_initsound", "1", CVAR_SYSTEMINFO );
host_sound = Cvar_Get("host_sound", "1", CVAR_SYSTEMINFO );
s_alDevice = Cvar_Get("s_device", "Generic Software", CVAR_LATCH|CVAR_ARCHIVE );
s_allowExtensions = Cvar_Get("s_allowextensions", "1", CVAR_LATCH|CVAR_ARCHIVE );
s_soundfx = Cvar_Get("s_soundfx", "1", CVAR_LATCH|CVAR_ARCHIVE );
s_ignoreALErrors = Cvar_Get("s_ignoreALErrors", "1", CVAR_ARCHIVE );
s_masterVolume = Cvar_Get("s_volume", "1.0", CVAR_ARCHIVE );
s_sfxVolume = Cvar_Get("s_soundvolume", "1.0", CVAR_ARCHIVE );
s_musicVolume = Cvar_Get("s_musicvolume", "1.0", CVAR_ARCHIVE );
s_check_errors = Cvar_Get("s_check_errors", "1", CVAR_ARCHIVE );
s_volume = Cvar_Get("s_volume", "1.0", CVAR_ARCHIVE );
s_musicvolume = Cvar_Get("s_musicvolume", "1.0", CVAR_ARCHIVE );
s_minDistance = Cvar_Get("s_mindistance", "240.0", CVAR_ARCHIVE );
s_maxDistance = Cvar_Get("s_maxdistance", "8192.0", CVAR_ARCHIVE );
s_rolloffFactor = Cvar_Get("s_rollofffactor", "1.0", CVAR_ARCHIVE );
@ -759,9 +765,9 @@ void S_Init( void *hInst )
Cmd_AddCommand("s_info", S_SoundInfo_f, "print sound system information" );
Cmd_AddCommand("soundlist", S_SoundList_f, "display loaded sounds" );
if(!s_initSound->integer)
if(!host_sound->integer)
{
MsgDev(D_INFO, "S_Init: sound system disabled\n" );
MsgDev(D_INFO, "Audio: disabled\n" );
return;
}
@ -776,9 +782,7 @@ void S_Init( void *hInst )
S_AllocChannels();
S_StopAllSounds();
if(!s_ignoreALErrors->integer)
S_CheckForErrors();
S_CheckForErrors();
al_state.active = true; // enabled
}

View File

@ -69,6 +69,11 @@ typedef struct alcontext_s alcontext;
#define AL_BUFFERS_QUEUED 0x1015
#define AL_BUFFERS_PROCESSED 0x1016
// source buffer position information
#define AL_SEC_OFFSET 0x1024
#define AL_SAMPLE_OFFSET 0x1025
#define AL_BYTE_OFFSET 0x1026
// openal errors
#define AL_NO_ERROR 0
#define AL_INVALID_NAME 0xA001

View File

@ -135,7 +135,7 @@ void S_StreamBackgroundTrack( void )
int size, read, dummy;
uint buffer;
if( !s_bgTrack.file || !s_musicVolume->value )
if( !s_bgTrack.file || !s_musicvolume->value )
return;
if(!s_streamingChannel) return;
@ -199,7 +199,7 @@ void S_StreamBackgroundTrack( void )
}
// update volume
palSourcef( s_streamingChannel->sourceNum, AL_GAIN, s_musicVolume->value );
palSourcef( s_streamingChannel->sourceNum, AL_GAIN, s_musicvolume->value );
// if not playing, then do so
palGetSourcei( s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state );
@ -359,7 +359,7 @@ void S_StreamRawSamples( int samples, int rate, int width, int channels, const b
palSourceQueueBuffers( s_streamingChannel->sourceNum, 1, &buffer );
// update volume
palSourcef( s_streamingChannel->sourceNum, AL_GAIN, s_sfxVolume->value );
palSourcef( s_streamingChannel->sourceNum, AL_GAIN, 1.0f );
// if not playing, then do so
palGetSourcei(s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state);

View File

@ -25,6 +25,7 @@ typedef struct
{
int rate;
int width;
int loopstart;
int channels;
int samples;
} wavinfo_t;
@ -32,14 +33,16 @@ typedef struct
typedef struct sfx_s
{
string name;
bool default_snd;
bool loaded;
int loopstart; // looping point (in samples)
bool loopfirst; // check it for set properly offset in samples
int samples;
int rate;
uint format;
uint bufferNum;
struct sfx_s *nextHash;
bool default_sound;
int registration_sequence;
} sfx_t;
typedef struct
@ -54,8 +57,8 @@ typedef struct
void *vorbisFile;
} bg_track_t;
// A playSound will be generated by each call to S_StartSound.
// When the mixer reaches playSound->beginTime, the playSound will be
// a playSound will be generated by each call to S_StartSound.
// when the mixer reaches playSound->beginTime, the playSound will be
// assigned to a channel.
typedef struct playsound_s
{
@ -74,17 +77,17 @@ typedef struct
{
bool streaming;
sfx_t *sfx; // NULL if unused
int entnum; // To allow overriding a specific sound
int entnum; // to allow overriding a specific sound
int entchannel;
int startTime; // For overriding oldest sounds
bool loopsound; // Looping sound
int loopnum; // Looping entity number
int loopframe; // For stopping looping sounds
bool fixedPosition; // Use position instead of fetching entity's origin
vec3_t position; // Only use if fixedPosition is set
int startTime; // for overriding oldest sounds
bool loopsound; // is looping sound ?
int loopnum; // looping entity number
int loopframe; // for stopping looping sounds
bool fixedPosition; // use position instead of fetching entity's origin
vec3_t position; // only use if fixedPosition is set
float volume;
float distanceMult;
uint sourceNum; // OpenAL source
uint sourceNum; // openAL source
} channel_t;
typedef struct
@ -130,78 +133,40 @@ extern alconfig_t al_config;
extern alstate_t al_state;
#define Host_Error com.error
#define Z_Malloc( size ) Mem_Alloc( sndpool, size )
// cvars
extern cvar_t *s_initSound;
extern cvar_t *s_show;
extern cvar_t *s_alDevice;
extern cvar_t *s_allowExtensions;
extern cvar_t *s_soundfx;
extern cvar_t *s_ignoreALErrors;
extern cvar_t *s_masterVolume;
extern cvar_t *s_sfxVolume;
extern cvar_t *s_musicVolume;
extern cvar_t *s_minDistance;
extern cvar_t *s_maxDistance;
extern cvar_t *s_rolloffFactor;
extern cvar_t *s_dopplerFactor;
extern cvar_t *s_dopplerVelocity;
extern int s_rawend;
extern int s_soundtime;
extern cvar_t *s_musicvolume;
extern cvar_t *s_check_errors;
void S_Init( void *hInst );
void S_Shutdown( void );
void S_Activate( bool active );
void S_SoundList_f( void );
// if origin is NULL, the sound will be dynamically sourced from the entity
void S_CheckForErrors( void );
void S_StartSound( const vec3_t origin, int entnum, int entchannel, sound_t sfx, float vol, float attn );
int S_StartLocalSound( const char *name );
void S_StartBackgroundTrack( const char *intro, const char *loop );
void S_StopBackgroundTrack( void );
sfx_t *S_GetSfxByHandle( sound_t handle );
bool S_LoadSound( sfx_t *sfx );
channel_t *S_PickChannel( int entNum, int entChannel );
void S_StartStreaming( void );
void S_StreamBackgroundTrack( void );
void S_StopStreaming( void );
// cinematics and voice-over-network will send raw samples
void S_Update( int clientnum, const vec3_t pos, const vec3_t vel, const vec3_t at, const vec3_t up );
void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
// stop all sounds and the background track
bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn );
void S_StartBackgroundTrack( const char *intro, const char *loop );
channel_t *S_PickChannel( int entNum, int entChannel );
int S_StartLocalSound( const char *name );
sfx_t *S_GetSfxByHandle( sound_t handle );
void S_StreamBackgroundTrack( void );
void S_StopBackgroundTrack( void );
void S_ClearSoundBuffer( void );
bool S_LoadSound( sfx_t *sfx );
void S_StartStreaming( void );
void S_StopStreaming( void );
void S_StopAllSounds( void );
void S_FreeSounds( void );
// all continuous looping sounds must be added before calling S_Update
bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn );
void S_StopLoopingSound(int entityNum );
// recompute the reletive volumes for all running sounds
// reletive to the given entityNum / orientation
void S_Respatialize( int entityNum, const vec3_t origin, const vec3_t v_forward, const vec3_t v_left, const vec3_t v_up );
// let the sound system know where an entity currently is
void S_UpdateEntityPosition( int entityNum, const vec3_t origin );
void S_Update( int clientnum, const vec3_t pos, const vec3_t vel, const vec3_t at, const vec3_t up );
void S_DisableSounds( void );
void S_EnableSounds( void );
// registration manager
void S_BeginRegistration( void );
sound_t S_RegisterSound( const char *sample );
void S_EndRegistration( void );
// RegisterSound will allways return a valid sample, even if it
// has to create a placeholder. This prevents continuous filesystem
// checks for missing files
sound_t S_RegisterSound( const char *sample );
void S_DisplayFreeMemory(void);
void S_ClearSoundBuffer( void );
void SNDDMA_Activate( void );
void S_UpdateBackgroundTrack( void );
#endif//SOUND_H