28 Jun 2010
This commit is contained in:
parent
cbc81f7861
commit
e048dd6518
|
@ -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>
|
|
@ -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>
|
|
@ -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>
|
|
@ -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 )
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
};
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
|
@ -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;
|
||||
return false;
|
||||
}
|
||||
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;
|
||||
}
|
||||
else
|
||||
{
|
||||
if( trace.fAllSolid )
|
||||
return -1;
|
||||
|
||||
if( trace.flFraction == 1.0f )
|
||||
return 0;
|
||||
|
||||
VectorCopy( trace.vecEndPos, e->v.origin );
|
||||
SV_LinkEdict( e, true );
|
||||
SV_LinkEdict( e, false );
|
||||
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;
|
||||
|
||||
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 );
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
|
@ -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!)
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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>
|
|
@ -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 );
|
||||
|
|
|
@ -303,7 +303,6 @@ S_SpatializeChannel
|
|||
static void S_SpatializeChannel( channel_t *ch )
|
||||
{
|
||||
vec3_t position, velocity;
|
||||
soundinfo_t SndInfo;
|
||||
|
||||
// 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" );
|
||||
|
|
|
@ -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>
|
|
@ -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
|
||||
|
|
|
@ -29,116 +29,244 @@ typedef enum
|
|||
SIS_SUCCESS,
|
||||
SIS_FAILURE,
|
||||
SIS_NOTAVAIL
|
||||
} sndinitstat;
|
||||
} si_state_t;
|
||||
|
||||
cvar_t *s_wavonly;
|
||||
|
||||
static HWND snd_hwnd;
|
||||
static bool dsound_init;
|
||||
static bool wav_init;
|
||||
static bool snd_firsttime = true, snd_isdirect, snd_iswave;
|
||||
static bool snd_firsttime = true;
|
||||
static bool snd_isdirect, snd_iswave;
|
||||
static bool primary_format_set;
|
||||
static HWND snd_hwnd;
|
||||
static int sample16;
|
||||
static int snd_buffer_count = 0;
|
||||
static int snd_sent, snd_completed;
|
||||
|
||||
static int sample16;
|
||||
|
||||
/*
|
||||
Global variables. Must be visible to window-procedure function
|
||||
so it can unlock and free the data block after it has been played.
|
||||
=======================================================================
|
||||
Global variables. Must be visible to window-procedure function
|
||||
so it can unlock and free the data block after it has been played.
|
||||
=======================================================================
|
||||
*/
|
||||
|
||||
DWORD locksize;
|
||||
HANDLE hData;
|
||||
HPSTR lpData, lpData2;
|
||||
|
||||
HGLOBAL hWaveHdr;
|
||||
LPWAVEHDR lpWaveHdr;
|
||||
HWAVEOUT hWaveOut;
|
||||
WAVEOUTCAPS wavecaps;
|
||||
|
||||
DWORD gSndBufSize;
|
||||
MMTIME mmstarttime;
|
||||
|
||||
LPDIRECTSOUND pDS;
|
||||
LPDIRECTSOUNDBUFFER pDSBuf, pDSPBuf;
|
||||
HINSTANCE hInstDS;
|
||||
LPDIRECTSOUND pDS;
|
||||
|
||||
bool SNDDMA_InitDirect( void );
|
||||
bool SNDDMA_InitDirect( void *hInst );
|
||||
bool SNDDMA_InitWav( void );
|
||||
void SNDDMA_FreeSound( void );
|
||||
|
||||
/*
|
||||
===========
|
||||
S_PrintDeviceName
|
||||
===========
|
||||
*/
|
||||
void S_PrintDeviceName( void )
|
||||
static const char *DSoundError( int error )
|
||||
{
|
||||
if( snd_isdirect ) Msg( "Audio: DirectSound\n" );
|
||||
if( snd_iswave ) Msg( "Audio: WaveOutput\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
S_SetHWND
|
||||
|
||||
cl_hwnd pointer come from engine
|
||||
===========
|
||||
*/
|
||||
void S_SetHWND( void *hInst )
|
||||
{
|
||||
snd_hwnd = (HWND)hInst;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
S_BlockSound
|
||||
==================
|
||||
*/
|
||||
void S_BlockSound( void )
|
||||
{
|
||||
// DirectSound takes care of blocking itself
|
||||
if( snd_iswave )
|
||||
switch( error )
|
||||
{
|
||||
snd_blocked++;
|
||||
|
||||
if( snd_blocked == 1 )
|
||||
waveOutReset( hWaveOut );
|
||||
case DSERR_BUFFERLOST:
|
||||
return "DSERR_BUFFERLOST";
|
||||
case DSERR_INVALIDCALL:
|
||||
return "DSERR_INVALIDCALLS";
|
||||
case DSERR_INVALIDPARAM:
|
||||
return "DSERR_INVALIDPARAM";
|
||||
case DSERR_PRIOLEVELNEEDED:
|
||||
return "DSERR_PRIOLEVELNEEDED";
|
||||
}
|
||||
return "Unknown Error";
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
S_UnblockSound
|
||||
DS_CreateBuffers
|
||||
==================
|
||||
*/
|
||||
void S_UnblockSound( void )
|
||||
static bool DS_CreateBuffers( void *hInst )
|
||||
{
|
||||
// DirectSound takes care of blocking itself
|
||||
if( snd_iswave )
|
||||
DSBUFFERDESC dsbuf;
|
||||
DSBCAPS dsbcaps;
|
||||
WAVEFORMATEX pformat, format;
|
||||
|
||||
Mem_Set( &format, 0, sizeof( format ));
|
||||
|
||||
format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
format.nChannels = dma.channels;
|
||||
format.wBitsPerSample = dma.samplebits;
|
||||
format.nSamplesPerSec = dma.speed;
|
||||
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
|
||||
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
|
||||
format.cbSize = 0;
|
||||
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: initialize\n" );
|
||||
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: setting EXCLUSIVE coop level " );
|
||||
if( DS_OK != pDS->lpVtbl->SetCooperativeLevel( pDS, hInst, DSSCL_EXCLUSIVE ))
|
||||
{
|
||||
snd_blocked--;
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
|
||||
/*
|
||||
===========
|
||||
S_Activate
|
||||
// get access to the primary buffer, if possible, so we can set the sound hardware format
|
||||
Mem_Set( &dsbuf, 0, sizeof( dsbuf ));
|
||||
dsbuf.dwSize = sizeof( DSBUFFERDESC );
|
||||
dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
dsbuf.dwBufferBytes = 0;
|
||||
dsbuf.lpwfxFormat = NULL;
|
||||
|
||||
Called when the main window gains or loses focus.
|
||||
The window have been destroyed and recreated
|
||||
between a deactivate and an activate.
|
||||
===========
|
||||
*/
|
||||
void S_Activate( bool active )
|
||||
{
|
||||
if( active )
|
||||
Mem_Set( &dsbcaps, 0, sizeof( dsbcaps ));
|
||||
dsbcaps.dwSize = sizeof( dsbcaps );
|
||||
primary_format_set = false;
|
||||
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: creating primary buffer " );
|
||||
if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSPBuf, NULL ) == DS_OK )
|
||||
{
|
||||
pformat = format;
|
||||
|
||||
S_AmbientOn();
|
||||
S_UnblockSound();
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: setting primary sound format " );
|
||||
|
||||
if( pDSPBuf->lpVtbl->SetFormat( pDSPBuf, &pformat ) != DS_OK )
|
||||
{
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
S_BlockSound();
|
||||
S_AmbientOff();
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
primary_format_set = true;
|
||||
}
|
||||
}
|
||||
else MsgDev( D_NOTE, "- failed\n" );
|
||||
|
||||
if( !primary_format_set || !s_primary->integer )
|
||||
{
|
||||
// create the secondary buffer we'll actually work with
|
||||
Mem_Set( &dsbuf, 0, sizeof( dsbuf ));
|
||||
dsbuf.dwSize = sizeof( DSBUFFERDESC );
|
||||
dsbuf.dwFlags = (DSBCAPS_CTRLFREQUENCY|DSBCAPS_LOCSOFTWARE);
|
||||
dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
|
||||
dsbuf.lpwfxFormat = &format;
|
||||
|
||||
Mem_Set( &dsbcaps, 0, sizeof( dsbcaps ));
|
||||
dsbcaps.dwSize = sizeof( dsbcaps );
|
||||
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: creating secondary buffer " );
|
||||
if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSBuf, NULL ) == DS_OK )
|
||||
{
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
// couldn't get hardware, fallback to software.
|
||||
dsbuf.dwFlags = (DSBCAPS_LOCSOFTWARE|DSBCAPS_GETCURRENTPOSITION2);
|
||||
if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSBuf, NULL ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
MsgDev( D_INFO, "- failed. forced to software\n" );
|
||||
}
|
||||
|
||||
dma.channels = format.nChannels;
|
||||
dma.samplebits = format.wBitsPerSample;
|
||||
dma.speed = format.nSamplesPerSec;
|
||||
|
||||
if( pDSBuf->lpVtbl->GetCaps( pDSBuf, &dsbcaps ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "DS_CreateBuffers: GetCaps failed\n");
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: using secondary sound buffer\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: using primary sound buffer\n" );
|
||||
MsgDev( D_NOTE, "DS_CreateBuffers: setting WRITEPRIMARY coop level " );
|
||||
if( pDS->lpVtbl->SetCooperativeLevel( pDS, hInst, DSSCL_WRITEPRIMARY ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
|
||||
if( pDSPBuf->lpVtbl->GetCaps( pDSPBuf, &dsbcaps ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "DS_CreateBuffers: GetCaps failed\n");
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
pDSBuf = pDSPBuf;
|
||||
}
|
||||
|
||||
// make sure mixer is active
|
||||
if( pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "DS_CreateBuffers: looped sound play failed\n" );
|
||||
SNDDMA_FreeSound ();
|
||||
return false;
|
||||
}
|
||||
|
||||
// we don't want anyone to access the buffer directly w/o locking it first
|
||||
lpData = NULL;
|
||||
dma.samplepos = 0;
|
||||
snd_hwnd = (HWND)hInst;
|
||||
gSndBufSize = dsbcaps.dwBufferBytes;
|
||||
dma.samples = gSndBufSize / (dma.samplebits / 8 );
|
||||
dma.submission_chunk = 1;
|
||||
dma.buffer = (byte *)lpData;
|
||||
sample16 = (dma.samplebits / 8) - 1;
|
||||
|
||||
SNDDMA_BeginPainting();
|
||||
if( dma.buffer ) Mem_Set( dma.buffer, 0, dma.samples * dma.samplebits / 8 );
|
||||
SNDDMA_Submit();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
DS_DestroyBuffers
|
||||
==================
|
||||
*/
|
||||
static void DS_DestroyBuffers( void )
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_DestroyBuffers: shutdown\n" );
|
||||
|
||||
if( pDS )
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_DestroyBuffers: setting NORMAL coop level\n" );
|
||||
pDS->lpVtbl->SetCooperativeLevel( pDS, snd_hwnd, DSSCL_NORMAL );
|
||||
}
|
||||
|
||||
if( pDSBuf )
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_DestroyBuffers: stopping and releasing sound buffer\n" );
|
||||
pDSBuf->lpVtbl->Stop( pDSBuf );
|
||||
pDSBuf->lpVtbl->Release( pDSBuf );
|
||||
}
|
||||
|
||||
// only release primary buffer if it's not also the mixing buffer we just released
|
||||
if( pDSPBuf && ( pDSBuf != pDSPBuf ))
|
||||
{
|
||||
MsgDev( D_NOTE, "DS_DestroyBuffers: releasing primary buffer\n" );
|
||||
pDSPBuf->lpVtbl->Release( pDSPBuf );
|
||||
}
|
||||
|
||||
pDSBuf = NULL;
|
||||
pDSPBuf = NULL;
|
||||
dma.buffer = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -150,22 +278,11 @@ void SNDDMA_FreeSound( void )
|
|||
{
|
||||
int i;
|
||||
|
||||
if( pDSBuf )
|
||||
if( pDS )
|
||||
{
|
||||
pDSBuf->lpVtbl->Stop( pDSBuf );
|
||||
pDSBuf->lpVtbl->Release( pDSBuf );
|
||||
}
|
||||
|
||||
// only release primary buffer if it's not also the mixing buffer we just released
|
||||
if( pDSPBuf && ( pDSBuf != pDSPBuf ))
|
||||
{
|
||||
pDSPBuf->lpVtbl->Release( pDSPBuf );
|
||||
}
|
||||
|
||||
if( pDS && snd_hwnd )
|
||||
{
|
||||
pDS->lpVtbl->SetCooperativeLevel( pDS, snd_hwnd, DSSCL_NORMAL );
|
||||
DS_DestroyBuffers();
|
||||
pDS->lpVtbl->Release( pDS );
|
||||
Sys_FreeLibrary( &dsound_dll );
|
||||
}
|
||||
|
||||
if( hWaveOut )
|
||||
|
@ -175,7 +292,7 @@ void SNDDMA_FreeSound( void )
|
|||
if( lpWaveHdr )
|
||||
{
|
||||
for( i = 0; i < WAV_BUFFERS; i++ )
|
||||
waveOutUnprepareHeader( hWaveOut, lpWaveHdr+i, sizeof( WAVEHDR ));
|
||||
waveOutUnprepareHeader( hWaveOut, lpWaveHdr + i, sizeof( WAVEHDR ));
|
||||
}
|
||||
|
||||
waveOutClose( hWaveOut );
|
||||
|
@ -213,59 +330,51 @@ SNDDMA_InitDirect
|
|||
Direct-Sound support
|
||||
==================
|
||||
*/
|
||||
sndinitstat SNDDMA_InitDirect( void )
|
||||
si_state_t SNDDMA_InitDirect( void *hInst )
|
||||
{
|
||||
DSBUFFERDESC dsbuf;
|
||||
DSBCAPS dsbcaps;
|
||||
DWORD dwSize, dwWrite;
|
||||
DSCAPS dscaps;
|
||||
WAVEFORMATEX format, pformat;
|
||||
HRESULT hresult;
|
||||
int reps;
|
||||
|
||||
Mem_Set( &dma, 0, sizeof( dma ));
|
||||
|
||||
dma.channels = 2;
|
||||
dma.samplebits = 16;
|
||||
dma.speed = 22050;
|
||||
|
||||
Mem_Set( &format, 0, sizeof( format ));
|
||||
switch( s_khz->integer )
|
||||
{
|
||||
case 44: dma.speed = 44100; break;
|
||||
case 22: dma.speed = 22050; break;
|
||||
default: dma.speed = 11025; break;
|
||||
}
|
||||
|
||||
format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
format.nChannels = dma.channels;
|
||||
format.wBitsPerSample = dma.samplebits;
|
||||
format.nSamplesPerSec = dma.speed;
|
||||
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
|
||||
format.cbSize = 0;
|
||||
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
|
||||
MsgDev( D_NOTE, "SNDDMA_InitDirect: initializing DirectSound ");
|
||||
|
||||
if( !dsound_dll.link )
|
||||
{
|
||||
if( !Sys_LoadLibrary( NULL, &dsound_dll ))
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: couldn't load dsound.dll\n" );
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
}
|
||||
|
||||
while(( hresult = iDirectSoundCreate( NULL, &pDS, NULL )) != DS_OK )
|
||||
MsgDev( D_NOTE, "SNDDMA_InitDirect: creating DS object " );
|
||||
if(( hresult = iDirectSoundCreate( NULL, &pDS, NULL )) != DS_OK )
|
||||
{
|
||||
if( hresult != DSERR_ALLOCATED )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: DirectSound create failed\n" );
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: hardware already in use\n" );
|
||||
MsgDev( D_NOTE, "- failed, hardware already in use\n" );
|
||||
return SIS_NOTAVAIL;
|
||||
}
|
||||
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
dscaps.dwSize = sizeof( dscaps );
|
||||
|
||||
if( DS_OK != pDS->lpVtbl->GetCaps( pDS, &dscaps ))
|
||||
{
|
||||
if( pDS->lpVtbl->GetCaps( pDS, &dscaps ) != DS_OK )
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: GetCaps failed\n");
|
||||
}
|
||||
|
||||
if( dscaps.dwFlags & DSCAPS_EMULDRIVER )
|
||||
{
|
||||
|
@ -274,139 +383,8 @@ sndinitstat SNDDMA_InitDirect( void )
|
|||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
if( pDS->lpVtbl->SetCooperativeLevel( pDS, snd_hwnd, DSSCL_EXCLUSIVE ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: set coop level failed\n" );
|
||||
SNDDMA_FreeSound();
|
||||
if( !DS_CreateBuffers( hInst ))
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
// get access to the primary buffer, if possible, so we can set the
|
||||
// sound hardware format
|
||||
Mem_Set( &dsbuf, 0, sizeof( dsbuf ));
|
||||
dsbuf.dwSize = sizeof( DSBUFFERDESC );
|
||||
dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
|
||||
dsbuf.dwBufferBytes = 0;
|
||||
dsbuf.lpwfxFormat = NULL;
|
||||
|
||||
Mem_Set( &dsbcaps, 0, sizeof( dsbcaps ));
|
||||
dsbcaps.dwSize = sizeof( dsbcaps );
|
||||
primary_format_set = false;
|
||||
|
||||
if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSPBuf, NULL ) == DS_OK )
|
||||
{
|
||||
pformat = format;
|
||||
|
||||
if( pDSPBuf->lpVtbl->SetFormat( pDSPBuf, &pformat ) != DS_OK )
|
||||
{
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_INFO, "Set primary sound buffer format: no\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_INFO, "Set primary sound buffer format: yes\n" );
|
||||
primary_format_set = true;
|
||||
}
|
||||
}
|
||||
|
||||
if( !primary_format_set )
|
||||
{
|
||||
// create the secondary buffer we'll actually work with
|
||||
Mem_Set( &dsbuf, 0, sizeof( dsbuf ));
|
||||
dsbuf.dwSize = sizeof( DSBUFFERDESC );
|
||||
dsbuf.dwFlags = (DSBCAPS_CTRLFREQUENCY|DSBCAPS_LOCSOFTWARE);
|
||||
dsbuf.dwBufferBytes = SECONDARY_BUFFER_SIZE;
|
||||
dsbuf.lpwfxFormat = &format;
|
||||
|
||||
Mem_Set( &dsbcaps, 0, sizeof( dsbcaps ));
|
||||
dsbcaps.dwSize = sizeof(dsbcaps);
|
||||
|
||||
if( pDS->lpVtbl->CreateSoundBuffer( pDS, &dsbuf, &pDSBuf, NULL ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: DS->CreateSoundBuffer failed\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
dma.channels = format.nChannels;
|
||||
dma.samplebits = format.wBitsPerSample;
|
||||
dma.speed = format.nSamplesPerSec;
|
||||
|
||||
if( pDSBuf->lpVtbl->GetCaps( pDSBuf, &dsbcaps ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: DS->GetCaps failed\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_INFO, "Using secondary sound buffer\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pDS->lpVtbl->SetCooperativeLevel( pDS, snd_hwnd, DSSCL_WRITEPRIMARY ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: DS->SetCooperativeLevel failed\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
if( pDSPBuf->lpVtbl->GetCaps (pDSPBuf, &dsbcaps ) != DS_OK )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: DS->GetCaps failed\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
pDSBuf = pDSPBuf;
|
||||
MsgDev( D_INFO, "Using primary sound buffer\n" );
|
||||
}
|
||||
|
||||
// make sure mixer is active
|
||||
pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING );
|
||||
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_INFO, " %d channel(s)\n"" %d bits/sample\n"" %d bytes/sec\n", dma.channels, dma.samplebits, dma.speed );
|
||||
|
||||
gSndBufSize = dsbcaps.dwBufferBytes;
|
||||
|
||||
// initialize the buffer
|
||||
reps = 0;
|
||||
|
||||
while(( hresult = pDSBuf->lpVtbl->Lock( pDSBuf, 0, gSndBufSize, &lpData, &dwSize, NULL, NULL, 0 )) != DS_OK )
|
||||
{
|
||||
if( hresult != DSERR_BUFFERLOST )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: DS->Lock failed\n");
|
||||
SNDDMA_FreeSound();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
if( ++reps > 10000 )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitDirect: couldn't restore buffer\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Mem_Set( lpData, 0, dwSize );
|
||||
pDSBuf->lpVtbl->Unlock( pDSBuf, lpData, dwSize, NULL, 0 );
|
||||
|
||||
// we don't want anyone to access the buffer directly w/o locking it first.
|
||||
lpData = NULL;
|
||||
|
||||
pDSBuf->lpVtbl->Stop( pDSBuf );
|
||||
pDSBuf->lpVtbl->GetCurrentPosition( pDSBuf, &mmstarttime.u.sample, &dwWrite );
|
||||
pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING );
|
||||
|
||||
dma.samples = gSndBufSize / (dma.samplebits / 8);
|
||||
dma.samplepos = 0;
|
||||
dma.submission_chunk = 1;
|
||||
dma.buffer = (byte *)lpData;
|
||||
sample16 = (dma.samplebits / 8) - 1;
|
||||
|
||||
dsound_init = true;
|
||||
|
||||
|
@ -421,7 +399,7 @@ SNDDM_InitWav
|
|||
Crappy windows multimedia base
|
||||
==================
|
||||
*/
|
||||
bool SNDDMA_InitWav( void )
|
||||
si_state_t SNDDMA_InitWav( void )
|
||||
{
|
||||
WAVEFORMATEX format;
|
||||
HRESULT hr;
|
||||
|
@ -430,11 +408,15 @@ bool SNDDMA_InitWav( void )
|
|||
snd_sent = 0;
|
||||
snd_completed = 0;
|
||||
|
||||
Mem_Set( &dma, 0, sizeof( dma ));
|
||||
|
||||
dma.channels = 2;
|
||||
dma.samplebits = 16;
|
||||
dma.speed = 22050;
|
||||
|
||||
switch( s_khz->integer )
|
||||
{
|
||||
case 44: dma.speed = 44100; break;
|
||||
case 22: dma.speed = 22050; break;
|
||||
default: dma.speed = 11025; break;
|
||||
}
|
||||
|
||||
Mem_Set( &format, 0, sizeof( format ));
|
||||
format.wFormatTag = WAVE_FORMAT_PCM;
|
||||
|
@ -442,42 +424,42 @@ bool SNDDMA_InitWav( void )
|
|||
format.wBitsPerSample = dma.samplebits;
|
||||
format.nSamplesPerSec = dma.speed;
|
||||
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
|
||||
format.cbSize = 0;
|
||||
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
|
||||
format.cbSize = 0;
|
||||
|
||||
// open a waveform device for output using window callback
|
||||
while(( hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, &format, 0, 0L, CALLBACK_NULL )) != MMSYSERR_NOERROR )
|
||||
// open a waveform device for output using window callback.
|
||||
MsgDev( D_NOTE, "SNDDMA_InitWav: initializing wave sound " );
|
||||
if(( hr = waveOutOpen((LPHWAVEOUT)&hWaveOut, WAVE_MAPPER, &format, 0, 0, CALLBACK_NULL)) != MMSYSERR_NOERROR )
|
||||
{
|
||||
if( hr != MMSYSERR_ALLOCATED )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitWav: waveOutOpen failed\n" );
|
||||
return false;
|
||||
MsgDev( D_NOTE, "- failed\n" );
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
MsgDev( D_ERROR, "SNDDMA_InitWav: hardware already in use\n" );
|
||||
MsgDev( D_NOTE, "- failed, hardware already in use\n" );
|
||||
return SIS_NOTAVAIL;
|
||||
}
|
||||
|
||||
// Allocate and lock memory for the waveform data. The memory
|
||||
MsgDev( D_NOTE, "- ok\n" );
|
||||
|
||||
// allocate and lock memory for the waveform data. The memory
|
||||
// for waveform data must be globally allocated with
|
||||
// GMEM_MOVEABLE and GMEM_SHARE flags.
|
||||
|
||||
gSndBufSize = WAV_BUFFERS * WAV_BUFFER_SIZE;
|
||||
hData = GlobalAlloc( GMEM_MOVEABLE|GMEM_SHARE, gSndBufSize );
|
||||
|
||||
if( !hData )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitWav: Out of memory.\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return false;
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
lpData = GlobalLock( hData );
|
||||
if( !lpData )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitWav: failed to lock.\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return false;
|
||||
SNDDMA_FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
Mem_Set( lpData, 0, gSndBufSize );
|
||||
|
@ -489,18 +471,16 @@ bool SNDDMA_InitWav( void )
|
|||
|
||||
if( hWaveHdr == NULL )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitWav: failed to alloc header.\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return false;
|
||||
SNDDMA_FreeSound ();
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
lpWaveHdr = (LPWAVEHDR) GlobalLock( hWaveHdr );
|
||||
lpWaveHdr = (LPWAVEHDR)GlobalLock( hWaveHdr );
|
||||
|
||||
if( lpWaveHdr == NULL )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitWav: failed to lock header.\n");
|
||||
SNDDMA_FreeSound();
|
||||
return false;
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
|
||||
Mem_Set( lpWaveHdr, 0, sizeof( WAVEHDR ) * WAV_BUFFERS );
|
||||
|
@ -511,23 +491,21 @@ bool SNDDMA_InitWav( void )
|
|||
lpWaveHdr[i].dwBufferLength = WAV_BUFFER_SIZE;
|
||||
lpWaveHdr[i].lpData = lpData + i * WAV_BUFFER_SIZE;
|
||||
|
||||
if( waveOutPrepareHeader( hWaveOut, lpWaveHdr + i, sizeof( WAVEHDR )) != MMSYSERR_NOERROR )
|
||||
if( waveOutPrepareHeader( hWaveOut, lpWaveHdr+i, sizeof( WAVEHDR )) != MMSYSERR_NOERROR )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_InitWav: failed to prepare wave headers\n" );
|
||||
SNDDMA_FreeSound();
|
||||
return false;
|
||||
return SIS_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
dma.samples = gSndBufSize / (dma.samplebits / 8);
|
||||
dma.samplepos = 0;
|
||||
dma.submission_chunk = 1;
|
||||
dma.samples = gSndBufSize / ( dma.samplebits / 8 );
|
||||
dma.submission_chunk = 512;
|
||||
dma.buffer = (byte *)lpData;
|
||||
sample16 = (dma.samplebits / 8) - 1;
|
||||
|
||||
wav_init = true;
|
||||
|
||||
return true;
|
||||
return SIS_SUCCESS;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -538,58 +516,64 @@ Try to find a sound device to mix for.
|
|||
Returns false if nothing is found.
|
||||
==================
|
||||
*/
|
||||
|
||||
int SNDDMA_Init( void )
|
||||
int SNDDMA_Init( void *hInst )
|
||||
{
|
||||
sndinitstat stat;
|
||||
si_state_t stat = SIS_FAILURE; // assume DirectSound won't initialize
|
||||
|
||||
// assume DirectSound won't initialize
|
||||
stat = SIS_FAILURE;
|
||||
Mem_Set( &dma, 0, sizeof( dma ));
|
||||
|
||||
s_wavonly = Cvar_Get( "s_wavonly", "0", CVAR_LATCH_AUDIO|CVAR_ARCHIVE, "force to use WaveOutput only" );
|
||||
dsound_init = wav_init = 0;
|
||||
|
||||
// Init DirectSound
|
||||
// init DirectSound
|
||||
if( !s_wavonly->integer )
|
||||
{
|
||||
if( snd_firsttime || snd_isdirect )
|
||||
{
|
||||
stat = SNDDMA_InitDirect();
|
||||
stat = SNDDMA_InitDirect( hInst );
|
||||
|
||||
if( stat == SIS_SUCCESS )
|
||||
{
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_INFO, "DirectSound initialized\n" );
|
||||
snd_isdirect = true;
|
||||
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_INFO, "Audio: DirectSound\n" );
|
||||
}
|
||||
else snd_isdirect = false;
|
||||
}
|
||||
}
|
||||
|
||||
// if DirectSound didn't succeed in initializing, try to initialize
|
||||
// waveOut sound, unless DirectSound failed because the hardware is
|
||||
// already allocated (in which case the user has already chosen not
|
||||
// to have sound )
|
||||
|
||||
// to have sound)
|
||||
if( !dsound_init && ( stat != SIS_NOTAVAIL ))
|
||||
{
|
||||
if( snd_firsttime || snd_iswave )
|
||||
{
|
||||
snd_iswave = SNDDMA_InitWav();
|
||||
stat = SNDDMA_InitWav();
|
||||
|
||||
if( snd_iswave )
|
||||
if( stat == SIS_SUCCESS )
|
||||
{
|
||||
snd_iswave = true;
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_INFO, "Wave sound initialized\n" );
|
||||
}
|
||||
MsgDev( D_INFO, "Audio: WaveOutput\n" );
|
||||
}
|
||||
else snd_iswave = false;
|
||||
}
|
||||
}
|
||||
|
||||
snd_buffer_count = 1;
|
||||
|
||||
if( !dsound_init && !wav_init )
|
||||
{
|
||||
if( snd_firsttime )
|
||||
MsgDev( D_NOTE, "No sound device initialized\n" );
|
||||
snd_firsttime = false;
|
||||
return 0;
|
||||
MsgDev( D_ERROR, "SNDDMA_Init: can't initialize sound device\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
snd_firsttime = false;
|
||||
return 1;
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -603,12 +587,13 @@ how many sample are required to fill it up.
|
|||
*/
|
||||
int SNDDMA_GetDMAPos( void )
|
||||
{
|
||||
MMTIME mmtime;
|
||||
DWORD dwWrite;
|
||||
int s;
|
||||
|
||||
if( dsound_init )
|
||||
{
|
||||
MMTIME mmtime;
|
||||
DWORD dwWrite;
|
||||
|
||||
mmtime.wType = TIME_SAMPLES;
|
||||
pDSBuf->lpVtbl->GetCurrentPosition( pDSBuf, &mmtime.u.sample, &dwWrite );
|
||||
s = mmtime.u.sample - mmstarttime.u.sample;
|
||||
|
@ -620,16 +605,99 @@ int SNDDMA_GetDMAPos( void )
|
|||
|
||||
|
||||
s >>= sample16;
|
||||
s &= ( dma.samples - 1 );
|
||||
s &= (dma.samples - 1);
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_GetSoundtime
|
||||
|
||||
update global soundtime
|
||||
===============
|
||||
*/
|
||||
int SNDDMA_GetSoundtime( void )
|
||||
{
|
||||
static int buffers, oldsamplepos;
|
||||
int samplepos, fullsamples;
|
||||
|
||||
fullsamples = dma.samples / dma.channels;
|
||||
|
||||
// it is possible to miscount buffers
|
||||
// if it has wrapped twice between
|
||||
// calls to S_Update. Oh well.
|
||||
samplepos = SNDDMA_GetDMAPos();
|
||||
|
||||
if( samplepos < oldsamplepos )
|
||||
{
|
||||
buffers++; // buffer wrapped
|
||||
|
||||
if( paintedtime > 0x40000000 )
|
||||
{
|
||||
// time to chop things off to avoid 32 bit limits
|
||||
buffers = 0;
|
||||
paintedtime = fullsamples;
|
||||
S_StopAllSounds();
|
||||
}
|
||||
}
|
||||
oldsamplepos = samplepos;
|
||||
|
||||
return (buffers * fullsamples + samplepos / dma.channels);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_BeginPainting
|
||||
|
||||
Makes sure dma.buffer is valid
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_BeginPainting( void )
|
||||
{
|
||||
int reps;
|
||||
DWORD dwSize2;
|
||||
DWORD *pbuf, *pbuf2;
|
||||
HRESULT hr;
|
||||
DWORD dwStatus;
|
||||
|
||||
if( !pDSBuf ) return;
|
||||
|
||||
// if the buffer was lost or stopped, restore it and/or restart it
|
||||
if( pDSBuf->lpVtbl->GetStatus( pDSBuf, &dwStatus ) != DS_OK )
|
||||
MsgDev( D_WARN, "SNDDMA_BeginPainting: couldn't get sound buffer status\n" );
|
||||
|
||||
if( dwStatus & DSBSTATUS_BUFFERLOST )
|
||||
pDSBuf->lpVtbl->Restore( pDSBuf );
|
||||
|
||||
if(!( dwStatus & DSBSTATUS_PLAYING ))
|
||||
pDSBuf->lpVtbl->Play( pDSBuf, 0, 0, DSBPLAY_LOOPING );
|
||||
|
||||
// lock the dsound buffer
|
||||
dma.buffer = NULL;
|
||||
reps = 0;
|
||||
|
||||
while(( hr = pDSBuf->lpVtbl->Lock( pDSBuf, 0, gSndBufSize, &pbuf, &locksize, &pbuf2, &dwSize2, 0 )) != DS_OK )
|
||||
{
|
||||
if( hr != DSERR_BUFFERLOST )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_BeginPainting: lock error '%s'\n", DSoundError( hr ));
|
||||
S_Shutdown ();
|
||||
return;
|
||||
}
|
||||
else pDSBuf->lpVtbl->Restore( pDSBuf );
|
||||
|
||||
if( ++reps > 2 ) return;
|
||||
}
|
||||
dma.buffer = (byte *)pbuf;
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
SNDDMA_Submit
|
||||
|
||||
Send sound to device if buffer isn't really the dma buffer
|
||||
Also unlocks the dsound buffer
|
||||
===============
|
||||
*/
|
||||
void SNDDMA_Submit( void )
|
||||
|
@ -637,28 +705,32 @@ void SNDDMA_Submit( void )
|
|||
LPWAVEHDR h;
|
||||
int wResult;
|
||||
|
||||
if( !wav_init )
|
||||
if( !dma.buffer )
|
||||
return;
|
||||
|
||||
// unlock the dsound buffer
|
||||
if( pDSBuf ) pDSBuf->lpVtbl->Unlock( pDSBuf, dma.buffer, locksize, NULL, 0 );
|
||||
|
||||
if( !wav_init ) return;
|
||||
|
||||
// find which sound blocks have completed
|
||||
while( 1)
|
||||
while( 1 )
|
||||
{
|
||||
if( snd_completed == snd_sent )
|
||||
{
|
||||
MsgDev( D_INFO, "Sound overrun\n" );
|
||||
break;
|
||||
}
|
||||
|
||||
if(!( lpWaveHdr[snd_completed & WAV_MASK].dwFlags & WHDR_DONE ))
|
||||
break;
|
||||
snd_completed++; // this buffer has been played
|
||||
}
|
||||
|
||||
// submit two new sound blocks
|
||||
while((( snd_sent - snd_completed ) >> sample16 ) < 4 )
|
||||
// submit a few new sound blocks
|
||||
while((( snd_sent - snd_completed ) >> sample16 ) < 8 )
|
||||
{
|
||||
h = lpWaveHdr + ( snd_sent & WAV_MASK );
|
||||
|
||||
if( paintedtime / 256 <= snd_sent )
|
||||
break;
|
||||
snd_sent++;
|
||||
|
||||
// Now the data block can be sent to the output device. The
|
||||
|
@ -669,7 +741,7 @@ void SNDDMA_Submit( void )
|
|||
if( wResult != MMSYSERR_NOERROR )
|
||||
{
|
||||
MsgDev( D_ERROR, "SNDDMA_Submit: failed to write block to device\n" );
|
||||
SNDDMA_FreeSound();
|
||||
SNDDMA_FreeSound ();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -686,3 +758,39 @@ void SNDDMA_Shutdown( void )
|
|||
{
|
||||
SNDDMA_FreeSound();
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
S_PrintDeviceName
|
||||
===========
|
||||
*/
|
||||
void S_PrintDeviceName( void )
|
||||
{
|
||||
if( snd_isdirect ) Msg( "Audio: DirectSound\n" );
|
||||
if( snd_iswave ) Msg( "Audio: WaveOutput\n" );
|
||||
}
|
||||
|
||||
/*
|
||||
===========
|
||||
S_Activate
|
||||
|
||||
Called when the main window gains or loses focus.
|
||||
The window have been destroyed and recreated
|
||||
between a deactivate and an activate.
|
||||
===========
|
||||
*/
|
||||
void S_Activate( bool active )
|
||||
{
|
||||
if( active )
|
||||
{
|
||||
if( pDS && snd_hwnd && snd_isdirect )
|
||||
DS_CreateBuffers( snd_hwnd );
|
||||
}
|
||||
else
|
||||
{
|
||||
if( pDS && snd_hwnd && snd_isdirect )
|
||||
DS_DestroyBuffers();
|
||||
else if( snd_iswave )
|
||||
waveOutReset( hWaveOut );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
1526
snd_dx/s_main.c
1526
snd_dx/s_main.c
File diff suppressed because it is too large
Load Diff
163
snd_dx/s_mix.c
163
snd_dx/s_mix.c
|
@ -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,21 +68,19 @@ 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;
|
||||
S_TransferStereo16( pbuf, endtime );
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// general case
|
||||
p = (int *)paintbuffer;
|
||||
count = (endtime - paintedtime) * dma.channels;
|
||||
|
@ -127,41 +88,13 @@ void S_TransferPaintBuffer( int endtime )
|
|||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
pbuf = (DWORD *)dma.buffer;
|
||||
}
|
||||
|
||||
if( dma.samplebits == 16 )
|
||||
{
|
||||
short *out = (short *)pbuf;
|
||||
|
||||
while( count-- )
|
||||
{
|
||||
val = (*p * snd_vol) >> 8;
|
||||
val = *p >> 8;
|
||||
p += step;
|
||||
if( val > 0x7fff ) val = 0x7fff;
|
||||
else if( val < (short)0x8000 )
|
||||
|
@ -176,7 +109,7 @@ void S_TransferPaintBuffer( int endtime )
|
|||
|
||||
while( count-- )
|
||||
{
|
||||
val = (*p * snd_vol) >> 8;
|
||||
val = *p >> 8;
|
||||
p += step;
|
||||
if( val > 0x7fff ) val = 0x7fff;
|
||||
else if( val < (short)0x8000 )
|
||||
|
@ -185,8 +118,7 @@ void S_TransferPaintBuffer( int endtime )
|
|||
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 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 data;
|
||||
int left, right;
|
||||
int leftvol, rightvol;
|
||||
short *sfx;
|
||||
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;
|
||||
}
|
||||
|
|
|
@ -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 )
|
||||
|
@ -44,3 +46,50 @@ void SND_CloseMouth( channel_t *ch )
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
615
snd_dx/s_vox.c
615
snd_dx/s_vox.c
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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>
|
216
snd_dx/sound.h
216
snd_dx/sound.h
|
@ -1,6 +1,6 @@
|
|||
//=======================================================================
|
||||
// Copyright XashXT Group 2009 ©
|
||||
// sound.h - client sound i/o functions
|
||||
// sound.h - sndlib main header
|
||||
//=======================================================================
|
||||
|
||||
#ifndef SOUND_H
|
||||
|
@ -17,12 +17,7 @@ extern stdlib_api_t com;
|
|||
extern vsound_imp_t si;
|
||||
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
|
|
@ -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
|
|
@ -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>
|
|
@ -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 );
|
||||
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -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>
|
|
@ -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>
|
Reference in New Issue