static void NET_QueuePacket( int length, const void *data, netadr_t to, int offset ) { packetQueue_t *newp, *next = packetQueue; if ( offset > 999 ) { offset = 999; } newp = (packetQueue_t*) S_Malloc( sizeof( packetQueue_t ) ); newp->data = (byte*) S_Malloc( length ); Com_Memcpy( newp->data, data, length ); newp->length = length; newp->to = to; newp->release = Sys_Milliseconds() + ( int )( ( float ) offset / com_timescale->value ); newp->next = nullptr; if ( !packetQueue ) { packetQueue = newp; return; } while ( next ) { if ( !next->next ) { next->next = newp; return; } next = next->next; } }
/* ============ Cmd_AddCommand ============ */ qboolean Cmd_AddCommandGeneric( const char *cmd_name, const char* helptext, xcommand_t function, qboolean warn, int power ) { cmd_function_t *cmd; // fail if the command already exists for ( cmd = cmd_functions ; cmd ; cmd = cmd->next ) { if ( !strcmp( cmd_name, cmd->name )) { // allow completion-only commands to be silently doubled if ( function != NULL && warn) { Com_PrintWarning( "Cmd_AddCommand: %s already defined\n", cmd_name ); } return qfalse; } } // use a small malloc to avoid zone fragmentation if(helptext != NULL) { cmd = S_Malloc( sizeof( cmd_function_t ) + strlen(cmd_name) + 1 + strlen(helptext) + 1); strcpy((char*)(cmd +1) + strlen(cmd_name) +1, helptext); cmd->helptext = (char*)(cmd +1) + strlen(cmd_name) +1; }else{ cmd = S_Malloc( sizeof( cmd_function_t ) + strlen(cmd_name) + 1); } strcpy((char*)(cmd +1), cmd_name); cmd->name = (char*)(cmd +1); cmd->function = function; cmd->minPower = power; cmd->next = cmd_functions; cmd_functions = cmd; return qtrue; }
sfxcache_t *AL_UploadSfx(sfx_t *s) { sfxcache_t *sc; ALsizei size = s_info.samples * s_info.width; ALenum format = s_info.width == 2 ? AL_FORMAT_MONO16 : AL_FORMAT_MONO8; ALuint name; if (!size) { s->error = Q_ERR_TOO_FEW; return NULL; } qalGetError(); qalGenBuffers(1, &name); qalBufferData(name, format, s_info.data, size, s_info.rate); if (qalGetError() != AL_NO_ERROR) { s->error = Q_ERR_LIBRARY_ERROR; return NULL; } // allocate placeholder sfxcache sc = s->cache = S_Malloc(sizeof(*sc)); sc->length = s_info.samples * 1000 / s_info.rate; // in msec sc->loopstart = s_info.loopstart; sc->width = s_info.width; sc->size = size; sc->bufnum = name; return sc; }
/* * S_InitSources */ qboolean S_InitSources( int maxEntities, qboolean verbose ) { int i; memset( srclist, 0, sizeof( srclist ) ); src_count = 0; // Allocate as many sources as possible for( i = 0; i < MAX_SRC; i++ ) { qalGenSources( 1, &srclist[i].source ); if( qalGetError() != AL_NO_ERROR ) break; src_count++; } if( !src_count ) return qfalse; if( verbose ) Com_Printf( "allocated %d sources\n", src_count ); if( maxEntities < 1 ) return qfalse; entlist = ( sentity_t * )S_Malloc( sizeof( sentity_t ) * maxEntities ); src_inited = qtrue; return qtrue; }
/* ============ Cmd_AddCommand ============ */ void Cmd_AddCommand( const char *cmd_name, xcommand_t function ) { cmd_function_t *cmd; // fail if the command already exists for ( cmd = cmd_functions ; cmd ; cmd=cmd->next ) { if ( !strcmp( cmd_name, cmd->name ) ) { // allow completion-only commands to be silently doubled if ( function != NULL ) { Com_Printf ("Cmd_AddCommand: %s already defined\n", cmd_name); } return; } } // use a small malloc to avoid zone fragmentation cmd = (cmd_function_t *)S_Malloc (sizeof(cmd_function_t)); cmd->name = CopyString( cmd_name ); cmd->function = function; cmd->next = cmd_functions; cmd_functions = cmd; }
/* ============ Cmd_AddCommand ============ */ void Cmd_AddCommand(const char *cmd_name, xcommand_t function, const char *cmd_desc) { cmd_function_t *cmd; // fail if the command is a variable name if( Cvar_FindVar( cmd_name )) { Com_Printf( "Cmd_AddCommand: %s already defined as a var\n", cmd_name ); return; } // fail if the command already exists if( Cmd_Exists( cmd_name )) { Com_Printf( "Cmd_AddCommand: %s already defined\n", cmd_name ); // ALARM! HACKED FOR NOW Cmd_RemoveCommand(cmd_name); return; } // use a small malloc to avoid zone fragmentation cmd = (cmd_function_t*)S_Malloc(sizeof(cmd_function_t)); cmd->name = CopyString(cmd_name); cmd->desc = CopyString(cmd_desc); cmd->function = function; cmd->next = cmd_functions; cmd->complete = NULL; cmd_functions = cmd; }
snd_stream_t *decoder_wav_open( const char *filename, qboolean *delay ) { snd_stream_t *stream; snd_wav_stream_t *wav_stream; stream = decoder_stream_init( &wav_decoder ); if( !stream ) return NULL; stream->isUrl = trap_FS_IsUrl( filename ); if( stream->isUrl ) return NULL; if( delay ) *delay = qfalse; stream->ptr = S_Malloc( sizeof( snd_wav_stream_t ) ); wav_stream = (snd_wav_stream_t *)stream->ptr; trap_FS_FOpenFile( filename, &wav_stream->filenum, FS_READ|FS_NOSIZE ); if( !wav_stream->filenum ) { decoder_wav_stream_shutdown( stream ); return NULL; } if( !decoder_wav_cont_open( stream ) ) { return NULL; } return stream; }
/** * Util functions used by decoders (snd_decoder.h) */ snd_stream_t *decoder_stream_init( snd_decoder_t *decoder ) { snd_stream_t *stream; // Allocate a stream stream = S_Malloc( sizeof( snd_stream_t ) ); stream->decoder = decoder; return stream; }
/* * SF_RawSamples */ void SF_RawSamples( unsigned int samples, unsigned int rate, unsigned short width, unsigned short channels, const uint8_t *data, bool music ) { size_t data_size = samples * width * channels; uint8_t *data_copy = S_Malloc( data_size ); memcpy( data_copy, data, data_size ); S_IssueRawSamplesCmd( s_cmdPipe, samples, rate, width, channels, data_copy, music ); }
/* * S_FindRawSound */ static rawsound_t *S_FindRawSound( int entnum, bool addNew ) { int i, free; int best, best_time; rawsound_t *rawsound; // check for replacement sound, or find the best one to replace best = free = -1; best_time = 0x7fffffff; for( i = 0; i < MAX_RAW_SOUNDS; i++ ) { rawsound = raw_sounds[i]; if( free < 0 && !rawsound ) { free = i; } else if( rawsound ) { int time; if( rawsound->entnum == entnum ) { // exact match return rawsound; } time = rawsound->rawend - paintedtime; if( time < best_time ) { best = i; best_time = time; } } } if( !addNew ) { return NULL; } if( free >= 0 ) { best = free; } if( best < 0 ) { // no free slots return NULL; } if( !raw_sounds[best] ) { raw_sounds[best] = S_Malloc( sizeof( *rawsound ) + sizeof( portable_samplepair_t ) * MAX_RAW_SAMPLES ); } rawsound = raw_sounds[best]; rawsound->entnum = entnum; rawsound->rawend = 0; rawsound->left_volume = rawsound->right_volume = 0; // will be spatialized later return rawsound; }
/* * SF_PositionedRawSamples */ void SF_PositionedRawSamples( int entnum, float fvol, float attenuation, unsigned int samples, unsigned int rate, unsigned short width, unsigned short channels, const uint8_t *data ) { size_t data_size = samples * width * channels; uint8_t *data_copy = S_Malloc( data_size ); memcpy( data_copy, data, data_size ); S_IssuePositionedRawSamplesCmd( s_cmdPipe, entnum, fvol, attenuation, samples, rate, width, channels, data_copy ); }
/* * S_AllocTrack */ static bgTrack_t *S_AllocTrack( const char *filename ) { bgTrack_t *track; track = S_Malloc( sizeof( *track ) + strlen( filename ) + 1 ); track->ignore = false; track->filename = (char *)( (uint8_t *)track + sizeof( *track ) ); strcpy( track->filename, filename ); track->isUrl = trap_FS_IsUrl( track->filename ); track->muteOnPause = track->isUrl; track->anext = s_bgTrackHead; s_bgTrackHead = track; return track; }
/* * S_AllocTrack */ static bgTrack_t *S_AllocTrack( const char *filename ) { bgTrack_t *track; track = S_Malloc( sizeof( *track ) + strlen( filename ) + 1 ); track->stream = NULL; track->ignore = qfalse; track->filename = (char *)((qbyte *)track + sizeof( *track )); strcpy( track->filename, filename ); track->isUrl = trap_FS_IsUrl( filename ); track->anext = s_bgTrackHead; s_bgTrackHead = track; return track; }
static void decoder_register( snd_decoder_t *decoder ) { decoder->next = decoders; decoders = decoder; if( extensionlist_size - strlen( extensionlist ) - 1 < strlen( decoder->ext ) + 1 ) { char *oldlist = extensionlist; extensionlist_size = max( extensionlist_size * 2, (int)( strlen( extensionlist ) + strlen( decoder->ext ) + 1 + 1 ) ); extensionlist = S_Malloc( extensionlist_size ); Q_strncpyz( extensionlist, oldlist, extensionlist_size ); S_Free( oldlist ); } Q_strncatz( extensionlist, " ", extensionlist_size ); Q_strncatz( extensionlist, decoder->ext, extensionlist_size ); }
/* ======================== CopyString NOTE: never write over the memory CopyString returns because memory from a memstatic_t might be returned ======================== */ char *CopyString( const char *in ) { char *out; if (!in[0]) { return ((char *)&gEmptyString) + sizeof(zoneHeader_t); } else if (!in[1]) { if (in[0] >= '0' && in[0] <= '9') { return ((char *)&gNumberString[in[0]-'0']) + sizeof(zoneHeader_t); } } out = (char *) S_Malloc (strlen(in)+1); strcpy (out, in); return out; }
qboolean S_InitDecoders( qboolean verbose ) { extensionlist_size = 32; extensionlist = S_Malloc( extensionlist_size ); extensionlist[0] = 0; // First codec has the priority. decoders = NULL; decoder_register( &wav_decoder ); if( SNDOGG_Init( verbose ) ) { decoder_register( &ogg_decoder ); } return qtrue; }
void * stereo_mono( void *data, snd_info_t *info ) { int i, interleave, gain; void *outdata; outdata = S_Malloc( info->samples * info->width ); interleave = info->channels * info->width; gain = s_stereo2mono->integer; clamp( gain, -1, 1 ); if( info->width == 2 ) { short *pin, *pout; pin = (short*)data; pout = (short*)outdata; for( i = 0; i < info->size; i += interleave, pin += info->channels, pout++ ) { *pout = ((1-gain) * pin[0] + (1+gain) * pin[1]) / 2; } } else if( info->width == 1 ) { char *pin, *pout; pin = (char*)data; pout = (char*)outdata; for( i = 0; i < info->size; i += interleave, pin += info->channels, pout++ ) { *pout = ((1-gain) * pin[0] + (1+gain) * pin[1]) / 2; } } else { S_Free( outdata ); return NULL; } info->channels = 1; info->size = info->samples * info->width; return outdata; }
snd_stream_t *decoder_ogg_open( const char *filename, qboolean *delay ) { snd_stream_t *stream; snd_ogg_stream_t *ogg_stream; // Open stream = decoder_stream_init( &ogg_decoder ); if( !stream ) { Com_Printf( "Error initializing .ogg stream: %s\n", filename ); return NULL; } stream->isUrl = trap_FS_IsUrl( filename ); stream->ptr = S_Malloc( sizeof( snd_ogg_stream_t ) ); ogg_stream = (snd_ogg_stream_t *)stream->ptr; trap_FS_FOpenFile( filename, &ogg_stream->filenum, FS_READ|FS_NOSIZE ); if( !ogg_stream->filenum ) { decoder_ogg_stream_shutdown( stream ); return NULL; } if( delay ) *delay = qfalse; if( stream->isUrl && delay ) { *delay = qtrue; return stream; } if( !decoder_ogg_cont_open( stream ) ) { decoder_ogg_close( stream ); return NULL; } return stream; }
/* ============ Cmd_AddCommandExtended ============ */ void Cmd_AddSystemCommand(const char *cmd_name, xcommand_t function, const char *description, completionFunc_t complete) { cmd_function_t *cmd; if (!cmd_name || !cmd_name[0]) { Com_Printf(S_COLOR_RED "Cmd_AddSystemCommand can't add NULL or empty command name\n"); return; } // fail if the command already exists if (Cmd_FindCommand(cmd_name)) { // allow completion-only commands to be silently doubled if (function != NULL) { Com_Printf("Cmd_AddCommandExtended: %s already defined\n", cmd_name); } return; } // use a small malloc to avoid zone fragmentation cmd = S_Malloc(sizeof(cmd_function_t)); cmd->name = CopyString(cmd_name); cmd->function = function; cmd->complete = complete; cmd->next = cmd_functions; cmd_functions = cmd; if (description && description[0]) { cmd->description = CopyString(description); } else { cmd->description = NULL; } }
void *decoder_wav_load( const char *filename, snd_info_t *info ) { int filenum; int read; void *buffer; if( trap_FS_IsUrl( filename ) ) return NULL; trap_FS_FOpenFile( filename, &filenum, FS_READ|FS_NOSIZE ); if( !filenum ) return NULL; if( !read_wav_header( filenum, info ) ) { trap_FS_FCloseFile( filenum ); Com_Printf( "Can't understand .wav file: %s\n", filename ); return NULL; } buffer = S_Malloc( info->size ); read = trap_FS_Read( buffer, info->size, filenum ); if( read != info->size ) { S_Free( buffer ); trap_FS_FCloseFile( filenum ); Com_Printf( "Error reading .wav file: %s\n", filename ); return NULL; } byteSwapRawSamples( info->samples, info->width, info->channels, (qbyte *)buffer ); trap_FS_FCloseFile( filenum ); return buffer; }
/* * S_ReadPlaylistFile */ static bgTrack_t *S_ReadPlaylistFile( const char *filename, bool shuffle, bool loop ) { int filenum, length; char *tmpname = 0; size_t tmpname_size = 0; char *data, *line, *entry; playlistItem_t items[MAX_PLAYLIST_ITEMS]; int i, numItems = 0; length = trap_FS_FOpenFile( filename, &filenum, FS_READ ); if( length < 0 ) return NULL; // load the playlist into memory data = S_Malloc( length + 1 ); trap_FS_Read( data, length, filenum ); trap_FS_FCloseFile( filenum ); srand( time( NULL ) ); while( *data ) { size_t s; entry = data; // read the whole line for( line = data; *line != '\0' && *line != '\n'; line++ ); // continue reading from the next character, if possible data = (*line == '\0' ? line : line + 1); *line = '\0'; // trim whitespaces, tabs, etc entry = Q_trim( entry ); // special M3U entry or comment if( !*entry || *entry == '#' ) continue; if( trap_FS_IsUrl( entry ) ) { items[numItems].track = S_AllocTrack( entry ); } else { // append the entry name to playlist path s = strlen( filename ) + 1 + strlen( entry ) + 1; if( s > tmpname_size ) { if( tmpname ) S_Free( tmpname ); tmpname_size = s; tmpname = S_Malloc( tmpname_size ); } Q_strncpyz( tmpname, filename, tmpname_size ); COM_StripFilename( tmpname ); Q_strncatz( tmpname, "/", tmpname_size ); Q_strncatz( tmpname, entry, tmpname_size ); COM_SanitizeFilePath( tmpname ); items[numItems].track = S_AllocTrack( tmpname ); } if( ++numItems == MAX_PLAYLIST_ITEMS ) break; } if( tmpname ) { S_Free( tmpname ); tmpname = NULL; } if( !numItems ) return NULL; // set the playing order for( i = 0; i < numItems; i++ ) items[i].order = (shuffle ? (rand() % numItems) : i); // sort the playlist R_SortPlaylistItems( numItems, items ); // link the playlist for( i = 1; i < numItems; i++ ) { items[i-1].track->next = items[i].track; items[i].track->prev = items[i-1].track; items[i].track->loop = loop; } items[numItems-1].track->next = items[0].track; items[0].track->prev = items[numItems-1].track; items[0].track->loop = loop; return items[0].track; }
/* ======================== CopyString NOTE: never write over the memory CopyString returns because memory from a memstatic_t might be returned ======================== */ char *CopyString( const char *in ) { struct ZoneSingleChar { ZoneHeader header; #ifdef _DEBUG ZoneDebugHeader start; #endif char data[2]; #ifdef _DEBUG ZoneDebugFooter end; #endif }; #ifdef _DEBUG static ZoneSingleChar empty = {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "\0", ZONE_MAGIC}; static ZoneSingleChar numbers[10] = { {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "0", ZONE_MAGIC}, {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "1", ZONE_MAGIC}, {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "2", ZONE_MAGIC}, {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "3", ZONE_MAGIC}, {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "4", ZONE_MAGIC}, {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "5", ZONE_MAGIC}, {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "6", ZONE_MAGIC}, {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "7", ZONE_MAGIC}, {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "8", ZONE_MAGIC}, {(TAG_STATIC << 25) | 2, ZONE_MAGIC, "9", ZONE_MAGIC}, }; #else static ZoneSingleChar empty = {(TAG_STATIC << 25) | 2, "\0"}; static ZoneSingleChar numbers[10] = { {(TAG_STATIC << 25) | 2, "0"}, {(TAG_STATIC << 25) | 2, "1"}, {(TAG_STATIC << 25) | 2, "2"}, {(TAG_STATIC << 25) | 2, "3"}, {(TAG_STATIC << 25) | 2, "4"}, {(TAG_STATIC << 25) | 2, "5"}, {(TAG_STATIC << 25) | 2, "6"}, {(TAG_STATIC << 25) | 2, "7"}, {(TAG_STATIC << 25) | 2, "8"}, {(TAG_STATIC << 25) | 2, "9"}, }; #endif char *out; if (!in[0]) { return empty.data; } else if (!in[1]) { if (in[0] >= '0' && in[0] <= '9') { return numbers[in[0]-'0'].data; } } out = (char *) S_Malloc (strlen(in)+1); strcpy (out, in); // Z_Label(out,in); return out; }
/* ============ Cmd_Alias_f ============ */ void Cmd_Alias_f(void) { cmd_alias_t *alias; const char *name; // Get args if (Cmd_Argc() < 2) { Com_Printf("alias <name> : show an alias\n"); Com_Printf("alias <name> <exec> : create an alias\n"); return; } name = Cmd_Argv(1); // Find existing alias for (alias = cmd_aliases; alias; alias = alias->next) { if (!Q_stricmp(name, alias->name)) break; } // Modify/create an alias if (Cmd_Argc() > 2) { cmd_function_t *cmd; // Crude protection from infinite loops if (!Q_stricmp(Cmd_Argv(2), name)) { Com_Printf("Can't make an alias to itself\n"); return; } // Don't allow overriding builtin commands cmd = Cmd_FindCommand( name ); if (cmd && cmd->function != Cmd_RunAlias_f) { Com_Printf("Can't override a builtin function with an alias\n"); return; } // Create/update an alias if (!alias) { alias = (cmd_alias_t*)S_Malloc(sizeof(cmd_alias_t)); alias->name = CopyString(name); alias->exec = CopyString(Cmd_ArgsFrom(2)); alias->next = cmd_aliases; cmd_aliases = alias; Cmd_AddCommand(name, Cmd_RunAlias_f, NULL); } else { // Reallocate the exec string Z_Free(alias->exec); alias->exec = CopyString(Cmd_ArgsFrom(2)); Cmd_AddCommand(name, Cmd_RunAlias_f, NULL); } } // Show the alias if (!alias) Com_Printf("Alias %s does not exist\n", name); else if (Cmd_Argc() == 2) Com_Printf("%s ==> %s\n", alias->name, alias->exec); // update autogen.cfg cvar_modifiedFlags |= CVAR_ARCHIVE; }
void *decoder_ogg_load( const char *filename, snd_info_t *info ) { OggVorbis_File vorbisfile; int filenum, bitstream, bytes_read, bytes_read_total; char *buffer; ov_callbacks callbacks = { ovcb_read, ovcb_seek, ovcb_close, ovcb_tell }; trap_FS_FOpenFile( filename, &filenum, FS_READ|FS_NOSIZE ); if( !filenum ) return NULL; if( trap_FS_IsUrl( filename ) ) { callbacks.seek_func = NULL; callbacks.tell_func = NULL; } qov_open_callbacks( (void *) (qintptr) filenum, &vorbisfile, NULL, 0, callbacks ); if( callbacks.seek_func && !qov_seekable( &vorbisfile ) ) { Com_Printf( "Error unsupported .ogg file (not seekable): %s\n", filename ); qov_clear( &vorbisfile ); // Does FS_FCloseFile return NULL; } if( qov_streams( &vorbisfile ) != 1 ) { Com_Printf( "Error unsupported .ogg file (multiple logical bitstreams): %s\n", filename ); qov_clear( &vorbisfile ); // Does FS_FCloseFile return NULL; } if( !read_ogg_header( vorbisfile, info ) ) { Com_Printf( "Error reading .ogg file header: %s\n", filename ); qov_clear( &vorbisfile ); // Does FS_FCloseFile return NULL; } buffer = S_Malloc( info->size ); bytes_read_total = 0; do { #ifdef ENDIAN_BIG bytes_read = qov_read( &vorbisfile, buffer+bytes_read_total, info->size-bytes_read_total, 1, 2, 1, &bitstream ); #elif defined (ENDIAN_LITTLE) bytes_read = qov_read( &vorbisfile, buffer+bytes_read_total, info->size-bytes_read_total, 0, 2, 1, &bitstream ); #else #error "runtime endianess detection support missing" #endif bytes_read_total += bytes_read; } while( bytes_read > 0 && bytes_read_total < info->size ); qov_clear( &vorbisfile ); // Does FS_FCloseFile if( !bytes_read_total ) { Com_Printf( "Error reading .ogg file: %s\n", filename ); S_Free( buffer ); return NULL; } return buffer; }