Esempio n. 1
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
void AASOuputFile( quakefile_t *qf, char *outputpath, char *filename ) {
	char ext[MAX_PATH];

	//
	if ( strlen( outputpath ) ) {
		strcpy( filename, outputpath );
		//append the bsp file base
		AppendPathSeperator( filename, MAX_PATH );
		ExtractFileBase( qf->origname, &filename[strlen( filename )] );

		// Ridah, add extension
		strcat( filename, aas_extension );
		// done.

		//append .aas
		strcat( filename, ".aas" );
		return;
	} //end if
	  //
	ExtractFileExtension( qf->filename, ext );
	if ( !stricmp( ext, "pk3" ) || !stricmp( ext, "pak" ) || !stricmp( ext, "sin" ) ) {
		strcpy( filename, qf->filename );
		while ( strlen( filename ) &&
				filename[strlen( filename ) - 1] != '\\' &&
				filename[strlen( filename ) - 1] != '/' )
		{
			filename[strlen( filename ) - 1] = '\0';
		} //end while
		strcat( filename, "maps" );
		if ( access( filename, 0x04 ) ) {
			CreatePath( filename );
		}
		//append the bsp file base
		AppendPathSeperator( filename, MAX_PATH );
		ExtractFileBase( qf->origname, &filename[strlen( filename )] );

		// Ridah, add extension
		strcat( filename, aas_extension );
		// done.

		//append .aas
		strcat( filename, ".aas" );
	} //end if
	else
	{
		strcpy( filename, qf->filename );
		while ( strlen( filename ) &&
				filename[strlen( filename ) - 1] != '.' )
		{
			filename[strlen( filename ) - 1] = '\0';
		} //end while

		// Ridah, add extension
		strcat( filename, aas_extension );
		// done.

		strcat( filename, "aas" );
	} //end else
} //end of the function AASOutputFile
Esempio n. 2
0
//===========================================================================
// find a Quake2 file
// returns full path in 'filename'
// sets offset and length of the file
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
qboolean FindQuakeFile2( char *basedir, char *gamedir, char *filename, foundfile_t *file ) {
	int dir, i;
	//NOTE: 3 is necessary (LCC bug???)
	char gamedirs[3][MAX_PATH] = {"","",""};
	char filedir[MAX_PATH] = "";

	//
	if ( gamedir ) {
		strncpy( gamedirs[0], gamedir, MAX_PATH );
	}
	strncpy( gamedirs[1], "baseq2", MAX_PATH );
	//
	//find the file in the two game directories
	for ( dir = 0; dir < 2; dir++ )
	{
		//check if the file is in a directory
		filedir[0] = 0;
		if ( basedir && strlen( basedir ) ) {
			strncpy( filedir, basedir, MAX_PATH );
			AppendPathSeperator( filedir, MAX_PATH );
		} //end if
		if ( strlen( gamedirs[dir] ) ) {
			strncat( filedir, gamedirs[dir], MAX_PATH - strlen( filedir ) );
			AppendPathSeperator( filedir, MAX_PATH );
		} //end if
		strncat( filedir, filename, MAX_PATH - strlen( filedir ) );
		ConvertPath( filedir );
		Log_Write( "accessing %s", filedir );
		if ( !access( filedir, 0x04 ) ) {
			strcpy( file->filename, filedir );
			file->length = 0;
			file->offset = 0;
			return true;
		} //end if
		  //check if the file is in a pak?.pak
		for ( i = 0; i < 10; i++ )
		{
			filedir[0] = 0;
			if ( basedir && strlen( basedir ) ) {
				strncpy( filedir, basedir, MAX_PATH );
				AppendPathSeperator( filedir, MAX_PATH );
			} //end if
			if ( strlen( gamedirs[dir] ) ) {
				strncat( filedir, gamedirs[dir], MAX_PATH - strlen( filedir ) );
				AppendPathSeperator( filedir, MAX_PATH );
			} //end if
			sprintf( &filedir[strlen( filedir )], "pak%d.pak", i );
			if ( !access( filedir, 0x04 ) ) {
				Log_Write( "searching %s in %s", filename, filedir );
				if ( FindFileInPak( filedir, filename, file ) ) {
					return true;
				}
			} //end if
		} //end for
	} //end for
	file->offset = 0;
	file->length = 0;
	return false;
} //end of the function FindQuakeFile2
Esempio n. 3
0
int main( int argc, char **argv ) {
	int i, comp = 0;
	char outputpath[MAX_PATH] = "";
	char filename[MAX_PATH] = "unknown";
	quakefile_t *qfiles, *qf;

	// Ridah, allow to specify an extension for multiple AAS files per map
	int has_ext = 0;
	// done.

	// Ridah, set the world pointer up for reachabilities
	aasworld = aasworlds;
	AAS_SetWorldPointer( &( *aasworld ) );
	// done.

	myargc = argc;
	myargv = argv;

	Log_Open( "bspc.log" );        //open a log file
	Log_Print( "BSPC version " BSPC_VERSION ", %s %s by Mr Elusive\n", __DATE__, __TIME__ );

	DefaultCfg();
	for ( i = 1; i < argc; i++ )
	{
		if ( !stricmp( argv[i],"-threads" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			numthreads = atoi( argv[++i] );
			Log_Print( "threads = %d\n", numthreads );
		} //end if
		else if ( !stricmp( argv[i], "-noverbose" ) ) {
			Log_Print( "verbose = false\n" );
			verbose = false;
		} //end else if
		else if ( !stricmp( argv[i], "-nocsg" ) ) {
			Log_Print( "nocsg = true\n" );
			nocsg = true;
		} //end else if
		else if ( !stricmp( argv[i], "-optimize" ) ) {
			Log_Print( "optimize = true\n" );
			optimize = true;
		} //end else if
		  /*
		  else if (!stricmp(argv[i],"-glview"))
		  {
			  glview = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-draw"))
		  {
			  Log_Print("drawflag = true\n");
			  drawflag = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-noweld"))
		  {
			  Log_Print("noweld = true\n");
			  noweld = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-noshare"))
		  {
			  Log_Print("noshare = true\n");
			  noshare = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-notjunc"))
		  {
			  Log_Print("notjunc = true\n");
			  notjunc = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-nowater"))
		  {
			  Log_Print("nowater = true\n");
			  nowater = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-noprune"))
		  {
			  Log_Print("noprune = true\n");
			  noprune = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-nomerge"))
		  {
			  Log_Print("nomerge = true\n");
			  nomerge = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-nosubdiv"))
		  {
			  Log_Print("nosubdiv = true\n");
			  nosubdiv = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-nodetail"))
		  {
			  Log_Print("nodetail = true\n");
			  nodetail = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-fulldetail"))
		  {
			  Log_Print("fulldetail = true\n");
			  fulldetail = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-onlyents"))
		  {
			  Log_Print("onlyents = true\n");
			  onlyents = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-micro"))
		  {
			  if (i + 1 >= argc) {i = 0; break;}
			  microvolume = atof(argv[++i]);
			  Log_Print("microvolume = %f\n", microvolume);
		  } //end else if
		  else if (!stricmp(argv[i], "-leaktest"))
		  {
			  Log_Print("leaktest = true\n");
			  leaktest = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-verboseentities"))
		  {
			  Log_Print("verboseentities = true\n");
			  verboseentities = true;
		  } //end else if
		  else if (!stricmp(argv[i], "-chop"))
		  {
			  if (i + 1 >= argc) {i = 0; break;}
			  subdivide_size = atof(argv[++i]);
			  Log_Print("subdivide_size = %f\n", subdivide_size);
		  } //end else if
		  else if (!stricmp (argv[i], "-tmpout"))
		  {
			  strcpy (outbase, "/tmp");
			  Log_Print("temp output\n");
		  } //end else if
		  */
#ifdef ME
		else if ( !stricmp( argv[i], "-freetree" ) ) {
			freetree = true;
			Log_Print( "freetree = true\n" );
		} //end else if
		else if ( !stricmp( argv[i], "-grapplereach" ) ) {
			calcgrapplereach = true;
			Log_Print( "grapplereach = true\n" );
		} //end else if
		else if ( !stricmp( argv[i], "-nobrushmerge" ) ) {
			nobrushmerge = true;
			Log_Print( "nobrushmerge = true\n" );
		} //end else if
		else if ( !stricmp( argv[i], "-noliquids" ) ) {
			noliquids = true;
			Log_Print( "noliquids = true\n" );
		} //end else if
		else if ( !stricmp( argv[i], "-forcesidesvisible" ) ) {
			forcesidesvisible = true;
			Log_Print( "forcesidesvisible = true\n" );
		} //end else if
		else if ( !stricmp( argv[i], "-output" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			if ( access( argv[i + 1], 0x04 ) ) {
				Warning( "the folder %s does not exist", argv[i + 1] );
			}
			strcpy( outputpath, argv[++i] );
		} //end else if
		else if ( !stricmp( argv[i], "-breadthfirst" ) ) {
			use_nodequeue = true;
			Log_Print( "breadthfirst = true\n" );
		} //end else if
		else if ( !stricmp( argv[i], "-cfg" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			if ( !LoadCfgFile( argv[++i] ) ) {
				exit( 0 );
			}
		} //end else if
		else if ( !stricmp( argv[i], "-bsp2map" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			comp = COMP_BSP2MAP;
			qfiles = GetArgumentFiles( argc, argv, &i, "bsp" );
		} //end else if
		else if ( !stricmp( argv[i], "-bsp2aas" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			comp = COMP_BSP2AAS;
			qfiles = GetArgumentFiles( argc, argv, &i, "bsp" );
		} //end else if
		else if ( !stricmp( argv[i], "-aasall" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			CreateAASFilesForAllBSPFiles( argv[++i] );
		} //end else if
		else if ( !stricmp( argv[i], "-reach" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			comp = COMP_REACH;
			qfiles = GetArgumentFiles( argc, argv, &i, "bsp" );
		} //end else if
		else if ( !stricmp( argv[i], "-cluster" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			comp = COMP_CLUSTER;
			qfiles = GetArgumentFiles( argc, argv, &i, "bsp" );
		} //end else if
		else if ( !stricmp( argv[i], "-aasinfo" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			comp = COMP_AASINFO;
			qfiles = GetArgumentFiles( argc, argv, &i, "aas" );
		} //end else if
		else if ( !stricmp( argv[i], "-aasopt" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			comp = COMP_AASOPTIMIZE;
			qfiles = GetArgumentFiles( argc, argv, &i, "aas" );
		} //end else if
		else if ( !stricmp( argv[i], "-tetra" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			comp = COMP_TETRA;
			qfiles = GetArgumentFiles( argc, argv, &i, "aas" );
		} //end else if
		  // Ridah, allow to specify an extension for multiple AAS files per map
		else if ( !stricmp( argv[i], "-ext" ) ) {
			if ( i + 1 >= argc ) {
				i = 0; break;
			}
			strcpy( aas_extension, argv[++i] );
			has_ext = 1;

		} //end else if
		  // done.

#endif //ME
		else
		{
			Log_Print( "unknown parameter %s\n", argv[i] );
			break;
		} //end else
	} //end for

	//if there are parameters and there's no mismatch in one of the parameters
	if ( argc > 1 && i == argc ) {
		switch ( comp )
		{
		case COMP_BSP2MAP:
		{
			if ( !qfiles ) {
				Log_Print( "no files found\n" );
			}
			for ( qf = qfiles; qf; qf = qf->next )
			{
				//copy the output path
				strcpy( filename, outputpath );
				//append the bsp file base
				AppendPathSeperator( filename, MAX_PATH );
				ExtractFileBase( qf->origname, &filename[strlen( filename )] );
				//append .map
				strcat( filename, ".map" );
				//
				Log_Print( "bsp2map: %s to %s\n", qf->origname, filename );
				if ( qf->type != QFILETYPE_BSP ) {
					Warning( "%s is probably not a BSP file\n", qf->origname );
				}
				//
				LoadMapFromBSP( qf );
				//write the map file
				WriteMapFile( filename );
			}     //end for
			break;
		}     //end case
		case COMP_BSP2AAS:
		{
			if ( !qfiles ) {
				Log_Print( "no files found\n" );
			}
			for ( qf = qfiles; qf; qf = qf->next )
			{
				AASOuputFile( qf, outputpath, filename );
				//
				Log_Print( "bsp2aas: %s to %s\n", qf->origname, filename );
				if ( qf->type != QFILETYPE_BSP ) {
					Warning( "%s is probably not a BSP file\n", qf->origname );
				}
				//set before map loading
				create_aas = 1;
				LoadMapFromBSP( qf );
				//create the AAS file
				AAS_Create( filename );
				//if it's a Quake3 map calculate the reachabilities and clusters
				if ( loadedmaptype == MAPTYPE_QUAKE3 ) {
					AAS_CalcReachAndClusters( qf );
				}
				//
				if ( optimize ) {
					AAS_Optimize();
				}
				//
				//write out the stored AAS file
				if ( !AAS_WriteAASFile( filename ) ) {
					Error( "error writing %s\n", filename );
				}     //end if
					  //deallocate memory
				AAS_FreeMaxAAS();
			}     //end for
			break;
		}     //end case
		case COMP_REACH:
		{
			if ( !qfiles ) {
				Log_Print( "no files found\n" );
			}
			for ( qf = qfiles; qf; qf = qf->next )
			{
				AASOuputFile( qf, outputpath, filename );
				//
				Log_Print( "reach: %s to %s\n", qf->origname, filename );
				if ( qf->type != QFILETYPE_BSP ) {
					Warning( "%s is probably not a BSP file\n", qf->origname );
				}
				//if the AAS file exists in the output directory
				if ( !access( filename, 0x04 ) ) {
					if ( !AAS_LoadAASFile( filename, 0, 0 ) ) {
						Error( "error loading aas file %s\n", filename );
					}     //end if
						  //assume it's a Quake3 BSP file
					loadedmaptype = MAPTYPE_QUAKE3;
				}     //end if
				else
				{
					Warning( "AAS file %s not found in output folder\n", filename );
					Log_Print( "creating %s...\n", filename );
					//set before map loading
					create_aas = 1;
					LoadMapFromBSP( qf );
					//create the AAS file
					AAS_Create( filename );
				}     //end else
					  //if it's a Quake3 map calculate the reachabilities and clusters
				if ( loadedmaptype == MAPTYPE_QUAKE3 ) {
					AAS_CalcReachAndClusters( qf );
				}     //end if
					  //
				if ( optimize ) {
					AAS_Optimize();
				}
				//write out the stored AAS file
				if ( !AAS_WriteAASFile( filename ) ) {
					Error( "error writing %s\n", filename );
				}     //end if
					  //deallocate memory
				AAS_FreeMaxAAS();
			}     //end for
			break;
		}     //end case
		case COMP_CLUSTER:
		{
			if ( !qfiles ) {
				Log_Print( "no files found\n" );
			}
			for ( qf = qfiles; qf; qf = qf->next )
			{
				AASOuputFile( qf, outputpath, filename );
				//
				Log_Print( "cluster: %s to %s\n", qf->origname, filename );
				if ( qf->type != QFILETYPE_BSP ) {
					Warning( "%s is probably not a BSP file\n", qf->origname );
				}
				//if the AAS file exists in the output directory
				if ( !access( filename, 0x04 ) ) {
					if ( !AAS_LoadAASFile( filename, 0, 0 ) ) {
						Error( "error loading aas file %s\n", filename );
					}     //end if
						  //assume it's a Quake3 BSP file
					loadedmaptype = MAPTYPE_QUAKE3;
					//if it's a Quake3 map calculate the clusters
					if ( loadedmaptype == MAPTYPE_QUAKE3 ) {
						( *aasworld ).numclusters = 0;
						AAS_InitBotImport();
						AAS_InitClustering();
					}     //end if
				}     //end if
				else
				{
					Warning( "AAS file %s not found in output folder\n", filename );
					Log_Print( "creating %s...\n", filename );
					//set before map loading
					create_aas = 1;
					LoadMapFromBSP( qf );
					//create the AAS file
					AAS_Create( filename );
					//if it's a Quake3 map calculate the reachabilities and clusters
					if ( loadedmaptype == MAPTYPE_QUAKE3 ) {
						AAS_CalcReachAndClusters( qf );
					}
				}     //end else
					  //
				if ( optimize ) {
					AAS_Optimize();
				}
				//write out the stored AAS file
				if ( !AAS_WriteAASFile( filename ) ) {
					Error( "error writing %s\n", filename );
				}     //end if
					  //deallocate memory
				AAS_FreeMaxAAS();
			}     //end for
			break;
		}     //end case
		case COMP_AASOPTIMIZE:
		{
			if ( !qfiles ) {
				Log_Print( "no files found\n" );
			}
			for ( qf = qfiles; qf; qf = qf->next )
			{
				AASOuputFile( qf, outputpath, filename );
				//
				Log_Print( "optimizing: %s to %s\n", qf->origname, filename );
				if ( qf->type != QFILETYPE_AAS ) {
					Warning( "%s is probably not a AAS file\n", qf->origname );
				}
				//
				AAS_InitBotImport();
				//
				if ( !AAS_LoadAASFile( qf->filename, qf->offset, qf->length ) ) {
					Error( "error loading aas file %s\n", qf->filename );
				}     //end if
				AAS_Optimize();
				//write out the stored AAS file
				if ( !AAS_WriteAASFile( filename ) ) {
					Error( "error writing %s\n", filename );
				}     //end if
					  //deallocate memory
				AAS_FreeMaxAAS();
			}     //end for
			break;
		}     //end case
		case COMP_AASINFO:
		{
			if ( !qfiles ) {
				Log_Print( "no files found\n" );
			}
			for ( qf = qfiles; qf; qf = qf->next )
			{
				AASOuputFile( qf, outputpath, filename );
				//
				Log_Print( "aas info for: %s\n", filename );
				if ( qf->type != QFILETYPE_AAS ) {
					Warning( "%s is probably not a AAS file\n", qf->origname );
				}
				//
				AAS_InitBotImport();
				//
				if ( !AAS_LoadAASFile( qf->filename, qf->offset, qf->length ) ) {
					Error( "error loading aas file %s\n", qf->filename );
				}     //end if
				AAS_ShowTotals();
			}     //end for
		}     //end case
		case COMP_TETRA:
		{
			if ( !qfiles ) {
				Log_Print( "no files found\n" );
			}
			for ( qf = qfiles; qf; qf = qf->next )
			{
				//TH_AASToTetrahedrons(qf->filename);
			}     //end for
			break;
		}     //end case
		default:
		{
			Log_Print( "don't know what to do\n" );
			break;
		}     //end default
		} //end switch
	} //end if
	else
	{
		Log_Print( "Usage:   bspc [-<switch> [-<switch> ...]]\n"
#if defined( WIN32 ) || defined( _WIN32 )
				   "Example 1: bspc -bsp2aas d:\\quake3\\baseq3\\maps\\mymap?.bsp\n"
				   "Example 2: bspc -bsp2aas d:\\quake3\\baseq3\\pak0.pk3\\maps/q3dm*.bsp\n"
#else
				   "Example 1: bspc -bsp2aas /quake3/baseq3/maps/mymap?.bsp\n"
				   "Example 2: bspc -bsp2aas /quake3/baseq3/pak0.pk3/maps/q3dm*.bsp\n"
#endif
				   "\n"
				   "Switches:\n"
				   //"   bsp2map  <[pakfilter/]filter.bsp>    = convert BSP to MAP\n"
				   "   bsp2aas  <[pakfilter/]filter.bsp>    = convert BSP to AAS\n"
				   //"   aasall   <quake3folder>              = create AAS files for all BSPs\n"
				   "   reach    <filter.bsp>                = compute reachability & clusters\n"
				   "   cluster  <filter.aas>                = compute clusters\n"
				   "   aasopt   <filter.aas>                = optimize aas file\n"
				   //"   tetra    <filter.aas>                = tetrahedral decomposition\n"
				   "   output   <output path>               = set output path\n"
				   "   threads  <X>                         = set number of threads to X\n"
				   "   cfg      <filename>                  = use this cfg file\n"
				   "   optimize                             = enable optimization\n"
				   "   noverbose                            = disable verbose output\n"
				   "   breadthfirst                         = breadth first bsp building\n"
				   "   nobrushmerge                         = don't merge brushes\n"
				   "   noliquids                            = don't write liquids to map\n"
				   "   freetree                             = free the bsp tree\n"
				   "   nocsg                                = disables brush chopping\n"
				   "   forcesidesvisible                    = force all sides to be visible\n"
				   "   grapplereach                         = calculate grapple reachabilities\n"

/*			"   glview     = output a GL view\n"
			"   draw       = enables drawing\n"
			"   noweld     = disables weld\n"
			"   noshare    = disables sharing\n"
			"   notjunc    = disables juncs\n"
			"   nowater    = disables water brushes\n"
			"   noprune    = disables node prunes\n"
			"   nomerge    = disables face merging\n"
			"   nosubdiv   = disables subdeviding\n"
			"   nodetail   = disables detail brushes\n"
			"   fulldetail = enables full detail\n"
			"   onlyents   = only compile entities with bsp\n"
			"   micro <volume>\n"
			"              = sets the micro volume to the given float\n"
			"   leaktest   = perform a leak test\n"
			"   verboseentities\n"
			"              = enable entity verbose mode\n"
			"   chop <subdivide_size>\n"
			"              = sets the subdivide size to the given float\n"*/
				   "\n" );
	} //end else
	Log_Close();                        //close the log file
	return 0;
} //end of the function main
Esempio n. 4
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
void CreateAASFilesForAllBSPFiles( char *quakepath ) {
#if defined( WIN32 ) | defined( _WIN32 )
	WIN32_FIND_DATA filedata;
	HWND handle;
	struct _stat statbuf;
#else
	glob_t globbuf;
	struct stat statbuf;
	int j;
#endif
	int done;
	char filter[_MAX_PATH], bspfilter[_MAX_PATH], aasfilter[_MAX_PATH];
	char aasfile[_MAX_PATH], buf[_MAX_PATH], foldername[_MAX_PATH];
	quakefile_t *qf, *qf2, *files, *bspfiles, *aasfiles;

	strcpy( filter, quakepath );
	AppendPathSeperator( filter, sizeof( filter ) );
	strcat( filter, "*" );

#if defined( WIN32 ) | defined( _WIN32 )
	handle = FindFirstFile( filter, &filedata );
	done = ( handle == INVALID_HANDLE_VALUE );
	while ( !done )
	{
		_splitpath( filter, foldername, NULL, NULL, NULL );
		_splitpath( filter, NULL, &foldername[strlen( foldername )], NULL, NULL );
		AppendPathSeperator( foldername, _MAX_PATH );
		strcat( foldername, filedata.cFileName );
		_stat( foldername, &statbuf );
#else
	glob( filter, 0, NULL, &globbuf );
	for ( j = 0; j < globbuf.gl_pathc; j++ )
	{
		strcpy( foldername, globbuf.gl_pathv[j] );
		stat( foldername, &statbuf );
#endif
		//if it is a folder
		if ( statbuf.st_mode & S_IFDIR ) {
			//
			AppendPathSeperator( foldername, sizeof( foldername ) );
			//get all the bsp files
			strcpy( bspfilter, foldername );
			strcat( bspfilter, "maps/*.bsp" );
			files = FindQuakeFiles( bspfilter );
			strcpy( bspfilter, foldername );
			strcat( bspfilter, "*.pk3/maps/*.bsp" );
			bspfiles = FindQuakeFiles( bspfilter );
			for ( qf = bspfiles; qf; qf = qf->next ) if ( !qf->next ) {
					break;
				}
			if ( qf ) {
				qf->next = files;
			} else { bspfiles = files;}
			//get all the aas files
			strcpy( aasfilter, foldername );
			strcat( aasfilter, "maps/*.aas" );
			files = FindQuakeFiles( aasfilter );
			strcpy( aasfilter, foldername );
			strcat( aasfilter, "*.pk3/maps/*.aas" );
			aasfiles = FindQuakeFiles( aasfilter );
			for ( qf = aasfiles; qf; qf = qf->next ) if ( !qf->next ) {
					break;
				}
			if ( qf ) {
				qf->next = files;
			} else { aasfiles = files;}
			//
			for ( qf = bspfiles; qf; qf = qf->next )
			{
				sprintf( aasfile, "%s/%s", qf->pakfile, qf->origname );
				Log_Print( "found %s\n", aasfile );
				strcpy( &aasfile[strlen( aasfile ) - strlen( ".bsp" )], ".aas" );
				for ( qf2 = aasfiles; qf2; qf2 = qf2->next )
				{
					sprintf( buf, "%s/%s", qf2->pakfile, qf2->origname );
					if ( !stricmp( aasfile, buf ) ) {
						Log_Print( "found %s\n", buf );
						break;
					} //end if
				} //end for
			} //end for
		} //end if
#if defined( WIN32 ) | defined( _WIN32 )
		//find the next file
		done = !FindNextFile( handle, &filedata );
	} //end while
#else
	} //end for
	globfree( &globbuf );
#endif
} //end of the function CreateAASFilesForAllBSPFiles
Esempio n. 5
0
int main (int argc, char **argv)
{
	int i, comp = 0;
	char outputpath[MAX_PATH] = "";
	char filename[MAX_PATH] = "unknown";
	quakefile_t *qfiles = NULL, *qf;
	double start_time;

	myargc = argc;
	myargv = argv;

	start_time = I_FloatTime();

	Log_Open("bspc.log");		//open a log file
	Log_Print(BSPC_NAME" version "BSPC_VERSION", %s %s\n", __DATE__, __TIME__);

#ifdef ZTMAUTOARGS
	calcgrapplereach = true;
	forcesidesvisible = true; // Currently always required or BSPC fails?
#endif
	DefaultCfg();
	for (i = 1; i < argc; i++)
	{
		if (!stricmp(argv[i],"-threads"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			numthreads = atoi(argv[++i]);
			Log_Print("threads = %d\n", numthreads);
		} //end if
		else if (!stricmp(argv[i], "-noverbose"))
		{
			Log_Print("verbose = false\n");
			verbose = false;
		} //end else if
		else if (!stricmp(argv[i], "-nocsg"))
		{
			Log_Print("nocsg = true\n");
			nocsg = true;
		} //end else if
		else if (!stricmp(argv[i], "-optimize"))
		{
			Log_Print("optimize = true\n");
			optimize = true;
		} //end else if
		/*
		else if (!stricmp(argv[i], "-noweld"))
		{
			Log_Print("noweld = true\n");
			noweld = true;
		} //end else if
		else if (!stricmp(argv[i], "-noshare"))
		{
			Log_Print("noshare = true\n");
			noshare = true;
		} //end else if
		else if (!stricmp(argv[i], "-notjunc"))
		{
			Log_Print("notjunc = true\n");
			notjunc = true;
		} //end else if
		else if (!stricmp(argv[i], "-nowater"))
		{
			Log_Print("nowater = true\n");
			nowater = true;
		} //end else if
		else if (!stricmp(argv[i], "-noprune"))
		{
			Log_Print("noprune = true\n");
			noprune = true;
		} //end else if
		else if (!stricmp(argv[i], "-nomerge"))
		{
			Log_Print("nomerge = true\n");
			nomerge = true;
		} //end else if
		else if (!stricmp(argv[i], "-nosubdiv"))
		{
			Log_Print("nosubdiv = true\n");
			nosubdiv = true;
		} //end else if
		else if (!stricmp(argv[i], "-nodetail"))
		{
			Log_Print("nodetail = true\n");
			nodetail = true;
		} //end else if
		else if (!stricmp(argv[i], "-fulldetail"))
		{
			Log_Print("fulldetail = true\n");
			fulldetail = true;
		} //end else if
		else if (!stricmp(argv[i], "-onlyents"))
		{
			Log_Print("onlyents = true\n");
			onlyents = true;
		} //end else if
		else if (!stricmp(argv[i], "-micro"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			microvolume = atof(argv[++i]);
			Log_Print("microvolume = %f\n", microvolume);
		} //end else if
		else if (!stricmp(argv[i], "-leaktest"))
		{
			Log_Print("leaktest = true\n");
			leaktest = true;
		} //end else if
		else if (!stricmp(argv[i], "-verboseentities"))
		{
			Log_Print("verboseentities = true\n");
			verboseentities = true;
		} //end else if
		else if (!stricmp(argv[i], "-chop"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			subdivide_size = atof(argv[++i]);
			Log_Print("subdivide_size = %f\n", subdivide_size);
		} //end else if
		else if (!stricmp (argv[i], "-tmpout"))
		{
			strcpy (outbase, "/tmp");
			Log_Print("temp output\n");
		} //end else if
		*/
		else if (!stricmp(argv[i], "-freetree"))
		{
			freetree = true;
			Log_Print("freetree = true\n");
		} //end else if
		else if (!stricmp(argv[i], "-grapplereach"))
		{
			calcgrapplereach = true;
			Log_Print("grapplereach = true\n");
		} //end else if
#ifdef ZTMAUTOARGS
		else if (!stricmp(argv[i], "-nograpplereach"))
		{
			calcgrapplereach = false;
			Log_Print("grapplereach = false\n");
		} //end else if
#endif
		else if (!stricmp(argv[i], "-nobrushmerge"))
		{
			nobrushmerge = true;
			Log_Print("nobrushmerge = true\n");
		} //end else if
		else if (!stricmp(argv[i], "-noliquids"))
		{
			noliquids = true;
			Log_Print("noliquids = true\n");
		} //end else if
		else if (!stricmp(argv[i], "-forcesidesvisible"))
		{
			forcesidesvisible = true;
			Log_Print("forcesidesvisible = true\n");
		} //end else if
#ifdef ZTMAUTOARGS
		else if (!stricmp(argv[i], "-noforcesidesvisible"))
		{
			forcesidesvisible = false;
			Log_Print("forcesidesvisible = false\n");
		} //end else if
#endif
		else if (!stricmp(argv[i], "-output"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			if (access(argv[i+1], 0x04)) Warning("the folder %s does not exist", argv[i+1]);
			strcpy(outputpath, argv[++i]);
		} //end else if
		else if (!stricmp(argv[i], "-breadthfirst"))
		{
			use_nodequeue = true;
			Log_Print("breadthfirst = true\n");
		} //end else if
		else if (!stricmp(argv[i], "-capsule"))
		{
			capsule_collision = true;
			Log_Print("capsule_collision = true\n");
		} //end else if
		else if (!stricmp(argv[i], "-cfg"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			if (!LoadCfgFile(argv[++i]))
				exit(0);
		} //end else if
		else if (!stricmp(argv[i], "-bsp2map"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			comp = COMP_BSP2MAP;
			qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
		} //end else if
		else if (!stricmp(argv[i], "-bsp2aas"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			comp = COMP_BSP2AAS;
			qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
		} //end else if
		else if (!stricmp(argv[i], "-aasall"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			CreateAASFilesForAllBSPFiles(argv[++i]);
		} //end else if
		else if (!stricmp(argv[i], "-reach"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			comp = COMP_REACH;
			qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
		} //end else if
		else if (!stricmp(argv[i], "-cluster"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			comp = COMP_CLUSTER;
			qfiles = GetArgumentFiles(argc, argv, &i, "bsp");
		} //end else if
		else if (!stricmp(argv[i], "-aasinfo"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			comp = COMP_AASINFO;
			qfiles = GetArgumentFiles(argc, argv, &i, "aas");
		} //end else if
		else if (!stricmp(argv[i], "-aasopt"))
		{
			if (i + 1 >= argc) {i = 0; break;}
			comp = COMP_AASOPTIMIZE;
			qfiles = GetArgumentFiles(argc, argv, &i, "aas");
		} //end else if
		else
		{
			Log_Print("unknown parameter %s\n", argv[i]);
			break;
		} //end else
	} //end for

	//if there are parameters and there's no mismatch in one of the parameters
	if (argc > 1 && i == argc)
	{
		switch(comp)
		{
			case COMP_BSP2MAP:
			{
				if (!qfiles) Log_Print("no files found\n");
				for (qf = qfiles; qf; qf = qf->next)
				{
					//copy the output path
					strcpy(filename, outputpath);
					//append the bsp file base
					AppendPathSeperator(filename, MAX_PATH);
					ExtractFileBase(qf->origname, &filename[strlen(filename)]);
					//append .map
					strcat(filename, ".map");
					//
					Log_Print("bsp2map: %s to %s\n", qf->origname, filename);
					if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
					//
					LoadMapFromBSP(qf);
					//write the map file
					WriteMapFile(filename);
				} //end for
				break;
			} //end case
			case COMP_BSP2AAS:
			{
				if (!qfiles) Log_Print("no files found\n");
				for (qf = qfiles; qf; qf = qf->next)
				{
					AASOuputFile(qf, outputpath, filename);
					//
					Log_Print("bsp2aas: %s to %s\n", qf->origname, filename);
					if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
					//set before map loading
					create_aas = 1;
					LoadMapFromBSP(qf);
					//create the AAS file
					AAS_Create(filename);
					//calculate the reachabilities and clusters
					AAS_CalcReachAndClusters(qf);
					//
					if (optimize) AAS_Optimize();
					//
					//write out the stored AAS file
					if (!AAS_WriteAASFile(filename))
					{
						Error("error writing %s\n", filename);
					} //end if
					//deallocate memory
					AAS_FreeMaxAAS();
				} //end for
				break;
			} //end case
			case COMP_REACH:
			{
				if (!qfiles) Log_Print("no files found\n");
				for (qf = qfiles; qf; qf = qf->next)
				{
					AASOuputFile(qf, outputpath, filename);
					//
					Log_Print("reach: %s to %s\n", qf->origname, filename);
					if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
					//if the AAS file exists in the output directory
					if (!access(filename, 0x04))
					{
						if (!AAS_LoadAASFile(filename))
						{
							Error("error loading aas file %s\n", filename);
						} //end if
					} //end if
					else
					{
						Warning("AAS file %s not found in output folder\n", filename);
						Log_Print("creating %s...\n", filename);
						//set before map loading
						create_aas = 1;
						LoadMapFromBSP(qf);
						//create the AAS file
						AAS_Create(filename);
					} //end else
					//calculate the reachabilities and clusters
					AAS_CalcReachAndClusters(qf);
					//
					if (optimize) AAS_Optimize();
					//write out the stored AAS file
					if (!AAS_WriteAASFile(filename))
					{
						Error("error writing %s\n", filename);
					} //end if
					//deallocate memory
					AAS_FreeMaxAAS();
				} //end for
				break;
			} //end case
			case COMP_CLUSTER:
			{
				if (!qfiles) Log_Print("no files found\n");
				for (qf = qfiles; qf; qf = qf->next)
				{
					AASOuputFile(qf, outputpath, filename);
					//
					Log_Print("cluster: %s to %s\n", qf->origname, filename);
					if (qf->type != QFILETYPE_BSP) Warning("%s is probably not a BSP file\n", qf->origname);
					//if the AAS file exists in the output directory
					if (!access(filename, 0x04))
					{
						if (!AAS_LoadAASFile(filename))
						{
							Error("error loading aas file %s\n", filename);
						} //end if
						//calculate the clusters
						AAS_RecalcClusters();
					} //end if
					else
					{
						Warning("AAS file %s not found in output folder\n", filename);
						Log_Print("creating %s...\n", filename);
						//set before map loading
						create_aas = 1;
						LoadMapFromBSP(qf);
						//create the AAS file
						AAS_Create(filename);
						//calculate the reachabilities and clusters
						AAS_CalcReachAndClusters(qf);
					} //end else
					//
					if (optimize) AAS_Optimize();
					//write out the stored AAS file
					if (!AAS_WriteAASFile(filename))
					{
						Error("error writing %s\n", filename);
					} //end if
					//deallocate memory
					AAS_FreeMaxAAS();
				} //end for
				break;
			} //end case
			case COMP_AASOPTIMIZE:
			{
				if (!qfiles) Log_Print("no files found\n");
				for (qf = qfiles; qf; qf = qf->next)
				{
					AASOuputFile(qf, outputpath, filename);
					//
					Log_Print("optimizing: %s to %s\n", qf->origname, filename);
					if (qf->type != QFILETYPE_AAS) Warning("%s is probably not a AAS file\n", qf->origname);
					//
					AAS_InitBotImport();
					//
					if (!AAS_LoadAASFile(qf->filename))
					{
						Error("error loading aas file %s\n", qf->filename);
					} //end if
					AAS_Optimize();
					//write out the stored AAS file
					if (!AAS_WriteAASFile(filename))
					{
						Error("error writing %s\n", filename);
					} //end if
					//deallocate memory
					AAS_FreeMaxAAS();
				} //end for
				break;
			} //end case
			case COMP_AASINFO:
			{
				if (!qfiles) Log_Print("no files found\n");
				for (qf = qfiles; qf; qf = qf->next)
				{
					AASOuputFile(qf, outputpath, filename);
					//
					Log_Print("aas info for: %s\n", filename);
					if (qf->type != QFILETYPE_AAS) Warning("%s is probably not a AAS file\n", qf->origname);
					//
					AAS_InitBotImport();
					//
					if (!AAS_LoadAASFile(qf->filename))
					{
						Error("error loading aas file %s\n", qf->filename);
					} //end if
					AAS_ShowTotals();
				} //end for
				break;
			} //end case
			default:
			{
				Log_Print("don't know what to do\n");
				break;
			} //end default
		} //end switch
	} //end if
	else
	{
		Log_Print("Usage:   bspc [-<switch> [-<switch> ...]]\n"
#ifdef _WIN32
			"Example 1: bspc -bsp2aas d:\\quake3\\baseq3\\maps\\mymap?.bsp\n"
			"Example 2: bspc -bsp2aas d:\\quake3\\baseq3\\pak0.pk3\\maps/q3dm*.bsp\n"
#else
			"Example 1: bspc -bsp2aas /quake3/baseq3/maps/mymap?.bsp\n"
			"Example 2: bspc -bsp2aas /quake3/baseq3/pak0.pk3/maps/q3dm*.bsp\n"
#endif
			"\n"
			"Switches:\n"
			//"   bsp2map  <[pakfilter/]filter.bsp>    = convert BSP to MAP\n"
			//"   aasall   <quake3folder>              = create AAS files for all BSPs\n"
			"   bsp2aas  <[pakfilter/]filter.bsp>    = convert BSP to AAS\n"
			"   reach    <filter.bsp>                = compute reachability & clusters\n"
			"   cluster  <filter.bsp>                = compute clusters\n"
			"   aasopt   <filter.aas>                = optimize aas file\n"
			"   aasinfo  <filter.aas>                = show AAS file info\n"
			"   output   <output path>               = set output path\n"
			"   threads  <X>                         = set number of threads to X\n"
			"   cfg      <filename>                  = use this cfg file\n"
			"   optimize                             = enable optimization\n"
			"   noverbose                            = disable verbose output\n"
			"   breadthfirst                         = breadth first bsp building\n"
			"   nobrushmerge                         = don't merge brushes\n"
			"   noliquids                            = don't write liquids to map\n"
			"   freetree                             = free the bsp tree\n"
			"   nocsg                                = disables brush chopping\n"
#ifdef ZTMAUTOARGS
			"   noforcesidesvisible                  = don't force all sides to be visible\n"
			"   nograpplereach                       = don't calculate grapple reachabilities\n"
#else
			"   forcesidesvisible                    = force all sides to be visible\n"
			"   grapplereach                         = calculate grapple reachabilities\n"
#endif

/*			"   noweld     = disables weld\n"
			"   noshare    = disables sharing\n"
			"   notjunc    = disables juncs\n"
			"   nowater    = disables water brushes\n"
			"   noprune    = disables node prunes\n"
			"   nomerge    = disables face merging\n"
			"   nosubdiv   = disables subdeviding\n"
			"   nodetail   = disables detail brushes\n"
			"   fulldetail = enables full detail\n"
			"   onlyents   = only compile entities with bsp\n"
			"   micro <volume>\n"
			"              = sets the micro volume to the given float\n"
			"   leaktest   = perform a leak test\n"
			"   verboseentities\n"
			"              = enable entity verbose mode\n"
			"   chop <subdivide_size>\n"
			"              = sets the subdivide size to the given float\n"*/
			"\n");
	} //end else
	Log_Print("BSPC run time is %5.0f seconds\n", I_FloatTime() - start_time);
	Log_Close();						//close the log file
	return 0;
} //end of the function main
Esempio n. 6
0
//===========================================================================
//
// Parameter:			-
// Returns:				-
// Changes Globals:		-
//===========================================================================
quakefile_t *FindQuakeFilesWithPakFilter(char *pakfilter, char *filter)
{
#ifdef _WIN32
	WIN32_FIND_DATA filedata;
	HWND handle;
	struct _stat statbuf;
	int done;
#else
	glob_t globbuf;
	struct stat statbuf;
	int j;
#endif
	quakefile_t *qfiles, *lastqf, *qf;
	char pakfile[_MAX_PATH], filename[_MAX_PATH], *str;

	qfiles = NULL;
	lastqf = NULL;
	if (pakfilter && strlen(pakfilter))
	{
#ifdef _WIN32
		handle = FindFirstFile(pakfilter, &filedata);
		done = (handle == INVALID_HANDLE_VALUE);
		while(!done)
		{
			_splitpath(pakfilter, pakfile, NULL, NULL, NULL);
			_splitpath(pakfilter, NULL, &pakfile[strlen(pakfile)], NULL, NULL);
			AppendPathSeperator(pakfile, _MAX_PATH);
			strcat(pakfile, filedata.cFileName);
			_stat(pakfile, &statbuf);
#else
		glob(pakfilter, 0, NULL, &globbuf);
		for (j = 0; j < globbuf.gl_pathc; j++)
		{
			strcpy(pakfile, globbuf.gl_pathv[j]);
			stat(pakfile, &statbuf);
#endif
			//if the file with .pak or .pk3 is a folder
			if (statbuf.st_mode & S_IFDIR)
			{
				strcpy(filename, pakfilter);
				AppendPathSeperator(filename, _MAX_PATH);
				strcat(filename, filter);
				qf = FindQuakeFilesWithPakFilter(NULL, filename);
				if (lastqf) lastqf->next = qf;
				else qfiles = qf;
				lastqf = qf;
				while(lastqf->next) lastqf = lastqf->next;
			} //end if
			else
			{
#ifdef _WIN32
				str = StringContains(pakfile, ".pk3", false);
#else
				str = StringContains(pakfile, ".pk3", true);
#endif
				if (str && str == pakfile + strlen(pakfile) - strlen(".pk3"))
				{
					qf = FindQuakeFilesInZip(pakfile, filter);
				} //end if
				else
				{
					qf = NULL;
				} //end else
				//
				if (qf)
				{
					if (lastqf) lastqf->next = qf;
					else qfiles = qf;
					lastqf = qf;
					while(lastqf->next) lastqf = lastqf->next;
				} //end if
			} //end else
			//
#ifdef _WIN32
			//find the next file
			done = !FindNextFile(handle, &filedata);
		} //end while
#else
		} //end for
		globfree(&globbuf);
#endif
	} //end if
	else
	{
#ifdef _WIN32
		handle = FindFirstFile(filter, &filedata);
		done = (handle == INVALID_HANDLE_VALUE);
		while(!done)
		{
			_splitpath(filter, filename, NULL, NULL, NULL);
			_splitpath(filter, NULL, &filename[strlen(filename)], NULL, NULL);
			AppendPathSeperator(filename, _MAX_PATH);
			strcat(filename, filedata.cFileName);
#else
		glob(filter, 0, NULL, &globbuf);
		for (j = 0; j < globbuf.gl_pathc; j++)
		{
			strcpy(filename, globbuf.gl_pathv[j]);
#endif
			//
			qf = malloc(sizeof(quakefile_t));
			if (!qf) Error("out of memory");
			memset(qf, 0, sizeof(quakefile_t));
			strcpy(qf->pakfile, "");
			strcpy(qf->filename, filename);
			strcpy(qf->origname, filename);
			qf->length = 0;
			qf->type = QuakeFileType(filename);
			//add the file ot the list
			qf->next = NULL;
			if (lastqf) lastqf->next = qf;
			else qfiles = qf;
			lastqf = qf;
#ifdef _WIN32
			//find the next file
			done = !FindNextFile(handle, &filedata);
		} //end while
#else
		} //end for
		globfree(&globbuf);
#endif
	} //end else
	return qfiles;
} //end of the function FindQuakeFilesWithPakFilter