Beispiel #1
0
//===========================================================================
//
// Parameter:				-
// Returns:					-
// Changes Globals:		-
//===========================================================================
void AAS_ContinueInit(float time)
{
	//if no AAS file loaded
	if (!aasworld.loaded) return;
	//if AAS is already initialized
	if (aasworld.initialized) return;
	//calculate reachability, if not finished return
	if (AAS_ContinueInitReachability(time)) return;
	//initialize clustering for the new map
	AAS_InitClustering();
	//if reachability has been calculated and an AAS file should be written
	//or there is a forced data optimization
	if (aasworld.savefile || ((int)LibVarGetValue("forcewrite")))
	{
		//optimize the AAS data
		if ((int)LibVarValue("aasoptimize", "0")) AAS_Optimize();
		//save the AAS file
		if (AAS_WriteAASFile(aasworld.filename))
		{
			botimport.Print(PRT_MESSAGE, "%s written succesfully\n", aasworld.filename);
		} //end if
		else
		{
			botimport.Print(PRT_ERROR, "couldn't write %s\n", aasworld.filename);
		} //end else
	} //end if
	//initialize the routing
	AAS_InitRouting();
	//at this point AAS is initialized
	AAS_SetInitialized();
} //end of the function AAS_ContinueInit
Beispiel #2
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
Beispiel #3
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