📄 bspc.c
字号:
#define COMP_BSP2MAP 1
#define COMP_BSP2AAS 2
#define COMP_REACH 3
#define COMP_CLUSTER 4
#define COMP_AASOPTIMIZE 5
#define COMP_AASINFO 6
int main (int argc, char **argv)
{
int i, comp = 0;
char outputpath[MAX_PATH] = "";
char filename[MAX_PATH] = "unknown";
quakefile_t *qfiles, *qf;
double start_time;
myargc = argc;
myargv = argv;
start_time = I_FloatTime();
Log_Open("bspc.log"); //open a log file
Log_Print("BSPC version "BSPC_VERSION", %s %s\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], "-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
#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
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"
//" 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.aas> = 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"
" 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_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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -