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)) if (!stricmp(name, textureref[i].texname))
return i; 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 // register texture
strcpy (textureref[i].texname, name ); 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 Build succeeded!
echo Please wait. Xash is now loading echo Please wait. Xash is now loading
cd D:\Xash3D\ 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 :done

View File

@ -241,6 +241,10 @@ void Field_CompleteCommand( field_t *field )
{ {
result = Cmd_GetMapList(Cmd_Argv(1), filename, MAX_STRING ); 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" )) else if(!stricmp(Cmd_Argv(0), "playdemo" ) || !stricmp(Cmd_Argv(0), "\\playdemo" ))
{ {
result = Cmd_GetDemoList(Cmd_Argv(1), filename, MAX_STRING ); result = Cmd_GetDemoList(Cmd_Argv(1), filename, MAX_STRING );

View File

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

View File

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

View File

@ -372,7 +372,6 @@ void SV_Transform( sv_edict_t *ed, matrix4x3 transform );
int CL_PMpointcontents( vec3_t point ); int CL_PMpointcontents( vec3_t point );
void CL_AddLoopingSounds( void ); void CL_AddLoopingSounds( void );
void CL_RegisterSounds( void ); void CL_RegisterSounds( void );
float CL_GetTime( void );
void CL_Drop( void ); void CL_Drop( void );
char *Info_ValueForKey( char *s, char *key ); char *Info_ValueForKey( char *s, char *key );
void Info_RemoveKey( 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_Userinfo( void );
char *Cvar_Serverinfo( void ); char *Cvar_Serverinfo( void );
void Cmd_WriteVariables( file_t *f ); void Cmd_WriteVariables( file_t *f );
bool Cmd_GetMapList (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_GetFontList(const char *s, char *completedname, int length );
bool Cmd_GetDemoList(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_Error( const char *msg, ... );
void Sys_SendKeyEvents( void ); void Sys_SendKeyEvents( void );

View File

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

View File

@ -197,16 +197,16 @@ typedef enum
*/ */
// per-level limits // per-level limits
#define MAX_ENTITIES 128 #define MAX_ENTITIES 512 // refdef ents
#define MAX_DLIGHTS 32 #define MAX_DLIGHTS 64
#define MAX_CLIENTS 256 // absolute limit #define MAX_CLIENTS 256 // absolute limit
#define MAX_PARTICLES 4096 #define MAX_PARTICLES 512
#define MAX_LIGHTSTYLES 256 #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_IMAGES 256 // hud graphics
#define MAX_DECALS 256 // various decals #define MAX_DECALS 256 // various decals
#define MAX_ITEMS 512 // player items #define MAX_ITEMS 128 // player items
#define MAX_GENERAL (MAX_CLIENTS*2) // general config strings #define MAX_GENERAL (MAX_CLIENTS * 2) // general config strings
// config strings are a general means of communication from // config strings are a general means of communication from
// the server to all connected clients. // 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; int i;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
if (min[i] > max[i]) if( min[i] > max[i] )
PRVM_ERROR("SV_SetMinMaxSize: backwards mins/maxs"); PRVM_ERROR("SV_SetMinMaxSize: backwards mins/maxs");
// set derived values // set derived values
@ -1440,7 +1440,8 @@ void PF_sound( void )
return; 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 ); 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 leafnum = 0, cluster = 0;
int area1 = 0, area2 = 0; int area1 = 0, area2 = 0;
int j, numclients = maxclients->value; int j, numclients = maxclients->value;
client_state_t *client, *current = svs.clients; client_state_t *client, *current = svs.clients;
bool reliable = false; bool reliable = false;
/*if(origin == NULL || ent == NULL) /*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 ); Mem_Free( var->reset_string );
var->reset_string = copystring( var_value ); 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 // 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 ); void (*GetSoundSpatialization)( int entnum, vec3_t origin, vec3_t velocity );
int (*PointContents)( vec3_t point ); int (*PointContents)( vec3_t point );
void (*AddLoopingSounds)( void ); void (*AddLoopingSounds)( void );
float (*GetClientTime)( void );
} vsound_imp_t; } vsound_imp_t;
// this is the only function actually exported at the linker level // this is the only function actually exported at the linker level

View File

@ -18,10 +18,6 @@ int numgltextures;
byte intensitytable[256]; byte intensitytable[256];
cvar_t *gl_maxsize; cvar_t *gl_maxsize;
byte *r_imagepool; byte *r_imagepool;
byte *imagebuffer;
int imagebufsize;
byte *uploadbuffer;
int uploadbufsize;
bool use_gl_extension = false; bool use_gl_extension = false;
cvar_t *intensity; cvar_t *intensity;
uint d_8to24table[256]; uint d_8to24table[256];
@ -47,6 +43,8 @@ typedef struct
int flags; int flags;
byte *pal; byte *pal;
byte *source;
byte *scaled;
} pixformat_desc_t; } pixformat_desc_t;
static pixformat_desc_t image_desc; 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)) // 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); 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);
} }
/* /*
@ -162,6 +157,7 @@ bool R_GetPixelFormat( rgbdata_t *pic, imagetype_t type )
if(!pic || !pic->buffer) return false; if(!pic || !pic->buffer) return false;
Mem_EmptyPool( r_imagepool ); // flush buffers
memset( &image_desc, 0, sizeof(image_desc)); memset( &image_desc, 0, sizeof(image_desc));
for(i = 0; i < PF_TOTALCOUNT; i++) for(i = 0; i < PF_TOTALCOUNT; i++)
{ {
@ -231,6 +227,9 @@ bool R_GetPixelFormat( rgbdata_t *pic, imagetype_t type )
use_gl_extension = true; use_gl_extension = true;
else use_gl_extension = false; 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) if(image_desc.flags & IMAGE_CUBEMAP)
totalsize *= 6; totalsize *= 6;
@ -315,27 +314,19 @@ void R_InitTextures( void )
gl_maxsize = Cvar_Get( "gl_maxsize", "4096", CVAR_ARCHIVE ); gl_maxsize = Cvar_Get( "gl_maxsize", "4096", CVAR_ARCHIVE );
qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &texsize); // merge value qglGetIntegerv(GL_MAX_TEXTURE_SIZE, &texsize); // merge value
if (gl_maxsize->integer != texsize) Cvar_SetValue ("gl_maxsize", texsize ); 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 );
registration_sequence = 1; registration_sequence = 1;
// init intensity conversions // init intensity conversions
intensity = Cvar_Get ("intensity", "2", 0 ); 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; gl_state.inverse_intensity = 1 / intensity->value;
for (i = 0; i < 256; i++) for (i = 0; i < 256; i++)
{ {
j = i * intensity->value; j = i * intensity->value;
intensitytable[i] = bound(0, j, 255); intensitytable[i] = bound( 0, j, 255 );
} }
R_GetPalette(); R_GetPalette();
} }
@ -347,8 +338,8 @@ void R_RoundImageDimensions( int *scaled_width, int *scaled_height )
for( width = 1; width < *scaled_width; width <<= 1 ); for( width = 1; width < *scaled_width; width <<= 1 );
for( height = 1; height < *scaled_height; height <<= 1 ); for( height = 1; height < *scaled_height; height <<= 1 );
*scaled_width = bound(1, width, gl_maxsize->integer ); *scaled_width = bound( 1, width, gl_maxsize->integer );
*scaled_height = bound(1, height, 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) 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; uint bits, bitmask, Offset;
int scaled_width, scaled_height; int scaled_width, scaled_height;
word sAlpha, sColor0, sColor1; word sAlpha, sColor0, sColor1;
byte *fin, *fout = imagebuffer; byte *fin, *fout = image_desc.source;
byte alphas[8], *alpha, *alphamask; byte alphas[8], *alpha, *alphamask;
int w, h, x, y, z, i, j, k, Select; int w, h, x, y, z, i, j, k, Select;
uint *scaled = (unsigned *)uploadbuffer; uint *scaled = (uint *)image_desc.scaled;
bool has_alpha = false; bool has_alpha = false;
int samples; int samples;
@ -790,8 +781,8 @@ bool qrsDecompressedTexImage2D( uint target, int level, int internalformat, uint
byte *fin; byte *fin;
int i, p, samples; int i, p, samples;
int scaled_width, scaled_height; int scaled_width, scaled_height;
uint *scaled = (uint *)uploadbuffer; uint *scaled = (uint *)image_desc.scaled;
byte *fout = imagebuffer; byte *fout = image_desc.source;
bool noalpha = true; bool noalpha = true;
if (!data) return false; if (!data) return false;
@ -853,8 +844,7 @@ bool qrsDecompressedTexImage2D( uint target, int level, int internalformat, uint
case PF_ABGR_64: case PF_ABGR_64:
case PF_RGBA_32: case PF_RGBA_32:
case PF_RGBA_GN: case PF_RGBA_GN:
// nothing to process fout = fin; // nothing to process
fout = fin;
break; break;
default: default:
MsgDev(D_WARN, "qrsDecompressedTexImage2D: invalid compression type: %s\n", PFDesc[internalformat].name ); 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 ReadI = 0, TempBpp;
uint RedL, RedR, GreenL, GreenR, BlueL, BlueR, AlphaL, AlphaR; uint RedL, RedR, GreenL, GreenR, BlueL, BlueR, AlphaL, AlphaR;
uint r_bitmask, g_bitmask, b_bitmask, a_bitmask; uint r_bitmask, g_bitmask, b_bitmask, a_bitmask;
uint *scaled = (unsigned *)uploadbuffer; uint *scaled = (unsigned *)image_desc.scaled;
byte *fin, *fout = imagebuffer; byte *fin, *fout = image_desc.source;
bool has_alpha = false; bool has_alpha = false;
int scaled_width, scaled_height; int scaled_width, scaled_height;
int i, w, h, samples; int i, w, h, samples;

View File

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

View File

@ -8,9 +8,8 @@
#define MAX_SFX 4096 #define MAX_SFX 4096
static sfx_t s_knownSfx[MAX_SFX]; static sfx_t s_knownSfx[MAX_SFX];
static int s_numSfx = 0; static int s_numSfx = 0;
int s_registration_sequence = 0;
#define SFX_HASHSIZE 128 bool s_registering = false;
static sfx_t *sfxHash[SFX_HASHSIZE];
/* /*
================= =================
@ -47,9 +46,7 @@ void S_SoundList_f( void )
if( sfx->name[0] == '#' ) Msg("%s", &sfx->name[1]); if( sfx->name[0] == '#' ) Msg("%s", &sfx->name[1]);
else Msg("sound/%s", sfx->name); else Msg("sound/%s", sfx->name);
Msg( "\n" );
if( sfx->default_snd ) Msg(" (DEFAULTED)\n");
else Msg("\n");
} }
else else
{ {
@ -59,8 +56,8 @@ void S_SoundList_f( void )
} }
Msg("-------------------------------------------\n"); Msg("-------------------------------------------\n");
Msg("%i total samples\n", samples); Msg("%i total samples\n", samples );
Msg("%i total sounds\n", s_numSfx); Msg("%i total sounds\n", s_numSfx );
Msg("\n"); Msg("\n");
} }
@ -162,7 +159,7 @@ S_LoadWAV
static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info ) static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
{ {
byte *buffer, *out; byte *buffer, *out;
int length; int length, samples;
buffer = FS_LoadFile( name, &length ); buffer = FS_LoadFile( name, &length );
if( !buffer ) return false; if( !buffer ) return false;
@ -216,7 +213,33 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
return false; 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"); S_FindChunk("data");
if( !iff_dataPtr ) if( !iff_dataPtr )
{ {
@ -226,7 +249,17 @@ static bool S_LoadWAV( const char *name, byte **wav, wavinfo_t *info )
} }
iff_dataPtr += 4; 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 ) if( info->samples <= 0 )
{ {
@ -268,8 +301,9 @@ static void S_UploadSound( byte *data, int width, int channels, sfx_t *sfx )
} }
// upload the sound // upload the sound
palGenBuffers(1, &sfx->bufferNum); palGenBuffers( 1, &sfx->bufferNum );
palBufferData( sfx->bufferNum, sfx->format, data, size, sfx->rate ); 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; info->samples = 11025;
*wav = out = Z_Malloc( info->samples * info->width ); *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)) if(!S_LoadWAV(name, &data, &info))
{ {
sfx->default_snd = true; sfx->default_sound = true;
MsgDev(D_WARN, "couldn't load %s\n", sfx->name );
MsgWarn( "couldn't find sound '%s', using default...\n", name );
S_CreateDefaultSound( &data, &info ); S_CreateDefaultSound( &data, &info );
info.loopstart = -1;
} }
// load it in // load it in
sfx->loaded = true; sfx->loopstart = info.loopstart;
sfx->samples = info.samples; sfx->samples = info.samples;
sfx->rate = info.rate; sfx->rate = info.rate;
S_UploadSound( data, info.width, info.channels, sfx ); S_UploadSound( data, info.width, info.channels, sfx );
Mem_Free(data); sfx->loaded = true;
Mem_Free( data );
return true; return true;
} }
@ -334,29 +380,6 @@ bool S_LoadSound( sfx_t *sfx )
// ======================================================================= // =======================================================================
// Load a sound // 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 S_FindSound
@ -364,53 +387,47 @@ S_FindSound
*/ */
sfx_t *S_FindSound( const char *name ) sfx_t *S_FindSound( const char *name )
{ {
int i, hash;
sfx_t *sfx; sfx_t *sfx;
int i;
if( !name || !name[0] ) if( !name || !name[0] ) return NULL;
{
MsgWarn("S_FindSound: empty name\n");
return NULL;
}
if( com.strlen(name) >= MAX_STRING ) 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; return NULL;
} }
hash = S_HashSFXName(name); for( i = 0; i < s_numSfx; i++ )
sfx = sfxHash[hash]; {
sfx = &s_knownSfx[i];
// see if already loaded if( !sfx->name[0] ) continue;
while( sfx ) if( !com.strcmp( name, sfx->name ))
{
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)
{ {
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; return NULL;
} }
s_numSfx++; s_numSfx++;
} }
sfx = &s_knownSfx[i]; sfx = &s_knownSfx[i];
memset (sfx, 0, sizeof(*sfx)); memset( sfx, 0, sizeof(*sfx));
strcpy (sfx->name, name); com.strncpy( sfx->name, name, MAX_STRING );
sfx->nextHash = sfxHash[hash]; sfx->registration_sequence = s_registration_sequence;
sfxHash[hash] = sfx;
return sfx; return sfx;
} }
@ -422,6 +439,8 @@ S_BeginRegistration
*/ */
void S_BeginRegistration( void ) void S_BeginRegistration( void )
{ {
s_registration_sequence++;
s_registering = true;
} }
/* /*
@ -431,6 +450,29 @@ S_EndRegistration
*/ */
void S_EndRegistration( void ) 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; return 0;
sfx = S_FindSound( name ); sfx = S_FindSound( name );
S_LoadSound( sfx );
if( !sfx ) return 0; if( !sfx ) return 0;
sfx->registration_sequence = s_registration_sequence;
if( !s_registering ) S_LoadSound( sfx );
return sfx - s_knownSfx; return sfx - s_knownSfx;
} }
@ -469,22 +513,20 @@ sfx_t *S_GetSfxByHandle( sound_t handle )
*/ */
void S_FreeSounds( void ) void S_FreeSounds( void )
{ {
sfx_t *sfx; sfx_t *sfx;
int i; int i;
// Stop all sounds // stop all sounds
S_StopAllSounds(); S_StopAllSounds();
// Free all sounds // free all sounds
for (i = 0; i < s_numSfx; i++) for (i = 0; i < s_numSfx; i++)
{ {
sfx = &s_knownSfx[i]; sfx = &s_knownSfx[i];
if( !sfx->loaded ) continue;
palDeleteBuffers(1, &sfx->bufferNum); palDeleteBuffers(1, &sfx->bufferNum);
} }
memset( sfxHash, 0, sizeof(sfx_t *)*SFX_HASHSIZE);
memset( s_knownSfx, 0, sizeof(s_knownSfx)); memset( s_knownSfx, 0, sizeof(s_knownSfx));
s_numSfx = 0; 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" #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_PLAYSOUNDS 128
#define MAX_CHANNELS 64 #define MAX_CHANNELS 64
static playSound_t s_playSounds[MAX_PLAYSOUNDS]; static playSound_t s_playSounds[MAX_PLAYSOUNDS];
static playSound_t s_freePlaySounds; static playSound_t s_freePlaySounds;
static playSound_t s_pendingPlaySounds; static playSound_t s_pendingPlaySounds;
static channel_t s_channels[MAX_CHANNELS];
static channel_t s_channels[MAX_CHANNELS]; static listener_t s_listener;
static int s_numChannels;
static listener_t s_listener;
static int s_frameCount;
const guid_t DSPROPSETID_EAX20_ListenerProperties = {0x306a6a8, 0xb224, 0x11d2, {0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22}}; 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}}; const guid_t DSPROPSETID_EAX20_BufferProperties = {0x306a6a7, 0xb224, 0x11d2, {0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7, 0x22}};
cvar_t *s_initSound; cvar_t *host_sound;
cvar_t *s_show;
cvar_t *s_alDriver;
cvar_t *s_alDevice; cvar_t *s_alDevice;
cvar_t *s_allowExtensions; cvar_t *s_soundfx;
cvar_t *s_ext_eax; cvar_t *s_check_errors;
cvar_t *s_ignoreALErrors; cvar_t *s_volume; // master volume
cvar_t *s_masterVolume; cvar_t *s_musicvolume; // background track volume
cvar_t *s_sfxVolume;
cvar_t *s_musicVolume;
cvar_t *s_minDistance; cvar_t *s_minDistance;
cvar_t *s_maxDistance; cvar_t *s_maxDistance;
cvar_t *s_rolloffFactor; cvar_t *s_rolloffFactor;
cvar_t *s_dopplerFactor; cvar_t *s_dopplerFactor;
cvar_t *s_dopplerVelocity; cvar_t *s_dopplerVelocity;
/* /*
================= =================
S_CheckForErrors S_CheckForErrors
================= =================
*/ */
static void S_CheckForErrors( void ) void S_CheckForErrors( void )
{ {
int err; int err;
char *str; char *str;
if( !s_check_errors->integer )
return;
if((err = palGetError()) == AL_NO_ERROR) if((err = palGetError()) == AL_NO_ERROR)
return; 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_BUFFER, sfx->bufferNum);
palSourcei(ch->sourceNum, AL_LOOPING, ch->loopsound); palSourcei(ch->sourceNum, AL_LOOPING, ch->loopsound);
palSourcei(ch->sourceNum, AL_SOURCE_RELATIVE, false); 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 ); palSourcef( ch->sourceNum, AL_MAX_DISTANCE, s_maxDistance->value );
// update volume and rolloff factor // 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 ); palSourcef( ch->sourceNum, AL_ROLLOFF_FACTOR, s_rolloffFactor->value );
} }
@ -226,7 +219,7 @@ channel_t *S_PickChannel( int entnum, int entChannel )
channel_t *ch; channel_t *ch;
int i; int i;
int firstToDie = -1; int firstToDie = -1;
int oldestTime = si.GetClientTime(); int oldestTime = Sys_DoubleTime();
if( entnum < 0 || entChannel < 0 ) if( entnum < 0 || entChannel < 0 )
Host_Error( "S_PickChannel: entnum or entChannel less than 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->entnum = entnum;
ch->entchannel = entChannel; ch->entchannel = entChannel;
ch->startTime = si.GetClientTime(); ch->startTime = Sys_DoubleTime();
// Make sure this channel is stopped // Make sure this channel is stopped
palSourceStop(ch->sourceNum); palSourceStop(ch->sourceNum);
@ -298,7 +291,7 @@ bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn )
sfx = S_GetSfxByHandle( handle ); sfx = S_GetSfxByHandle( handle );
// default looped sound it's terrible :) // default looped sound it's terrible :)
if( !sfx || !sfx->loaded || sfx->default_snd ) if( !sfx || !sfx->loaded || sfx->default_sound )
return false; return false;
// if this entity is already playing the same sound effect on an // 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; ps = s_pendingPlaySounds.next;
if(ps == &s_pendingPlaySounds) if(ps == &s_pendingPlaySounds)
{
Msg("no more pending playsounds\n");
break; // no more pending playSounds 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 break; // No more pending playSounds this frame
}
// pick a channel and start the sound effect // pick a channel and start the sound effect
ch = S_PickChannel( ps->entnum, ps->entchannel ); ch = S_PickChannel( ps->entnum, ps->entchannel );
if(!ch) if(!ch)
@ -405,8 +402,12 @@ static void S_IssuePlaySounds( void )
S_FreePlaySound( ps ); S_FreePlaySound( ps );
continue; continue;
} }
// check for looping sounds with "cue " marker
if( ps->sfx->loopstart > -1 )
{
ps->sfx->loopfirst = true;
}
ch->loopsound = false;
ch->fixedPosition = ps->fixedPosition; ch->fixedPosition = ps->fixedPosition;
VectorCopy( ps->position, ch->position ); VectorCopy( ps->position, ch->position );
ch->volume = ps->volume; ch->volume = ps->volume;
@ -419,6 +420,16 @@ static void S_IssuePlaySounds( void )
// free the playSound // free the playSound
S_FreePlaySound( ps ); 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 ) if(!al_state.initialized )
return; return;
sfx = S_GetSfxByHandle( handle ); sfx = S_GetSfxByHandle( handle );
if( !sfx ) return; if( !sfx ) return;
Msg("CL_StartSound %s ( entnum %d, channel %d)\n", sfx->name, entnum, entChannel );
// Make sure the sound is loaded // Make sure the sound is loaded
if(!S_LoadSound(sfx)) return; 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 ); else MsgDev( D_ERROR, "dropped sound \"sound/%s\"\n", sfx->name );
return; return;
} }
ps->sfx = sfx; ps->sfx = sfx;
ps->entnum = entnum; ps->entnum = entnum;
ps->entchannel = entChannel; 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->volume = volume;
ps->attenuation = attenuation; ps->attenuation = attenuation;
ps->beginTime = si.GetClientTime(); ps->beginTime = Sys_DoubleTime();
// Sort into the pending playSounds list // Sort into the pending playSounds list
for( sort = s_pendingPlaySounds.next; sort != &s_pendingPlaySounds&& sort->beginTime < ps->beginTime; sort = sort->next ); 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; return false;
sfxHandle = S_RegisterSound( name ); 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; 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_POSITION, s_listener.position);
palListenerfv(AL_VELOCITY, s_listener.velocity); palListenerfv(AL_VELOCITY, s_listener.velocity);
palListenerfv(AL_ORIENTATION, s_listener.orientation); 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 // Set state
palDistanceModel( AL_INVERSE_DISTANCE_CLAMPED ); 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 // check for errors
if(!s_ignoreALErrors->integer) S_CheckForErrors();
S_CheckForErrors();
} }
/* /*
@ -655,7 +663,7 @@ void S_Activate( bool active )
return; return;
al_state.active = active; 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 ); else palListenerf( AL_GAIN, 0.0 );
} }
@ -739,14 +747,12 @@ void S_SoundInfo_f( void )
*/ */
void S_Init( void *hInst ) 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_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_soundfx = Cvar_Get("s_soundfx", "1", CVAR_LATCH|CVAR_ARCHIVE );
s_ignoreALErrors = Cvar_Get("s_ignoreALErrors", "1", CVAR_ARCHIVE ); s_check_errors = Cvar_Get("s_check_errors", "1", CVAR_ARCHIVE );
s_masterVolume = Cvar_Get("s_volume", "1.0", CVAR_ARCHIVE ); s_volume = 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_musicVolume = Cvar_Get("s_musicvolume", "1.0", CVAR_ARCHIVE );
s_minDistance = Cvar_Get("s_mindistance", "240.0", CVAR_ARCHIVE ); s_minDistance = Cvar_Get("s_mindistance", "240.0", CVAR_ARCHIVE );
s_maxDistance = Cvar_Get("s_maxdistance", "8192.0", CVAR_ARCHIVE ); s_maxDistance = Cvar_Get("s_maxdistance", "8192.0", CVAR_ARCHIVE );
s_rolloffFactor = Cvar_Get("s_rollofffactor", "1.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("s_info", S_SoundInfo_f, "print sound system information" );
Cmd_AddCommand("soundlist", S_SoundList_f, "display loaded sounds" ); 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; return;
} }
@ -776,9 +782,7 @@ void S_Init( void *hInst )
S_AllocChannels(); S_AllocChannels();
S_StopAllSounds(); S_StopAllSounds();
S_CheckForErrors();
if(!s_ignoreALErrors->integer)
S_CheckForErrors();
al_state.active = true; // enabled al_state.active = true; // enabled
} }

View File

@ -69,6 +69,11 @@ typedef struct alcontext_s alcontext;
#define AL_BUFFERS_QUEUED 0x1015 #define AL_BUFFERS_QUEUED 0x1015
#define AL_BUFFERS_PROCESSED 0x1016 #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 // openal errors
#define AL_NO_ERROR 0 #define AL_NO_ERROR 0
#define AL_INVALID_NAME 0xA001 #define AL_INVALID_NAME 0xA001

View File

@ -135,7 +135,7 @@ void S_StreamBackgroundTrack( void )
int size, read, dummy; int size, read, dummy;
uint buffer; uint buffer;
if( !s_bgTrack.file || !s_musicVolume->value ) if( !s_bgTrack.file || !s_musicvolume->value )
return; return;
if(!s_streamingChannel) return; if(!s_streamingChannel) return;
@ -199,7 +199,7 @@ void S_StreamBackgroundTrack( void )
} }
// update volume // 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 // if not playing, then do so
palGetSourcei( s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state ); 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 ); palSourceQueueBuffers( s_streamingChannel->sourceNum, 1, &buffer );
// update volume // 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 // if not playing, then do so
palGetSourcei(s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state); palGetSourcei(s_streamingChannel->sourceNum, AL_SOURCE_STATE, &state);

View File

@ -25,6 +25,7 @@ typedef struct
{ {
int rate; int rate;
int width; int width;
int loopstart;
int channels; int channels;
int samples; int samples;
} wavinfo_t; } wavinfo_t;
@ -32,14 +33,16 @@ typedef struct
typedef struct sfx_s typedef struct sfx_s
{ {
string name; string name;
bool default_snd;
bool loaded; bool loaded;
int loopstart; // looping point (in samples)
bool loopfirst; // check it for set properly offset in samples
int samples; int samples;
int rate; int rate;
uint format; uint format;
uint bufferNum; uint bufferNum;
struct sfx_s *nextHash; bool default_sound;
int registration_sequence;
} sfx_t; } sfx_t;
typedef struct typedef struct
@ -54,8 +57,8 @@ typedef struct
void *vorbisFile; void *vorbisFile;
} bg_track_t; } bg_track_t;
// A playSound will be generated by each call to S_StartSound. // a playSound will be generated by each call to S_StartSound.
// When the mixer reaches playSound->beginTime, the playSound will be // when the mixer reaches playSound->beginTime, the playSound will be
// assigned to a channel. // assigned to a channel.
typedef struct playsound_s typedef struct playsound_s
{ {
@ -74,17 +77,17 @@ typedef struct
{ {
bool streaming; bool streaming;
sfx_t *sfx; // NULL if unused 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 entchannel;
int startTime; // For overriding oldest sounds int startTime; // for overriding oldest sounds
bool loopsound; // Looping sound bool loopsound; // is looping sound ?
int loopnum; // Looping entity number int loopnum; // looping entity number
int loopframe; // For stopping looping sounds int loopframe; // for stopping looping sounds
bool fixedPosition; // Use position instead of fetching entity's origin bool fixedPosition; // use position instead of fetching entity's origin
vec3_t position; // Only use if fixedPosition is set vec3_t position; // only use if fixedPosition is set
float volume; float volume;
float distanceMult; float distanceMult;
uint sourceNum; // OpenAL source uint sourceNum; // openAL source
} channel_t; } channel_t;
typedef struct typedef struct
@ -130,78 +133,40 @@ extern alconfig_t al_config;
extern alstate_t al_state; extern alstate_t al_state;
#define Host_Error com.error #define Host_Error com.error
#define Z_Malloc( size ) Mem_Alloc( sndpool, size ) #define Z_Malloc( size ) Mem_Alloc( sndpool, size )
// cvars // cvars
extern cvar_t *s_initSound;
extern cvar_t *s_show;
extern cvar_t *s_alDevice; extern cvar_t *s_alDevice;
extern cvar_t *s_allowExtensions;
extern cvar_t *s_soundfx; extern cvar_t *s_soundfx;
extern cvar_t *s_ignoreALErrors; extern cvar_t *s_musicvolume;
extern cvar_t *s_masterVolume; extern cvar_t *s_check_errors;
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;
void S_Init( void *hInst ); void S_Init( void *hInst );
void S_Shutdown( void ); void S_Shutdown( void );
void S_Activate( bool active ); void S_Activate( bool active );
void S_SoundList_f( void ); void S_SoundList_f( void );
void S_CheckForErrors( void );
// if origin is NULL, the sound will be dynamically sourced from the entity
void S_StartSound( const vec3_t origin, int entnum, int entchannel, sound_t sfx, float vol, float attn ); 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_Update( int clientnum, const vec3_t pos, const vec3_t vel, const vec3_t at, const vec3_t up );
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_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data ); void S_StreamRawSamples( int samples, int rate, int width, int channels, const byte *data );
bool S_AddLoopingSound( int entnum, sound_t handle, float volume, float attn );
// stop all sounds and the background track 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_StopAllSounds( void );
void S_FreeSounds( void ); void S_FreeSounds( void );
// all continuous looping sounds must be added before calling S_Update // registration manager
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 );
void S_BeginRegistration( void ); void S_BeginRegistration( void );
sound_t S_RegisterSound( const char *sample );
void S_EndRegistration( void ); 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 #endif//SOUND_H