/* ================== 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 ); }
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.worldDir + strlen("maps/") ); source = (byte*) Z_Malloc( glConfig.vidWidth * glConfig.vidHeight * 3, TAG_TEMP_WORKSPACE, qfalse ); buffer = (byte*) Z_Malloc( LEVELSHOTSIZE * LEVELSHOTSIZE*3 + 18, TAG_TEMP_WORKSPACE, qfalse ); 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 ( glConfig.deviceSupportsGamma ) { R_GammaCorrect( buffer + 18, LEVELSHOTSIZE * LEVELSHOTSIZE * 3 ); } FS_WriteFile( checkname, buffer, LEVELSHOTSIZE * LEVELSHOTSIZE*3 + 18 ); Z_Free( buffer ); Z_Free( source ); VID_Printf( PRINT_ALL, "Wrote %s\n", checkname ); #endif }
void R_SaveTGA( const char* FileName, byte* Data, int Width, int Height, bool HaveAlpha ) { int Bpp = HaveAlpha ? 4 : 3; int Length = 18 + Width * Height * Bpp; byte* Buffer = new byte[ Length ]; 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 ] = 8 * Bpp; // pixel size // swap rgb to bgr for ( int i = 18; i < Length; i += Bpp ) { Buffer[ i ] = Data[ i - 18 + 2 ]; // blue Buffer[ i + 1 ] = Data[ i - 18 + 1 ]; // green Buffer[ i + 2 ] = Data[ i - 18 + 0 ]; // red if ( HaveAlpha ) { Buffer[ i + 3 ] = Data[ i - 18 + 3 ]; // alpha } } FS_WriteFile( FileName, Buffer, Length ); delete[] Buffer; }
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 }
void MD2GLCmdsRemove (const byte* buf, const char* fileName, int bufSize, void* userData) { uint32_t numGLCmds; const dMD2Model_t* md2 = (const dMD2Model_t*)buf; MD2HeaderCheck(md2, fileName, bufSize); numGLCmds = LittleLong(md2->num_glcmds); if (numGLCmds > 0) { byte *const copy = Mem_Dup(byte, buf, bufSize); dMD2Model_t* const fixedMD2 = (dMD2Model_t*)copy; const size_t delta = numGLCmds * sizeof(uint32_t); const uint32_t offset = LittleLong(fixedMD2->ofs_glcmds); if (LittleLong(fixedMD2->ofs_skins) > offset || LittleLong(fixedMD2->ofs_frames) > offset || LittleLong(fixedMD2->ofs_st) > offset || LittleLong(fixedMD2->ofs_tris) > offset) { Com_Error(ERR_DROP, "Unexpected order of the different data lumps"); } fixedMD2->ofs_end = LittleLong(fixedMD2->ofs_end - delta); fixedMD2->ofs_glcmds = 0; fixedMD2->num_glcmds = 0; bufSize -= delta; FS_WriteFile(fixedMD2, bufSize, fileName); Mem_Free(copy); *(size_t*)userData += delta; Com_Printf(" \\ - removed %i glcmds from '%s' (save " UFO_SIZE_T " bytes)\n", numGLCmds, fileName, delta); } }
static qboolean DoFileFindReplace( LPCSTR psMenuFile, LPCSTR psFind, LPCSTR psReplace ) { char *buffer; OutputDebugString(va("Loading: \"%s\"\n",psMenuFile)); int iLen = FS_ReadFile( psMenuFile,(void **) &buffer); if (iLen<1) { OutputDebugString("Failed!\n"); assert(0); return qfalse; } // find/rep... // string str(buffer); str += "\r\n"; // safety for *(char+1) stuff FS_FreeFile( buffer ); // let go of the buffer // originally this kept looping for replacements, but now it only does one (since the find/replace args are repeated // and this is called again if there are >1 replacements of the same strings to be made... // // int iReplacedCount = 0; char *pFound; int iSearchPos = 0; while ( (pFound = strstr(str.c_str()+iSearchPos,psFind)) != NULL) { // special check, the next char must be whitespace or carriage return etc, or we're not on a whole-word position... // int iFoundLoc = pFound - str.c_str(); char cAfterFind = pFound[strlen(psFind)]; if (cAfterFind > 32) { // ... then this string was part of a larger one, so ignore it... // iSearchPos = iFoundLoc+1; continue; } str.replace(iFoundLoc, strlen(psFind), psReplace); // iSearchPos = iFoundLoc+1; // iReplacedCount++; break; } // assert(iReplacedCount); // if (iReplacedCount>1) // { // int z=1; // } FS_WriteFile( psMenuFile, str.c_str(), strlen(str.c_str())); OutputDebugString("Ok\n"); return qtrue; }
/* ============ ConvRAW write to disk without conversions ============ */ bool ConvRAW( const char *name, byte *buffer, size_t filesize, const char *ext ) { if( FS_WriteFile( va("%s/%s.%s", gs_gamedir, name, ext ), buffer, filesize )) { Msg( "%s.%s\n", name, ext ); // echo to console return true; } return false; }
/* ================= 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 ) ); } }
void SaveJPG(const char * filename, int quality, int image_width, int image_height, unsigned char *image_buffer) { int iOutputSize = 0; byte *pbOut = Compress_JPG(&iOutputSize, quality, image_width, image_height, image_buffer, qtrue); FS_WriteFile( filename, pbOut, iOutputSize ); Z_Free(pbOut); }
// "filename" param is something like "screenshots/shot0000.tga" // note that if the last extension is ".jpg", then it'll save a JPG, else TGA // void R_TakeScreenshot( int x, int y, int width, int height, char *fileName ) { #ifndef _XBOX byte *buffer; int i, c, temp; qboolean bSaveAsJPG = !strnicmp(&fileName[strlen(fileName)-4],".jpg",4); if (bSaveAsJPG) { // JPG saver expects to be fed RGBA data, though it presumably ignores 'A'... // buffer = (unsigned char *) Z_Malloc(glConfig.vidWidth*glConfig.vidHeight*4, TAG_TEMP_WORKSPACE, qfalse); 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 ); } SaveJPG(fileName, 95, width, height, buffer); } else { // TGA... // buffer = (unsigned char *) Z_Malloc(glConfig.vidWidth*glConfig.vidHeight*3 + 18, TAG_TEMP_WORKSPACE, qfalse); 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 ); } Z_Free( buffer ); #endif }
/* ================== R_TakeScreenshot ================== */ void R_TakeScreenshot( int x, int y, int width, int height, char *fileName ) { byte *allbuf, *buffer; byte *srcptr, *destptr; byte *endline, *endmem; byte temp; int linelen, padlen; size_t offset = 18, memcount; allbuf = RB_ReadPixels(x, y, width, height, &offset, &padlen); buffer = allbuf + offset - 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 // swap rgb to bgr and remove padding from line endings linelen = width * 3; srcptr = destptr = allbuf + offset; endmem = srcptr + (linelen + padlen) * height; while(srcptr < endmem) { endline = srcptr + linelen; while(srcptr < endline) { temp = srcptr[0]; *destptr++ = srcptr[2]; *destptr++ = srcptr[1]; *destptr++ = temp; srcptr += 3; } // Skip the pad srcptr += padlen; } memcount = linelen * height; // gamma correct if(glConfig.deviceSupportsGamma) R_GammaCorrect(allbuf + offset, memcount); FS_WriteFile(fileName, buffer, memcount + 18); Hunk_FreeTempMemory(allbuf); }
static int write_server_file(qboolean autosave) { char name[MAX_OSPATH]; cvar_t *var; size_t len; qerror_t ret; uint64_t timestamp; // write magic MSG_WriteLong(SAVE_MAGIC1); MSG_WriteLong(SAVE_VERSION); timestamp = (uint64_t)time(NULL); // write the comment field MSG_WriteLong(timestamp & 0xffffffff); MSG_WriteLong(timestamp >> 32); MSG_WriteByte(autosave); MSG_WriteString(sv.configstrings[CS_NAME]); // write the mapcmd MSG_WriteString(sv.mapcmd); // write all CVAR_LATCH cvars // these will be things like coop, skill, deathmatch, etc for (var = cvar_vars; var; var = var->next) { if (!(var->flags & CVAR_LATCH)) continue; if (var->flags & CVAR_PRIVATE) continue; MSG_WriteString(var->name); MSG_WriteString(var->string); } MSG_WriteString(NULL); // write server state ret = FS_WriteFile("save/" SAVE_CURRENT "/server.ssv", msg_write.data, msg_write.cursize); SZ_Clear(&msg_write); if (ret < 0) return -1; // write game state len = Q_snprintf(name, MAX_OSPATH, "%s/save/" SAVE_CURRENT "/game.ssv", fs_gamedir); if (len >= MAX_OSPATH) return -1; ge->WriteGame(name, autosave); return 0; }
static int write_level_file(void) { char name[MAX_OSPATH]; int i; char *s; size_t len; byte portalbits[MAX_MAP_PORTAL_BYTES]; qerror_t ret; // write magic MSG_WriteLong(SAVE_MAGIC2); MSG_WriteLong(SAVE_VERSION); // write configstrings for (i = 0; i < MAX_CONFIGSTRINGS; i++) { s = sv.configstrings[i]; if (!s[0]) continue; len = strlen(s); if (len > MAX_QPATH) len = MAX_QPATH; MSG_WriteShort(i); MSG_WriteData(s, len); MSG_WriteByte(0); } MSG_WriteShort(MAX_CONFIGSTRINGS); len = CM_WritePortalBits(&sv.cm, portalbits); MSG_WriteByte(len); MSG_WriteData(portalbits, len); len = Q_snprintf(name, MAX_QPATH, "save/" SAVE_CURRENT "/%s.sv2", sv.name); if (len >= MAX_QPATH) ret = -1; else ret = FS_WriteFile(name, msg_write.data, msg_write.cursize); SZ_Clear(&msg_write); if (ret < 0) return -1; // write game level len = Q_snprintf(name, MAX_OSPATH, "%s/save/" SAVE_CURRENT "/%s.sav", fs_gamedir, sv.name); if (len >= MAX_OSPATH) return -1; ge->WriteLevel(name); return 0; }
void R_Shadow_SaveWorldLights(void) { int i; R_ShaderLight light; size_t bufchars, bufmaxchars; char *buf, *oldbuf; char name[MAX_QPATH]; char line[16384]; if (cl.worldmodel == NULL) { Con_Print("No map loaded.\n"); return; } COM_StripExtension (cl.worldmodel->name, name); strlcat (name, ".rtlights", sizeof (name)); bufchars = bufmaxchars = 0; buf = NULL; for (i=R_DROPLIGHT_MAX_LIGHTS, light = r_shader_lights[i]; i < R_MIN_SHADER_DLIGHTS; i++, light = r_shader_lights[i]) { if (!r_shader_lights[i].active) continue; if (light.coronasizescale != 0.25f || light.ambientscale != 0 || light.diffusescale != 1 || light.specularscale != 1 || light.flags != LIGHTFLAG_REALTIMEMODE) sprintf(line, "%s%f %f %f %f %f %f %f %d \"%s\" %f %f %f %f %f %f %f %f %i\n", light.shadow ? "" : "!", light.origin[0], light.origin[1], light.origin[2], light.maxDistance, light.color[0], light.color[1], light.color[2], light.style, light.cubemapname, light.corona, light.angles[0], light.angles[1], light.angles[2], light.coronasizescale, light.ambientscale, light.diffusescale, light.specularscale, light.flags); else if (light.cubemapname[0] || light.corona || light.angles[0] || light.angles[1] || light.angles[2]) sprintf(line, "%s%f %f %f %f %f %f %f %d \"%s\" %f %f %f %f\n", light.shadow ? "" : "!", light.origin[0], light.origin[1], light.origin[2], light.maxDistance, light.color[0], light.color[1], light.color[2], light.style, light.cubemapname, light.corona, light.angles[0], light.angles[1], light.angles[2]); else sprintf(line, "%s%f %f %f %f %f %f %f %d\n", light.shadow ? "" : "!", light.origin[0], light.origin[1], light.origin[2], light.maxDistance, light.color[0], light.color[1], light.color[2], light.style); if (bufchars + strlen(line) > bufmaxchars) { bufmaxchars = bufchars + strlen(line) + 2048; oldbuf = buf; buf = (char *)malloc(bufmaxchars); if (oldbuf) { if (bufchars) memcpy(buf, oldbuf, bufchars); free(oldbuf); } } if (strlen(line)) { memcpy(buf + bufchars, line, strlen(line)); bufchars += strlen(line); } } if (bufchars) FS_WriteFile(name, buf, (long)bufchars, FS_GAMEONLY); if (buf) free(buf); }
uint16_t DataloggerFile_WriteAtomic(DataloggerFile *dlgFile, uint8_t *data, uint16_t dataLen) { // Check if there is enough free space in the buffer for an atomic write if (dataLen > dlgFile->bufferFree) { return 0; } if (dlgFile->requestClose) { return 0; } // If the buffer is clear and the file is ready, write directly to the file if (dlgFile->bufferFree == dlgFile->bufferSize && dlgFile->file->state != FILE_Uninitialized && dlgFile->file->state != FILE_Creating) { fs_length_t writeLength = FS_WriteFile(dlgFile->file, data, dataLen); data += writeLength; dataLen -= writeLength; DBG_SPAM_printf("DLGFile: write->card %u bytes", writeLength); } while (dataLen > 0) { fs_length_t writeLength; // Determine maximum contigious write length if (dlgFile->readPos > dlgFile->writePos) { writeLength = dlgFile->bufferFree; } else { writeLength = dlgFile->bufferSize - dlgFile->writePos; } // Cap write length at data length if (dataLen < writeLength) { writeLength = dataLen; } // Write data and update buffer variables memcpy(dlgFile->buffer + dlgFile->writePos, data, writeLength); dlgFile->writePos += writeLength; if (dlgFile->writePos >= dlgFile->bufferSize) { dlgFile->writePos = 0; } dlgFile->bufferFree -= writeLength; // Update remaining data dataLen -= writeLength; data += writeLength; DBG_SPAM_printf("DLGFile: write->buffer %u bytes, bufFree = %u", writeLength, dlgFile->bufferFree); } return 1; }
fs_result_t DataloggerFile_Tasks(DataloggerFile *dlgFile) { // Check if there is data to write if (dlgFile->file->state != FILE_Uninitialized && dlgFile->file->state != FILE_Creating) { while (dlgFile->bufferFree != dlgFile->bufferSize) { fs_length_t writeLength; if (dlgFile->writePos > dlgFile->readPos) { writeLength = dlgFile->writePos - dlgFile->readPos; } else { writeLength = dlgFile->bufferSize - dlgFile->readPos; } writeLength = FS_WriteFile(dlgFile->file, dlgFile->buffer + dlgFile->readPos, writeLength); if (writeLength > 0) { dlgFile->readPos += writeLength; if (dlgFile->readPos >= dlgFile->bufferSize) { dlgFile->readPos = 0; } dlgFile->bufferFree += writeLength; DBG_SPAM_printf("DLGFile: buffer->card %u bytes, bufFree = %u", writeLength, dlgFile->bufferFree); } else { // No data written (no filesystem file buffer left), we're done break; } } } // Check if we want to close the file if (dlgFile->requestClose && !dlgFile->file->requestClose && dlgFile->bufferFree == dlgFile->bufferSize) { DBG_DATA_printf("DLGFile: Request file close"); FS_RequestFileClose(dlgFile->file); } if (T1CON == 0x00) { DBG_ERR_printf("T1CON = 0"); T1CON = 0x8002; } // Do filesystem tasks if (dlgFile->file->state != FILE_Uninitialized && dlgFile->file->state != FILE_Creating) { return FS_FileTasks(dlgFile->file); } else { return FS_UNREADY; } }
/* ================== 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 ); }
static void RB_TakeScreenshot( int x, int y, int width, int height, const char* fileName, bool IsJpeg ) { byte* buffer = new byte[ width * height * 3 ]; qglReadPixels( x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, buffer ); // gamma correct if ( tr.overbrightBits > 0 && glConfig.deviceSupportsGamma ) { R_GammaCorrect( buffer, width * height * 3 ); } if ( IsJpeg ) { FS_WriteFile( fileName, buffer, 1 ); // create path R_SaveJPG( fileName, 95, width, height, buffer ); } else { R_SaveTGA( fileName, buffer, width, height, false ); } delete[] buffer; }
/* * Class: xreal_Engine * Method: writeFile * Signature: (Ljava/lang/String;[B)V */ void JNICALL Java_xreal_Engine_writeFile(JNIEnv *env, jclass cls, jstring jfileName, jbyteArray array) { char *fileName; int length; byte *buf = NULL; fileName = (char *)((*env)->GetStringUTFChars(env, jfileName, 0)); length = (*env)->GetArrayLength(env, array); //Com_Printf("Java_xreal_Engine_writeFile: file '%s' has length = %i\n", fileName, length); buf = (byte*) malloc(length); (*env)->GetByteArrayRegion(env, array, 0, length, buf); FS_WriteFile(fileName, buf, length); (*env)->ReleaseStringUTFChars(env, jfileName, fileName); (*env)->ReleaseByteArrayElements(env, array, buf, 0); // Com_Dealloc(buf); }
TEST_F(WebApiTest, FileManagement) { if (Q_strnull(user) || Q_strnull(password)) return; /* we can only upload files from within our user directory - so let's copy it there */ if (!FS_FileExists("%s/" FILENAME, FS_Gamedir())) { byte* buf; const int size = FS_LoadFile(FILENAME, &buf); ASSERT_TRUE(size > 0); ASSERT_TRUE(nullptr != buf); FS_WriteFile(buf, size, FILENAME); FS_FreeFile(buf); } ASSERT_TRUE(WEB_CGameUpload(CGAME, CATEGORY, FILENAME)); ASSERT_TRUE(WEB_CGameDownloadFromUser(CGAME, CATEGORY, FILE, web_userid->integer)); const int countAfterUpload = WEB_CGameListForUser(CGAME, CATEGORY, web_userid->integer); ASSERT_TRUE(countAfterUpload != -1); ASSERT_TRUE(countAfterUpload >= 1); ASSERT_TRUE(WEB_CGameDelete(CGAME, CATEGORY, FILE)); const int countAfterDelete = WEB_CGameListForUser(CGAME, CATEGORY, web_userid->integer); ASSERT_TRUE(countAfterDelete != -1); ASSERT_EQ(countAfterDelete, countAfterUpload - 1); }
void VLight_DumpLightTable_f(void) { FS_WriteFile ("lighttable.raw", vlighttable, 256*256); }
qboolean Cmd_CheckMapsList_R( qboolean fRefresh, qboolean onlyingamedir ) { byte buf[MAX_SYSPATH]; char *buffer; string result; int i, size; search_t *t; file_t *f; if( FS_FileSize( "maps.lst", onlyingamedir ) > 0 && !fRefresh ) { MsgDev( D_NOTE, "maps.lst is exist: %s\n", onlyingamedir ? "basedir" : "gamedir" ); return true; // exist } t = FS_Search( "maps/*.bsp", false, onlyingamedir ); if( !t ) { if( onlyingamedir ) { // mod doesn't contain any maps (probably this is a bot) return Cmd_CheckMapsList_R( fRefresh, false ); } return false; } buffer = Mem_Alloc( host.mempool, t->numfilenames * 2 * sizeof( result )); for( i = 0; i < t->numfilenames; i++ ) { char *ents = NULL, *pfile; int ver = -1, lumpofs = 0, lumplen = 0; string mapname, message, entfilename; const char *ext = FS_FileExtension( t->filenames[i] ); if( Q_stricmp( ext, "bsp" )) continue; f = FS_Open( t->filenames[i], "rb", onlyingamedir ); FS_FileBase( t->filenames[i], mapname ); if( f ) { int num_spawnpoints = 0; dheader_t *header; Q_memset( buf, 0, MAX_SYSPATH ); FS_Read( f, buf, MAX_SYSPATH ); ver = *(uint *)buf; switch( ver ) { case Q1BSP_VERSION: case HLBSP_VERSION: case XTBSP_VERSION: header = (dheader_t *)buf; if( header->lumps[LUMP_ENTITIES].fileofs <= 1024 ) { lumpofs = header->lumps[LUMP_PLANES].fileofs; lumplen = header->lumps[LUMP_PLANES].filelen; } else { lumpofs = header->lumps[LUMP_ENTITIES].fileofs; lumplen = header->lumps[LUMP_ENTITIES].filelen; } break; } Q_strncpy( entfilename, t->filenames[i], sizeof( entfilename )); FS_StripExtension( entfilename ); FS_DefaultExtension( entfilename, ".ent" ); ents = FS_LoadFile( entfilename, NULL, true ); if( !ents && lumplen >= 10 ) { FS_Seek( f, lumpofs, SEEK_SET ); ents = (char *)Mem_Alloc( host.mempool, lumplen + 1 ); FS_Read( f, ents, lumplen ); } if( ents ) { // if there are entities to parse, a missing message key just // means there is no title, so clear the message string now char token[2048]; qboolean worldspawn = true; Q_strncpy( message, "No Title", MAX_STRING ); pfile = ents; while(( pfile = COM_ParseFile( pfile, token )) != NULL ) { if( token[0] == '}' && worldspawn ) worldspawn = false; else if( !Q_strcmp( token, "message" ) && worldspawn ) { // get the message contents pfile = COM_ParseFile( pfile, message ); } else if( !Q_strcmp( token, "classname" )) { pfile = COM_ParseFile( pfile, token ); if( !Q_strcmp( token, GI->mp_entity )) num_spawnpoints++; } if( num_spawnpoints ) break; // valid map } Mem_Free( ents ); } if( f ) FS_Close( f ); if( num_spawnpoints ) { // format: mapname "maptitle"\n Q_sprintf( result, "%s \"%s\"\n", mapname, message ); Q_strcat( buffer, result ); // add new string } } } if( t ) Mem_Free( t ); // free search result size = Q_strlen( buffer ); if( !size ) { if( buffer ) Mem_Free( buffer ); if( onlyingamedir ) return Cmd_CheckMapsList_R( fRefresh, false ); return false; } // write generated maps.lst if( FS_WriteFile( "maps.lst", buffer, Q_strlen( buffer ))) { if( buffer ) Mem_Free( buffer ); return true; } return false; }
/* ================== SV_Map_f Restart the server on a different map ================== */ static void SV_Map_f(void) { char *cmd, *map, smapname[MAX_QPATH], mapname[MAX_QPATH], expanded[MAX_QPATH], *cl_profileStr = Cvar_VariableString("cl_profile"); qboolean killBots, cheat, buildScript; int savegameTime = -1; map = Cmd_Argv(1); if(!map) { return; } if(!com_gameInfo.spEnabled) { if(!Q_stricmp(Cmd_Argv(0), "spdevmap") || !Q_stricmp(Cmd_Argv(0), "spmap")) { Com_Printf("Single Player is not enabled.\n"); return; } } buildScript = (qboolean)Cvar_VariableIntegerValue("com_buildScript"); if(SV_GameIsSinglePlayer()) { if(!buildScript && sv_reloading->integer && sv_reloading->integer != RELOAD_NEXTMAP) { // game is in 'reload' mode, don't allow starting new maps yet. return; } // Trap a savegame load if(strstr(map, ".sav")) { // open the savegame, read the mapname, and copy it to the map string char savemap[MAX_QPATH], savedir[MAX_QPATH]; byte *buffer; int size, csize; if(com_gameInfo.usesProfiles && cl_profileStr[0]) { Com_sprintf(savedir, sizeof(savedir), "profiles/%s/save/", cl_profileStr); } else { Q_strncpyz(savedir, "save/", sizeof(savedir)); } if(!(strstr(map, savedir) == map)) { Com_sprintf(savemap, sizeof(savemap), "%s%s", savedir, map); } else { strcpy(savemap, map); } size = FS_ReadFile(savemap, NULL); if(size < 0) { Com_Printf("Can't find savegame %s\n", savemap); return; } //buffer = Hunk_AllocateTempMemory(size); FS_ReadFile(savemap, (void **)&buffer); if(Q_stricmp(savemap, va("%scurrent.sav", savedir)) != 0) { // copy it to the current savegame file FS_WriteFile(va("%scurrent.sav", savedir), buffer, size); // make sure it is the correct size csize = FS_ReadFile(va("%scurrent.sav", savedir), NULL); if(csize != size) { Hunk_FreeTempMemory(buffer); FS_Delete(va("%scurrent.sav", savedir)); // TTimo #ifdef __linux__ Com_Error(ERR_DROP, "Unable to save game.\n\nPlease check that you have at least 5mb free of disk space in your home directory."); #else Com_Error(ERR_DROP, "Insufficient free disk space.\n\nPlease free at least 5mb of free space on game drive."); #endif return; } } // set the cvar, so the game knows it needs to load the savegame once the clients have connected Cvar_Set("savegame_loading", "1"); // set the filename Cvar_Set("savegame_filename", savemap); // the mapname is at the very start of the savegame file Q_strncpyz(savemap, (char *)(buffer + sizeof(int)), sizeof(savemap)); // skip the version Q_strncpyz(smapname, savemap, sizeof(smapname)); map = smapname; savegameTime = *(int *)(buffer + sizeof(int) + MAX_QPATH); if(savegameTime >= 0) { svs.time = savegameTime; } Hunk_FreeTempMemory(buffer); } else { Cvar_Set("savegame_loading", "0"); // make sure it's turned off // set the filename Cvar_Set("savegame_filename", ""); } } else { Cvar_Set("savegame_loading", "0"); // make sure it's turned off // set the filename Cvar_Set("savegame_filename", ""); } // make sure the level exists before trying to change, so that // a typo at the server console won't end the game Com_sprintf(expanded, sizeof(expanded), "maps/%s.bsp", map); if(FS_ReadFile(expanded, NULL) == -1) { Com_Printf("Can't find map %s\n", expanded); return; } Cvar_Set("gamestate", va("%i", GS_INITIALIZE)); // NERVE - SMF - reset gamestate on map/devmap Cvar_Set("g_currentRound", "0"); // NERVE - SMF - reset the current round Cvar_Set("g_nextTimeLimit", "0"); // NERVE - SMF - reset the next time limit // START Mad Doctor I changes, 8/14/2002. Need a way to force load a single player map as single player if(!Q_stricmp(Cmd_Argv(0), "spdevmap") || !Q_stricmp(Cmd_Argv(0), "spmap")) { // This is explicitly asking for a single player load of this map Cvar_Set("g_gametype", va("%i", com_gameInfo.defaultSPGameType)); // force latched values to get set Cvar_Get("g_gametype", va("%i", com_gameInfo.defaultSPGameType), CVAR_SERVERINFO | CVAR_USERINFO | CVAR_LATCH, "test"); // enable bot support for AI Cvar_Set("bot_enable", "1"); } // Rafael gameskill // Cvar_Get ("g_gameskill", "3", CVAR_SERVERINFO | CVAR_LATCH); // done cmd = Cmd_Argv(0); if(!Q_stricmp(cmd, "devmap")) { cheat = qtrue; killBots = qtrue; } else if(!Q_stricmp(Cmd_Argv(0), "spdevmap")) { cheat = qtrue; killBots = qtrue; } else { cheat = qfalse; killBots = qfalse; } // save the map name here cause on a map restart we reload the q3config.cfg // and thus nuke the arguments of the map command Q_strncpyz(mapname, map, sizeof(mapname)); // start up the map SV_SpawnServer(mapname, killBots); // set the cheat value // if the level was started with "map <levelname>", then // cheats will not be allowed. If started with "devmap <levelname>" // then cheats will be allowed if(cheat) { Cvar_Set("sv_cheats", "1"); } else { Cvar_Set("sv_cheats", "0"); } }
int main( int argc, char **argv ) { bspFile_t *bsp; int saveLength; void *saveData; char *conversion, *inputFile, *formatName, *outputFile; bspFormat_t *outFormat; void (*convertFunc)( bspFile_t *bsp ); if ( argc < 5 ) { Com_Printf( "bspsekai <conversion> <input-BSP> <format> <output-BSP>\n" ); Com_Printf( "BSP sekai - v0.1\n" ); Com_Printf( "Convert a BSP for use on a different engine\n" ); Com_Printf( "BSP conversion can lose data, keep the original BSP!\n" ); Com_Printf( "\n" ); Com_Printf( "<conversion> specifies how surface and content flags are remapped.\n" ); Com_Printf( "Conversion list:\n" ); Com_Printf( " none - No conversion.\n" ); Com_Printf( " nsco2et - Convert Navy SEALS: Covert Operation surface/content flags to ET values.\n" ); Com_Printf( " et2nsco - Convert ET surface/content flags to Navy SEALS: Covert Operation values.\n" ); Com_Printf( "\n" ); Com_Printf( "The format of <input-BSP> is automatically determined from the file.\n" ); Com_Printf( "Input BSP formats: (not all are fully supported)\n" ); Com_Printf( " Quake 3, RTCW, ET, EF, EF2, FAKK, Alice, Dark Salvation, MOHAA, Q3Test 1.06 or later, SoF2, JK2, JA\n" ); Com_Printf( "\n" ); Com_Printf( "<format> is used to determine output BSP format.\n" ); Com_Printf( "BSP format list:\n" ); Com_Printf( " quake3 - Quake 3.\n" ); //Com_Printf( " q3test106 - Q3Test 1.06/1.07/1.08. Later Q3Test versions use 'quake3' format.\n" ); Com_Printf( " rtcw - Return to Castle Wolfenstein.\n" ); Com_Printf( " et - Wolfenstein: Enemy Territory.\n" ); Com_Printf( " darks - Dark Salvation.\n" ); //Com_Printf( " rbsp - Raven's BSP format used by SoF2, Jedi Knight 2, and Jedi Academy.\n" ); //Com_Printf( " fakk - Heavy Metal: FAKK2.\n" ); //Com_Printf( " alice - American McGee's Alice.\n" ); //Com_Printf( " ef2 - Elite Force 2.\n" ); //Com_Printf( " mohaa - Medal of Honor Allied Assult.\n" ); return 0; } conversion = argv[1]; inputFile = argv[2]; formatName = argv[3]; outputFile = argv[4]; if ( Q_stricmp( conversion, "none" ) == 0 ) { convertFunc = NULL; } else if ( Q_stricmp( conversion, "nsco2et" ) == 0 ) { convertFunc = ConvertNscoToNscoET; } else if ( Q_stricmp( conversion, "et2nsco" ) == 0 ) { convertFunc = ConvertNscoETToNsco; } else { Com_Printf( "Error: Unknown conversion '%s'.\n", conversion ); return 1; } if ( Q_stricmp( formatName, "quake3" ) == 0 ) { outFormat = &quake3BspFormat; } else if ( Q_stricmp( formatName, "rtcw" ) == 0 ) { outFormat = &wolfBspFormat; } else if ( Q_stricmp( formatName, "et" ) == 0 ) { // ZTM: TODO: This need to be a different format than RTCW so that there is a different save function; so that converting et maps to rtcw can convert foliage outFormat = &wolfBspFormat; } else if ( Q_stricmp( formatName, "darks" ) == 0 ) { outFormat = &darksBspFormat; } else if ( Q_stricmp( formatName, "rbsp" ) == 0 ) { outFormat = &sof2BspFormat; } else if ( Q_stricmp( formatName, "fakk" ) == 0 ) { outFormat = &fakkBspFormat; } else if ( Q_stricmp( formatName, "alice" ) == 0 ) { outFormat = &aliceBspFormat; } else if ( Q_stricmp( formatName, "ef2" ) == 0 ) { outFormat = &ef2BspFormat; } else if ( Q_stricmp( formatName, "mohaa" ) == 0 ) { outFormat = &mohaaBspFormat; } else if ( Q_stricmp( formatName, "q3test106" ) == 0 ) { outFormat = &q3Test106BspFormat; } else { Com_Printf( "Error: Unknown format '%s'.\n", formatName ); return 1; } if ( Q_stricmp( inputFile, "-" ) == 0 || Q_stricmp( outputFile, "-" ) == 0 ) { Com_Printf( "Error: reading / writing to stdout is not supported.\n" ); return 1; } // this will work, but might result in user overwritting original BSP without backup. so let's baby the user. >.> if ( Q_stricmp( inputFile, outputFile ) == 0 ) { Com_Printf( "Error: same input and output file (exiting to avoid data lose)\n" ); return 1; } bsp = BSP_Load( inputFile ); if ( !bsp ) { Com_Printf( "Error: Could not read file '%s'\n", inputFile ); return 1; } Com_Printf( "Loaded BSP '%s' successfully.\n", inputFile ); if ( outFormat->saveFunction ) { if ( convertFunc ) { convertFunc( bsp ); } saveData = NULL; saveLength = outFormat->saveFunction( outFormat, outputFile, bsp, &saveData ); if ( saveData && FS_WriteFile( outputFile, saveData, saveLength ) == saveLength ) { Com_Printf( "Saved BSP '%s' successfully.\n", outputFile ); } else { Com_Printf( "Saving BSP '%s' failed.\n", outputFile ); } if ( saveData ) { free( saveData ); } } else { Com_Printf( "BSP format for '%s' does not support saving.\n", outFormat->gameName ); } BSP_Free( bsp ); return 0; }
/* ================= SV_LoadGame_f ================= */ void SV_LoadGame_f(void) { char filename[MAX_QPATH], mapname[MAX_QPATH], savedir[MAX_QPATH], *cl_profileStr = Cvar_VariableString("cl_profile"); byte *buffer; int size; // dont allow command if another loadgame is pending if(Cvar_VariableIntegerValue("savegame_loading")) { return; } if(sv_reloading->integer) { // (SA) disabling // if(sv_reloading->integer && sv_reloading->integer != RELOAD_FAILED ) // game is in 'reload' mode, don't allow starting new maps yet. return; } Q_strncpyz(filename, Cmd_Argv(1), sizeof(filename)); if(!filename[0]) { Com_Printf("You must specify a savegame to load\n"); return; } if(com_gameInfo.usesProfiles && cl_profileStr[0]) { Com_sprintf(savedir, sizeof(savedir), "profiles/%s/save/", cl_profileStr); } else { Q_strncpyz(savedir, "save/", sizeof(savedir)); } /*if ( Q_strncmp( filename, "save/", 5 ) && Q_strncmp( filename, "save\\", 5 ) ) { Q_strncpyz( filename, va("save/%s", filename), sizeof( filename ) ); } */ // go through a va to avoid vsnprintf call with same source and target Q_strncpyz(filename, va("%s%s", savedir, filename), sizeof(filename)); // enforce .sav extension if(!strstr(filename, ".") || Q_strncmp(strstr(filename, ".") + 1, "sav", 3)) { Q_strcat(filename, sizeof(filename), ".sav"); } // use '/' instead of '\\' for directories while(strstr(filename, "\\")) { *(char *)strstr(filename, "\\") = '/'; } 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 Q_strncpyz(mapname, (const char *)(buffer + sizeof(int)), sizeof(mapname)); if(com_sv_running->integer && (com_frameTime != sv.serverId)) { // check mapname if(!Q_stricmp(mapname, sv_mapname->string)) { // same if(Q_stricmp(filename, va("%scurrent.sav", savedir)) != 0) { // copy it to the current savegame file FS_WriteFile(va("%scurrent.sav", savedir), buffer, size); } Hunk_FreeTempMemory(buffer); Cvar_Set("savegame_loading", "2"); // 2 means it's a restart, so stop rendering until we are loaded // set the filename Cvar_Set("savegame_filename", filename); // quick-restart the server 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)); } }
/** * @brief This is a savegame function which stores the game in xml-Format. * @param[in] filename The Filename to save to (without extension) * @param[in] comment Description of the savegame * @param[out] error On failure an errormessage may be set. */ static bool SAV_GameSave (const char *filename, const char *comment, char **error) { xmlNode_t *topNode, *node; char savegame[MAX_OSPATH]; int res; int requiredBufferLength; uLongf bufLen; saveFileHeader_t header; char dummy[2]; int i; dateLong_t date; char message[30]; char timeStampBuffer[32]; if (!CP_IsRunning()) { *error = _("No campaign active."); Com_Printf("Error: No campaign active.\n"); return false; } if (!B_AtLeastOneExists()) { *error = _("Nothing to save yet."); Com_Printf("Error: Nothing to save yet.\n"); return false; } Com_MakeTimestamp(timeStampBuffer, sizeof(timeStampBuffer)); Com_sprintf(savegame, sizeof(savegame), "save/%s.%s", filename, SAVEGAME_EXTENSION); topNode = mxmlNewXML("1.0"); node = XML_AddNode(topNode, SAVE_ROOTNODE); /* writing Header */ XML_AddInt(node, SAVE_SAVEVERSION, SAVE_FILE_VERSION); XML_AddString(node, SAVE_COMMENT, comment); XML_AddString(node, SAVE_UFOVERSION, UFO_VERSION); XML_AddString(node, SAVE_REALDATE, timeStampBuffer); CP_DateConvertLong(&ccs.date, &date); Com_sprintf(message, sizeof(message), _("%i %s %02i"), date.year, Date_GetMonthName(date.month - 1), date.day); XML_AddString(node, SAVE_GAMEDATE, message); /* working through all subsystems. perhaps we should redesign it, order is not important anymore */ Com_Printf("Calling subsystems\n"); for (i = 0; i < saveSubsystemsAmount; i++) { if (!saveSubsystems[i].save(node)) Com_Printf("...subsystem '%s' failed to save the data\n", saveSubsystems[i].name); else Com_Printf("...subsystem '%s' - saved\n", saveSubsystems[i].name); } /* calculate the needed buffer size */ OBJZERO(header); header.compressed = LittleLong(save_compressed->integer); header.version = LittleLong(SAVE_FILE_VERSION); header.subsystems = LittleLong(saveSubsystemsAmount); Q_strncpyz(header.name, comment, sizeof(header.name)); Q_strncpyz(header.gameVersion, UFO_VERSION, sizeof(header.gameVersion)); CP_DateConvertLong(&ccs.date, &date); Com_sprintf(header.gameDate, sizeof(header.gameDate), _("%i %s %02i"), date.year, Date_GetMonthName(date.month - 1), date.day); Q_strncpyz(header.realDate, timeStampBuffer, sizeof(header.realDate)); requiredBufferLength = mxmlSaveString(topNode, dummy, 2, MXML_NO_CALLBACK); header.xmlSize = LittleLong(requiredBufferLength); byte* const buf = Mem_PoolAllocTypeN(byte, requiredBufferLength + 1, cp_campaignPool); if (!buf) { mxmlDelete(topNode); *error = _("Could not allocate enough memory to save this game"); Com_Printf("Error: Could not allocate enough memory to save this game\n"); return false; } res = mxmlSaveString(topNode, (char*)buf, requiredBufferLength + 1, MXML_NO_CALLBACK); mxmlDelete(topNode); Com_Printf("XML Written to buffer (%d Bytes)\n", res); if (header.compressed) bufLen = compressBound(requiredBufferLength); else bufLen = requiredBufferLength; byte* const fbuf = Mem_PoolAllocTypeN(byte, bufLen + sizeof(header), cp_campaignPool); memcpy(fbuf, &header, sizeof(header)); if (header.compressed) { res = compress(fbuf + sizeof(header), &bufLen, buf, requiredBufferLength); Mem_Free(buf); if (res != Z_OK) { Mem_Free(fbuf); *error = _("Memory error compressing save-game data - set save_compressed cvar to 0"); Com_Printf("Memory error compressing save-game data (%s) (Error: %i)!\n", comment, res); return false; } } else { memcpy(fbuf + sizeof(header), buf, requiredBufferLength); Mem_Free(buf); } /* last step - write data */ res = FS_WriteFile(fbuf, bufLen + sizeof(header), savegame); Mem_Free(fbuf); return true; }
void VID_StartupGamma( void ) { // Device supports gamma anyway, but cannot do anything with it. fs_offset_t gamma_size; byte *savedGamma; size_t gammaTypeSize = sizeof(glState.stateRamp); // init gamma ramp Q_memset( glState.stateRamp, 0, gammaTypeSize); #if defined(XASH_SDL) glConfig.deviceSupportsGamma = !SDL_GetWindowGammaRamp( host.hWnd, NULL, NULL, NULL); #endif if( !glConfig.deviceSupportsGamma ) { // force to set cvar Cvar_FullSet( "gl_ignorehwgamma", "1", CVAR_GLCONFIG ); MsgDev( D_ERROR, "VID_StartupGamma: hardware gamma unsupported\n"); } if( gl_ignorehwgamma->integer ) { glConfig.deviceSupportsGamma = false; // even if supported! BuildGammaTable( vid_gamma->value, vid_texgamma->value ); MsgDev( D_NOTE, "VID_StartupGamma: software gamma initialized\n" ); return; } // share this extension so engine can grab them GL_SetExtension( GL_HARDWARE_GAMMA_CONTROL, glConfig.deviceSupportsGamma ); savedGamma = FS_LoadFile( "gamma.dat", &gamma_size, false ); if( !savedGamma || gamma_size != (fs_offset_t)gammaTypeSize) { // saved gamma not found or corrupted file FS_WriteFile( "gamma.dat", glState.stateRamp, gammaTypeSize); MsgDev( D_NOTE, "VID_StartupGamma: gamma.dat initialized\n" ); if( savedGamma ) Mem_Free( savedGamma ); } else { GL_BuildGammaTable(); // validate base gamma if( !Q_memcmp( savedGamma, glState.stateRamp, gammaTypeSize)) { // all ok, previous gamma is valid MsgDev( D_NOTE, "VID_StartupGamma: validate screen gamma - ok\n" ); } else if( !Q_memcmp( glState.gammaRamp, glState.stateRamp, gammaTypeSize)) { // screen gamma is equal to render gamma (probably previous instance crashed) // run additional check to make sure for it if( Q_memcmp( savedGamma, glState.stateRamp, gammaTypeSize)) { // yes, current gamma it's totally wrong, restore it from gamma.dat MsgDev( D_NOTE, "VID_StartupGamma: restore original gamma after crash\n" ); Q_memcpy( glState.stateRamp, savedGamma, gammaTypeSize); } else { // oops, savedGamma == glState.stateRamp == glState.gammaRamp // probably r_gamma set as default MsgDev( D_NOTE, "VID_StartupGamma: validate screen gamma - disabled\n" ); } } else if( !Q_memcmp( glState.gammaRamp, savedGamma, gammaTypeSize)) { // saved gamma is equal render gamma, probably gamma.dat wroted after crash // run additional check to make sure it if( Q_memcmp( savedGamma, glState.stateRamp, gammaTypeSize)) { // yes, saved gamma it's totally wrong, get origianl gamma from screen MsgDev( D_NOTE, "VID_StartupGamma: merge gamma.dat after crash\n" ); FS_WriteFile( "gamma.dat", glState.stateRamp, gammaTypeSize); } else { // oops, savedGamma == glState.stateRamp == glState.gammaRamp // probably r_gamma set as default MsgDev( D_NOTE, "VID_StartupGamma: validate screen gamma - disabled\n" ); } } else { // current gamma unset by other application, so we can restore it here MsgDev( D_NOTE, "VID_StartupGamma: restore original gamma after crash\n" ); Q_memcpy( glState.stateRamp, savedGamma, gammaTypeSize); } Mem_Free( savedGamma ); } vid_gamma->modified = true; }
/* ============================== Netchan_CopyFileFragments ============================== */ qboolean Netchan_CopyFileFragments( netchan_t *chan, sizebuf_t *msg ) { fragbuf_t *p, *n; char filename[CS_SIZE]; int nsize; byte *buffer; int pos; if( !chan->incomingready[FRAG_FILE_STREAM] ) return false; if( !chan->incomingbufs[FRAG_FILE_STREAM] ) { MsgDev( D_WARN, "Netchan_CopyFileFragments: Called with no fragments readied\n" ); chan->incomingready[FRAG_FILE_STREAM] = false; return false; } p = chan->incomingbufs[FRAG_FILE_STREAM]; BF_Init( msg, "NetMessage", net_message_buffer, sizeof( net_message_buffer )); // copy in first chunk so we can get filename out BF_WriteBits( msg, BF_GetData( &p->frag_message ), BF_GetNumBitsWritten( &p->frag_message )); BF_SeekToBit( msg, 0 ); // rewind buffer //Q_strncpy( filename, BF_ReadString( msg ), sizeof( filename )); Q_snprintf( filename, sizeof( filename ), "downloaded/%s", BF_ReadString( msg ) ); if( Q_strlen( filename ) <= 0 ) { MsgDev( D_ERROR, "File fragment received with no filename\nFlushing input queue\n" ); // clear out bufs Netchan_FlushIncoming( chan, FRAG_FILE_STREAM ); return false; } else if( Q_strstr( filename, ".." )) { MsgDev( D_ERROR, "File fragment received with relative path, ignoring\n" ); // clear out bufs Netchan_FlushIncoming( chan, FRAG_FILE_STREAM ); return false; } Q_strncpy( chan->incomingfilename, filename, sizeof( chan->incomingfilename )); if( FS_FileExists( filename, false )) { MsgDev( D_ERROR, "Can't download %s, already exists\n", filename ); // clear out bufs Netchan_FlushIncoming( chan, FRAG_FILE_STREAM ); return true; } // create file from buffers nsize = 0; while ( p ) { nsize += BF_GetNumBytesWritten( &p->frag_message ); // Size will include a bit of slop, oh well if( p == chan->incomingbufs[FRAG_FILE_STREAM] ) { nsize -= BF_GetNumBytesRead( msg ); } p = p->next; } buffer = Mem_Alloc( net_mempool, nsize + 1 ); p = chan->incomingbufs[ FRAG_FILE_STREAM ]; pos = 0; while( p ) { int cursize; n = p->next; cursize = BF_GetNumBytesWritten( &p->frag_message ); // first message has the file name, don't write that into the data stream, // just write the rest of the actual data if( p == chan->incomingbufs[FRAG_FILE_STREAM] ) { // copy it in cursize -= BF_GetNumBytesRead( msg ); Q_memcpy( &buffer[pos], &p->frag_message.pData[BF_GetNumBytesRead( msg )], cursize ); } else { Q_memcpy( &buffer[pos], p->frag_message.pData, cursize ); } pos += cursize; Mem_Free( p ); p = n; } FS_WriteFile( filename, buffer, pos ); Mem_Free( buffer ); // clear remnants BF_Clear( msg ); chan->incomingbufs[FRAG_FILE_STREAM] = NULL; // reset flag chan->incomingready[FRAG_FILE_STREAM] = false; return true; }