/** * @brief Displays an error message and writes the error into crashlog.txt * @param[in] error Error String */ void Sys_ErrorDialog(const char *error) { char buffer[1024]; unsigned int size; int f = -1; const char *homepath = Cvar_VariableString("fs_homepath"); const char *gamedir = Cvar_VariableString("fs_gamedir"); const char *fileName = "crashlog.txt"; char *dirpath = FS_BuildOSPath(homepath, gamedir, ""); char *ospath = FS_BuildOSPath(homepath, gamedir, fileName); Sys_Print(va("%s\n", error)); #ifndef DEDICATED // We may have grabbed input devices. Need to release. if (SDL_WasInit(SDL_INIT_VIDEO)) { SDL_WM_GrabInput(SDL_GRAB_OFF); } Sys_Dialog(DT_ERROR, va("%s\nSee \"%s\" for details.\n", error, ospath), "Error"); #endif // Make sure the write path for the crashlog exists... // check homepath if (!Sys_Mkdir(homepath)) { Com_Printf("ERROR: couldn't create path '%s' to write file '%s'.\n", homepath, ospath); return; } // check gamedir (inside homepath) if (!Sys_Mkdir(dirpath)) { Com_Printf("ERROR: couldn't create path '%s' to write file '%s'.\n", dirpath, ospath); return; } // We might be crashing because we maxed out the Quake MAX_FILE_HANDLES, // which will come through here, so we don't want to recurse forever by // calling FS_FOpenFileWrite()...use the Unix system APIs instead. f = open(ospath, O_CREAT | O_TRUNC | O_WRONLY, 0640); if (f == -1) { Com_Printf("ERROR: couldn't open '%s'\n", fileName); return; } // We're crashing, so we don't care much if write() or close() fails. while ((size = CON_LogRead(buffer, sizeof(buffer))) > 0) { if (write(f, buffer, size) != size) { Com_Printf("ERROR: couldn't fully write to '%s'\n", fileName); break; } } close(f); }
/* * Creates any directories needed to store the given filename. */ void FS_CreatePath(char *path) { char *cur; /* Current '/'. */ char *old; /* Old '/'. */ FS_DPrintf("FS_CreatePath(%s)\n", path); if (strstr(path, "..") != NULL) { Com_Printf("WARNING: refusing to create relative path '%s'.\n", path); return; } cur = old = path; while (cur != NULL) { if ((cur - old) > 1) { *cur = '\0'; Sys_Mkdir(path); *cur = '/'; } old = cur; cur = strchr(old + 1, '/'); } }
void CL_LocWrite(char *filename) { char mapname[32]; int i; FILE *f; strcpy(mapname, cl.configstrings[CS_MODELS + 1] + 5); // Xile; lets just keep saving em to one file mmmkay? mapname[strlen(mapname) - 4] = 0; Sys_Mkdir("locs"); if (!(f = fopen(va("locs/%s.loc", mapname), "w"))) { Com_Printf("Warning: Unable to open locs/%s.loc for writing.\n", mapname); return; } for (i = 0; i < MAX_LOCATIONS; i++) { if (!locations[i].used) continue; fprintf(f, "%d %d %d %s\n", locations[i].origin[0], locations[i].origin[1], locations[i].origin[2], locations[i].name); } fclose(f); Com_Printf("locs/%s.loc was successfully saved.\n", mapname); }
const char* PbSv6makefn(char *outmodname, char *modulename) { char homepath[MAX_OSPATH]; if ( !pbsv.pbPath[0] ) { PbSvBuildBasePath( pbsv.pbPath ); PbSvBuildHomePath( homepath ); if ( Q_stricmp(homepath, pbsv.pbPath) && homepath[0] && pbsv.pbPath[0] ) { Sys_Mkdir( pbsv.pbPath ); Sys_Mkdir( homepath ); PbSvMakeHomepathCopy("pbsv" DLL_EXT, homepath); PbSvMakeHomepathCopy("pbcl" DLL_EXT, homepath); PbSvMakeHomepathCopy("pbag" DLL_EXT, homepath); } } Q_strncpyz(outmodname, pbsv.pbPath, MAX_OSPATH); Q_strcat(outmodname, MAX_OSPATH, modulename); return outmodname; }
/* ============ FS_CreatePath Creates any directories needed to store the given filename ============ */ void FS_CreatePath (char *path) { char *ofs; for (ofs = path+1 ; *ofs ; ofs++) { if (*ofs == '/') { // create the directory *ofs = 0; Sys_Mkdir (path); *ofs = '/'; } } }
/* ================== R_ScreenShot_f ================== */ void R_ScreenShot_f (void) { int i; char pcxname[80]; char checkname[MAX_OSPATH]; FILE *f; byte palette[768]; // create the scrnshots directory if it doesn't exist Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir()); Sys_Mkdir (checkname); // // find a file name to save it to // strcpy(pcxname,"quake00.pcx"); for (i=0 ; i<=99 ; i++) { pcxname[5] = i/10 + '0'; pcxname[6] = i%10 + '0'; Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), pcxname); f = fopen (checkname, "r"); if (!f) break; // file doesn't exist fclose (f); } if (i==100) { ri.Con_Printf (PRINT_ALL, "R_ScreenShot_f: Couldn't create a PCX"); return; } // turn the current 32 bit palette into a 24 bit palette for (i=0 ; i<256 ; i++) { palette[i*3+0] = sw_state.currentpalette[i*4+0]; palette[i*3+1] = sw_state.currentpalette[i*4+1]; palette[i*3+2] = sw_state.currentpalette[i*4+2]; } // // save the pcx file // WritePCXfile (checkname, vid.buffer, vid.width, vid.height, vid.rowbytes, palette); ri.Con_Printf (PRINT_ALL, "Wrote %s\n", checkname); }
void Sys_RedirectStdout(void) { char *cur; char *old; char dir[MAX_OSPATH]; char path_stdout[MAX_OSPATH]; char path_stderr[MAX_OSPATH]; const char *tmp; if (is_portable) { tmp = Sys_GetBinaryDir(); Q_strlcpy(dir, tmp, sizeof(dir)); } else { tmp = Sys_GetHomeDir(); Q_strlcpy(dir, tmp, sizeof(dir)); } if (dir == NULL) { return; } cur = old = dir; while (cur != NULL) { if ((cur - old) > 1) { *cur = '\0'; Sys_Mkdir(dir); *cur = '/'; } old = cur; cur = strchr(old + 1, '/'); } snprintf(path_stdout, sizeof(path_stdout), "%s/%s", dir, "stdout.txt"); snprintf(path_stderr, sizeof(path_stderr), "%s/%s", dir, "stderr.txt"); freopen(path_stdout, "w", stdout); freopen(path_stderr, "w", stderr); }
static void Sys_ErrorDialog( const char *error ) { time_t rawtime; char timeStr[32] = {}; // should really only reach ~19 chars char crashLogPath[MAX_OSPATH]; time( &rawtime ); strftime( timeStr, sizeof( timeStr ), "%Y-%m-%d_%H-%M-%S", localtime( &rawtime ) ); // or gmtime Com_sprintf( crashLogPath, sizeof( crashLogPath ), "%s%ccrashlog-%s.txt", Sys_DefaultHomePath(), PATH_SEP, timeStr ); Sys_Mkdir( Sys_DefaultHomePath() ); FILE *fp = fopen( crashLogPath, "w" ); if ( fp ) { ConsoleLogWriteOut( fp ); fclose( fp ); const char *errorMessage = va( "%s\n\nThe crash log was written to %s", error, crashLogPath ); if ( SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Error", errorMessage, NULL ) < 0 ) { fprintf( stderr, "%s", errorMessage ); } } else { // Getting pretty desperate now ConsoleLogWriteOut( stderr ); fflush( stderr ); const char *errorMessage = va( "%s\nCould not write the crash log file, but we printed it to stderr.\n" "Try running the game using a command line interface.", error ); if ( SDL_ShowSimpleMessageBox( SDL_MESSAGEBOX_ERROR, "Error", errorMessage, NULL ) < 0 ) { // We really have hit rock bottom here :( fprintf( stderr, "%s", errorMessage ); } } }
/* ============ FS_CreatePath Creates any directories needed to store the given filename ============ */ void FS_CreatePath (char *OSPath) { char *ofs; // make absolutely sure that it can't back up the path // FIXME: is c: allowed??? if ( strstr( OSPath, ".." ) || strstr( OSPath, "::" ) ) { Com_Printf( "WARNING: refusing to create relative path \"%s\"\n", OSPath ); return; } strlwr(OSPath); for (ofs = OSPath+1 ; *ofs ; ofs++) { if (*ofs == PATH_SEP) { // create the directory *ofs = 0; Sys_Mkdir (OSPath); *ofs = PATH_SEP; } } }
/* ============ FS_CreatePath Creates any directories needed to store the given filename ============ */ void FS_CreatePath(char *path) { char *ofs; // Knightmare added if (strstr(path, "..") || strstr(path, "::") || strstr(path, "\\\\") || strstr(path, "//")) { Com_Printf("WARNING: refusing to create relative path '%s'\n", path); return; } for (ofs = path + 1; *ofs; ofs++) { if (*ofs == '/') { // create the directory *ofs = 0; Sys_Mkdir(path); *ofs = '/'; } } }
/* ================== R_ScreenShot_f ================== */ void R_ScreenShot_f (void) { int i; // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Allocating in big stack. Stack in this device is pretty small: //char pcxname[80]; //char checkname[MAX_OSPATH]; //FILE *f; //byte palette[768]; FILE *f; char* pcxname = Sys_BigStackAlloc(80, "R_ScreenShot_f"); char* checkname = Sys_BigStackAlloc(MAX_OSPATH, "R_ScreenShot_f"); byte* palette = Sys_BigStackAlloc(768, "R_ScreenShot_f"); // <<< FIX // create the scrnshots directory if it doesn't exist // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Adjusting for previous fix: //Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir()); Com_sprintf (checkname, MAX_OSPATH, "%s/scrnshot", ri.FS_Gamedir()); // <<< FIX Sys_Mkdir (checkname); // // find a file name to save it to // strcpy(pcxname,"quake00.pcx"); for (i=0 ; i<=99 ; i++) { pcxname[5] = i/10 + '0'; pcxname[6] = i%10 + '0'; // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Adjusting for previous fix: //Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), pcxname); Com_sprintf (checkname, MAX_OSPATH, "%s/scrnshot/%s", ri.FS_Gamedir(), pcxname); // <<< FIX f = fopen (checkname, "r"); if (!f) break; // file doesn't exist fclose (f); } if (i==100) { ri.Con_Printf (PRINT_ALL, "R_ScreenShot_f: Couldn't create a PCX"); // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Deallocating from previous fix: Sys_BigStackFree(80 + MAX_OSPATH + 768, "R_ScreenShot_f"); // <<< FIX return; } // turn the current 32 bit palette into a 24 bit palette for (i=0 ; i<256 ; i++) { palette[i*3+0] = sw_state.currentpalette[i*4+0]; palette[i*3+1] = sw_state.currentpalette[i*4+1]; palette[i*3+2] = sw_state.currentpalette[i*4+2]; } // // save the pcx file // WritePCXfile (checkname, vid.buffer, vid.width, vid.height, vid.rowbytes, palette); ri.Con_Printf (PRINT_ALL, "Wrote %s\n", checkname); // >>> FIX: For Nintendo Wii using devkitPPC / libogc // Deallocating from previous fix: Sys_BigStackFree(80 + MAX_OSPATH + 768, "R_ScreenShot_f"); // <<< FIX }
void R_ScreenShot(void) { byte *buffer, temp; char picname[80]; char checkname[MAX_OSPATH]; int i, c; FILE *f; /* create the scrnshots directory if it doesn't exist */ Com_sprintf(checkname, sizeof(checkname), "%s/scrnshot", FS_Gamedir()); Sys_Mkdir(checkname); /* find a file name to save it to */ strcpy(picname, "quake00.tga"); for (i = 0; i <= 99; i++) { picname[5] = i / 10 + '0'; picname[6] = i % 10 + '0'; Com_sprintf(checkname, sizeof(checkname), "%s/scrnshot/%s", FS_Gamedir(), picname); f = fopen(checkname, "rb"); if (!f) { break; /* file doesn't exist */ } fclose(f); } if (i == 100) { VID_Printf(PRINT_ALL, "SCR_ScreenShot_f: Couldn't create a file\n"); return; } static const int headerLength = 18+4; c = headerLength + vid.width * vid.height * 3; buffer = malloc(c); if (!buffer) { VID_Printf(PRINT_ALL, "SCR_ScreenShot_f: Couldn't malloc %d bytes\n", c); return; } memset(buffer, 0, headerLength); buffer[0] = 4; // image ID: "yq2\0" buffer[2] = 2; /* uncompressed type */ buffer[12] = vid.width & 255; buffer[13] = vid.width >> 8; buffer[14] = vid.height & 255; buffer[15] = vid.height >> 8; buffer[16] = 24; /* pixel size */ buffer[17] = 0; // image descriptor buffer[18] = 'y'; // following: the 4 image ID fields buffer[19] = 'q'; buffer[20] = '2'; buffer[21] = '\0'; glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadPixels(0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, buffer + headerLength); /* swap rgb to bgr */ for (i = headerLength; i < c; i += 3) { temp = buffer[i]; buffer[i] = buffer[i + 2]; buffer[i + 2] = temp; } f = fopen(checkname, "wb"); if (f) { fwrite(buffer, 1, c, f); fclose(f); VID_Printf(PRINT_ALL, "Wrote %s\n", picname); } else { VID_Printf(PRINT_ALL, "SCR_ScreenShot_f: Couldn't write %s\n", picname); } free(buffer); }
void CL_AnimDump (void) { byte *buffer; char checkname[MAX_OSPATH]; int c, temp,o; unsigned int i; FILE *f; // create the scrnshots directory if it doesn't exist Com_sprintf (checkname, sizeof(checkname), "%s/animdump", ri.FS_Gamedir()); Sys_Mkdir (checkname); // // find a file name to save it to // for (i = cl_anim_count; i <= 99999999; i++) { Com_sprintf(checkname, sizeof(checkname), "%s/animdump/anim%5i.tga", ri.FS_Gamedir(), i); for (o = 0; o < strlen(checkname); o++) if (checkname[o] == ' ') checkname[o] = '0'; f = fopen (checkname, "rb"); if (!f) break; // file doesn't exist fclose(f); } if (i == 100000000) { ri.Cvar_Set("cl_animdump", "0"); ri.Con_Printf(PRINT_ALL, "CL_AnimDump: Max frames exported.\n"); return; } cl_anim_count = i; buffer = malloc(vid.width*vid.height*3 + 18); memset (buffer, 0, 18); buffer[2] = 2; // uncompressed type buffer[12] = vid.width&255; buffer[13] = vid.width>>8; buffer[14] = vid.height&255; buffer[15] = vid.height>>8; buffer[16] = 24; // pixel size qgl.PixelStorei(GL_PACK_ALIGNMENT, 1); qgl.ReadPixels(0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, buffer + 18); apply_gamma(buffer + 18, vid.width, vid.height); // jitgamma -- apply video gammaramp to screenshot // swap rgb to bgr c = 18 + vid.width * vid.height * 3; for (i=18 ; i<c ; i+=3) { temp = buffer[i]; buffer[i] = buffer[i+2]; buffer[i+2] = temp; } f = fopen (checkname, "wb"); fwrite (buffer, 1, c, f); fclose (f); free (buffer); }
/* ================== GL_ScreenShot_f ================== */ void GL_ScreenShot_f (void) { byte *buffer; char picname[80]; char checkname[MAX_OSPATH]; int i, c, temp; FILE *f; // create the scrnshots directory if it doesn't exist Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir()); Sys_Mkdir (checkname); // // find a file name to save it to // strcpy(picname,"quake00.tga"); for (i=0 ; i<=99 ; i++) { picname[5] = i/10 + '0'; picname[6] = i%10 + '0'; Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), picname); f = fopen (checkname, "rb"); if (!f) break; // file doesn't exist fclose (f); } if (i==100) { ri.Con_Printf (PRINT_ALL, "SCR_ScreenShot_f: Couldn't create a file\n"); return; } buffer = malloc(vid.width*vid.height*3 + 18); memset (buffer, 0, 18); buffer[2] = 2; // uncompressed type buffer[12] = vid.width&255; buffer[13] = vid.width>>8; buffer[14] = vid.height&255; buffer[15] = vid.height>>8; buffer[16] = 24; // pixel size qglReadPixels (0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, buffer+18 ); // swap rgb to bgr c = 18+vid.width*vid.height*3; for (i=18 ; i<c ; i+=3) { temp = buffer[i]; buffer[i] = buffer[i+2]; buffer[i+2] = temp; } f = fopen (checkname, "wb"); fwrite (buffer, 1, c, f); fclose (f); free (buffer); ri.Con_Printf (PRINT_ALL, "Wrote %s\n", picname); }
/* ================== GL_ScreenShot_JPG By Robert 'Heffo' Heffernan ================== */ void GL_ScreenShot_JPG_f (void) { struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; byte *rgbdata; JSAMPROW s[1]; FILE *file; char picname[80], checkname[MAX_OSPATH]; int i, offset; // Create the scrnshots directory if it doesn't exist Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir()); Sys_Mkdir (checkname); // Find a file name to save it to strcpy(picname,"quake00.jpg"); for (i=0 ; i<=99 ; i++) { picname[5] = i/10 + '0'; picname[6] = i%10 + '0'; Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), picname); file = fopen (checkname, "rb"); if (!file) break; // file doesn't exist fclose (file); } if (i==100) { ri.Con_Printf (PRINT_ALL, "SCR_JPGScreenShot_f: Couldn't create a file\n"); return; } // Open the file for Binary Output file = fopen(checkname, "wb"); if(!file) { ri.Con_Printf (PRINT_ALL, "GL_ScreenShotJPG_f: Couldn't create a file\n"); return; } // Allocate room for a copy of the framebuffer rgbdata = malloc(vid.width * vid.height * 3); if(!rgbdata) { fclose(file); return; } // Read the framebuffer into our storage qglReadPixels(0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, rgbdata); // Initialise the JPEG compression object cinfo.err = jpeg_std_error(&jerr); jpeg_create_compress(&cinfo); jpeg_stdio_dest(&cinfo, file); // Setup JPEG Parameters cinfo.image_width = vid.width; cinfo.image_height = vid.height; cinfo.in_color_space = JCS_RGB; cinfo.input_components = 3; jpeg_set_defaults(&cinfo); if((r_jpeg_quality->value >= 101) || (r_jpeg_quality->value <= 0)) ri.Cvar_Set("r_jpeg_quality", "85"); jpeg_set_quality(&cinfo, r_jpeg_quality->value, 1); // Start Compression jpeg_start_compress(&cinfo, 1); // Feed Scanline data offset = (cinfo.image_width * cinfo.image_height * 3) - (cinfo.image_width * 3); while(cinfo.next_scanline < cinfo.image_height) { s[0] = &rgbdata[offset - (cinfo.next_scanline * (cinfo.image_width * 3))]; jpeg_write_scanlines(&cinfo, s, 1); } // Finish Compression jpeg_finish_compress(&cinfo); // Destroy JPEG object jpeg_destroy_compress(&cinfo); // Close File fclose(file); // Free Temp Framebuffer free(rgbdata); // Done! ri.Con_Printf (PRINT_ALL, "Wrote %s\n", picname); }
void GL_ScreenShot_PNG (void) { byte *rgbdata; FILE *file; char picname[80], checkname[MAX_OSPATH]; int i, j, k; png_structp png_ptr; png_infop info_ptr; //not working yet... ri.Con_Printf (PRINT_ALL, "PNG Screenshot...(^iDisabled^r)\n"); return; // Create the scrnshots directory if it doesn't exist Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot", ri.FS_Gamedir()); Sys_Mkdir (checkname); for (i=0 ; i<=999 ; i++) { Com_sprintf (picname, sizeof(picname), "quake2max%i%i%i.png", (int)(i/100)%10, (int)(i/10)%10, i%10); Com_sprintf (checkname, sizeof(checkname), "%s/scrnshot/%s", ri.FS_Gamedir(), picname); file = fopen (checkname, "rb"); if (!file) break; // file doesn't exist fclose (file); } if (i==1000) { ri.Con_Printf (PRINT_ALL, "GL_ScreenShot_PNG: Couldn't create a file\n"); return; } // Allocate room for a copy of the framebuffer rgbdata = malloc(vid.width * vid.height * 3); if(!rgbdata) return; // Read the framebuffer into our storage qglReadPixels(0, 0, vid.width, vid.height, GL_RGB, GL_UNSIGNED_BYTE, rgbdata); png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0,0,0); if (!png_ptr) { free(rgbdata); ri.Con_Printf (PRINT_ALL, "GL_ScreenShot_PNG: Couldn't create image (NO PNG_PTR)\n"); return; } // Allocate/initialize the image information data. REQUIRED info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_write_struct(&png_ptr, 0); free(rgbdata); ri.Con_Printf (PRINT_ALL, "GL_ScreenShot_PNG: Couldn't create image (NO INFO_PTR)\n"); return; } if (setjmp(png_ptr->jmpbuf)) { png_destroy_write_struct(&png_ptr, &info_ptr); free(rgbdata); ri.Con_Printf (PRINT_ALL, "GL_ScreenShot_PNG: Couldn't create image (BAD INFO)\n"); return; } // Open the file for Binary Output file = fopen(checkname, "wb"); if(!file) { ri.Con_Printf (PRINT_ALL, "GL_ScreenShot_PNG: Couldn't create a file\n"); return; } png_init_io(png_ptr, file); png_set_IHDR(png_ptr, info_ptr, vid.width, vid.height, 8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); png_write_info(png_ptr, info_ptr); for (k = 0; k < vid.height; k++) { void *pointer = rgbdata + k*vid.width*3; png_write_row(png_ptr, pointer); } png_write_end(png_ptr, info_ptr); png_destroy_write_struct(&png_ptr, &info_ptr); // Close File fclose(file); // Free Temp Framebuffer free(rgbdata); // Done! ri.Con_Printf (PRINT_ALL, "Wrote %s\n", picname); }