mirror of
https://github.com/FWGS/xash3d-fwgs.git
synced 2026-08-08 21:31:46 +08:00
engine: client: switch to dynamically allocating vox words, freeing up 320 Kb of memory
This commit is contained in:
@@ -171,11 +171,16 @@ S_FreeChannel
|
||||
*/
|
||||
void S_FreeChannel( channel_t *ch )
|
||||
{
|
||||
// free the currently loaded word's audio cache before nuking the channel
|
||||
if( ch->words )
|
||||
VOX_FreeWord( ch );
|
||||
|
||||
ch->sfx = NULL;
|
||||
ch->name[0] = '\0';
|
||||
ch->flags = 0;
|
||||
ch->forced_end = ch->sample = 0.0;
|
||||
ch->data = NULL;
|
||||
Mem_Free2( &ch->words );
|
||||
|
||||
SND_CloseMouth( ch );
|
||||
}
|
||||
@@ -256,7 +261,7 @@ static int SND_GetChannelTimeLeft( const channel_t *ch )
|
||||
if( FBitSet( ch->flags, FL_CHAN_FINISHED ) || !ch->sfx || !ch->sfx->cache )
|
||||
return 0;
|
||||
|
||||
if( FBitSet( ch->flags, FL_CHAN_IS_SENTENCE )) // sentences are special, count all remaining words
|
||||
if( ch->words ) // sentences are special, count all remaining words
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -268,7 +273,7 @@ static int SND_GetChannelTimeLeft( const channel_t *ch )
|
||||
|
||||
// here we count all remaining words, stopping if no sfx or sound file is available
|
||||
// see VOX_LoadWord
|
||||
for( i = ch->word_index + 1; i < ARRAYSIZE( ch->words ); i++ )
|
||||
for( i = ch->word_index + 1; i < CVOXWORDMAX; i++ )
|
||||
{
|
||||
wavdata_t *sc;
|
||||
int end;
|
||||
@@ -440,7 +445,7 @@ static qboolean S_MaybeAlterChannel( channel_t *ch, int entnum, int entchannel,
|
||||
// if no sfx passed, check if it's a sentence
|
||||
if( !sfx )
|
||||
{
|
||||
if( !FBitSet( ch->flags, FL_CHAN_IS_SENTENCE ))
|
||||
if( !ch->words )
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -876,7 +881,6 @@ void S_AmbientSound( const vec3_t pos, int ent, sound_t handle, float fvol, floa
|
||||
// load regular or stream sound
|
||||
pSource = S_LoadSound( sfx );
|
||||
ch->sfx = sfx;
|
||||
ClearBits( ch->flags, FL_CHAN_IS_SENTENCE );
|
||||
ch->name[0] = '\0';
|
||||
}
|
||||
|
||||
@@ -945,7 +949,7 @@ int S_GetCurrentStaticSounds( soundlist_t *pout, int size )
|
||||
if( ch->entchannel != CHAN_STATIC || !ch->sfx || !ch->sfx->name[0] )
|
||||
continue;
|
||||
|
||||
if( FBitSet( ch->flags, FL_CHAN_IS_SENTENCE ) && ch->name[0] )
|
||||
if( ch->words && ch->name[0] )
|
||||
Q_strncpy( pout->name, ch->name, sizeof( pout->name ));
|
||||
else
|
||||
Q_strncpy( pout->name, ch->sfx->name, sizeof( pout->name ));
|
||||
@@ -995,7 +999,7 @@ int S_GetCurrentDynamicSounds( soundlist_t *pout, int size )
|
||||
if( ch->entchannel == CHAN_STATIC && looped && !Host_IsQuakeCompatible())
|
||||
continue; // never serialize static looped sounds. It will be restoring in game code
|
||||
|
||||
if( FBitSet( ch->flags, FL_CHAN_IS_SENTENCE ) && ch->name[0] )
|
||||
if( ch->words && ch->name[0] )
|
||||
Q_strncpy( pout->name, ch->name, sizeof( pout->name ));
|
||||
else
|
||||
Q_strncpy( pout->name, ch->sfx->name, sizeof( pout->name ));
|
||||
|
||||
@@ -318,7 +318,7 @@ static int S_MixNormalChannels( portable_samplepair_t *dst, int end, int rate )
|
||||
|
||||
num_mixed_channels++;
|
||||
|
||||
if( FBitSet( ch->flags, FL_CHAN_IS_SENTENCE ))
|
||||
if( ch->words )
|
||||
{
|
||||
VOX_MixChannelToBuffer( dst, ch, num_samples, rate, pitch );
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ void VOX_SetChanVol( channel_t *ch )
|
||||
{
|
||||
voxword_t *word;
|
||||
|
||||
if( !FBitSet( ch->flags, FL_CHAN_IS_SENTENCE ) || FBitSet( ch->flags, FL_CHAN_SENTENCE_FINISHED ))
|
||||
if( !ch->words || FBitSet( ch->flags, FL_CHAN_SENTENCE_FINISHED ))
|
||||
return;
|
||||
|
||||
word = &ch->words[ch->word_index];
|
||||
@@ -207,7 +207,7 @@ float VOX_ModifyPitch( channel_t *ch, float pitch )
|
||||
{
|
||||
voxword_t *word;
|
||||
|
||||
if( !FBitSet( ch->flags, FL_CHAN_IS_SENTENCE ) || FBitSet( ch->flags, FL_CHAN_SENTENCE_FINISHED ))
|
||||
if( !ch->words || FBitSet( ch->flags, FL_CHAN_SENTENCE_FINISHED ))
|
||||
return pitch;
|
||||
|
||||
word = &ch->words[ch->word_index];
|
||||
@@ -449,10 +449,18 @@ void VOX_LoadSound( channel_t *ch, const char *pszin )
|
||||
int i, j;
|
||||
int num_words;
|
||||
voxword_t default_voxword;
|
||||
voxword_t words_buf[CVOXWORDMAX + 1]; // local scratch: parsed words + null terminator
|
||||
|
||||
if( !pszin )
|
||||
return;
|
||||
|
||||
// free any existing words from a previous sentence on this channel
|
||||
if( ch->words )
|
||||
{
|
||||
VOX_FreeWord( ch );
|
||||
Mem_Free2( &ch->words );
|
||||
}
|
||||
|
||||
psz = VOX_LookupString( pszin );
|
||||
|
||||
if( !psz )
|
||||
@@ -480,12 +488,13 @@ void VOX_LoadSound( channel_t *ch, const char *pszin )
|
||||
num_words = VOX_ParseString( buffer, rgpparseword );
|
||||
|
||||
VOX_MakeDefaultWordParams( &default_voxword );
|
||||
memset( words_buf, 0, sizeof( words_buf ));
|
||||
|
||||
for( i = 0, j = 0; i < num_words; i++ )
|
||||
{
|
||||
char pathbuffer[MAX_SYSPATH];
|
||||
|
||||
if( !VOX_ParseWordParams( rgpparseword[i], &ch->words[j], &default_voxword ))
|
||||
if( !VOX_ParseWordParams( rgpparseword[i], &words_buf[j], &default_voxword ))
|
||||
continue;
|
||||
|
||||
if( Q_snprintf( pathbuffer, sizeof( pathbuffer ), "%s%s", szpath, rgpparseword[i] ) < 0 )
|
||||
@@ -495,18 +504,19 @@ void VOX_LoadSound( channel_t *ch, const char *pszin )
|
||||
}
|
||||
|
||||
qboolean in_cache = false;
|
||||
ch->words[j].sfx = S_FindName( pathbuffer, &in_cache );
|
||||
words_buf[j].sfx = S_FindName( pathbuffer, &in_cache );
|
||||
if( in_cache )
|
||||
SetBits( ch->words[j].flags, FL_VOXWORD_IN_CACHE );
|
||||
SetBits( words_buf[j].flags, FL_VOXWORD_IN_CACHE );
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
ch->words[j].sfx = NULL;
|
||||
// words_buf[j].sfx is already NULL from the memset — null terminator
|
||||
ch->words = Mem_Malloc( sndpool, ( j + 1 ) * sizeof( voxword_t ));
|
||||
memcpy( ch->words, words_buf, ( j + 1 ) * sizeof( voxword_t ));
|
||||
|
||||
ch->sfx = ch->words[0].sfx;
|
||||
ch->word_index = 0;
|
||||
SetBits( ch->flags, FL_CHAN_IS_SENTENCE );
|
||||
|
||||
VOX_LoadWord( ch );
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,6 @@ typedef struct rawchan_s
|
||||
#define FL_CHAN_USE_LOOP BIT( 0 ) // don't loop default and local sounds
|
||||
#define FL_CHAN_STATIC_SOUND BIT( 1 ) // use origin instead of fetching entnum's origin
|
||||
#define FL_CHAN_LOCAL_SOUND BIT( 2 ) // it's a local menu sound (not looped, not paused)
|
||||
#define FL_CHAN_IS_SENTENCE BIT( 3 ) // bit indicating vox sentence
|
||||
#define FL_CHAN_SENTENCE_FINISHED BIT( 4 ) // if set, finished playing sentence
|
||||
#define FL_CHAN_FINISHED BIT( 5 ) // if set, finished playing single word
|
||||
|
||||
@@ -123,7 +122,7 @@ typedef struct channel_s
|
||||
double sample;
|
||||
double forced_end;
|
||||
wavdata_t *data;
|
||||
voxword_t words[CVOXWORDMAX];
|
||||
voxword_t *words; // dynamically allocated, (num_words + 1) entries, null sfx terminates
|
||||
|
||||
// TODO: add reserved bytes
|
||||
} channel_t;
|
||||
|
||||
Reference in New Issue
Block a user