static void R_LevelShot( void ) { #ifndef _XBOX char checkname[MAX_OSPATH]; byte *buffer; byte *source; byte *src, *dst; int x, y; int r, g, b; float xScale, yScale; int xx, yy; sprintf( checkname, "levelshots/%s.tga", tr.world->baseName ); source = (unsigned char *)Hunk_AllocateTempMemory( glConfig.vidWidth * glConfig.vidHeight * 3 ); buffer = (unsigned char *)Hunk_AllocateTempMemory( LEVELSHOTSIZE * LEVELSHOTSIZE*3 + 18); Com_Memset (buffer, 0, 18); buffer[2] = 2; // uncompressed type buffer[12] = LEVELSHOTSIZE & 255; buffer[13] = LEVELSHOTSIZE >> 8; buffer[14] = LEVELSHOTSIZE & 255; buffer[15] = LEVELSHOTSIZE >> 8; buffer[16] = 24; // pixel size qglReadPixels( 0, 0, glConfig.vidWidth, glConfig.vidHeight, GL_RGB, GL_UNSIGNED_BYTE, source ); // resample from source xScale = glConfig.vidWidth / (4.0*LEVELSHOTSIZE); yScale = glConfig.vidHeight / (3.0*LEVELSHOTSIZE); for ( y = 0 ; y < LEVELSHOTSIZE ; y++ ) { for ( x = 0 ; x < LEVELSHOTSIZE ; x++ ) { r = g = b = 0; for ( yy = 0 ; yy < 3 ; yy++ ) { for ( xx = 0 ; xx < 4 ; xx++ ) { src = source + 3 * ( glConfig.vidWidth * (int)( (y*3+yy)*yScale ) + (int)( (x*4+xx)*xScale ) ); r += src[0]; g += src[1]; b += src[2]; } } dst = buffer + 18 + 3 * ( y * LEVELSHOTSIZE + x ); dst[0] = b / 12; dst[1] = g / 12; dst[2] = r / 12; } } // gamma correct if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) { R_GammaCorrect( buffer + 18, LEVELSHOTSIZE * LEVELSHOTSIZE * 3 ); } FS_WriteFile( checkname, buffer, LEVELSHOTSIZE * LEVELSHOTSIZE*3 + 18 ); Hunk_FreeTempMemory( buffer ); Hunk_FreeTempMemory( source ); Com_Printf ("Wrote %s\n", checkname ); #endif }
/* ============== S_LoadSound The filename may be different than sfx->name in the case of a forced fallback of a player specific sound ============== */ bool S_LoadSound( sfx_t *sfx ) { byte *data; short *samples; wavinfo_t info; int size; // player specific sounds are never directly loaded if ( sfx->soundName[0] == '*') return false; // load it in size = FS_ReadFile( sfx->soundName, (void **)&data ); if ( !data ) return false; info = GetWavinfo( sfx->soundName, data, size ); if ( info.channels != 1 ) { Com_Printf ("%s is a stereo wav file\n", sfx->soundName); FS_FreeFile (data); return false; } if ( info.width == 1 ) Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is a 8 bit wav file\n", sfx->soundName); if ( info.rate != 22050 ) Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz wav file\n", sfx->soundName); samples = reinterpret_cast<short*>(Hunk_AllocateTempMemory(info.samples * sizeof(short) * 2)); sfx->lastTimeUsed = Com_Milliseconds()+1; // each of these compression schemes works just fine // but the 16bit quality is much nicer and with a local // install assured we can rely upon the sound memory // manager to do the right thing for us and page // sound in as needed if( sfx->soundCompressed == true) { sfx->soundCompressionMethod = 1; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, (data + info.dataofs) ); S_AdpcmEncodeSound(sfx, samples); } else { sfx->soundCompressionMethod = 0; sfx->soundLength = info.samples; sfx->soundData = NULL; ResampleSfx( sfx, info.rate, info.width, data + info.dataofs, false ); } Hunk_FreeTempMemory(samples); FS_FreeFile( data ); return true; }
/* ============== S_LoadSound The filename may be different than sfx->name in the case of a forced fallback of a player specific sound ============== */ qboolean S_LoadSound( sfx_t *sfx ) { byte *data; short *samples; snd_info_t info; // int size; // load it in data = S_CodecLoad(sfx->soundName, &info); if(!data) return qfalse; if ( info.width == 1 ) { Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is a 8 bit audio file\n", sfx->soundName); } if ( info.rate != 22050 ) { Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz audio file\n", sfx->soundName); } samples = Hunk_AllocateTempMemory(info.channels * info.samples * sizeof(short) * 2); sfx->lastTimeUsed = Com_Milliseconds()+1; // each of these compression schemes works just fine // but the 16bit quality is much nicer and with a local // install assured we can rely upon the sound memory // manager to do the right thing for us and page // sound in as needed if( info.channels == 1 && sfx->soundCompressed == qtrue) { sfx->soundCompressionMethod = 1; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, data + info.dataofs ); S_AdpcmEncodeSound(sfx, samples); #if 0 } else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*16) && info.width >1) { sfx->soundCompressionMethod = 3; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) ); encodeMuLaw( sfx, samples); } else if (info.channels == 1 && info.samples>(SND_CHUNK_SIZE*6400) && info.width >1) { sfx->soundCompressionMethod = 2; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw( samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs) ); encodeWavelet( sfx, samples); #endif } else { sfx->soundCompressionMethod = 0; sfx->soundData = NULL; sfx->soundLength = ResampleSfx( sfx, info.channels, info.rate, info.width, info.samples, data + info.dataofs, qfalse ); } sfx->soundChannels = info.channels; Hunk_FreeTempMemory(samples); Hunk_FreeTempMemory(data); return qtrue; }
/* ================== SV_ChangeMaxClients ================== */ void SV_ChangeMaxClients( void ) { int oldMaxClients; int i; client_t *oldClients; int count; // get the highest client number in use count = 0; for ( i = 0 ; i < sv_maxclients->integer ; i++ ) { if ( svs.clients[i].state >= CS_CONNECTED ) { if (i > count) count = i; } } count++; oldMaxClients = sv_maxclients->integer; // never go below the highest client number in use SV_BoundMaxClients( count ); // if still the same if ( sv_maxclients->integer == oldMaxClients ) { return; } oldClients = Hunk_AllocateTempMemory( count * sizeof(client_t) ); // copy the clients to hunk memory for ( i = 0 ; i < count ; i++ ) { if ( svs.clients[i].state >= CS_CONNECTED ) { oldClients[i] = svs.clients[i]; } else { Com_Memset(&oldClients[i], 0, sizeof(client_t)); } } // free old clients arrays Z_Free( svs.clients ); // allocate new clients svs.clients = Z_Malloc ( sv_maxclients->integer * sizeof(client_t) ); Com_Memset( svs.clients, 0, sv_maxclients->integer * sizeof(client_t) ); // copy the clients over for ( i = 0 ; i < count ; i++ ) { if ( oldClients[i].state >= CS_CONNECTED ) { svs.clients[i] = oldClients[i]; } } // free the old clients on the hunk Hunk_FreeTempMemory( oldClients ); // allocate new snapshot entities if ( com_dedicated->integer ) { svs.numSnapshotEntities = sv_maxclients->integer * PACKET_BACKUP * 64; } else { // we don't need nearly as many when playing locally svs.numSnapshotEntities = sv_maxclients->integer * 4 * 64; } }
/* ================== R_TakeScreenshot ================== */ void R_TakeScreenshot( int x, int y, int width, int height, char *fileName ) { byte *buffer; int i, c, temp; buffer = (unsigned char *)Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*3+18); Com_Memset (buffer, 0, 18); buffer[2] = 2; // uncompressed type buffer[12] = width & 255; buffer[13] = width >> 8; buffer[14] = height & 255; buffer[15] = height >> 8; buffer[16] = 24; // pixel size qglReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); // swap rgb to bgr c = 18 + width * height * 3; for (i=18 ; i<c ; i+=3) { temp = buffer[i]; buffer[i] = buffer[i+2]; buffer[i+2] = temp; } // gamma correct if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) { R_GammaCorrect( buffer + 18, glConfig.vidWidth * glConfig.vidHeight * 3 ); } FS_WriteFile( fileName, buffer, c ); Hunk_FreeTempMemory( buffer ); }
/* ================= SV_LoadGame_f ================= */ void SV_LoadGame_f( void ) { char filename[MAX_QPATH], mapname[MAX_QPATH]; byte *buffer; int size; Q_strncpyz( filename, Cmd_Argv( 1 ), sizeof( filename ) ); if ( !filename[0] ) { Com_Printf( "You must specify a savegame to load\n" ); return; } if ( Q_strncmp( filename, "save/", 5 ) && Q_strncmp( filename, "save\\", 5 ) ) { Q_strncpyz( filename, va( "save/%s", filename ), sizeof( filename ) ); } if ( !strstr( filename, ".svg" ) ) { Q_strcat( filename, sizeof( filename ), ".svg" ); } size = FS_ReadFile( filename, NULL ); if ( size < 0 ) { Com_Printf( "Can't find savegame %s\n", filename ); return; } buffer = Hunk_AllocateTempMemory( size ); FS_ReadFile( filename, (void **)&buffer ); // read the mapname, if it is the same as the current map, then do a fast load Com_sprintf( mapname, sizeof( mapname ), buffer + sizeof( int ) ); if ( com_sv_running->integer && ( com_frameTime != sv.serverId ) ) { // check mapname if ( !Q_stricmp( mapname, sv_mapname->string ) ) { // same if ( Q_stricmp( filename, "save/current.svg" ) != 0 ) { // copy it to the current savegame file FS_WriteFile( "save/current.svg", buffer, size ); } Hunk_FreeTempMemory( buffer ); Cvar_Set( "savegame_loading", "2" ); // 2 means it's a restart, so stop rendering until we are loaded SV_MapRestart_f(); // savegame will be loaded after restart return; } } Hunk_FreeTempMemory( buffer ); // otherwise, do a slow load if ( Cvar_VariableIntegerValue( "sv_cheats" ) ) { Cbuf_ExecuteText( EXEC_APPEND, va( "spdevmap %s", filename ) ); } else { // no cheats Cbuf_ExecuteText( EXEC_APPEND, va( "spmap %s", filename ) ); } }
/* ===================================================================== S_OggOpus_CodecLoad We handle S_OggOpus_CodecLoad as a special case of the streaming functions where we read the whole stream at once. ====================================================================== */ void *S_OggOpus_CodecLoad( const char *filename, snd_info_t *info ) { snd_stream_t *stream; byte *buffer; int bytesRead; // check if input is valid if ( !( filename && info ) ) { return NULL; } // open the file as a stream stream = S_OggOpus_CodecOpenStream( filename ); if ( !stream ) { return NULL; } // copy over the info info->rate = stream->info.rate; info->width = stream->info.width; info->channels = stream->info.channels; info->samples = stream->info.samples; info->size = stream->info.size; info->dataofs = stream->info.dataofs; // allocate a buffer // this buffer must be free-ed by the caller of this function buffer = Hunk_AllocateTempMemory( info->size ); if ( !buffer ) { S_OggOpus_CodecCloseStream( stream ); return NULL; } // fill the buffer bytesRead = S_OggOpus_CodecReadStream( stream, info->size, buffer ); // we don't even have read a single byte if ( bytesRead <= 0 ) { Hunk_FreeTempMemory( buffer ); S_OggOpus_CodecCloseStream( stream ); return NULL; } S_OggOpus_CodecCloseStream( stream ); return buffer; }
void RE_SaveJPG(const char * filename, int quality, int image_width, int image_height, byte *image_buffer, int padding) { byte *out; size_t bufSize; bufSize = image_width * image_height * 3; out = (byte *)Hunk_AllocateTempMemory(bufSize); bufSize = RE_SaveJPGToBuffer(out, bufSize, quality, image_width, image_height, image_buffer, padding); ri->FS_WriteFile(filename, out, bufSize); Hunk_FreeTempMemory(out); }
/* ================ R_MipMap2 Operates in place, quartering the size of the texture Proper linear filter ================ */ static void R_MipMap2( unsigned *in, int inWidth, int inHeight ) { int i, j, k; byte *outpix; int inWidthMask, inHeightMask; int total; int outWidth, outHeight; unsigned *temp; outWidth = inWidth >> 1; outHeight = inHeight >> 1; temp = (unsigned int *)Hunk_AllocateTempMemory( outWidth * outHeight * 4 ); inWidthMask = inWidth - 1; inHeightMask = inHeight - 1; for ( i = 0 ; i < outHeight ; i++ ) { for ( j = 0 ; j < outWidth ; j++ ) { outpix = (byte *) ( temp + i * outWidth + j ); for ( k = 0 ; k < 4 ; k++ ) { total = 1 * ((byte *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] + 2 * ((byte *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] + 2 * ((byte *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] + 1 * ((byte *)&in[ ((i*2-1)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k] + 2 * ((byte *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] + 4 * ((byte *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] + 4 * ((byte *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] + 2 * ((byte *)&in[ ((i*2)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k] + 2 * ((byte *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] + 4 * ((byte *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] + 4 * ((byte *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] + 2 * ((byte *)&in[ ((i*2+1)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k] + 1 * ((byte *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2-1)&inWidthMask) ])[k] + 2 * ((byte *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2)&inWidthMask) ])[k] + 2 * ((byte *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2+1)&inWidthMask) ])[k] + 1 * ((byte *)&in[ ((i*2+2)&inHeightMask)*inWidth + ((j*2+2)&inWidthMask) ])[k]; outpix[k] = total / 36; } } } memcpy( in, temp, outWidth * outHeight * 4 ); Hunk_FreeTempMemory( temp ); }
/* ================== R_TakeScreenshot ================== */ void R_TakeScreenshotJPEG( int x, int y, int width, int height, char *fileName ) { byte *buffer; buffer = (unsigned char *)Hunk_AllocateTempMemory(glConfig.vidWidth*glConfig.vidHeight*4); qglReadPixels( x, y, width, height, GL_RGBA, GL_UNSIGNED_BYTE, buffer ); // gamma correct if ( ( tr.overbrightBits > 0 ) && glConfig.deviceSupportsGamma ) { R_GammaCorrect( buffer, glConfig.vidWidth * glConfig.vidHeight * 4 ); } FS_WriteFile( fileName, buffer, 1 ); // create path SaveJPG( fileName, 95, glConfig.vidWidth, glConfig.vidHeight, buffer); Hunk_FreeTempMemory( buffer ); }
/* =============== Cmd_Exec_f =============== */ void Cmd_Exec_f(void) { union { char *c; void *v; } f; int len; char filename[MAX_QPATH]; fileHandle_t h; bool success = false; if (Cmd_Argc () < 2) { Com_Printf ("exec <filename> (args) : execute a script file\n"); return; } Com_Printf ("execing %s\n", Cmd_Argv(1)); Q_strncpyz( filename, Cmd_Argv(1), sizeof( filename ) ); COM_DefaultExtension( filename, sizeof( filename ), ".cfg" ); len = FS_SV_FOpenFileRead(filename, &h); if (h) { success = true; f.v = Hunk_AllocateTempMemory(len + 1); FS_Read(f.v, len, h); f.c[len] = 0; FS_FCloseFile(h); Cmd_ExecFile(f.c); Hunk_FreeTempMemory(f.v); } FS_ReadFile( filename, &f.v); if (f.c) { success = true; Cmd_ExecFile(f.c); FS_FreeFile (f.v); } if (!success) Com_Printf ("couldn't exec %s\n",Cmd_Argv(1)); }
/* ================= S_WAV_CodecLoad ================= */ void *S_WAV_CodecLoad(const char *filename, snd_info_t *info) { fileHandle_t file; void *buffer; // Try to open the file FS_FOpenFileRead(filename, &file, qtrue, qtrue); if(!file) { Com_Printf( S_COLOR_RED "ERROR: Could not open \"%s\"\n", filename); return NULL; } // Read the RIFF header if(!S_ReadRIFFHeader(file, info)) { FS_FCloseFile(file); Com_Printf( S_COLOR_RED "ERROR: Incorrect/unsupported format in \"%s\"\n", filename); return NULL; } // Allocate some memory // buffer = Z_Malloc(info->size); buffer = Hunk_AllocateTempMemory(info->size); if(!buffer) { FS_FCloseFile(file); Com_Printf( S_COLOR_RED "ERROR: Out of memory reading \"%s\"\n", filename); return NULL; } // Read, byteswap FS_Read(buffer, info->size, file); S_ByteSwapRawSamples(info->samples, info->width, info->channels, (byte *)buffer); // Close and return FS_FCloseFile(file); return buffer; }
/* ============== S_LoadSound The filename may be different than sfx->name in the case of a forced fallback of a player specific sound ============== */ qboolean S_LoadSound(sfx_t * sfx) { byte *data; short *samples; snd_info_t info; // player specific sounds are never directly loaded if(sfx->soundName[0] == '*') { return qfalse; } // load it in data = S_CodecLoad(sfx->soundName, &info); if(!data) return qfalse; if(info.width == 1) { Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is a 8 bit wav file\n", sfx->soundName); } if(info.rate != 22050) { Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 22kHz wav file\n", sfx->soundName); } samples = Hunk_AllocateTempMemory(info.samples * sizeof(short) * 2); sfx->lastTimeUsed = Com_Milliseconds() + 1; sfx->soundLength = info.samples; sfx->soundData = NULL; ResampleSfx(sfx, info.rate, info.width, data + info.dataofs, qfalse); Hunk_FreeTempMemory(samples); Z_Free(data); return qtrue; }
byte *RB_ReadPixels(int x, int y, int width, int height, size_t *offset, int *padlen) { byte *buffer, *bufstart; int padwidth, linelen; GLint packAlign; qglGetIntegerv(GL_PACK_ALIGNMENT, &packAlign); linelen = width * 3; padwidth = PAD(linelen, packAlign); // Allocate a few more bytes so that we can choose an alignment we like buffer = (byte *)Hunk_AllocateTempMemory(padwidth * height + *offset + packAlign - 1); bufstart = (byte *)PADP((intptr_t) buffer + *offset, packAlign); qglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, bufstart); *offset = bufstart - buffer; *padlen = padwidth - linelen; return buffer; }
void NV_WriteConfig(){ char* buffer; if( nvEntered == qtrue ){ return; } buffer = Hunk_AllocateTempMemory(MAX_NVCONFIG_SIZE); if(!buffer){ Com_Printf( "Error Updating NVConfig: Hunk_Alloc failed\n" ); return; } Com_Memset(buffer,0,MAX_NVCONFIG_SIZE); Q_strcat(buffer,MAX_NVCONFIG_SIZE,"//Autogenerated non volatile config settings\n"); Cmd_WritePowerConfig( buffer, MAX_NVCONFIG_SIZE ); Auth_WriteAdminConfig( buffer, MAX_NVCONFIG_SIZE ); FS_SV_WriteFile(NV_CONFIGFILE, buffer, strlen(buffer)); Hunk_FreeTempMemory( buffer ); Com_DPrintf("NV-Config Updated\n"); }
/* ============== S_LoadSound The filename may be different than sfx->name in the case of a forced fallback of a player specific sound ============== */ qboolean S_LoadSound( sfx_t *sfx ) { byte *data; short *samples; wavinfo_t info; int size; // player specific sounds are never directly loaded if ( sfx->soundName[0] == '*' ) { return qfalse; } // load it in size = FS_ReadFile( sfx->soundName, (void **)&data ); if ( !data ) { return qfalse; } info = GetWavinfo( sfx->soundName, data, size ); if ( info.channels != 1 ) { Com_Printf( "%s is a stereo wav file\n", sfx->soundName ); FS_FreeFile( data ); return qfalse; } if ( info.width == 1 ) { Com_DPrintf( S_COLOR_YELLOW "WARNING: %s is a 8 bit wav file\n", sfx->soundName ); } if ( info.rate != 22050 ) { Com_DPrintf( S_COLOR_YELLOW "WARNING: %s is not a 22kHz wav file\n", sfx->soundName ); } samples = Hunk_AllocateTempMemory( info.samples * sizeof( short ) * 2 ); // DHM - Nerve sfx->lastTimeUsed = Sys_Milliseconds() + 1; // each of these compression schemes works just fine // but the 16bit quality is much nicer and with a local // install assured we can rely upon the sound memory // manager to do the right thing for us and page // sound in as needed if ( s_nocompressed->value ) { sfx->soundCompressionMethod = 0; sfx->soundLength = info.samples; sfx->soundData = NULL; ResampleSfx( sfx, info.rate, info.width, data + info.dataofs, qfalse ); } else if ( sfx->soundCompressed == qtrue ) { sfx->soundCompressionMethod = 1; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, ( data + info.dataofs ) ); S_AdpcmEncodeSound( sfx, samples ); #ifdef COMPRESSION } else if ( info.samples > ( SND_CHUNK_SIZE * 16 ) && info.width > 1 ) { sfx->soundCompressionMethod = 3; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, ( data + info.dataofs ) ); encodeMuLaw( sfx, samples ); } else if ( info.samples > ( SND_CHUNK_SIZE * 6400 ) && info.width > 1 ) { sfx->soundCompressionMethod = 2; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw( samples, info.rate, info.width, info.samples, ( data + info.dataofs ) ); encodeWavelet( sfx, samples ); #endif } else { sfx->soundCompressionMethod = 0; sfx->soundLength = info.samples; sfx->soundData = NULL; ResampleSfx( sfx, info.rate, info.width, data + info.dataofs, qfalse ); } Hunk_FreeTempMemory( samples ); FS_FreeFile( data ); return qtrue; }
/* ================== SV_ChangeMaxClients ================== */ void SV_ChangeMaxClients( void ) { int oldMaxClients; int i, j; client_t *oldClients; player_t *oldPlayers; int count; // get the highest client or player number in use count = 0; for ( i = 0 ; i < sv_maxclients->integer ; i++ ) { if ( svs.clients[i].state >= CS_CONNECTED || svs.players[i].inUse ) { if (i > count) count = i; } } count++; oldMaxClients = sv_maxclients->integer; // never go below the highest client number in use SV_BoundMaxClients( count ); // if still the same if ( sv_maxclients->integer == oldMaxClients ) { return; } oldClients = Hunk_AllocateTempMemory( count * sizeof(client_t) ); oldPlayers = Hunk_AllocateTempMemory( count * sizeof(player_t) ); // copy the clients and players to hunk memory for ( i = 0 ; i < count ; i++ ) { if ( svs.players[i].inUse && svs.players[i].client->state >= CS_CONNECTED ) { oldPlayers[i] = svs.players[i]; oldPlayers[i].client = NULL; // client pointer gets restored using localPlayers pointers. } else { Com_Memset(&oldPlayers[i], 0, sizeof(player_t)); } if ( svs.clients[i].state >= CS_CONNECTED ) { oldClients[i] = svs.clients[i]; // save player indexes for ( j = 0; j < MAX_SPLITVIEW; j++ ) { if (svs.clients[i].localPlayers[j]) { oldClients[i].localPlayers[j] = (void*)((svs.clients[i].localPlayers[j] - svs.players) + 1); } } } else { Com_Memset(&oldClients[i], 0, sizeof(client_t)); } } // free old clients and players arrays Z_Free( svs.clients ); Z_Free( svs.players ); // allocate new clients and players svs.clients = Z_Malloc ( sv_maxclients->integer * sizeof(client_t) ); Com_Memset( svs.clients, 0, sv_maxclients->integer * sizeof(client_t) ); svs.players = Z_Malloc ( sv_maxclients->integer * sizeof(player_t) ); Com_Memset( svs.players, 0, sv_maxclients->integer * sizeof(player_t) ); // copy the clients and players over for ( i = 0 ; i < count ; i++ ) { if ( oldPlayers[i].inUse ) { svs.players[i] = oldPlayers[i]; } if ( oldClients[i].state >= CS_CONNECTED ) { svs.clients[i] = oldClients[i]; // restore pointers for ( j = 0; j < MAX_SPLITVIEW; j++ ) { if (oldClients[i].localPlayers[j]) { svs.clients[i].localPlayers[j] = &svs.players[ (intptr_t)oldClients[i].localPlayers[j] - 1 ]; svs.clients[i].localPlayers[j]->client = &svs.clients[i]; } } } } // free the old playes and clients on the hunk Hunk_FreeTempMemory( oldPlayers ); Hunk_FreeTempMemory( oldClients ); // allocate new snapshot entities if ( !Com_GameIsSinglePlayer() ) { svs.numSnapshotEntities = sv_maxclients->integer * PACKET_BACKUP * MAX_SNAPSHOT_ENTITIES; } else { // we don't need nearly as many when playing locally svs.numSnapshotEntities = sv_maxclients->integer * 4 * MAX_SNAPSHOT_ENTITIES; } }
/* ================== SV_DemoChangeMaxClients change sv_maxclients and move real clients slots when a demo is playing or stopped ================== */ void SV_DemoChangeMaxClients(void) { int oldMaxClients, oldDemoClients; int i, j, k; client_t *oldClients = NULL; int count; //qboolean firstTime = svs.clients == NULL; // == Checking the prerequisites // Note: we check here that we have enough slots to fit all clients, and that it doesn't overflow the MAX_CLIENTS the engine can support. Also, we save the oldMaxClients and oldDemoClients values. // -- Get the highest client number in use count = 0; for (i = 0 ; i < sv_maxclients->integer ; i++) { if (svs.clients[i].state >= CS_CONNECTED) { if (i > count) { count = i; } } } count++; // -- Save the previous oldMaxClients and oldDemoClients values, and update // Save the previous sv_maxclients value before updating it oldMaxClients = sv_maxclients->integer; // update the cvars Cvar_Get("sv_maxclients", "8", 0); Cvar_Get("sv_democlients", "0", 0); // unnecessary now that sv_democlients is not latched anymore? // Save the previous sv_democlients (since it's updated instantly, we cannot get it directly), we use a trick by computing the difference between the new and previous sv_maxclients (the difference should indeed be the exact value of sv_democlients) oldDemoClients = (oldMaxClients - sv_maxclients->integer); if (oldDemoClients < 0) // if the difference is negative, this means that before it was set to 0 (because the newer sv_maxclients is greater than the old) { oldDemoClients = 0; } // -- Check limits // never go below the highest client number in use (make sure we have enough room for all players) SV_BoundMaxClients(count); // -- Change check: if still the same, we just quit, there's nothing to do if (sv_maxclients->integer == oldMaxClients) { return; } // == Memorizing clients // Note: we save in a temporary variables the clients, because after we will wipe completely the svs.clients struct // copy the clients to hunk memory oldClients = Hunk_AllocateTempMemory((sv_maxclients->integer - sv_democlients->integer) * sizeof(client_t)); // we allocate just enough memory for the real clients (not counting in the democlients) // For all previous clients slots, we copy the entire client into a temporary var for (i = 0, j = 0, k = sv_privateClients->integer ; i < oldMaxClients ; i++) // for all the previously connected clients, we copy them to a temporary var { // If there is a real client in this slot if (svs.clients[i].state >= CS_CONNECTED) { // if the client is in a privateClient reserved slot, we move him on the reserved slots if (i >= oldDemoClients && i < oldDemoClients + sv_privateClients->integer) { oldClients[j++] = svs.clients[i]; // else the client is not a privateClient, and we move him to the first available slot after the privateClients slots } else { oldClients[k++] = svs.clients[i]; } } } // Fill in the remaining clients slots with empty clients (else the engine crash when copying into memory svs.clients) for (i = j; i < sv_privateClients->integer; i++) // Fill the privateClients empty slots { Com_Memset(&oldClients[i], 0, sizeof(client_t)); } for (i = k; i < (sv_maxclients->integer - sv_democlients->integer); i++) // Fill the other normal clients slots { Com_Memset(&oldClients[i], 0, sizeof(client_t)); } // free old clients arrays Z_Free(svs.clients); // == Allocating the new svs.clients and moving the saved clients over from the temporary var // allocate new svs.clients svs.clients = Z_Malloc(sv_maxclients->integer * sizeof(client_t)); Com_Memset(svs.clients, 0, sv_maxclients->integer * sizeof(client_t)); // copy the clients over (and move them depending on sv_democlients: if >0, move them upwards, if == 0, move them to their original slots) Com_Memcpy(svs.clients + sv_democlients->integer, oldClients, (sv_maxclients->integer - sv_democlients->integer) * sizeof(client_t)); // free the old clients on the hunk Hunk_FreeTempMemory(oldClients); // == Allocating snapshot entities // allocate new snapshot entities if (com_dedicated->integer) { svs.numSnapshotEntities = sv_maxclients->integer * PACKET_BACKUP * 64; } else { // we don't need nearly as many when playing locally svs.numSnapshotEntities = sv_maxclients->integer * 4 * 64; } // == Server-side demos management // set demostate to none if it was just waiting to set maxclients and move real clients slots if (sv.demoState == DS_WAITINGSTOP) { sv.demoState = DS_NONE; Cvar_SetValue("sv_demoState", DS_NONE); } }
char * Sys_SecretSauce( char * buffer, int size ) { int len, bufLen; char *buf; bufLen = 4096; buf = Hunk_AllocateTempMemory( bufLen ); len = 0; if( bufLen - len >= sizeof( OSVERSIONINFO ) ) { OSVERSIONINFO vinfo; Com_Memset( &vinfo, 0, sizeof( vinfo ) ); //some bytes aren't written by the GetVersionEx vinfo.dwOSVersionInfoSize = sizeof( vinfo ); GetVersionEx( &vinfo ); Com_Memcpy( buf + len, &vinfo, sizeof( vinfo ) ); len += sizeof( vinfo ); } #if 0 // don't rely on mac address, if user disconects or disables then game becomes unregistered { DWORD cb, err; IP_ADAPTER_INFO *pInfos; cb = sizeof( IP_ADAPTER_INFO ) * 4; pInfos = Hunk_AllocateTempMemory( cb ); err = GetAdaptersInfo( pInfos, &cb ); if( err == ERROR_BUFFER_OVERFLOW ) { Hunk_FreeTempMemory( pInfos ); pInfos = Hunk_AllocateTempMemory( cb ); err = GetAdaptersInfo( pInfos, &cb ); } if( err == ERROR_SUCCESS ) { int i; int numAddrs = 0; int maxAddrs = cb / sizeof( IP_ADAPTER_INFO ); macAddr_t *addrs = Hunk_AllocateTempMemory( sizeof( macAddr_t ) * maxAddrs ); IP_ADAPTER_INFO *p; for( p = pInfos; p; p = p->Next ) { if( p->Type != MIB_IF_TYPE_ETHERNET ) continue; if( numAddrs == maxAddrs ) break; addrs[numAddrs].len = p->AddressLength; Com_Memcpy( &addrs[numAddrs].addr, p->Address, p->AddressLength ); numAddrs++; } qsort( addrs, numAddrs, sizeof( macAddr_t ), MacAddr_Cmp ); for( i = 0; i < numAddrs; i++ ) { if( addrs[i].len > bufLen - len ) break; Com_Memcpy( buf + len, addrs[i].addr, addrs[i].len ); len += addrs[i].len; } Hunk_FreeTempMemory( addrs ); } Hunk_FreeTempMemory( pInfos ); } #endif if( sizeof( cpuInfo_t ) <= bufLen - len ) { cpuInfo_t cpuInfo; Sys_GetCpuInfo( &cpuInfo ); Com_Memcpy( buf + len, &cpuInfo, sizeof( cpuInfo ) ); len += sizeof( cpuInfo ); } //MD5 the blob up Com_MD5Buffer( buffer, buf, len ); Hunk_FreeTempMemory( buf ); return buffer; }
/** * @brief The filename may be different than sfx->name in the case * of a forced fallback of a player specific sound * @param[in,out] sfx * @return */ qboolean S_LoadSound(sfx_t *sfx) { byte *data; short *samples; snd_info_t info; // player specific sounds are never directly loaded if (sfx->soundName[0] == '*') { return qfalse; } if (FS_FOpenFileRead(sfx->soundName, NULL, qfalse) <= 0) { // changed from debug to common print - let admins know and fix such missing files ... Com_Printf(S_COLOR_RED "ERROR: sound file \"%s\" does not exist or can't be read\n", sfx->soundName); return qfalse; } // load it in data = S_CodecLoad(sfx->soundName, &info); if (!data) { return qfalse; } if (info.width == 1) { Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is a 8 bit audio file\n", sfx->soundName); } if ((info.rate != 11025) && (info.rate != 22050) && (info.rate != 44100)) { Com_DPrintf(S_COLOR_YELLOW "WARNING: %s is not a 11kHz, 22kHz nor 44kHz audio file. It has sample rate %i\n", sfx->soundName, info.rate); } samples = Hunk_AllocateTempMemory(info.channels * info.samples * sizeof(short) * 2); sfx->lastTimeUsed = Sys_Milliseconds() + 1; // each of these compression schemes works just fine // but the 16bit quality is much nicer and with a local // install assured we can rely upon the sound memory // manager to do the right thing for us and page // sound in as needed if (info.channels == 1 && sfx->soundCompressed == qtrue) { sfx->soundCompressionMethod = 1; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw(samples, info.channels, info.rate, info.width, info.samples, data + info.dataofs); S_AdpcmEncodeSound(sfx, samples); #if 0 } else if (info.channels == 1 && info.samples > (SND_CHUNK_SIZE * 16) && info.width > 1) { sfx->soundCompressionMethod = 3; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw(samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs)); encodeMuLaw(sfx, samples); } else if (info.channels == 1 && info.samples > (SND_CHUNK_SIZE * 6400) && info.width > 1) { sfx->soundCompressionMethod = 2; sfx->soundData = NULL; sfx->soundLength = ResampleSfxRaw(samples, info.channels, info.rate, info.width, info.samples, (data + info.dataofs)); encodeWavelet(sfx, samples); #endif } else { sfx->soundCompressionMethod = 0; sfx->soundLength = info.samples; sfx->soundData = NULL; sfx->soundLength = ResampleSfx(sfx, info.channels, info.rate, info.width, info.samples, data + info.dataofs, qfalse); } sfx->soundChannels = info.channels; Hunk_FreeTempMemory(samples); Hunk_FreeTempMemory(data); return qtrue; }
/* ================== SV_ChangeMaxClients ================== */ void SV_ChangeMaxClients( void ) { int oldMaxClients; int i; client_t *oldClients; int count; // get the highest client number in use count = 0; for ( i = 0; i < sv_maxclients->integer; i++ ) { if ( svs.clients[ i ].state >= CS_CONNECTED ) { if ( i > count ) { count = i; } } } count++; oldMaxClients = sv_maxclients->integer; // never go below the highest client number in use SV_BoundMaxClients( count ); // if still the same if ( sv_maxclients->integer == oldMaxClients ) { return; } oldClients = Hunk_AllocateTempMemory( count * sizeof( client_t ) ); // copy the clients to hunk memory for ( i = 0; i < count; i++ ) { if ( svs.clients[ i ].state >= CS_CONNECTED ) { oldClients[ i ] = svs.clients[ i ]; } else { Com_Memset( &oldClients[ i ], 0, sizeof( client_t ) ); } } // free old clients arrays //Z_Free( svs.clients ); free( svs.clients ); // RF, avoid trying to allocate large chunk on a fragmented zone // allocate new clients // RF, avoid trying to allocate large chunk on a fragmented zone svs.clients = calloc( sizeof( client_t ) * sv_maxclients->integer, 1 ); if ( !svs.clients ) { Com_Error( ERR_FATAL, "SV_Startup: unable to allocate svs.clients" ); } Com_Memset( svs.clients, 0, sv_maxclients->integer * sizeof( client_t ) ); // copy the clients over for ( i = 0; i < count; i++ ) { if ( oldClients[ i ].state >= CS_CONNECTED ) { svs.clients[ i ] = oldClients[ i ]; } } // free the old clients on the hunk Hunk_FreeTempMemory( oldClients ); // allocate new snapshot entities if ( com_dedicated->integer ) { svs.numSnapshotEntities = sv_maxclients->integer * PACKET_BACKUP * 64; } else { // we don't need nearly as many when playing locally svs.numSnapshotEntities = sv_maxclients->integer * 4 * 64; } }
/* ================== SV_ChangeMaxClients ================== */ static void SV_ChangeMaxClients( void ) { int oldMaxClients; int i, j; client_t *oldClients = NULL; int count = 0; qboolean firstTime = svs.clients == NULL; if ( !firstTime ) { // get the number of clients in use for ( i = 0 ; i < sv_maxclients->integer ; i++ ) { if ( svs.clients[i].state >= CS_CONNECTED ) { count++; } } } oldMaxClients = sv_maxclients->integer; // update the cvars Cvar_Get( "sv_maxclients", "8", 0 ); Cvar_Get( "sv_democlients", "0", 0 ); // make sure we have enough room for all clients if ( sv_democlients->integer + count > MAX_CLIENTS ) Cvar_SetValue( "sv_democlients", MAX_CLIENTS - count ); if ( sv_maxclients->integer < sv_democlients->integer + count ) { Cvar_SetValue( "sv_maxclients", sv_democlients->integer + count ); } sv_maxclients->modified = qfalse; sv_democlients->modified = qfalse; // if still the same if ( !firstTime && sv_maxclients->integer == oldMaxClients ) { // move people who are below sv_democlients up for ( i = 0; i < sv_democlients->integer; i++ ) { if ( svs.clients[i].state >= CS_CONNECTED ) { for ( j = sv_democlients->integer; j < sv_maxclients->integer; j++ ) { if ( svs.clients[j].state < CS_CONNECTED ) { svs.clients[j] = svs.clients[i]; break; } } Com_Memset( svs.clients + i, 0, sizeof(client_t) ); } } return; } if ( !firstTime ) { // copy the clients to hunk memory oldClients = Hunk_AllocateTempMemory( count * sizeof(client_t) ); for ( i = 0, j = 0 ; i < oldMaxClients ; i++ ) { if ( svs.clients[i].state >= CS_CONNECTED ) { oldClients[j++] = svs.clients[i]; } } // free old clients arrays Z_Free( svs.clients ); } // allocate new clients svs.clients = Z_Malloc( sv_maxclients->integer * sizeof(client_t) ); Com_Memset( svs.clients, 0, sv_maxclients->integer * sizeof(client_t) ); if ( !firstTime ) { // copy the clients over Com_Memcpy( svs.clients + sv_democlients->integer, oldClients, count * sizeof(client_t) ); // free the old clients on the hunk Hunk_FreeTempMemory( oldClients ); } // allocate new snapshot entities if ( com_dedicated->integer ) { svs.numSnapshotEntities = sv_maxclients->integer * PACKET_BACKUP * 64; } else { // we don't need nearly as many when playing locally svs.numSnapshotEntities = sv_maxclients->integer * 4 * 64; } }
/* ================= CL_OpenJoystickRemap joystickIdent could be a name or hash ================= */ qboolean CL_OpenJoystickRemap( int localPlayerNum, const char *joystickName, const char *joystickIdent ) { fileHandle_t f; char filename[MAX_QPATH]; char *buffer, *text, *token; int len, i; joyevent_t joyevent; int key; if ( !joystickName ) { return qfalse; } if ( !joystickIdent ) { joystickIdent = joystickName; } // check if already loaded for ( i = 0; i < CL_MAX_SPLITVIEW; i++ ) { if ( !strcmp(joyDevice[i].ident, joystickIdent ) ) { break; } } if ( i != CL_MAX_SPLITVIEW ) { playerJoyRemapIndex[localPlayerNum] = i; joyDevice[i].references++; return qtrue; } // find free slot for ( i = 0; i < CL_MAX_SPLITVIEW; i++ ) { if ( !joyDevice[i].references ) { break; } } if ( i == CL_MAX_SPLITVIEW ) { Com_Printf("BUG: Tried to open joystick but no free slot\n"); playerJoyRemapIndex[localPlayerNum] = -1; return qfalse; } playerJoyRemapIndex[localPlayerNum] = i; // initialize remap Com_Memset( &joyDevice[i], 0, sizeof ( joyDevice[0] ) ); Q_strncpyz( joyDevice[i].ident, joystickIdent, sizeof ( joyDevice[i].ident ) ); Q_strncpyz( joyDevice[i].name, joystickName, sizeof ( joyDevice[i].ident ) ); joyDevice[i].references = 1; Com_sprintf( filename, sizeof ( filename ), "joy-%s-%s.txt", JOY_PLATFORM, joyDevice[i].ident ); len = FS_SV_FOpenFileRead( filename, &f ); if ( !f ) { return qfalse; } buffer = Hunk_AllocateTempMemory(len+1); FS_Read (buffer, len, f); // guarantee that it will have a trailing 0 for string operations buffer[len] = 0; FS_FCloseFile( f ); text = buffer; while ( 1 ) { token = COM_Parse( &text ); if ( !*token ) { break; } if ( !CL_StringToJoyEvent( token, &joyevent) ) { SkipRestOfLine( &text ); Com_Printf ("\"%s\" isn't a valid joystick event in %s\n", token, filename ); continue; } token = COM_ParseExt( &text, qfalse ); if ( !*token ) { Com_Printf("WARNING: Missing key for joy event in %s\n", filename ); continue; } key = Key_StringToKeynum( token ); if ( key == -1 ) { Com_Printf( "\"%s\" isn't a valid key in %s\n", token, filename ); continue; } if ( !CL_SetKeyForJoyEvent( localPlayerNum, &joyevent, key ) ) { Com_Printf ("Max joystick remaps reached (%d), cannot add remap for %s.\n", MAX_JOY_REMAPS, CL_JoyEventToString( &joyevent ) ); break; } } Hunk_FreeTempMemory( buffer ); return qtrue; }
/* ================ Con_Dump_f Save the console contents out to a file ================ */ void Con_Dump_f (void) { int l, x, i; int32_t *line; fileHandle_t f; int bufferlen; char *buffer; char filename[MAX_QPATH]; if (Cmd_Argc() != 2) { Com_Printf ("%s\n", SE_GetString("CON_TEXT_DUMP_USAGE")); return; } Q_strncpyz( filename, Cmd_Argv( 1 ), sizeof( filename ) ); COM_DefaultExtension( filename, sizeof( filename ), ".txt" ); if(!COM_CompareExtension(filename, ".txt")) { Com_Printf( "Con_Dump_f: Only the \".txt\" extension is supported by this command!\n" ); return; } f = FS_FOpenFileWrite( filename ); if (!f) { Com_Printf ("ERROR: couldn't open %s.\n", filename); return; } Com_Printf ("Dumped console text to %s.\n", filename ); // skip empty lines for (l = con.current - con.totallines + 1 ; l <= con.current ; l++) { line = con.text + (l%con.totallines)*con.linewidth; for (x=0 ; x<con.linewidth ; x++) if ((line[x] & 0xff) != ' ') //che break; if (x != con.linewidth) break; } #ifdef _WIN32 bufferlen = con.linewidth + 3 * sizeof ( char ); #else bufferlen = con.linewidth + 2 * sizeof ( char ); #endif buffer = (char *)Hunk_AllocateTempMemory( bufferlen ); // write the remaining lines buffer[bufferlen-1] = 0; for ( ; l <= con.current ; l++) { line = con.text + (l%con.totallines)*con.linewidth; for(i=0; i<con.linewidth; i++) buffer[i] = (char) (line[i] & 0xff); for (x=con.linewidth-1 ; x>=0 ; x--) { if (buffer[x] == ' ') buffer[x] = 0; else break; } #ifdef _WIN32 Q_strcat(buffer, bufferlen, "\r\n"); #else Q_strcat(buffer, bufferlen, "\n"); #endif FS_Write(buffer, strlen(buffer), f); } Hunk_FreeTempMemory( buffer ); FS_FCloseFile( f ); }