/* =========================================================================== Doom 3 GPL Source Code Copyright (C) 1999-2011 id Software LLC, a ZeniMax Media company. This file is part of the Doom 3 GPL Source Code (?Doom 3 Source Code?). Doom 3 Source Code is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Doom 3 Source Code is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Doom 3 Source Code. If not, see . In addition, the Doom 3 Source Code is also subject to certain additional terms. You should have received a copy of these additional terms immediately following the terms and conditions of the GNU General Public License which accompanied the Doom 3 Source Code. If not, please request a copy in writing from id Software at the address below. If you have questions concerning this license or the applicable additional terms, you may contact in writing id Software LLC, c/o ZeniMax Media Inc., Suite 120, Rockville, Maryland 20850 USA. =========================================================================== */ #include "../../../idlib/precompiled.h" #pragma hdrstop #include "roqParam.h" // // read a parameter file in (true I bloddy well had to do this again) (and yet again to c++) // int parseRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] ); int parseTimecodeRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] ); void roqParam::InitFromFile( const char *fileName ) { idParser *src; idToken token; int i, readarg; src = new idParser( fileName, LEXFL_NOSTRINGCONCAT | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ); if ( !src->IsLoaded() ) { delete src; common->Printf("Error: can't open param file %s\n", fileName); return; } common->Printf("initFromFile: %s\n", fileName); fullSearch = false; scaleDown = false; encodeVideo = false; addPath = false; screenShots = false; startPalette = false; endPalette = false; fixedPalette = false; keyColor = false; justDelta = false; useTimecodeForRange = false; onFrame = 0; numInputFiles = 0; currentPath[0] = '\0'; make3DO = false; makeVectors = false; justDeltaFlag = false; noAlphaAtAll = false; twentyFourToThirty = false; hasSound = false; isScaleable = false; firstframesize = 56*1024; normalframesize = 20000; jpegDefault = 85; realnum = 0; while( 1 ) { if ( !src->ReadToken( &token ) ) { break; } readarg = 0; // input dir if (token.Icmp( "input_dir") == 0) { src->ReadToken( &token ); addPath = true; currentPath = token; // common->Printf(" + input directory is %s\n", currentPath ); readarg++; continue; } // input dir if (token.Icmp( "scale_down") == 0) { scaleDown = true; // common->Printf(" + scaling down input\n" ); readarg++; continue; } // full search if (token.Icmp( "fullsearch") == 0) { normalframesize += normalframesize/2; fullSearch = true; readarg++; continue; } // scaleable if (token.Icmp( "scaleable") == 0) { isScaleable = true; readarg++; continue; } // input dir if (token.Icmp( "no_alpha") == 0) { noAlphaAtAll = true; // common->Printf(" + scaling down input\n" ); readarg++; continue; } if (token.Icmp( "24_fps_in_30_fps_out") == 0) { twentyFourToThirty = true; readarg++; continue; } // video in if (token.Icmp( "video_in") == 0) { encodeVideo = true; // common->Printf(" + Using the video port as input\n"); continue; } //timecode range if (token.Icmp( "timecode") == 0) { useTimecodeForRange = true; firstframesize = 12*1024; normalframesize = 4500; // common->Printf(" + Using timecode as range\n"); continue; } // soundfile for making a .RnR if (token.Icmp( "sound") == 0) { src->ReadToken( &token ); soundfile = token; hasSound = true; // common->Printf(" + Using timecode as range\n"); continue; } // soundfile for making a .RnR if (token.Icmp( "has_sound") == 0) { hasSound = true; continue; } // outfile if (token.Icmp( "filename") == 0) { src->ReadToken( &token ); outputFilename = token; i = strlen(outputFilename); // common->Printf(" + output file is %s\n", outputFilename ); readarg++; continue; } // starting palette if (token.Icmp( "start_palette") == 0) { src->ReadToken( &token ); sprintf(startPal, "/LocalLibrary/vdxPalettes/%s", token.c_str()); // common->Error(" + starting palette is %s\n", startPal ); startPalette = true; readarg++; continue; } // ending palette if (token.Icmp( "end_palette") == 0) { src->ReadToken( &token ); sprintf(endPal, "/LocalLibrary/vdxPalettes/%s", token.c_str()); // common->Printf(" + ending palette is %s\n", endPal ); endPalette = true; readarg++; continue; } // fixed palette if (token.Icmp( "fixed_palette") == 0) { src->ReadToken( &token ); sprintf(startPal, "/LocalLibrary/vdxPalettes/%s", token.c_str()); // common->Printf(" + fixed palette is %s\n", startPal ); fixedPalette = true; readarg++; continue; } // these are screen shots if (token.Icmp( "screenshot") == 0) { // common->Printf(" + shooting screen shots\n" ); screenShots = true; readarg++; continue; } // key_color r g b if (token.Icmp( "key_color") == 0) { keyR = src->ParseInt(); keyG = src->ParseInt(); keyB = src->ParseInt(); keyColor = true; // common->Printf(" + key color is %03d %03d %03d\n", keyR, keyG, keyB ); readarg++; continue; } // only want deltas if (token.Icmp( "just_delta") == 0) { // common->Printf(" + outputting deltas in the night\n" ); // justDelta = true; // justDeltaFlag = true; readarg++; continue; } // doing 3DO if (token.Icmp( "3DO") == 0) { make3DO = true; readarg++; continue; } // makes codebook vector tables if (token.Icmp( "codebook") == 0) { makeVectors = true; readarg++; continue; } // set first frame size if (token.Icmp( "firstframesize") == 0) { firstframesize = src->ParseInt(); readarg++; continue; } // set normal frame size if (token.Icmp( "normalframesize") == 0) { normalframesize = src->ParseInt(); readarg++; continue; } // set normal frame size if (token.Icmp( "stillframequality") == 0) { jpegDefault = src->ParseInt(); readarg++; continue; } if (token.Icmp( "input") == 0) { int num_files = 255; range = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); padding = (bool *)Mem_ClearedAlloc( num_files * sizeof(bool) ); padding2 = (bool *)Mem_ClearedAlloc( num_files * sizeof(bool) ); skipnum = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); skipnum2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); startnum = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); startnum2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); endnum = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); endnum2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); numpadding = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); numpadding2 = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); numfiles = (int *)Mem_ClearedAlloc( num_files * sizeof(int) ); idStr empty; file.AssureSize( num_files, empty ); file.AssureSize( num_files, empty ); field = 0; realnum = 0; do { src->ReadToken(&token); if ( token.Icmp( "end_input") != 0 ) { idStr arg1, arg2, arg3; file[field] = token; while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) { file[field].Append( token ); } arg1 = token; while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) { arg1 += token; } arg2 = token; while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) { arg2 += token; } arg3 = token; while (src->ReadTokenOnLine( &token ) && token.Icmp( "[" ) ) { arg3 += token; } if ( arg1[0] != '[' ) { // common->Printf(" + reading %s\n", file[field] ); range[field] = 0; numfiles[field] = 1; realnum++; } else { if ( arg1[0] == '[' ) { range[field] = 1; if (useTimecodeForRange) { realnum += parseTimecodeRange( arg1, field, skipnum, startnum, endnum, numfiles, padding, numpadding); // common->Printf(" + reading %s from %d to %d\n", file[field], startnum[field], endnum[field]); } else { realnum += parseRange( arg1, field, skipnum, startnum, endnum, numfiles, padding, numpadding); // common->Printf(" + reading %s from %d to %d\n", file[field], startnum[field], endnum[field]); } } else if (( arg1[0] != '[' ) && ( arg2[0] == '[') && ( arg3[0] =='[')) { //a double ranger... int files1,files2; file2[field] = arg1; range[field] = 2; files1 = parseRange(arg2, field, skipnum, startnum, endnum, numfiles, padding, numpadding); // common->Printf(" + reading %s from %d to %d\n", file[field], startnum[field], endnum[field]); files2 = parseRange(arg3, field, skipnum2, startnum2, endnum2, numfiles, padding2, numpadding2); // common->Printf(" + reading %s from %d to %d\n", file2[field], startnum2[field], endnum2[field]); if (files1 != files2) { common->Error( "You had %d files for %s and %d for %s!", files1, arg1.c_str(), files2, arg2.c_str() ); } else { realnum += files1;//not both, they are parallel } } else { common->Error("Error: invalid range on open (%s %s %s)\n", arg1.c_str(), arg2.c_str(), arg3.c_str() ); } } field++; } } while (token.Icmp( "end_input")); } } if (TwentyFourToThirty()) realnum = realnum+(realnum>>2); numInputFiles = realnum; common->Printf(" + reading a total of %d frames in %s\n", numInputFiles, currentPath.c_str() ); delete src; } void roqParam::GetNthInputFileName( idStr &fileName, int n ) { int i, myfield, index,hrs,mins,secs,frs; char tempfile[33], left[256], right[256], *strp; if ( n > realnum ) n = realnum; // overcome starting at zero by ++ing and then --ing. if (TwentyFourToThirty()) { n++; n = (n/5) * 4 + (n % 5); n--; } i = 0; myfield = 0; while (i <= n) { i += numfiles[myfield++]; } myfield--; i -= numfiles[myfield]; if ( range[myfield] == 1 ) { strcpy( left, file[myfield] ); strp = strstr( left, "*" ); *strp++ = 0; sprintf(right, "%s", strp); if ( startnum[myfield] <= endnum[myfield] ) { index = startnum[myfield] + ((n-i)*skipnum[myfield]); } else { index = startnum[myfield] - ((n-i)*skipnum[myfield]); } if ( padding[myfield] == true ) { if (useTimecodeForRange) { hrs = index/(30*60*60) ; mins = (index/(30*60)) %60; secs = (index/(30)) % 60; frs = index % 30; sprintf(fileName,"%s%.02d%.02d/%.02d%.02d%.02d%.02d%s",left,hrs,mins,hrs,mins,secs,frs,right); } else { sprintf(tempfile, "%032d", index ); sprintf(fileName, "%s%s%s", left, &tempfile[ 32-numpadding[myfield] ], right ); } } else { if (useTimecodeForRange) { hrs = index/(30*60*60) ; mins = (index/(30*60)) %60; secs = (index/(30)) % 60; frs = index % 30; sprintf(fileName,"%s%.02d%.02d/%.02d%.02d%.02d%.02d%s",left,hrs,mins,hrs,mins,secs,frs,right); } else { sprintf(fileName, "%s%d%s", left, index, right ); } } } else if ( range[myfield] == 2 ) { strcpy( left, file[myfield] ); strp = strstr( left, "*" ); *strp++ = 0; sprintf(right, "%s", strp); if ( startnum[myfield] <= endnum[myfield] ) { index = startnum[myfield] + ((n-i)*skipnum[myfield]); } else { index = startnum[myfield] - ((n-i)*skipnum[myfield]); } if ( padding[myfield] == true ) { sprintf(tempfile, "%032d", index ); sprintf(fileName, "%s%s%s", left, &tempfile[ 32-numpadding[myfield] ], right ); } else { sprintf(fileName, "%s%d%s", left, index, right ); } strcpy( left, file2[myfield] ); strp = strstr( left, "*" ); *strp++ = 0; sprintf(right, "%s", strp); if ( startnum2[myfield] <= endnum2[myfield] ) { index = startnum2[myfield] + ((n-i)*skipnum2[myfield]); } else { index = startnum2[myfield] - ((n-i)*skipnum2[myfield]); } if ( padding2[myfield] == true ) { sprintf(tempfile, "%032d", index ); fileName += va( "\n%s%s%s", left, &tempfile[ 32-numpadding2[myfield] ], right ); } else { fileName += va( "\n%s%d%s", left, index, right ); } } else { fileName = file[myfield]; } } const char* roqParam::GetNextImageFilename( void ) { idStr tempBuffer; int i; int len; GetNthInputFileName( tempBuffer, onFrame++); if ( justDeltaFlag == true ) { onFrame--; justDeltaFlag = false; } if ( addPath == true ) { currentFile = currentPath + "/" + tempBuffer; } else { currentFile = tempBuffer; } len = currentFile.Length(); for(i=0;i= '0' && rangeStr[i] <= '9' ); *stptr = '\0'; if ( rangeStr[i++] != '-' ) { common->Error("Error: invalid range on middle \n"); } do { *enptr++ = rangeStr[i++]; } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); *enptr = '\0'; if ( rangeStr[i] != ']' ) { if ( rangeStr[i++] != '+' ) { common->Error("Error: invalid range on close\n"); } do { *skptr++ = rangeStr[i++]; } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); *skptr = '\0'; skipnum[field] = atoi( skip ); } else { skipnum[field] = 1; } startnum[field] = atoi( start ); endnum[field] = atoi( end ); numfiles[field] = (abs( startnum[field] - endnum[field] ) / skipnum[field]) + 1; realnum += numfiles[field]; if ( start[0] == '0' && start[1] != '\0' ) { padding[field] = true; numpadding[field] = strlen( start ); } else { padding[field] = false; } return realnum; } int parseTimecodeRange(const char *rangeStr,int field, int skipnum[], int startnum[], int endnum[],int numfiles[],bool padding[],int numpadding[] ) { char start[64], end[64], skip[64]; char *stptr, *enptr, *skptr; int i,realnum,hrs,mins,secs,frs; i = 1;//skip the '[' realnum = 0; stptr = start; enptr = end; skptr = skip; do { *stptr++ = rangeStr[i++]; } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); *stptr = '\0'; if ( rangeStr[i++] != '-' ) { common->Error("Error: invalid range on middle \n"); } do { *enptr++ = rangeStr[i++]; } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); *enptr = '\0'; if ( rangeStr[i] != ']' ) { if ( rangeStr[i++] != '+' ) { common->Error("Error: invalid range on close\n"); } do { *skptr++ = rangeStr[i++]; } while ( rangeStr[i] >= '0' && rangeStr[i] <= '9' ); *skptr = '\0'; skipnum[field] = atoi( skip ); } else { skipnum[field] = 1; } sscanf(start,"%2d%2d%2d%2d",&hrs,&mins,&secs,&frs); startnum[field] = hrs*30*60*60 + mins *60*30 + secs*30 +frs; sscanf(end,"%2d%2d%2d%2d",&hrs,&mins,&secs,&frs); endnum[field] = hrs*30*60*60 + mins *60*30 + secs*30 +frs; numfiles[field] = (abs( startnum[field] - endnum[field] ) / skipnum[field]) + 1; realnum += numfiles[field]; if ( start[0] == '0' && start[1] != '\0' ) { padding[field] = true; numpadding[field] = strlen( start ); } else { padding[field] = false; } return realnum; }