28 Jun 2010

This commit is contained in:
g-cont 2010-06-28 00:00:00 +04:00 committed by Alibek Omarov
parent cbc81f7861
commit e048dd6518
43 changed files with 2618 additions and 1828 deletions

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: baserc - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
baserc.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: bshift - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
server.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: client - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
client.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -352,7 +352,7 @@ int CHudSound :: Draw( float flTime )
if( !fmod_dll || !fmod_data )
return 0;
float vol = CVAR_GET_FLOAT( "s_musicvolume" ); // sound engine cvar
float vol = CVAR_GET_FLOAT( "musicvolume" ); // sound engine cvar
if( vol != m_flVolume )
{

View File

@ -140,7 +140,7 @@ typedef struct
// cdlight_t private starts here
int key; // so entities can reuse same entry
float start; // stop lighting after this time
int end; // drop this each second
float end; // drop this each second
float radius; // radius (not an intensity)
bool fade;
bool free; // this light is unused at current time

View File

@ -344,87 +344,23 @@ void CL_AddEntities( void )
//
// sound engine implementation
//
bool CL_GetEntitySpatialization( int entnum, soundinfo_t *info )
{
edict_t *pSound;
// world is always audible
if( entnum == 0 )
return true;
if( entnum < 0 || entnum >= GI->max_edicts )
{
MsgDev( D_ERROR, "CL_GetEntitySoundSpatialization: invalid entnum %d\n", entnum );
return false;
}
// while explosion entity can be died before sound played completely
if( entnum >= clgame.globals->numEntities )
return false;
pSound = CL_GetEdictByIndex( entnum );
// out of PVS, removed etc
if( !CL_IsValidEdict( pSound )) return false;
if( !pSound->v.modelindex )
return true;
if( info->pflRadius )
{
vec3_t mins, maxs;
Mod_GetBounds( pSound->v.modelindex, mins, maxs );
*info->pflRadius = RadiusFromBounds( mins, maxs );
}
if( info->pOrigin )
{
VectorCopy( pSound->v.origin, info->pOrigin );
if( CM_GetModelType( pSound->v.modelindex ) == mod_brush )
{
vec3_t mins, maxs, center;
Mod_GetBounds( pSound->v.modelindex, mins, maxs );
VectorAverage( mins, maxs, center );
VectorAdd( info->pOrigin, center, info->pOrigin );
}
}
if( info->pAngles )
{
VectorCopy( pSound->v.angles, info->pAngles );
}
return true;
}
void CL_GetEntitySoundSpatialization( int entnum, vec3_t origin, vec3_t velocity )
void CL_GetEntitySpatialization( int entnum, vec3_t origin, vec3_t velocity )
{
edict_t *ent;
vec3_t mins, maxs, midPoint;
if( entnum < 0 || entnum >= GI->max_edicts )
{
MsgDev( D_ERROR, "CL_GetEntitySoundSpatialization: invalid entnum %d\n", entnum );
VectorCopy( vec3_origin, origin );
VectorCopy( vec3_origin, velocity );
return;
}
// while explosion entity can be died before sound played completely
if( entnum >= clgame.globals->numEntities ) return;
ent = CL_GetEdictByIndex( entnum );
if( !CL_IsValidEdict( ent )) return; // leave uncahnged
if( !CL_IsValidEdict( ent ))
return; // leave uncahnged
// setup origin and velocity
VectorCopy( ent->v.origin, origin );
VectorCopy( ent->v.velocity, velocity );
if( origin ) VectorCopy( ent->v.origin, origin );
if( velocity ) VectorCopy( ent->v.velocity, velocity );
// if a brush model, offset the origin
if( CM_GetModelType( ent->v.modelindex ) == mod_brush )
if( origin && CM_GetModelType( ent->v.modelindex ) == mod_brush )
{
vec3_t mins, maxs, midPoint;
Mod_GetBounds( ent->v.modelindex, mins, maxs );
VectorAverage( mins, maxs, midPoint );
VectorAdd( origin, midPoint, origin );

View File

@ -781,7 +781,7 @@ bool CL_IsValidEdict( const edict_t *e )
if( e == EDICT_NUM( 0 )) return false; // world is the read-only entity
if( !e->pvServerData ) return false;
// edict without pvPrivateData is valid edict
// server.dll know how allocate it
// client.dll know how allocate it
return true;
}

View File

@ -334,6 +334,7 @@ void CL_ParseSoundPacket( sizebuf_t *msg, bool is_ambient )
int chan, sound;
float volume, attn;
int flags, pitch, entnum;
sound_t handle;
flags = MSG_ReadWord( msg );
sound = MSG_ReadWord( msg );
@ -361,13 +362,22 @@ void CL_ParseSoundPacket( sizebuf_t *msg, bool is_ambient )
MSG_ReadPos( msg, pos );
}
if( flags & SND_SENTENCE )
{
char sentenceName[32];
com.snprintf( sentenceName, sizeof( sentenceName ), "!%i", sound );
handle = S_RegisterSound( sentenceName );
}
else handle = cl.sound_precache[sound]; // see precached sound
if( is_ambient )
{
S_AmbientSound( pos, entnum, chan, cl.sound_precache[sound], volume, attn, pitch, flags );
S_AmbientSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
}
else
{
S_StartSound( pos, entnum, chan, cl.sound_precache[sound], volume, attn, pitch, flags );
S_StartSound( pos, entnum, chan, handle, volume, attn, pitch, flags );
}
}

View File

@ -541,7 +541,7 @@ void CL_UpdateBaseVelocity( edict_t *ent );
// cl_frame.c
//
void CL_ParseFrame( sizebuf_t *msg );
void CL_GetEntitySoundSpatialization( int ent, vec3_t origin, vec3_t velocity );
void CL_GetEntitySpatialization( int ent, vec3_t origin, vec3_t velocity );
//
// cl_effects.c

View File

@ -218,7 +218,7 @@ void CL_CharEvent( int key );
void Tri_DrawTriangles( int fTrans );
int CL_PointContents( const vec3_t point );
void CL_StudioFxTransform( edict_t *ent, float transform[4][4] );
bool CL_GetEntitySpatialization( int entnum, soundinfo_t *info );
void CL_GetEntitySpatialization( int entnum, vec3_t origin, vec3_t velocity );
bool CL_GetAttachment( int entityIndex, int number, vec3_t origin, vec3_t angles );
bool CL_SetAttachment( int entityIndex, int number, vec3_t origin, vec3_t angles );
void CL_StudioEvent( dstudioevent_t *event, edict_t *ent );

View File

@ -720,7 +720,6 @@ autocomplete_list_t cmd_list[] =
{
{ "gl_texturemode", Cmd_GetTexturemodes },
{ "stringlist", Cmd_GetStringTablesList },
{ "playsound", Cmd_GetSoundList },
{ "changelevel", Cmd_GetMapList },
{ "playdemo", Cmd_GetDemoList, },
{ "menufont", Cmd_GetFontList, },
@ -732,6 +731,7 @@ autocomplete_list_t cmd_list[] =
{ "game", Cmd_GetGamesList },
{ "save", Cmd_GetSavesList },
{ "load", Cmd_GetSavesList },
{ "play", Cmd_GetSoundList },
{ "map", Cmd_GetMapList },
{ NULL }, // termiantor
};

View File

@ -35,7 +35,7 @@ static net_field_t ent_fields[] =
{ ES_FIELD(framerate), NET_FLOAT, false }, // custom framerate
{ ES_FIELD(sequence), NET_WORD, false }, // 1024 sequences
{ ES_FIELD(gaitsequence), NET_WORD, false }, // 1024 gaitsequences
{ ES_FIELD(skin), NET_CHAR, false }, // beacuse negative skins are contents
{ ES_FIELD(skin), NET_SHORT, false }, // beacuse negative skins are contents
{ ES_FIELD(body), NET_BYTE, false }, // 255 bodies
{ ES_FIELD(weaponmodel), NET_WORD, false }, // p_model index, not name
{ ES_FIELD(contents), NET_LONG, false }, // full range contents

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: engine - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
engine.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -1267,52 +1267,17 @@ int pfnDropToFloor( edict_t* e )
trace = SV_Move( e->v.origin, e->v.mins, e->v.maxs, end, MOVE_NORMAL, e );
if( trace.fStartSolid )
if( trace.flFraction == 1.0f || trace.fAllSolid )
{
vec3_t offset, org;
VectorSet( offset, 0.5f * (e->v.mins[0] + e->v.maxs[0]), 0.5f * (e->v.mins[1] + e->v.maxs[1]), e->v.mins[2] );
VectorAdd( e->v.origin, offset, org );
trace = SV_Move( org, vec3_origin, vec3_origin, end, MOVE_NORMAL, e );
VectorSubtract( trace.vecEndPos, offset, trace.vecEndPos );
if( trace.fStartSolid )
{
MsgDev( D_NOTE, "SV_DropToFloor: startsolid at %g %g %g\n", e->v.origin[0], e->v.origin[1], e->v.origin[2] );
SV_LinkEdict( e, true );
e->v.flags |= FL_ONGROUND;
e->v.groundentity = NULL;
return 1;
}
else if( trace.flFraction < 1.0f )
{
MsgDev( D_NOTE, "SV_DropToFloor: moved to %g %g %g\n", e->v.origin[0], e->v.origin[1], e->v.origin[2] );
VectorCopy( trace.vecEndPos, e->v.origin );
SV_LinkEdict( e, true );
e->v.flags |= FL_ONGROUND;
e->v.groundentity = trace.pHit;
return 1;
}
else
{
MsgDev( D_ERROR, "SV_DropToFloor: allsolid at %g %g %g\n", e->v.origin[0], e->v.origin[1], e->v.origin[2] );
}
return 0;
return false;
}
else
{
if( trace.fAllSolid )
return -1;
if( trace.flFraction == 1.0f )
return 0;
VectorCopy( trace.vecEndPos, e->v.origin );
SV_LinkEdict( e, false );
e->v.flags |= FL_ONGROUND;
e->v.groundentity = trace.pHit;
VectorCopy( trace.vecEndPos, e->v.origin );
SV_LinkEdict( e, true );
e->v.flags |= FL_ONGROUND;
e->v.groundentity = trace.pHit;
return 1;
}
return true;
}
/*
@ -1399,8 +1364,15 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
VectorAverage( ent->v.absmin, ent->v.absmax, origin );
if( flags & SND_SPAWNING )
{
msg_dest = MSG_INIT;
else msg_dest = MSG_ALL;
}
else
{
if( chan == CHAN_STATIC )
msg_dest = MSG_ALL;
else msg_dest = MSG_PAS;
}
}
else
{
@ -1408,16 +1380,31 @@ void SV_StartSound( edict_t *ent, int chan, const char *sample, float vol, float
VectorAdd( origin, ent->v.origin, origin );
if( flags & SND_SPAWNING )
{
msg_dest = MSG_INIT;
else msg_dest = MSG_PAS_R;
}
else
{
if( chan == CHAN_STATIC )
msg_dest = MSG_ALL;
else msg_dest = MSG_PAS;
}
}
// always sending stop sound command
if( flags & SND_STOP ) msg_dest = MSG_ALL;
// precache_sound can be used twice: cache sounds when loading
// and return sound index when server is active
sound_idx = SV_SoundIndex( sample );
if( sample[0] == '!' && com.is_digit( sample + 1 ))
{
flags |= SND_SENTENCE;
sound_idx = com.atoi( sample + 1 );
}
else
{
// precache_sound can be used twice: cache sounds when loading
// and return sound index when server is active
sound_idx = SV_SoundIndex( sample );
}
MSG_Begin( svc_sound );
MSG_WriteWord( &sv.multicast, flags );

View File

@ -103,8 +103,8 @@ static void UI_Audio_GetConfig( void )
{
UI_Audio_GetDeviceList();
uiAudio.soundVolume.curValue = Cvar_VariableValue( "s_volume" );
uiAudio.musicVolume.curValue = Cvar_VariableValue( "s_musicvolume" );
uiAudio.soundVolume.curValue = Cvar_VariableValue( "volume" );
uiAudio.musicVolume.curValue = Cvar_VariableValue( "musicvolume" );
if( Cvar_VariableInteger( "s_allowEAX" ))
uiAudio.EAX.enabled = 1;
@ -128,8 +128,8 @@ UI_Audio_SetConfig
static void UI_Audio_SetConfig( void )
{
Cvar_FullSet( "host_audio", uiAudio.audioList[(int)uiAudio.soundLibrary.curValue], CVAR_SYSTEMINFO );
Cvar_SetValue( "s_volume", uiAudio.soundVolume.curValue );
Cvar_SetValue( "s_musicvolume", uiAudio.musicVolume.curValue );
Cvar_SetValue( "volume", uiAudio.soundVolume.curValue );
Cvar_SetValue( "musicvolume", uiAudio.musicVolume.curValue );
Cvar_SetValue( "s_allowEAX", uiAudio.EAX.enabled );
Cvar_SetValue( "s_allowA3D", uiAudio.A3D.enabled );
@ -146,8 +146,8 @@ static void UI_Audio_UpdateConfig( void )
{
uiAudio.soundLibrary.generic.name = uiAudio.audioList[(int)uiAudio.soundLibrary.curValue];
Cvar_SetValue( "s_volume", uiAudio.soundVolume.curValue );
Cvar_SetValue( "s_musicvolume", uiAudio.musicVolume.curValue );
Cvar_SetValue( "volume", uiAudio.soundVolume.curValue );
Cvar_SetValue( "musicvolume", uiAudio.musicVolume.curValue );
// See if the apply button should be enabled or disabled
uiAudio.apply.generic.flags |= QMF_GRAYED;

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: launch - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
launch.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: physic - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
physic.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -13,13 +13,13 @@
#define MAX_CLIENTS 32 // max allowed clients (modify with precaution)
#define MAX_DLIGHTS 32 // dynamic lights (rendered per one frame)
#define MAX_LIGHTSTYLES 256 // can't be blindly increased
#define MAX_DECALS 512 // server decal indexes (different decalnames, not a render limit)
#define MAX_DECALS 1024 // server decal indexes (different decalnames, not a render limit)
#define MAX_USER_MESSAGES 200 // another 56 messages reserved for engine routines
#define MAX_EVENTS 256 // playback events that can be queued (a byte range, don't touch)
#define MAX_GENERICS 256 // generic files that can download from server
#define MAX_EVENTS 1024 // playback events that can be queued (a byte range, don't touch)
#define MAX_GENERICS 1024 // generic files that can download from server
#define MAX_CLASSNAMES 512 // maxcount of various edicts classnames
#define MAX_SOUNDS 4096 // max unique loaded sounds
#define MAX_MODELS 4096 // total count of brush & studio various models per one map
#define MAX_SOUNDS 2048 // max unique loaded sounds (not counting sequences)
#define MAX_MODELS 2048 // total count of brush & studio various models per one map
#define MAX_PARTICLES 4096 // total particle count per one frame
#define MAX_EDICTS 32768 // absolute limit that never be reached, (do not edit!)

View File

@ -17,14 +17,6 @@ typedef struct
int sndavg; // running average
} mouth_t;
typedef struct
{
// requested outputs ( NULL == not requested )
float *pOrigin; // vec3_t
float *pAngles; // vec3_t
float *pflRadius; // vec_t
} soundinfo_t;
/*
==============================================================================
@ -70,7 +62,7 @@ typedef struct vsound_imp_s
size_t api_size; // must matched with sizeof(vsound_imp_t)
trace_t (*TraceLine)( const vec3_t start, const vec3_t end );
bool (*GetEntitySpatialization)( int entnum, soundinfo_t *info );
void (*GetEntitySpatialization)( int entnum, vec3_t origin, vec3_t velocity );
void (*AmbientLevels)( const vec3_t p, byte *pvolumes );
edict_t *(*GetClientEdict)( int index );
mouth_t *(*GetEntityMouth)( edict_t *ent );

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: server - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
server.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -9,12 +9,13 @@
// than could actually be referenced during gameplay,
// because we don't want to free anything until we are
// sure we won't need it.
#define MAX_SFX 4096
#define MAX_SFX 8192
#define MAX_SFX_HASH (MAX_SFX/4)
static int s_numSfx = 0;
static sfx_t s_knownSfx[MAX_SFX];
static sfx_t *s_sfxHashList[MAX_SFX_HASH];
static string s_sentenceImmediateName; // keep dummy sentence name
bool s_registering = false;
int s_registration_sequence = 0;
@ -342,6 +343,12 @@ sound_t S_RegisterSound( const char *name )
{
sfx_t *sfx;
if( name[0] == '!' )
{
com.strncpy( s_sentenceImmediateName, name, sizeof( s_sentenceImmediateName ));
return SENTENCE_INDEX;
}
sfx = S_FindSound( name );
if( !sfx ) return -1;
@ -353,6 +360,12 @@ sound_t S_RegisterSound( const char *name )
sfx_t *S_GetSfxByHandle( sound_t handle )
{
if( handle == SENTENCE_INDEX )
{
// create new sfx
return S_FindSound( s_sentenceImmediateName );
}
if( handle < 0 || handle >= s_numSfx )
{
MsgDev( D_ERROR, "S_GetSfxByHandle: handle %i out of range (%i)\n", handle, s_numSfx );

View File

@ -302,8 +302,7 @@ S_SpatializeChannel
*/
static void S_SpatializeChannel( channel_t *ch )
{
vec3_t position, velocity;
soundinfo_t SndInfo;
vec3_t position, velocity;
// update position and velocity
if( ch->entnum == al_state.clientnum || !ch->dist_mult )
@ -320,11 +319,7 @@ static void S_SpatializeChannel( channel_t *ch )
}
else
{
SndInfo.pOrigin = position;
SndInfo.pAngles = velocity; // FIXME: this is angles, not velocity
SndInfo.pflRadius = NULL;
si.GetEntitySpatialization( ch->entnum, &SndInfo );
si.GetEntitySpatialization( ch->entnum, position, velocity );
palSource3f( ch->sourceNum, AL_POSITION, position[1], position[2], -position[0] );
palSource3f( ch->sourceNum, AL_VELOCITY, velocity[1], velocity[2], -velocity[0] );
@ -515,7 +510,7 @@ int S_AlterChannel( int entnum, int channel, sfx_t *sfx, float vol, int pitch, i
// regular sound or streaming sound
for( i = 0, ch = s_channels; i < al_state.total_channels; i++, ch++ )
{
if( ch->entnum == entnum && ch->entchannel == channel && ch->sfx )
if( ch->entnum == entnum && ch->entchannel == channel && ch->sfx == sfx )
{
if( flags & SND_CHANGE_PITCH )
ch->pitch = pitch / (float)PITCH_NORM;
@ -523,7 +518,7 @@ int S_AlterChannel( int entnum, int channel, sfx_t *sfx, float vol, int pitch, i
if( flags & SND_CHANGE_VOL )
ch->volume = vol;
if( flags & SND_STOP && ch->sfx->loopStart >= 0 )
if( flags & SND_STOP )
S_StopChannel( ch );
return true;
@ -952,8 +947,8 @@ bool S_Init( void *hInst )
s_allowEAX = Cvar_Get("s_allowEAX", "1", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "allow EAX 2.0 extension" );
s_allowA3D = Cvar_Get("s_allowA3D", "1", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "allow A3D 2.0 extension" );
s_check_errors = Cvar_Get("s_check_errors", "1", CVAR_ARCHIVE, "ignore audio engine errors" );
s_volume = Cvar_Get("s_volume", "1.0", CVAR_ARCHIVE, "sound volume" );
s_musicvolume = Cvar_Get("s_musicvolume", "1.0", CVAR_ARCHIVE, "background music volume" );
s_volume = Cvar_Get("volume", "1.0", CVAR_ARCHIVE, "sound volume" );
s_musicvolume = Cvar_Get("musicvolume", "1.0", CVAR_ARCHIVE, "background music volume" );
s_minDistance = Cvar_Get("s_mindistance", "240.0", CVAR_ARCHIVE, "3d sound min distance" );
s_maxDistance = Cvar_Get("s_maxdistance", "8192.0", CVAR_ARCHIVE, "3d sound max distance" );
s_rolloffFactor = Cvar_Get("s_rollofffactor", "1.0", CVAR_ARCHIVE, "3d sound rolloff factor" );

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: snd_al - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
snd_al.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -17,6 +17,8 @@ extern stdlib_api_t com;
extern vsound_imp_t si;
extern byte *sndpool;
#define SENTENCE_INDEX -99999 // unique sentence index
#include "mathlib.h"
typedef enum

File diff suppressed because it is too large Load Diff

View File

@ -1241,7 +1241,7 @@ void SX_RoomFX( int endtime, int fFilter, int fTimefx )
if( sampleCount < 0 ) return;
fReset = false;
if( listener.waterlevel > 2 )
if( s_listener.waterlevel > 2 )
roomType = sxroomwater_type->integer;
else roomType = sxroom_type->integer;

View File

@ -42,7 +42,7 @@ vsound_exp_t DLLEXPORT *CreateAPI( stdlib_api_t *input, vsound_imp_t *engfuncs )
snd.StartStreaming = S_StartStreaming;
snd.StopStreaming = S_StopStreaming;
snd.RenderFrame = S_SoundFrame;
snd.RenderFrame = S_RenderFrame;
snd.StopSound = S_StopSound;
snd.StopAllSounds = S_StopAllSounds;

View File

@ -10,14 +10,15 @@
// than could actually be referenced during gameplay,
// because we don't want to free anything until we are
// sure we won't need it.
#define MAX_SFX 4096
#define MAX_SFX 8192
#define MAX_SFX_HASH (MAX_SFX/4)
static int numSfx = 0;
static sfx_t knownSfx[MAX_SFX];
static sfx_t *sfxHashList[MAX_SFX_HASH];
bool registering = false;
int registration_sequence = 0;
static int s_numSfx = 0;
static sfx_t s_knownSfx[MAX_SFX];
static sfx_t *s_sfxHashList[MAX_SFX_HASH];
static string s_sentenceImmediateName; // keep dummy sentence name
bool s_registering = false;
int s_registration_sequence = 0;
/*
=================
@ -31,7 +32,7 @@ void S_SoundList_f( void )
int i, totalSfx = 0;
int totalSize = 0;
for( i = 0, sfx = knownSfx; i < numSfx; i++, sfx++ )
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
{
if( !sfx->touchFrame )
continue;
@ -216,11 +217,11 @@ wavdata_t *S_LoadSound( sfx_t *sfx )
// =======================================================================
/*
==================
S_FindSound
S_FindName
==================
*/
sfx_t *S_FindSound( const char *name )
sfx_t *S_FindName( const char *name, int *pfInCache )
{
int i;
sfx_t *sfx;
@ -235,40 +236,46 @@ sfx_t *S_FindSound( const char *name )
// see if already loaded
hash = Com_HashKey( name, MAX_SFX_HASH );
for( sfx = sfxHashList[hash]; sfx; sfx = sfx->hashNext )
for( sfx = s_sfxHashList[hash]; sfx; sfx = sfx->hashNext )
{
if( !com.strcmp( sfx->name, name ))
{
if( pfInCache )
{
// indicate whether or not sound is currently in the cache.
*pfInCache = ( sfx->cache != NULL ) ? true : false;
}
// prolonge registration
sfx->touchFrame = registration_sequence;
sfx->touchFrame = s_registration_sequence;
return sfx;
}
}
// find a free sfx slot spot
for( i = 0, sfx = knownSfx; i < numSfx; i++, sfx++)
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++)
{
if( !sfx->name[0] ) break; // free spot
}
if( i == numSfx )
if( i == s_numSfx )
{
if( numSfx == MAX_SFX )
if( s_numSfx == MAX_SFX )
{
MsgDev( D_ERROR, "S_FindName: MAX_SFX limit exceeded\n" );
return NULL;
}
numSfx++;
s_numSfx++;
}
sfx = &knownSfx[i];
sfx = &s_knownSfx[i];
Mem_Set( sfx, 0, sizeof( *sfx ));
if( pfInCache ) *pfInCache = false;
com.strncpy( sfx->name, name, MAX_STRING );
sfx->touchFrame = registration_sequence;
sfx->touchFrame = s_registration_sequence;
sfx->hashValue = Com_HashKey( sfx->name, MAX_SFX_HASH );
// link it in
sfx->hashNext = sfxHashList[sfx->hashValue];
sfxHashList[sfx->hashValue] = sfx;
sfx->hashNext = s_sfxHashList[sfx->hashValue];
s_sfxHashList[sfx->hashValue] = sfx;
return sfx;
}
@ -286,7 +293,7 @@ static void S_FreeSound( sfx_t *sfx )
if( !sfx || !sfx->name[0] ) return;
// de-link it from the hash tree
prev = &sfxHashList[sfx->hashValue];
prev = &s_sfxHashList[sfx->hashValue];
while( 1 )
{
hashSfx = *prev;
@ -313,8 +320,8 @@ S_BeginRegistration
*/
void S_BeginRegistration( void )
{
registration_sequence++;
registering = true;
s_registration_sequence++;
s_registering = true;
}
/*
@ -329,20 +336,20 @@ void S_EndRegistration( void )
int i;
// free any sounds not from this registration sequence
for( i = 0, sfx = knownSfx; i < numSfx; i++, sfx++ )
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
{
if( !sfx->name[0] ) continue;
if( sfx->touchFrame != registration_sequence )
if( sfx->touchFrame != s_registration_sequence )
S_FreeSound( sfx ); // don't need this sound
}
// load everything in
for( i = 0, sfx = knownSfx; i < numSfx; i++, sfx++ )
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
{
if( !sfx->name[0] ) continue;
S_LoadSound( sfx );
}
registering = false;
s_registering = false;
}
/*
@ -355,23 +362,35 @@ sound_t S_RegisterSound( const char *name )
{
sfx_t *sfx;
sfx = S_FindSound( name );
if( S_TestSoundChar( name, '!' ))
{
com.strncpy( s_sentenceImmediateName, name, sizeof( s_sentenceImmediateName ));
return SENTENCE_INDEX;
}
sfx = S_FindName( name, NULL );
if( !sfx ) return -1;
sfx->touchFrame = registration_sequence;
if( !registering ) S_LoadSound( sfx );
sfx->touchFrame = s_registration_sequence;
if( !s_registering ) S_LoadSound( sfx );
return sfx - knownSfx;
return sfx - s_knownSfx;
}
sfx_t *S_GetSfxByHandle( sound_t handle )
{
if( handle < 0 || handle >= numSfx )
if( handle == SENTENCE_INDEX )
{
MsgDev( D_ERROR, "S_GetSfxByHandle: handle %i out of range (%i)\n", handle, numSfx );
// create new sfx
return S_FindName( s_sentenceImmediateName, NULL );
}
if( handle < 0 || handle >= s_numSfx )
{
MsgDev( D_ERROR, "S_GetSfxByHandle: handle %i out of range (%i)\n", handle, s_numSfx );
return NULL;
}
return &knownSfx[handle];
return &s_knownSfx[handle];
}
/*
@ -388,11 +407,11 @@ void S_FreeSounds( void )
S_StopAllSounds();
// free all sounds
for( i = 0, sfx = knownSfx; i < numSfx; i++, sfx++ )
for( i = 0, sfx = s_knownSfx; i < s_numSfx; i++, sfx++ )
S_FreeSound( sfx );
Mem_Set( knownSfx, 0, sizeof( knownSfx ));
Mem_Set( sfxHashList, 0, sizeof( sfxHashList ));
Mem_Set( s_knownSfx, 0, sizeof( s_knownSfx ));
Mem_Set( s_sfxHashList, 0, sizeof( s_sfxHashList ));
numSfx = 0;
s_numSfx = 0;
}

File diff suppressed because it is too large Load Diff

View File

@ -3,11 +3,9 @@
// s_mix.c - portable code to mix sounds
//=======================================================================
#include <dsound.h>
#include "sound.h"
extern DWORD gSndBufSize;
extern LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf;
#define PAINTBUFFER_SIZE 2048
portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
int snd_scaletable[32][256];
int *snd_p, snd_linear_count, snd_vol;
@ -33,46 +31,13 @@ void S_WriteLinearBlastStereo16( void )
}
}
void S_TransferStereo16( int endtime )
void S_TransferStereo16( dword *pbuf, int endtime )
{
int lpos, lpaintedtime;
DWORD *pbuf, *pbuf2;
DWORD dwSize,dwSize2;
HRESULT hresult;
int reps;
snd_p = (int *)paintbuffer;
lpaintedtime = paintedtime;
if( pDSBuf )
{
reps = 0;
while(( hresult = pDSBuf->lpVtbl->Lock( pDSBuf, 0, gSndBufSize, &pbuf, &dwSize, &pbuf2, &dwSize2, 0 )) != DS_OK )
{
if( hresult != DSERR_BUFFERLOST )
{
MsgDev( D_ERROR, "S_TransferStereo16: DS->Lock failed\n" );
SNDDMA_Shutdown();
SNDDMA_Init();
return;
}
if( ++reps > 10000 )
{
MsgDev( D_ERROR, "S_TransferStereo16: couldn't restore buffer\n" );
SNDDMA_Shutdown();
SNDDMA_Init();
return;
}
}
}
else
{
pbuf = (DWORD *)dma.buffer;
}
while( lpaintedtime < endtime )
{
// handle recirculating buffer issues
@ -92,8 +57,6 @@ void S_TransferStereo16( int endtime )
snd_p += snd_linear_count;
lpaintedtime += (snd_linear_count >> 1);
}
if( pDSBuf ) pDSBuf->lpVtbl->Unlock( pDSBuf, pbuf, dwSize, NULL, 0 );
}
/*
@ -105,88 +68,57 @@ S_TransferPaintBuffer
void S_TransferPaintBuffer( int endtime )
{
int out_idx, count;
int step, val, reps;
int step, val;
int *p, out_mask;
DWORD *pbuf, *pbuf2;
DWORD dwSize,dwSize2;
HRESULT hresult;
dword *pbuf;
pbuf = (dword *)dma.buffer;
if( dma.samplebits == 16 && dma.channels == 2 )
{
// optimized case
S_TransferStereo16( endtime );
return;
}
// general case
p = (int *)paintbuffer;
count = (endtime - paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
if( pDSBuf )
{
reps = 0;
while(( hresult = pDSBuf->lpVtbl->Lock( pDSBuf, 0, gSndBufSize, &pbuf, &dwSize, &pbuf2,&dwSize2, 0 )) != DS_OK )
{
if( hresult != DSERR_BUFFERLOST )
{
MsgDev( D_ERROR, "S_TransferPaintBuffer: DS->Lock failed\n" );
SNDDMA_Shutdown();
SNDDMA_Init();
return;
}
if( ++reps > 10000 )
{
MsgDev( D_ERROR, "S_TransferPaintBuffer: couldn't restore buffer\n" );
SNDDMA_Shutdown();
SNDDMA_Init();
return;
}
}
S_TransferStereo16( pbuf, endtime );
}
else
{
pbuf = (DWORD *)dma.buffer;
}
{
// general case
p = (int *)paintbuffer;
count = (endtime - paintedtime) * dma.channels;
out_mask = dma.samples - 1;
out_idx = paintedtime * dma.channels & out_mask;
step = 3 - dma.channels;
if( dma.samplebits == 16 )
{
short *out = (short *)pbuf;
while( count-- )
if( dma.samplebits == 16 )
{
val = (*p * snd_vol) >> 8;
p += step;
if( val > 0x7fff ) val = 0x7fff;
else if( val < (short)0x8000 )
val = (short)0x8000;
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
short *out = (short *)pbuf;
while( count-- )
{
val = *p >> 8;
p += step;
if( val > 0x7fff ) val = 0x7fff;
else if( val < (short)0x8000 )
val = (short)0x8000;
out[out_idx] = val;
out_idx = (out_idx + 1) & out_mask;
}
}
else if( dma.samplebits == 8 )
{
byte *out = (byte *)pbuf;
while( count-- )
{
val = *p >> 8;
p += step;
if( val > 0x7fff ) val = 0x7fff;
else if( val < (short)0x8000 )
val = (short)0x8000;
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask;
}
}
}
else if( dma.samplebits == 8 )
{
byte *out = (byte *)pbuf;
while( count-- )
{
val = (*p * snd_vol) >> 8;
p += step;
if( val > 0x7fff ) val = 0x7fff;
else if( val < (short)0x8000 )
val = (short)0x8000;
out[out_idx] = (val>>8) + 128;
out_idx = (out_idx + 1) & out_mask;
}
}
if( pDSBuf ) pDSBuf->lpVtbl->Unlock( pDSBuf, pbuf, dwSize, NULL, 0 );
}
/*
@ -196,11 +128,13 @@ CHANNEL MIXING
===============================================================================
*/
void S_PaintChannelFrom8( channel_t *ch, wavdata_t *sc, int count )
void S_PaintChannelFrom8( channel_t *ch, wavdata_t *sc, int count, int offset )
{
int i, data;
int *lscale, *rscale;
byte *sfx;
int data;
int *lscale, *rscale;
byte *sfx;
portable_samplepair_t *samp;
int i;
if( ch->leftvol > 255 ) ch->leftvol = 255;
if( ch->rightvol > 255 ) ch->rightvol = 255;
@ -209,33 +143,39 @@ void S_PaintChannelFrom8( channel_t *ch, wavdata_t *sc, int count )
rscale = snd_scaletable[ch->rightvol>>3];
sfx = (signed char *)sc->buffer + ch->pos;
for( i = 0; i < count; i++ )
samp = &paintbuffer[offset];
for( i = 0; i < count; i++, samp++ )
{
data = sfx[i];
paintbuffer[i].left += lscale[data];
paintbuffer[i].right += rscale[data];
samp->left += lscale[data];
samp->right += rscale[data];
}
ch->pos += count;
}
void S_PaintChannelFrom16( channel_t *ch, wavdata_t *sc, int count )
void S_PaintChannelFrom16( channel_t *ch, wavdata_t *sc, int count, int offset )
{
int i, data;
int left, right;
int leftvol, rightvol;
short *sfx;
int data;
int left, right;
int leftvol, rightvol;
signed short *sfx;
portable_samplepair_t *samp;
int i;
leftvol = ch->leftvol * snd_vol;
rightvol = ch->rightvol * snd_vol;
sfx = (signed short *)sc->buffer + ch->pos;
for( i = 0; i < count; i++ )
samp = &paintbuffer[offset];
for( i = 0; i < count; i++, samp++ )
{
data = sfx[i];
left = ( data * leftvol ) >> 8;
right = (data * rightvol) >> 8;
paintbuffer[i].left += left;
paintbuffer[i].right += right;
samp->left += left;
samp->right += right;
}
ch->pos += count;
}
@ -252,7 +192,7 @@ void S_MixAllChannels( int endtime, int end )
{
if( !ch->sfx ) continue;
if( !ch->leftvol && !ch->rightvol )
continue; // not audible
continue;
sc = S_LoadSound( ch->sfx );
if( !sc ) continue;
@ -261,24 +201,36 @@ void S_MixAllChannels( int endtime, int end )
while( ltime < end )
{
// paint up to end
if( ch->end < end )
count = ch->end - ltime;
else count = end - ltime;
// max painting is to the end of the buffer
count = end - ltime;
// might be stopped by running out of data
if( ch->end - ltime < count ) count = ch->end - ltime;
if( count > 0 )
{
if( sc->width == 1 )
S_PaintChannelFrom8( ch, sc, count );
else S_PaintChannelFrom16( ch, sc, count );
S_PaintChannelFrom8( ch, sc, count, ltime - paintedtime );
else S_PaintChannelFrom16( ch, sc, count, ltime - paintedtime );
ltime += count;
}
if( si.GetClientEdict( ch->entnum ) && ( ch->entchannel == CHAN_VOICE ))
{
// UNDONE: recode this as a member function of CAudioMixer
SND_MoveMouth8( ch, ch->sfx->cache, count );
}
// if at end of loop, restart
if( ltime >= ch->end )
{
if( sc->loopStart >= 0 )
if( ch->isSentence )
{
VOX_LoadNextWord( ch );
if( !ch->sfx ) break; // sentence is finished
}
else if( sc->loopStart >= 0 && ch->use_loop )
{
ch->pos = sc->loopStart;
ch->end = ltime + sc->samples - ch->pos;
@ -308,7 +260,7 @@ void S_PaintChannels( int endtime )
end = paintedtime + PAINTBUFFER_SIZE;
// clear the paint buffer
if( rawend < paintedtime )
if( s_rawend < paintedtime )
{
Mem_Set( paintbuffer, 0, (end - paintedtime) * sizeof( portable_samplepair_t ));
}
@ -317,10 +269,10 @@ void S_PaintChannels( int endtime )
int i, stop;
// copy from the streaming sound source
stop = (end < rawend) ? end : rawend;
stop = (end < s_rawend) ? end : s_rawend;
for( i = paintedtime; i < stop; i++ )
paintbuffer[i - paintedtime] = rawsamples[i & (MAX_RAW_SAMPLES - 1)];
paintbuffer[i - paintedtime] = s_rawsamples[i & (MAX_RAW_SAMPLES - 1)];
for( ; i < end; i++ )
paintbuffer[i-paintedtime].left = paintbuffer[i-paintedtime].right = 0;
@ -328,8 +280,7 @@ void S_PaintChannels( int endtime )
S_MixAllChannels( endtime, end );
// add dsp processing effects
SX_RoomFX( endtime, true, true );
// SX_RoomFX( endtime, true, true );
// transfer out according to DMA format
S_TransferPaintBuffer( end );
@ -337,7 +288,7 @@ void S_PaintChannels( int endtime )
}
}
void SND_InitScaletable( void )
void S_InitScaletable( void )
{
int i, j;
int scale;
@ -345,9 +296,7 @@ void SND_InitScaletable( void )
for( i = 0; i < 32; i++ )
{
scale = i * 8 * 256 * S_GetMasterVolume();
for( j = 0; j < 256; j++ )
snd_scaletable[i][j] = ((signed char)j) * scale;
for( j = 0; j < 256; j++ ) snd_scaletable[i][j] = ((signed char)j) * scale;
}
volume->modified = false;
s_volume->modified = false;
}

View File

@ -6,6 +6,8 @@
#include "sound.h"
#include "const.h"
#define CAVGSAMPLES 10
void SND_InitMouth( int entnum, int entchannel )
{
if(( entchannel == CHAN_VOICE || entchannel == CHAN_STREAM ) && entnum > 0 )
@ -43,4 +45,51 @@ void SND_CloseMouth( channel_t *ch )
m->mouthopen = 0;
}
}
}
void SND_MoveMouth8( channel_t *ch, wavdata_t *pSource, int count )
{
int i, data;
edict_t *clientEntity;
char *pdata = NULL;
mouth_t *pMouth = NULL;
int savg;
int scount;
clientEntity = si.GetClientEdict( ch->entnum );
if( clientEntity && !clientEntity->free )
{
pMouth = si.GetEntityMouth( clientEntity );
}
if( !pMouth ) return;
S_GetOutputData( pSource, &pdata, ch->pos, count );
if( pdata == NULL )
return;
i = 0;
scount = pMouth->sndcount;
savg = 0;
while( i < count && scount < CAVGSAMPLES )
{
data = pdata[i];
savg += abs( data );
i += 80 + ((byte)data & 0x1F);
scount++;
}
pMouth->sndavg += savg;
pMouth->sndcount = (byte)scount;
if( pMouth->sndcount >= CAVGSAMPLES )
{
pMouth->mouthopen = pMouth->sndavg / CAVGSAMPLES;
pMouth->sndavg = 0;
pMouth->sndcount = 0;
}
}

View File

@ -6,9 +6,9 @@
#include "sound.h"
#include "byteorder.h"
portable_samplepair_t rawsamples[MAX_RAW_SAMPLES];
static bg_track_t bgTrack;
int rawend;
portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
int s_rawend;
static bg_track_t s_bgTrack;
/*
=================
@ -23,40 +23,44 @@ void S_StartBackgroundTrack( const char *introTrack, const char *mainTrack )
return;
if( !introTrack )
{
introTrack = "";
}
if( !mainTrack || !*mainTrack )
{
mainTrack = introTrack;
}
if( !*introTrack ) return;
if( mainTrack )
com.snprintf( bgTrack.loopName, sizeof( bgTrack.loopName ), "media/%s", mainTrack );
else bgTrack.loopName[0] = 0;
{
com.snprintf( s_bgTrack.loopName, sizeof( s_bgTrack.loopName ), "media/%s", mainTrack );
}
else s_bgTrack.loopName[0] = 0;
S_StartStreaming();
// close the background track, but DON'T reset rawend
// close the background track, but DON'T reset s_rawend
// if restarting the same back ground track
if( bgTrack.stream )
if( s_bgTrack.stream )
{
FS_CloseStream( bgTrack.stream );
bgTrack.stream = NULL;
FS_CloseStream( s_bgTrack.stream );
s_bgTrack.stream = NULL;
}
// open stream
bgTrack.stream = FS_OpenStream( va( "media/%s", introTrack ));
s_bgTrack.stream = FS_OpenStream( va( "media/%s", introTrack ));
}
void S_StopBackgroundTrack( void )
{
S_StopStreaming();
if( !bgTrack.stream ) return;
if( !s_bgTrack.stream ) return;
FS_CloseStream( bgTrack.stream );
Mem_Set( &bgTrack, 0, sizeof( bg_track_t ));
rawend = 0;
FS_CloseStream( s_bgTrack.stream );
Mem_Set( &s_bgTrack, 0, sizeof( bg_track_t ));
s_rawend = 0;
}
/*
@ -69,25 +73,26 @@ void S_StreamBackgroundTrack( void )
int bufferSamples;
int fileSamples;
byte raw[MAX_RAW_SAMPLES];
float musicVolume = 0.5f;
int r, fileBytes;
float musicVolume = 0.5f;
if( !bgTrack.stream ) return;
if( !s_bgTrack.stream ) return;
// graeme see if this is OK
musicVolume = ( musicVolume + ( musicvolume->value * 2 )) / 4.0f;
musicVolume = ( musicVolume + ( s_musicvolume->value * 2 )) / 4.0f;
// don't bother playing anything if musicvolume is 0
if( musicVolume <= 0 ) return;
// see how many samples should be copied into the raw buffer
if( rawend < soundtime ) rawend = soundtime;
if( s_rawend < soundtime )
s_rawend = soundtime;
while( rawend < soundtime + MAX_RAW_SAMPLES )
while( s_rawend < soundtime + MAX_RAW_SAMPLES )
{
wavdata_t *info = FS_StreamInfo( bgTrack.stream );
wavdata_t *info = FS_StreamInfo( s_bgTrack.stream );
bufferSamples = MAX_RAW_SAMPLES - ( rawend - soundtime );
bufferSamples = MAX_RAW_SAMPLES - (s_rawend - soundtime);
// decide how much data needs to be read from the file
fileSamples = bufferSamples * info->rate / dma.speed;
@ -102,7 +107,7 @@ void S_StreamBackgroundTrack( void )
}
// read
r = FS_ReadStream( bgTrack.stream, fileBytes, raw );
r = FS_ReadStream( s_bgTrack.stream, fileBytes, raw );
if( r < fileBytes )
{
@ -119,12 +124,12 @@ void S_StreamBackgroundTrack( void )
else
{
// loop
if( bgTrack.loopName[0] )
if( s_bgTrack.loopName[0] )
{
FS_CloseStream( bgTrack.stream );
bgTrack.stream = NULL;
S_StartBackgroundTrack( bgTrack.loopName, bgTrack.loopName );
if( !bgTrack.stream ) return;
FS_CloseStream( s_bgTrack.stream );
s_bgTrack.stream = NULL;
S_StartBackgroundTrack( s_bgTrack.loopName, s_bgTrack.loopName );
if( !s_bgTrack.stream ) return;
}
else
{
@ -152,7 +157,7 @@ S_StopStreaming
*/
void S_StopStreaming( void )
{
// clear rawend here ?
// clear s_rawend here ?
}
/*
@ -167,8 +172,8 @@ void S_StreamRawSamples( int samples, int rate, int width, int channels, const b
int i, src, dst;
float scale;
if( rawend < paintedtime )
rawend = paintedtime;
if( s_rawend < paintedtime )
s_rawend = paintedtime;
scale = (float)rate / dma.speed;
if( channels == 2 && width == 2 )
@ -178,10 +183,10 @@ void S_StreamRawSamples( int samples, int rate, int width, int channels, const b
// optimized case
for( i = 0; i < samples; i++ )
{
dst = rawend & (MAX_RAW_SAMPLES - 1);
rawend++;
rawsamples[dst].left = LittleShort(((short *)data)[i*2]) << 8;
rawsamples[dst].right = LittleShort(((short *)data)[i*2+1]) << 8;
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
s_rawend++;
s_rawsamples[dst].left = LittleShort(((short *)data)[i*2]) << 8;
s_rawsamples[dst].right = LittleShort(((short *)data)[i*2+1]) << 8;
}
}
else
@ -191,10 +196,10 @@ void S_StreamRawSamples( int samples, int rate, int width, int channels, const b
src = i * scale;
if( src >= samples ) break;
dst = rawend & (MAX_RAW_SAMPLES - 1);
rawend++;
rawsamples[dst].left = LittleShort(((short *)data)[src*2]) << 8;
rawsamples[dst].right = LittleShort(((short *)data)[src*2+1]) << 8;
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
s_rawend++;
s_rawsamples[dst].left = LittleShort(((short *)data)[src*2]) << 8;
s_rawsamples[dst].right = LittleShort(((short *)data)[src*2+1]) << 8;
}
}
}
@ -205,10 +210,10 @@ void S_StreamRawSamples( int samples, int rate, int width, int channels, const b
src = i * scale;
if( src >= samples ) break;
dst = rawend & (MAX_RAW_SAMPLES - 1);
rawend++;
rawsamples[dst].left = LittleShort(((short *)data)[src]) << 8;
rawsamples[dst].right = LittleShort(((short *)data)[src]) << 8;
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
s_rawend++;
s_rawsamples[dst].left = LittleShort(((short *)data)[src]) << 8;
s_rawsamples[dst].right = LittleShort(((short *)data)[src]) << 8;
}
}
else if( channels == 2 && width == 1 )
@ -218,10 +223,10 @@ void S_StreamRawSamples( int samples, int rate, int width, int channels, const b
src = i * scale;
if( src >= samples ) break;
dst = rawend & (MAX_RAW_SAMPLES - 1);
rawend++;
rawsamples[dst].left = ((char *)data)[src*2] << 16;
rawsamples[dst].right = ((char *)data)[src*2+1] << 16;
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
s_rawend++;
s_rawsamples[dst].left = ((char *)data)[src*2] << 16;
s_rawsamples[dst].right = ((char *)data)[src*2+1] << 16;
}
}
else if( channels == 1 && width == 1 )
@ -231,10 +236,10 @@ void S_StreamRawSamples( int samples, int rate, int width, int channels, const b
src = i * scale;
if( src >= samples ) break;
dst = rawend & (MAX_RAW_SAMPLES - 1);
rawend++;
rawsamples[dst].left = (((byte *)data)[src]-128) << 16;
rawsamples[dst].right = (((byte *)data)[src]-128) << 16;
dst = s_rawend & (MAX_RAW_SAMPLES - 1);
s_rawend++;
s_rawsamples[dst].left = (((byte *)data)[src]-128) << 16;
s_rawsamples[dst].right = (((byte *)data)[src]-128) << 16;
}
}
}

245
snd_dx/s_utils.c Normal file
View File

@ -0,0 +1,245 @@
//=======================================================================
// Copyright XashXT Group 2009 ©
// s_utils.c - common sound functions
//=======================================================================
#include "sound.h"
// hardcoded macros to test for zero crossing
#define ZERO_X_8( b ) (( b )< 2 && ( b ) > -2 )
#define ZERO_X_16( b ) (( b )< 512 && ( b ) > -512 )
//-----------------------------------------------------------------------------
// Purpose: Search backward for a zero crossing starting at sample
// Input : sample - starting point
// Output : position of zero crossing
//-----------------------------------------------------------------------------
int S_ZeroCrossingBefore( wavdata_t *pWaveData, int sample )
{
if( pWaveData == NULL )
return sample;
if( pWaveData->type == WF_PCMDATA )
{
if( pWaveData->width == 1 )
{
// FIXME: this is right ?
char *pData = pWaveData->buffer + sample * pWaveData->width;
bool zero = false;
if( pWaveData->channels == 1 )
{
while( sample > 0 && !zero )
{
if( ZERO_X_8( *pData ))
{
zero = true;
}
else
{
sample--;
pData--;
}
}
}
else
{
while( sample > 0 && !zero )
{
if( ZERO_X_8( *pData ) && ZERO_X_8( pData[1] ))
{
zero = true;
}
else
{
sample--;
pData--;
}
}
}
}
else
{ // FIXME: this is right ?
short *pData = (short *)(pWaveData->buffer + sample * pWaveData->width);
bool zero = false;
if( pWaveData->channels == 1 )
{
while( sample > 0 && !zero )
{
if( ZERO_X_16(*pData ))
{
zero = true;
}
else
{
pData--;
sample--;
}
}
}
else
{
while( sample > 0 && !zero )
{
if( ZERO_X_16( *pData ) && ZERO_X_16( pData[1] ))
{
zero = true;
}
else
{
sample--;
pData--;
}
}
}
}
}
return sample;
}
//-----------------------------------------------------------------------------
// Purpose: Search forward for a zero crossing
// Input : sample - starting point
// Output : position of found zero crossing
//-----------------------------------------------------------------------------
int S_ZeroCrossingAfter( wavdata_t *pWaveData, int sample )
{
if( pWaveData == NULL )
return sample;
if( pWaveData->type == WF_PCMDATA )
{
if( pWaveData->width == 1 ) // 8-bit
{
// FIXME: this is right ?
char *pData = pWaveData->buffer + sample * pWaveData->width;
bool zero = false;
if( pWaveData->channels == 1 )
{
while( sample < pWaveData->samples && !zero )
{
if( ZERO_X_8( *pData ))
{
zero = true;
}
else
{
sample++;
pData++;
}
}
}
else
{
while( sample < pWaveData->samples && !zero )
{
if( ZERO_X_8( *pData ) && ZERO_X_8( pData[1] ))
{
zero = true;
}
else
{
sample++;
pData++;
}
}
}
}
else
{ // FIXME: this is right ?
short *pData = (short *)(pWaveData->buffer + sample * pWaveData->width);
bool zero = false;
if( pWaveData->channels == 1 )
{
while( sample > 0 && !zero )
{
if( ZERO_X_16( *pData ))
{
zero = true;
}
else
{
pData++;
sample++;
}
}
}
else
{
while( sample > 0 && !zero )
{
if( ZERO_X_16( *pData ) && ZERO_X_16( pData[1] ))
{
zero = true;
}
else
{
sample++;
pData++;
}
}
}
}
}
return sample;
}
//-----------------------------------------------------------------------------
// Purpose: wrap the position wrt looping
// Input : samplePosition - absolute position
// Output : int - looped position
//-----------------------------------------------------------------------------
int S_ConvertLoopedPosition( wavdata_t *pSource, int samplePosition )
{
// if the wave is looping and we're past the end of the sample
// convert to a position within the loop
// At the end of the loop, we return a short buffer, and subsequent call
// will loop back and get the rest of the buffer
if( pSource->loopStart >= 0 && samplePosition >= pSource->samples )
{
// size of loop
int loopSize = pSource->samples - pSource->loopStart;
// subtract off starting bit of the wave
samplePosition -= pSource->loopStart;
if( loopSize )
{
// "real" position in memory (mod off extra loops)
samplePosition = pSource->loopStart + ( samplePosition % loopSize );
}
// ERROR? if no loopSize
}
return samplePosition;
}
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount )
{
int totalSampleCount;
// handle position looping
samplePosition = S_ConvertLoopedPosition( pSource, samplePosition );
// how many samples are available (linearly not counting looping)
totalSampleCount = pSource->samples - samplePosition;
// may be asking for a sample out of range, clip at zero
if( totalSampleCount < 0 ) totalSampleCount = 0;
// clip max output samples to max available
if( sampleCount > totalSampleCount )
sampleCount = totalSampleCount;
// byte offset in sample database
samplePosition *= pSource->width; // FIXME: this is right ?
// if we are returning some samples, store the pointer
if( sampleCount )
{
*pData = pSource->buffer + samplePosition;
}
return sampleCount;
}

View File

@ -6,17 +6,620 @@
#include "sound.h"
#include "const.h"
void VOX_SetChanVol( channel_t *ch )
{
float scale = 1.0f; // FIXME: get volume from words
if( scale == 1.0f ) return;
sentence_t g_Sentences[MAX_SENTENCES];
static uint g_numSentences;
static char *rgpparseword[CVOXWORDMAX]; // array of pointers to parsed words
static char voxperiod[] = "_period"; // vocal pause
static char voxcomma[] = "_comma"; // vocal pause
ch->rightvol = (int)( ch->rightvol * scale );
ch->leftvol = (int)( ch->leftvol * scale );
static int IsNextWord( char c )
{
if( c == '.' || c == ',' || c == ' ' || c == '(' )
return 1;
return 0;
}
static int IsSkipSpace( char c )
{
if( c == ',' || c == '.' || c == ' ' )
return 1;
return 0;
}
static int IsWhiteSpace( char space )
{
if( space == ' ' || space == '\t' || space == '\r' || space == '\n' )
return 1;
return 0;
}
static int IsCommandChar( char c )
{
if( c == 'v' || c == 'p' || c == 's' || c == 'e' || c == 't' )
return 1;
return 0;
}
static int IsDelimitChar( char c )
{
if( c == '(' || c == ')' )
return 1;
return 0;
}
static char *ScanForwardUntil( char *string, char scan )
{
while( string[0] )
{
if ( string[0] == scan )
return string;
string++;
}
return string;
}
// backwards scan psz for last '/'
// return substring in szpath null terminated
// if '/' not found, return 'vox/'
static char *VOX_GetDirectory( char *szpath, char *psz )
{
char c;
int cb = 0;
char *pszscan = psz + com.strlen( psz ) - 1;
// scan backwards until first '/' or start of string
c = *pszscan;
while( pszscan > psz && c != '/' )
{
c = *( --pszscan );
cb++;
}
if( c != '/' )
{
// didn't find '/', return default directory
com.strcpy( szpath, "vox/" );
return psz;
}
cb = com.strlen( psz ) - cb;
Mem_Copy( szpath, psz, cb );
szpath[cb] = 0;
return pszscan + 1;
}
// scan g_Sentences, looking for pszin sentence name
// return pointer to sentence data if found, null if not
// CONSIDER: if we have a large number of sentences, should
// CONSIDER: sort strings in g_Sentences and do binary search.
char *VOX_LookupString( const char *pSentenceName, int *psentencenum )
{
int i;
if( com.is_digit( pSentenceName ) && (i = com.atoi( pSentenceName )) < g_numSentences )
{
if( psentencenum ) *psentencenum = i;
return (g_Sentences[i].pName + com.strlen( g_Sentences[i].pName ) + 1 );
}
for( i = 0; i < g_numSentences; i++ )
{
if( !com.stricmp( pSentenceName, g_Sentences[i].pName ))
{
if( psentencenum ) *psentencenum = i;
return (g_Sentences[i].pName + com.strlen( g_Sentences[i].pName ) + 1 );
}
}
return NULL;
}
// parse a null terminated string of text into component words, with
// pointers to each word stored in rgpparseword
// note: this code actually alters the passed in string!
char **VOX_ParseString( char *psz )
{
int i, fdone = 0;
char c, *pszscan = psz;
Mem_Set( rgpparseword, 0, sizeof( char* ) * CVOXWORDMAX );
if( !psz ) return NULL;
i = 0;
rgpparseword[i++] = psz;
while( !fdone && i < CVOXWORDMAX )
{
// scan up to next word
c = *pszscan;
while( c && !IsNextWord( c ))
c = *(++pszscan);
// if '(' then scan for matching ')'
if( c == '(' )
{
pszscan = ScanForwardUntil( pszscan, ')' );
c = *(++pszscan);
if( !c ) fdone = 1;
}
if( fdone || !c )
{
fdone = 1;
}
else
{
// if . or , insert pause into rgpparseword,
// unless this is the last character
if(( c == '.' || c == ',' ) && *(pszscan+1) != '\n' && *(pszscan+1) != '\r' && *(pszscan+1) != 0 )
{
if( c == '.' ) rgpparseword[i++] = voxperiod;
else rgpparseword[i++] = voxcomma;
if( i >= CVOXWORDMAX )
break;
}
// null terminate substring
*pszscan++ = 0;
// skip whitespace
c = *pszscan;
while( c && IsSkipSpace( c ))
c = *(++pszscan);
if( !c ) fdone = 1;
else rgpparseword[i++] = pszscan;
}
}
return rgpparseword;
}
float VOX_GetVolumeScale( channel_t *pchan )
{
if( pchan->currentWord.pData )
{
if ( pchan->words[pchan->wordIndex].volume )
{
float volume = pchan->words[pchan->wordIndex].volume * 0.01f;
if( volume < 1.0f ) return volume;
}
}
return 1.0f;
}
void VOX_SetChanVol( channel_t *ch )
{
float scale;
if( !ch->currentWord.pData )
return;
scale = VOX_GetVolumeScale( ch );
if( scale == 1.0f ) return;
ch->rightvol = (int)(ch->rightvol * scale);
ch->leftvol = (int)(ch->leftvol * scale);
}
//===============================================================================
// Get any pitch, volume, start, end params into voxword
// and null out trailing format characters
// Format:
// someword(v100 p110 s10 e20)
//
// v is volume, 0% to n%
// p is pitch shift up 0% to n%
// s is start wave offset %
// e is end wave offset %
// t is timecompression %
//
// pass fFirst == 1 if this is the first string in sentence
// returns 1 if valid string, 0 if parameter block only.
//
// If a ( xxx ) parameter block does not directly follow a word,
// then that 'default' parameter block will be used as the default value
// for all following words. Default parameter values are reset
// by another 'default' parameter block. Default parameter values
// for a single word are overridden for that word if it has a parameter block.
//
//===============================================================================
int VOX_ParseWordParams( char *psz, voxword_t *pvoxword, int fFirst )
{
char *pszsave = psz;
char c, ct, sznum[8];
static voxword_t voxwordDefault;
int i;
// init to defaults if this is the first word in string.
if( fFirst )
{
voxwordDefault.pitch = -1;
voxwordDefault.volume = 100;
voxwordDefault.start = 0;
voxwordDefault.end = 100;
voxwordDefault.fKeepCached = 0;
voxwordDefault.timecompress = 0;
}
*pvoxword = voxwordDefault;
// look at next to last char to see if we have a
// valid format:
c = *( psz + com.strlen( psz ) - 1 );
// no formatting, return
if( c != ')' ) return 1;
// scan forward to first '('
c = *psz;
while( !IsDelimitChar( c ))
c = *(++psz);
// bogus formatting
if( c == ')' ) return 0;
// null terminate
*psz = 0;
ct = *(++psz);
while( 1 )
{
// scan until we hit a character in the commandSet
while( ct && !IsCommandChar( ct ))
ct = *(++psz);
if( ct == ')' )
break;
Mem_Set( sznum, 0, sizeof( sznum ));
i = 0;
c = *(++psz);
if( !isdigit( c ))
break;
// read number
while( isdigit( c ) && i < sizeof( sznum ) - 1 )
{
sznum[i++] = c;
c = *(++psz);
}
// get value of number
i = com.atoi( sznum );
switch( ct )
{
case 'v': pvoxword->volume = i; break;
case 'p': pvoxword->pitch = i; break;
case 's': pvoxword->start = i; break;
case 'e': pvoxword->end = i; break;
case 't': pvoxword->timecompress = i; break;
}
ct = c;
}
// if the string has zero length, this was an isolated
// parameter block. Set default voxword to these
// values
if( com.strlen( pszsave ) == 0 )
{
voxwordDefault = *pvoxword;
return 0;
}
return 1;
}
void VOX_LoadWord( channel_t *pchan )
{
if( pchan->words[pchan->wordIndex].sfx )
{
wavdata_t *pSource = S_LoadSound( pchan->words[pchan->wordIndex].sfx );
if( pSource )
{
int start = pchan->words[pchan->wordIndex].start;
int end = pchan->words[pchan->wordIndex].end;
// don't allow overlapped ranges
if( end <= start ) end = 0;
if( start || end )
{
int sampleCount = pSource->samples;
if( start )
{
pchan->currentWord.sample = S_ZeroCrossingAfter( pSource, (int)(sampleCount * 0.01f * start));
}
if( end )
{
pchan->currentWord.forcedEndSample = S_ZeroCrossingBefore( pSource, (int)(sampleCount * 0.01f * end) );
// past current position? limit.
if( pchan->currentWord.forcedEndSample < pchan->currentWord.sample )
pchan->currentWord.forcedEndSample = pchan->currentWord.sample;
}
}
pchan->currentWord.pData = pSource;
}
}
else pchan->currentWord.pData = NULL; // sentence is finished
}
void VOX_LoadFirstWord( channel_t *pchan, voxword_t *pwords )
{
int i = 0;
// copy each pointer in the sfx temp array into the
// sentence array, and set the channel to point to the
// sentence array
while( pwords[i].sfx != NULL )
pchan->words[i] = pwords[i++];
pchan->words[i].sfx = NULL;
pchan->wordIndex = 0;
VOX_LoadWord( pchan );
}
void VOX_LoadNextWord( channel_t *pchan )
{
pchan->wordIndex++;
VOX_LoadWord( pchan );
// set new word
if( pchan->currentWord.pData )
{
pchan->sfx = pchan->words[pchan->wordIndex].sfx;
pchan->pos = pchan->currentWord.sample;
pchan->end = paintedtime + pchan->currentWord.forcedEndSample;
}
else S_FreeChannel( pchan ); // channel stopped
}
// link all sounds in sentence, start playing first word.
void VOX_LoadSound( channel_t *pchan, const char *pszin )
{
char buffer[512];
int i, cword;
char pathbuffer[64];
char szpath[32];
voxword_t rgvoxword[CVOXWORDMAX];
char *psz;
if( !pszin || !*pszin )
return;
Mem_Set( rgvoxword, 0, sizeof( voxword_t ) * CVOXWORDMAX );
Mem_Set( buffer, 0, sizeof( buffer ));
// lookup actual string in g_Sentences,
// set pointer to string data
psz = VOX_LookupString( pszin, NULL );
if( !psz )
{
MsgDev( D_ERROR, "VOX_LoadSound: no sentence named %s\n", pszin );
return;
}
// get directory from string, advance psz
psz = VOX_GetDirectory( szpath, psz );
if( com.strlen( psz ) > sizeof( buffer ) - 1 )
{
MsgDev( D_ERROR, "VOX_LoadSound: sentence is too long %s\n", psz );
return;
}
// copy into buffer
com.strcpy( buffer, psz );
psz = buffer;
// parse sentence (also inserts null terminators between words)
VOX_ParseString( psz );
// for each word in the sentence, construct the filename,
// lookup the sfx and save each pointer in a temp array
i = 0;
cword = 0;
while( rgpparseword[i] )
{
// Get any pitch, volume, start, end params into voxword
if( VOX_ParseWordParams( rgpparseword[i], &rgvoxword[cword], i == 0 ))
{
// this is a valid word (as opposed to a parameter block)
com.strcpy( pathbuffer, szpath );
com.strncat( pathbuffer, rgpparseword[i], sizeof( pathbuffer ));
com.strncat( pathbuffer, ".wav", sizeof( pathbuffer ));
// find name, if already in cache, mark voxword
// so we don't discard when word is done playing
rgvoxword[cword].sfx = S_FindName( pathbuffer, &( rgvoxword[cword].fKeepCached ));
cword++;
}
i++;
}
VOX_LoadFirstWord( pchan, rgvoxword );
pchan->isSentence = true;
pchan->sfx = rgvoxword[0].sfx;
}
//-----------------------------------------------------------------------------
// Purpose: Take a NULL terminated sentence, and parse any commands contained in
// {}. The string is rewritten in place with those commands removed.
//
// Input : *pSentenceData - sentence data to be modified in place
// sentenceIndex - global sentence table index for any data that is
// parsed out
//-----------------------------------------------------------------------------
void VOX_ParseLineCommands( char *pSentenceData, int sentenceIndex )
{
char tempBuffer[512];
char *pNext, *pStart;
int length, tempBufferPos = 0;
if( !pSentenceData )
return;
pStart = pSentenceData;
while( *pSentenceData )
{
pNext = ScanForwardUntil( pSentenceData, '{' );
// find length of "good" portion of the string (not a {} command)
length = pNext - pSentenceData;
if( tempBufferPos + length > sizeof( tempBuffer ))
{
MsgDev( D_ERROR, "sentence too long!\n" );
return;
}
// Copy good string to temp buffer
Mem_Copy( tempBuffer + tempBufferPos, pSentenceData, length );
// move the copy position
tempBufferPos += length;
pSentenceData = pNext;
// skip ahead of the opening brace
if( *pSentenceData ) pSentenceData++;
// skip whitespace
while( *pSentenceData && *pSentenceData <= 32 )
pSentenceData++;
// simple comparison of string commands:
switch( com.tolower( *pSentenceData ))
{
case 'l':
// all commands starting with the letter 'l' here
if( !com.strnicmp( pSentenceData, "len", 3 ))
{
g_Sentences[sentenceIndex].length = com.atof( pSentenceData + 3 );
}
break;
case 0:
default:
break;
}
pSentenceData = ScanForwardUntil( pSentenceData, '}' );
// skip the closing brace
if( *pSentenceData ) pSentenceData++;
// skip trailing whitespace
while( *pSentenceData && *pSentenceData <= 32 )
pSentenceData++;
}
if( tempBufferPos < sizeof( tempBuffer ))
{
// terminate cleaned up copy
tempBuffer[tempBufferPos] = 0;
// copy it over the original data
com.strcpy( pStart, tempBuffer );
}
}
// Load sentence file into memory, insert null terminators to
// delimit sentence name/sentence pairs. Keep pointer to each
// sentence name so we can search later.
void VOX_ReadSentenceFile( const char *psentenceFileName )
{
char c, *pch, *pFileData;
char *pchlast, *pSentenceData;
int fileSize;
// load file
pFileData = (char *)FS_LoadFile( psentenceFileName, &fileSize );
if( !pFileData )
{
MsgDev( D_WARN, "couldn't load %s\n", psentenceFileName );
return;
}
pch = pFileData;
pchlast = pch + fileSize;
while( pch < pchlast )
{
// only process this pass on sentences
pSentenceData = NULL;
// skip newline, cr, tab, space
c = *pch;
while( pch < pchlast && IsWhiteSpace( c ))
c = *(++pch);
// skip entire line if first char is /
if( *pch != '/' )
{
sentence_t *pSentence = &g_Sentences[g_numSentences++];
pSentence->pName = pch;
pSentence->length = 0;
// scan forward to first space, insert null terminator
// after sentence name
c = *pch;
while( pch < pchlast && c != ' ' )
c = *(++pch);
if( pch < pchlast )
*pch++ = 0;
// a sentence may have some line commands, make an extra pass
pSentenceData = pch;
}
// scan forward to end of sentence or eof
while( pch < pchlast && pch[0] != '\n' && pch[0] != '\r' )
pch++;
// insert null terminator
if( pch < pchlast )
*pch++ = 0;
// If we have some sentence data, parse out any line commands
if( pSentenceData && pSentenceData < pchlast )
{
int index = g_numSentences - 1;
// the current sentence has an index of count-1
VOX_ParseLineCommands( pSentenceData, index );
}
}
}
void VOX_Init( void )
{
Mem_Set( g_Sentences, 0, sizeof( g_Sentences ));
g_numSentences = 0;
VOX_ReadSentenceFile( "sound/sentences.txt" );
}
void VOX_Shutdown( void )
{
g_numSentences = 0;
}

View File

@ -146,6 +146,10 @@ SOURCE=.\s_stream.c
# End Source File
# Begin Source File
SOURCE=.\s_utils.c
# End Source File
# Begin Source File
SOURCE=.\s_vox.c
# End Source File
# End Group

View File

@ -1,128 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: snd_dx - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP5173.tmp" with contents
[
/nologo /MD /W3 /GX /O2 /I "./" /I "../public" /I "../common" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /Fo"..\temp\snd_dx\!release/" /Fd"..\temp\snd_dx\!release/" /FD /c
"D:\Xash3D\src_main\snd_dx\s_main.c"
]
Creating command line "cl.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP5173.tmp""
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP5174.tmp" with contents
[
winmm.lib /nologo /dll /pdb:none /machine:I386 /nodefaultlib:"libcmt.lib" /out:"..\temp\snd_dx\!release/snd_dx.dll" /implib:"..\temp\snd_dx\!release/snd_dx.lib" /opt:nowin98
"\Xash3D\src_main\temp\snd_dx\!release\s_backend.obj"
"\Xash3D\src_main\temp\snd_dx\!release\s_dsp.obj"
"\Xash3D\src_main\temp\snd_dx\!release\s_export.obj"
"\Xash3D\src_main\temp\snd_dx\!release\s_load.obj"
"\Xash3D\src_main\temp\snd_dx\!release\s_main.obj"
"\Xash3D\src_main\temp\snd_dx\!release\s_mix.obj"
"\Xash3D\src_main\temp\snd_dx\!release\s_mouth.obj"
"\Xash3D\src_main\temp\snd_dx\!release\s_stream.obj"
"\Xash3D\src_main\temp\snd_dx\!release\s_vox.obj"
]
Creating command line "link.exe @"C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP5174.tmp""
Creating temporary file "C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP5175.bat" with contents
[
@echo off
copy \Xash3D\src_main\temp\snd_dx\!release\snd_dx.dll "D:\Xash3D\bin\snd_dx.dll"
]
Creating command line ""C:\DOCUME~1\ÌÈØÀ\LOCALS~1\Temp\RSP5175.bat""
Compiling...
s_main.c
D:\Xash3D\src_main\snd_dx\s_main.c(592) : error C2065: 'sound_started' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(595) : error C2065: 'listener_origin' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(595) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(595) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(595) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(595) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(595) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(595) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(596) : error C2065: 'listener_forward' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(596) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(596) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(596) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(596) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(596) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(596) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(597) : error C2065: 'listener_right' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(597) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(597) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(597) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(597) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(597) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(597) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(598) : error C2065: 'listener_up' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(598) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(598) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(598) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(598) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(598) : error C2109: subscript requires array or pointer type
D:\Xash3D\src_main\snd_dx\s_main.c(598) : error C2106: '=' : left operand must be l-value
D:\Xash3D\src_main\snd_dx\s_main.c(656) : error C2231: '.value' : left operand points to 'struct', use '->'
D:\Xash3D\src_main\snd_dx\s_main.c(667) : warning C4013: 'Con_Printf' undefined; assuming extern returning int
D:\Xash3D\src_main\snd_dx\s_main.c(671) : warning C4013: 'S_Update_' undefined; assuming extern returning int
D:\Xash3D\src_main\snd_dx\s_main.c(699) : warning C4087: 'S_StopAllSounds' : declared with 'void' parameter list
D:\Xash3D\src_main\snd_dx\s_main.c(712) : warning C4013: 'IN_Accumulate' undefined; assuming extern returning int
D:\Xash3D\src_main\snd_dx\s_main.c(715) : error C2231: '.value' : left operand points to 'struct', use '->'
D:\Xash3D\src_main\snd_dx\s_main.c(721) : error C2371: 'S_Update_' : redefinition; different basic types
D:\Xash3D\src_main\snd_dx\s_main.c(739) : error C2065: '_snd_mixahead' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(739) : error C2224: left of '.value' must have struct/union type
D:\Xash3D\src_main\snd_dx\s_main.c(786) : warning C4013: 'Q_strrchr' undefined; assuming extern returning int
D:\Xash3D\src_main\snd_dx\s_main.c(788) : warning C4013: 'Q_strcpy' undefined; assuming extern returning int
D:\Xash3D\src_main\snd_dx\s_main.c(789) : warning C4013: 'Q_strcat' undefined; assuming extern returning int
D:\Xash3D\src_main\snd_dx\s_main.c(793) : warning C4013: 'S_PrecacheSound' undefined; assuming extern returning int
D:\Xash3D\src_main\snd_dx\s_main.c(793) : warning C4047: '=' : 'struct sfx_s *' differs in levels of indirection from 'int '
D:\Xash3D\src_main\snd_dx\s_main.c(794) : warning C4047: 'function' : 'const float *' differs in levels of indirection from 'int '
D:\Xash3D\src_main\snd_dx\s_main.c(794) : warning C4024: 'S_StartSound' : different types for formal and actual parameter 1
D:\Xash3D\src_main\snd_dx\s_main.c(794) : warning C4047: 'function' : 'int ' differs in levels of indirection from 'struct sfx_s *'
D:\Xash3D\src_main\snd_dx\s_main.c(794) : warning C4024: 'S_StartSound' : different types for formal and actual parameter 3
D:\Xash3D\src_main\snd_dx\s_main.c(794) : error C2198: 'S_StartSound' : too few actual parameters
D:\Xash3D\src_main\snd_dx\s_main.c(817) : warning C4047: '=' : 'struct sfx_s *' differs in levels of indirection from 'int '
D:\Xash3D\src_main\snd_dx\s_main.c(818) : warning C4013: 'Q_atof' undefined; assuming extern returning int
D:\Xash3D\src_main\snd_dx\s_main.c(819) : warning C4047: 'function' : 'const float *' differs in levels of indirection from 'int '
D:\Xash3D\src_main\snd_dx\s_main.c(819) : warning C4024: 'S_StartSound' : different types for formal and actual parameter 1
D:\Xash3D\src_main\snd_dx\s_main.c(819) : warning C4047: 'function' : 'int ' differs in levels of indirection from 'struct sfx_s *'
D:\Xash3D\src_main\snd_dx\s_main.c(819) : warning C4024: 'S_StartSound' : different types for formal and actual parameter 3
D:\Xash3D\src_main\snd_dx\s_main.c(819) : error C2198: 'S_StartSound' : too few actual parameters
D:\Xash3D\src_main\snd_dx\s_main.c(828) : error C2065: 'sfxcache_t' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(828) : error C2065: 'sc' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(828) : warning C4552: '*' : operator has no effect; expected operator with side-effect
D:\Xash3D\src_main\snd_dx\s_main.c(829) : error C2143: syntax error : missing ';' before 'type'
D:\Xash3D\src_main\snd_dx\s_main.c(831) : error C2065: 'total' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(832) : error C2065: 'known_sfx' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(832) : warning C4047: '=' : 'struct sfx_s *' differs in levels of indirection from 'int '
D:\Xash3D\src_main\snd_dx\s_main.c(832) : error C2065: 'num_sfx' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(834) : warning C4013: 'Cache_Check' undefined; assuming extern returning int
D:\Xash3D\src_main\snd_dx\s_main.c(837) : error C2065: 'size' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(837) : error C2223: left of '->length' must point to struct/union
D:\Xash3D\src_main\snd_dx\s_main.c(837) : error C2223: left of '->width' must point to struct/union
D:\Xash3D\src_main\snd_dx\s_main.c(837) : error C2223: left of '->stereo' must point to struct/union
D:\Xash3D\src_main\snd_dx\s_main.c(839) : error C2223: left of '->loopstart' must point to struct/union
D:\Xash3D\src_main\snd_dx\s_main.c(843) : error C2223: left of '->width' must point to struct/union
D:\Xash3D\src_main\snd_dx\s_main.c(853) : error C2065: 'nosound' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(853) : error C2224: left of '.value' must have struct/union type
D:\Xash3D\src_main\snd_dx\s_main.c(858) : warning C4047: '=' : 'struct sfx_s *' differs in levels of indirection from 'int '
D:\Xash3D\src_main\snd_dx\s_main.c(864) : error C2065: 'cl' : undeclared identifier
D:\Xash3D\src_main\snd_dx\s_main.c(864) : error C2224: left of '.viewentity' must have struct/union type
D:\Xash3D\src_main\snd_dx\s_main.c(864) : warning C4047: 'function' : 'const float *' differs in levels of indirection from 'const int '
D:\Xash3D\src_main\snd_dx\s_main.c(864) : warning C4024: 'S_StartSound' : different types for formal and actual parameter 1
D:\Xash3D\src_main\snd_dx\s_main.c(864) : warning C4047: 'function' : 'int ' differs in levels of indirection from 'struct sfx_s *'
D:\Xash3D\src_main\snd_dx\s_main.c(864) : warning C4024: 'S_StartSound' : different types for formal and actual parameter 2
D:\Xash3D\src_main\snd_dx\s_main.c(864) : warning C4047: 'function' : 'int ' differs in levels of indirection from 'float [3]'
D:\Xash3D\src_main\snd_dx\s_main.c(864) : warning C4024: 'S_StartSound' : different types for formal and actual parameter 3
D:\Xash3D\src_main\snd_dx\s_main.c(864) : error C2198: 'S_StartSound' : too few actual parameters
Error executing cl.exe.
<h3>Output Window</h3>
<h3>Results</h3>
snd_dx.dll - 53 error(s), 29 warning(s)
</pre>
</body>
</html>

View File

@ -1,6 +1,6 @@
//=======================================================================
// Copyright XashXT Group 2009 ©
// sound.h - client sound i/o functions
// sound.h - sndlib main header
//=======================================================================
#ifndef SOUND_H
@ -13,16 +13,11 @@
#include "vsound_api.h"
#include "entity_def.h"
extern stdlib_api_t com;
extern stdlib_api_t com;
extern vsound_imp_t si;
extern byte *sndpool;
extern byte *sndpool;
#define DEFAULT_SOUND_PACKET_VOLUME 255
#define DEFAULT_SOUND_PACKET_ATTENUATION 1.0
#define MAX_CHANNELS 128
#define MAX_DYNAMIC_CHANNELS 8
#define PAINTBUFFER_SIZE 512
#define MAX_RAW_SAMPLES 8192
#include "mathlib.h"
typedef struct
{
@ -62,19 +57,42 @@ typedef struct
byte *buffer;
} dma_t;
#include "vox.h"
typedef struct
{
double sample;
wavdata_t *pData;
double forcedEndSample;
bool m_finished;
int delaySamples;
} mixer_t;
typedef struct
{
sfx_t *sfx; // sfx number
int leftvol; // 0-255 volume
int rightvol; // 0-255 volume
int end; // end time in global paintsamples
int pos; // sample position in sfx
int looping; // where to loop, -1 = no looping
int entnum; // to allow overriding a specific sound
int entchannel; //
vec3_t origin; // origin of sound effect
vec_t dist_mult; // distance multiplier (attenuation/clipK)
int leftvol; // 0-255 left volume
int rightvol; // 0-255 right volume
int entnum; // entity soundsource
int entchannel; // sound channel (CHAN_STREAM, CHAN_VOICE, etc.)
vec3_t origin; // only use if fixed_origin is set
float dist_mult; // distance multiplier (attenuation/clipK)
int master_vol; // 0-255 master volume
bool isSentence; // bit who indicated sentence
int basePitch; // base pitch percent (100% is normal pitch playback)
float pitch; // real-time pitch after any modulation or shift by dynamic data
bool use_loop; // don't loop default and local sounds
bool staticsound; // use origin instead of fetching entnum's origin
// sentence mixer
int wordIndex;
mixer_t currentWord;
voxword_t words[CVOXWORDMAX];
} channel_t;
typedef struct
@ -93,6 +111,16 @@ typedef struct
bool paused;
} listener_t;
typedef struct
{
int rate;
int width;
int channels;
int loopstart;
int samples;
int dataofs; // chunk starts this many bytes from file start
} wavinfo_t;
typedef struct
{
string loopName;
@ -109,69 +137,83 @@ typedef struct
#define Host_Error com.error
#define Z_Malloc( size ) Mem_Alloc( sndpool, size )
void S_Shutdown( void );
void S_StopSound( int entnum, int channel, const char *soundname );
void S_StopAllSounds( void );
void S_ClearBuffer( void );
void S_ExtraUpdate( void );
void S_PaintChannels( int endtime );
void S_InitPaintChannels( void );
// picks a channel based on priorities, empty slots, number of channels
channel_t *SND_PickChannel( int entnum, int entchannel );
// spatializes a channel
void SND_Spatialize( channel_t *ch );
//
// s_backend.c
//
void S_PrintDeviceName( void );
void S_SetHWND( void *hInst );
int SNDDMA_Init( void );
int SNDDMA_GetDMAPos( void );
// initializes cycling through a DMA buffer and returns information on it
bool SNDDMA_Init( void *hInst );
int SNDDMA_GetSoundtime( void );
void SNDDMA_Shutdown( void );
void SNDDMA_BeginPainting( void );
void SNDDMA_Submit( void );
//
// s_dsp.c
//
void SX_Init( void );
void SX_Free( void );
void SX_RoomFX( int endtime, int fFilter, int fTimefx );
//====================================================================
//
// s_load.c
//
void S_SoundList_f( void );
void S_BeginRegistration( void );
sound_t S_RegisterSound( const char *sample );
sfx_t *S_GetSfxByHandle( sound_t handle );
void S_EndRegistration( void );
void S_FreeSounds( void );
#define MAX_DYNAMIC_CHANNELS 24
#define MAX_CHANNELS 128
#define MAX_RAW_SAMPLES 8192
extern portable_samplepair_t paintbuffer[];
extern channel_t channels[MAX_CHANNELS];
extern int total_channels;
extern int paintedtime;
extern int s_rawend;
extern int soundtime;
extern dma_t dma;
extern listener_t s_listener;
extern cvar_t *s_check_errors;
extern cvar_t *s_volume;
extern cvar_t *s_musicvolume;
extern cvar_t *s_khz;
extern cvar_t *s_show;
extern cvar_t *s_mixahead;
extern cvar_t *s_primary;
extern portable_samplepair_t s_rawsamples[MAX_RAW_SAMPLES];
void S_InitScaletable( void );
wavdata_t *S_LoadSound( sfx_t *sfx );
void S_PaintChannels( int endtime );
float S_GetMasterVolume( void );
void S_PrintDeviceName( void );
//
// s_main.c
//
void S_FreeChannel( channel_t *ch );
// s_load.c
bool S_TestSoundChar( const char *pch, char c );
char *S_SkipSoundChar( const char *pch );
sfx_t *S_FindName( const char *name, int *pfInCache );
// s_dsp.c
void SX_Init( void );
void SX_Free( void );
void SX_RoomFX( int endtime, int fFilter, int fTimefx );
bool S_Init( void *hInst );
void S_Shutdown( void );
void S_Activate( bool active );
void S_SoundList_f( void );
void S_SoundInfo_f( void );
// if origin is NULL, the sound will be dynamically sourced from the entity
void S_StartSound( const vec3_t pos, int ent, int chan, sound_t sfx, float vol, float attn, int pitch, int flags );
void S_StaticSound( const vec3_t pos, int ent, int chan, sound_t handle, float fvol, float attn, int pitch, int flags );
channel_t *SND_PickDynamicChannel( int entnum, int channel, sfx_t *sfx );
channel_t *SND_PickStaticChannel( int entnum, sfx_t *sfx );
void S_FadeClientVolume( float fadePercent, float fadeOutSeconds, float holdTime, float fadeInSeconds );
int S_StartLocalSound( const char *name, float volume, int pitch, const float *org );
void S_StartSound( const vec3_t pos, int ent, int chan, sound_t sfx, float fvol, float attn, int pitch, int flags );
void S_StaticSound( const vec3_t pos, int ent, int chan, sound_t sfx, float fvol, float attn, int pitch, int flags );
void S_SoundFrame( ref_params_t *fd );
float S_GetMasterVolume( void );
//
// s_mix.c
//
void SND_InitScaletable( void );
sfx_t *S_GetSfxByHandle( sound_t handle );
void S_StopSound( int entnum, int channel, const char *soundname );
void S_RenderFrame( ref_params_t *fd );
void S_StopAllSounds( void );
void S_FreeSounds( void );
//
// s_mouth.c
//
void SND_InitMouth( int entnum, int entchannel );
void SND_MoveMouth8( channel_t *ch, wavdata_t *pSource, int count );
void SND_CloseMouth( channel_t *ch );
//
@ -184,43 +226,25 @@ void S_StartBackgroundTrack( const char *intro, const char *loop );
void S_StreamBackgroundTrack( void );
void S_StopBackgroundTrack( void );
// ====================================================================
// User-setable variables
// ====================================================================
//
// s_utils.c
//
int S_ZeroCrossingAfter( wavdata_t *pWaveData, int sample );
int S_ZeroCrossingBefore( wavdata_t *pWaveData, int sample );
int S_GetOutputData( wavdata_t *pSource, void **pData, int samplePosition, int sampleCount );
// 0 to MAX_DYNAMIC_CHANNELS-1 = normal entity sounds
// MAX_DYNAMIC_CHANNELS to MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS -1 = water, etc
// MAX_DYNAMIC_CHANNELS + NUM_AMBIENTS to total_channels = static sounds
//
// s_vox.c
//
void VOX_Init( void );
void VOX_Shutdown( void );
void VOX_SetChanVol( channel_t *ch );
void VOX_LoadSound( channel_t *pchan, const char *psz );
void VOX_LoadNextWord( channel_t *pchan );
extern listener_t listener;
extern portable_samplepair_t paintbuffer[PAINTBUFFER_SIZE];
extern portable_samplepair_t rawsamples[MAX_RAW_SAMPLES];
extern channel_t channels[MAX_CHANNELS];
extern int total_channels;
// Fake dma is a synchronous faking of the DMA progress used for
// isolating performance in the renderer. The fakedma_updates is
// number of times S_Update() is called per second.
extern bool fakedma;
extern int fakedma_updates;
extern int paintedtime;
extern int soundtime;
extern int rawend;
extern dma_t dma;
extern float sound_nominal_clip_dist;
extern cvar_t *musicvolume;
extern cvar_t *volume;
extern bool snd_initialized;
extern int snd_blocked;
wavdata_t *S_LoadSound( sfx_t *s );
void SNDDMA_Submit( void );
void S_AmbientOff( void );
void S_AmbientOn( void );
void S_BeginRegistration( void );
sound_t S_RegisterSound( const char *sample );
void S_EndRegistration( void );
#endif//SOUND_H

37
snd_dx/vox.h Normal file
View File

@ -0,0 +1,37 @@
//=======================================================================
// Copyright XashXT Group 2010 ©
// vox.h - sentences vox private header
//=======================================================================
#ifndef VOX_H
#define VOX_H
#define CVOXWORDMAX 32
#define CVOXSENTENCEMAX 24
#define CVOXZEROSCANMAX 255 // scan up to this many samples for next zero crossing
#define MAX_SENTENCES 2048
#define SENTENCE_INDEX -99999 // unique sentence index
typedef struct voxword_s
{
int volume; // increase percent, ie: 125 = 125% increase
int pitch; // pitch shift up percent
int start; // offset start of wave percent
int end; // offset end of wave percent
int cbtrim; // end of wave after being trimmed to 'end'
int fKeepCached; // 1 if this word was already in cache before sentence referenced it
int samplefrac; // if pitch shifting, this is position into wav * 256
int timecompress; // % of wave to skip during playback (causes no pitch shift)
sfx_t *sfx; // name and cache pointer
} voxword_t;
typedef struct
{
char *pName;
float length;
} sentence_t;
extern sentence_t g_Sentences[MAX_SENTENCES];
#endif

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: spirit - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
server.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -1644,7 +1644,7 @@ void R_ModifyColor( const ref_stage_t *pass )
VectorCopy( triState.lightingOrigin, lightingOrigin );
else VectorClear( lightingOrigin ); // FIXME: MB_POLY
if( RI.currententity->flags & EF_FULLBRIGHT || !r_worldbrushmodel->lightdata )
if( RI.currententity->flags & EF_FULLBRIGHT || r_fullbright->integer || !r_worldbrushmodel->lightdata )
VectorSet( ambient, 1.0f, 1.0f, 1.0f );
else R_LightForPoint( lightingOrigin, ambient );

View File

@ -244,11 +244,11 @@ void R_InitVertexBuffers( void )
{
int i;
tr.vertexBuffer = R_AllocVertexBuffer( MAX_ARRAY_VERTS * sizeof( vec4_t ), GL_STREAM_DRAW_ARB );
tr.colorsBuffer = R_AllocVertexBuffer( MAX_ARRAY_VERTS * sizeof( rgba_t ), GL_STREAM_DRAW_ARB );
tr.normalBuffer = R_AllocVertexBuffer( MAX_ARRAY_VERTS * sizeof( vec4_t ), GL_STREAM_DRAW_ARB );
tr.vertexBuffer = R_AllocVertexBuffer( MAX_ARRAY_VERTS * sizeof( vec4_t ), GL_DYNAMIC_DRAW_ARB );
tr.colorsBuffer = R_AllocVertexBuffer( MAX_ARRAY_VERTS * sizeof( rgba_t ), GL_DYNAMIC_DRAW_ARB );
tr.normalBuffer = R_AllocVertexBuffer( MAX_ARRAY_VERTS * sizeof( vec4_t ), GL_DYNAMIC_DRAW_ARB );
for( i = 0; i < MAX_TEXTURE_UNITS; i++ )
tr.tcoordBuffer[i] = R_AllocVertexBuffer( MAX_ARRAY_VERTS * sizeof( vec4_t ), GL_STREAM_DRAW_ARB );
tr.tcoordBuffer[i] = R_AllocVertexBuffer( MAX_ARRAY_VERTS * sizeof( vec4_t ), GL_DYNAMIC_DRAW_ARB );
}
/*

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: vid_gl - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
vid_gl.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>

View File

@ -1,16 +0,0 @@
<html>
<body>
<pre>
<h1>Build Log</h1>
<h3>
--------------------Configuration: xtools - Win32 Release--------------------
</h3>
<h3>Command Lines</h3>
<h3>Results</h3>
xtools.dll - 0 error(s), 0 warning(s)
</pre>
</body>
</html>