00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "cmdlib.h"
00024 #include "mathlib.h"
00025 #include "bspfile.h"
00026 #include "scriplib.h"
00027
00028 void GetLeafNums (void);
00029
00030
00031
00032 int nummodels;
00033 dmodel_t dmodels[MAX_MAP_MODELS];
00034
00035 int numShaders;
00036 dshader_t dshaders[MAX_MAP_SHADERS];
00037
00038 int entdatasize;
00039 char dentdata[MAX_MAP_ENTSTRING];
00040
00041 int numleafs;
00042 dleaf_t dleafs[MAX_MAP_LEAFS];
00043
00044 int numplanes;
00045 dplane_t dplanes[MAX_MAP_PLANES];
00046
00047 int numnodes;
00048 dnode_t dnodes[MAX_MAP_NODES];
00049
00050 int numleafsurfaces;
00051 int dleafsurfaces[MAX_MAP_LEAFFACES];
00052
00053 int numleafbrushes;
00054 int dleafbrushes[MAX_MAP_LEAFBRUSHES];
00055
00056 int numbrushes;
00057 dbrush_t dbrushes[MAX_MAP_BRUSHES];
00058
00059 int numbrushsides;
00060 dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES];
00061
00062 int numLightBytes;
00063 byte lightBytes[MAX_MAP_LIGHTING];
00064
00065 int numGridPoints;
00066 byte gridData[MAX_MAP_LIGHTGRID];
00067
00068 int numVisBytes;
00069 byte visBytes[MAX_MAP_VISIBILITY];
00070
00071 int numDrawVerts;
00072 drawVert_t drawVerts[MAX_MAP_DRAW_VERTS];
00073
00074 int numDrawIndexes;
00075 int drawIndexes[MAX_MAP_DRAW_INDEXES];
00076
00077 int numDrawSurfaces;
00078 dsurface_t drawSurfaces[MAX_MAP_DRAW_SURFS];
00079
00080 int numFogs;
00081 dfog_t dfogs[MAX_MAP_FOGS];
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092 void SwapBlock( int *block, int sizeOfBlock ) {
00093 int i;
00094
00095 sizeOfBlock >>= 2;
00096 for ( i = 0 ; i < sizeOfBlock ; i++ ) {
00097 block[i] = LittleLong( block[i] );
00098 }
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108 void SwapBSPFile( void ) {
00109 int i;
00110
00111
00112 SwapBlock( (int *)dmodels, nummodels * sizeof( dmodels[0] ) );
00113
00114
00115 for ( i = 0 ; i < numShaders ; i++ ) {
00116 dshaders[i].contentFlags = LittleLong( dshaders[i].contentFlags );
00117 dshaders[i].surfaceFlags = LittleLong( dshaders[i].surfaceFlags );
00118 }
00119
00120
00121 SwapBlock( (int *)dplanes, numplanes * sizeof( dplanes[0] ) );
00122
00123
00124 SwapBlock( (int *)dnodes, numnodes * sizeof( dnodes[0] ) );
00125
00126
00127 SwapBlock( (int *)dleafs, numleafs * sizeof( dleafs[0] ) );
00128
00129
00130 SwapBlock( (int *)dleafsurfaces, numleafsurfaces * sizeof( dleafsurfaces[0] ) );
00131
00132
00133 SwapBlock( (int *)dleafbrushes, numleafbrushes * sizeof( dleafbrushes[0] ) );
00134
00135
00136 SwapBlock( (int *)dbrushes, numbrushes * sizeof( dbrushes[0] ) );
00137
00138
00139 SwapBlock( (int *)dbrushsides, numbrushsides * sizeof( dbrushsides[0] ) );
00140
00141
00142 ((int *)&visBytes)[0] = LittleLong( ((int *)&visBytes)[0] );
00143 ((int *)&visBytes)[1] = LittleLong( ((int *)&visBytes)[1] );
00144
00145
00146 for ( i = 0 ; i < numDrawVerts ; i++ ) {
00147 drawVerts[i].lightmap[0] = LittleFloat( drawVerts[i].lightmap[0] );
00148 drawVerts[i].lightmap[1] = LittleFloat( drawVerts[i].lightmap[1] );
00149 drawVerts[i].st[0] = LittleFloat( drawVerts[i].st[0] );
00150 drawVerts[i].st[1] = LittleFloat( drawVerts[i].st[1] );
00151 drawVerts[i].xyz[0] = LittleFloat( drawVerts[i].xyz[0] );
00152 drawVerts[i].xyz[1] = LittleFloat( drawVerts[i].xyz[1] );
00153 drawVerts[i].xyz[2] = LittleFloat( drawVerts[i].xyz[2] );
00154 drawVerts[i].normal[0] = LittleFloat( drawVerts[i].normal[0] );
00155 drawVerts[i].normal[1] = LittleFloat( drawVerts[i].normal[1] );
00156 drawVerts[i].normal[2] = LittleFloat( drawVerts[i].normal[2] );
00157 }
00158
00159
00160 SwapBlock( (int *)drawIndexes, numDrawIndexes * sizeof( drawIndexes[0] ) );
00161
00162
00163 SwapBlock( (int *)drawSurfaces, numDrawSurfaces * sizeof( drawSurfaces[0] ) );
00164
00165
00166 for ( i = 0 ; i < numFogs ; i++ ) {
00167 dfogs[i].brushNum = LittleLong( dfogs[i].brushNum );
00168 dfogs[i].visibleSide = LittleLong( dfogs[i].visibleSide );
00169 }
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179 int CopyLump( dheader_t *header, int lump, void *dest, int size ) {
00180 int length, ofs;
00181
00182 length = header->lumps[lump].filelen;
00183 ofs = header->lumps[lump].fileofs;
00184
00185 if ( length % size ) {
00186 Error ("LoadBSPFile: odd lump size");
00187 }
00188
00189 memcpy( dest, (byte *)header + ofs, length );
00190
00191 return length / size;
00192 }
00193
00194
00195
00196
00197
00198
00199 void LoadBSPFile( const char *filename ) {
00200 dheader_t *header;
00201
00202
00203 LoadFile (filename, (void **)&header);
00204
00205
00206 SwapBlock( (int *)header, sizeof(*header) );
00207
00208 if ( header->ident != BSP_IDENT ) {
00209 Error( "%s is not a IBSP file", filename );
00210 }
00211 if ( header->version != BSP_VERSION ) {
00212 Error( "%s is version %i, not %i", filename, header->version, BSP_VERSION );
00213 }
00214
00215 numShaders = CopyLump( header, LUMP_SHADERS, dshaders, sizeof(dshader_t) );
00216 nummodels = CopyLump( header, LUMP_MODELS, dmodels, sizeof(dmodel_t) );
00217 numplanes = CopyLump( header, LUMP_PLANES, dplanes, sizeof(dplane_t) );
00218 numleafs = CopyLump( header, LUMP_LEAFS, dleafs, sizeof(dleaf_t) );
00219 numnodes = CopyLump( header, LUMP_NODES, dnodes, sizeof(dnode_t) );
00220 numleafsurfaces = CopyLump( header, LUMP_LEAFSURFACES, dleafsurfaces, sizeof(dleafsurfaces[0]) );
00221 numleafbrushes = CopyLump( header, LUMP_LEAFBRUSHES, dleafbrushes, sizeof(dleafbrushes[0]) );
00222 numbrushes = CopyLump( header, LUMP_BRUSHES, dbrushes, sizeof(dbrush_t) );
00223 numbrushsides = CopyLump( header, LUMP_BRUSHSIDES, dbrushsides, sizeof(dbrushside_t) );
00224 numDrawVerts = CopyLump( header, LUMP_DRAWVERTS, drawVerts, sizeof(drawVert_t) );
00225 numDrawSurfaces = CopyLump( header, LUMP_SURFACES, drawSurfaces, sizeof(dsurface_t) );
00226 numFogs = CopyLump( header, LUMP_FOGS, dfogs, sizeof(dfog_t) );
00227 numDrawIndexes = CopyLump( header, LUMP_DRAWINDEXES, drawIndexes, sizeof(drawIndexes[0]) );
00228
00229 numVisBytes = CopyLump( header, LUMP_VISIBILITY, visBytes, 1 );
00230 numLightBytes = CopyLump( header, LUMP_LIGHTMAPS, lightBytes, 1 );
00231 entdatasize = CopyLump( header, LUMP_ENTITIES, dentdata, 1);
00232
00233 numGridPoints = CopyLump( header, LUMP_LIGHTGRID, gridData, 8 );
00234
00235
00236 free( header );
00237
00238
00239 SwapBSPFile();
00240 }
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250 void AddLump( FILE *bspfile, dheader_t *header, int lumpnum, const void *data, int len ) {
00251 lump_t *lump;
00252
00253 lump = &header->lumps[lumpnum];
00254
00255 lump->fileofs = LittleLong( ftell(bspfile) );
00256 lump->filelen = LittleLong( len );
00257 SafeWrite( bspfile, data, (len+3)&~3 );
00258 }
00259
00260
00261
00262
00263
00264
00265
00266
00267 void WriteBSPFile( const char *filename ) {
00268 dheader_t outheader, *header;
00269 FILE *bspfile;
00270
00271 header = &outheader;
00272 memset( header, 0, sizeof(dheader_t) );
00273
00274 SwapBSPFile();
00275
00276 header->ident = LittleLong( BSP_IDENT );
00277 header->version = LittleLong( BSP_VERSION );
00278
00279 bspfile = SafeOpenWrite( filename );
00280 SafeWrite( bspfile, header, sizeof(dheader_t) );
00281
00282 AddLump( bspfile, header, LUMP_SHADERS, dshaders, numShaders*sizeof(dshader_t) );
00283 AddLump( bspfile, header, LUMP_PLANES, dplanes, numplanes*sizeof(dplane_t) );
00284 AddLump( bspfile, header, LUMP_LEAFS, dleafs, numleafs*sizeof(dleaf_t) );
00285 AddLump( bspfile, header, LUMP_NODES, dnodes, numnodes*sizeof(dnode_t) );
00286 AddLump( bspfile, header, LUMP_BRUSHES, dbrushes, numbrushes*sizeof(dbrush_t) );
00287 AddLump( bspfile, header, LUMP_BRUSHSIDES, dbrushsides, numbrushsides*sizeof(dbrushside_t) );
00288 AddLump( bspfile, header, LUMP_LEAFSURFACES, dleafsurfaces, numleafsurfaces*sizeof(dleafsurfaces[0]) );
00289 AddLump( bspfile, header, LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes*sizeof(dleafbrushes[0]) );
00290 AddLump( bspfile, header, LUMP_MODELS, dmodels, nummodels*sizeof(dmodel_t) );
00291 AddLump( bspfile, header, LUMP_DRAWVERTS, drawVerts, numDrawVerts*sizeof(drawVert_t) );
00292 AddLump( bspfile, header, LUMP_SURFACES, drawSurfaces, numDrawSurfaces*sizeof(dsurface_t) );
00293 AddLump( bspfile, header, LUMP_VISIBILITY, visBytes, numVisBytes );
00294 AddLump( bspfile, header, LUMP_LIGHTMAPS, lightBytes, numLightBytes );
00295 AddLump( bspfile, header, LUMP_LIGHTGRID, gridData, 8 * numGridPoints );
00296 AddLump( bspfile, header, LUMP_ENTITIES, dentdata, entdatasize );
00297 AddLump( bspfile, header, LUMP_FOGS, dfogs, numFogs * sizeof(dfog_t) );
00298 AddLump( bspfile, header, LUMP_DRAWINDEXES, drawIndexes, numDrawIndexes * sizeof(drawIndexes[0]) );
00299
00300 fseek (bspfile, 0, SEEK_SET);
00301 SafeWrite (bspfile, header, sizeof(dheader_t));
00302 fclose (bspfile);
00303 }
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314 void PrintBSPFileSizes( void ) {
00315 if ( !num_entities ) {
00316 ParseEntities();
00317 }
00318
00319 printf ("%6i models %7i\n"
00320 ,nummodels, (int)(nummodels*sizeof(dmodel_t)));
00321 printf ("%6i shaders %7i\n"
00322 ,numShaders, (int)(numShaders*sizeof(dshader_t)));
00323 printf ("%6i brushes %7i\n"
00324 ,numbrushes, (int)(numbrushes*sizeof(dbrush_t)));
00325 printf ("%6i brushsides %7i\n"
00326 ,numbrushsides, (int)(numbrushsides*sizeof(dbrushside_t)));
00327 printf ("%6i fogs %7i\n"
00328 ,numFogs, (int)(numFogs*sizeof(dfog_t)));
00329 printf ("%6i planes %7i\n"
00330 ,numplanes, (int)(numplanes*sizeof(dplane_t)));
00331 printf ("%6i entdata %7i\n", num_entities, entdatasize);
00332
00333 printf ("\n");
00334
00335 printf ("%6i nodes %7i\n"
00336 ,numnodes, (int)(numnodes*sizeof(dnode_t)));
00337 printf ("%6i leafs %7i\n"
00338 ,numleafs, (int)(numleafs*sizeof(dleaf_t)));
00339 printf ("%6i leafsurfaces %7i\n"
00340 ,numleafsurfaces, (int)(numleafsurfaces*sizeof(dleafsurfaces[0])));
00341 printf ("%6i leafbrushes %7i\n"
00342 ,numleafbrushes, (int)(numleafbrushes*sizeof(dleafbrushes[0])));
00343 printf ("%6i drawverts %7i\n"
00344 ,numDrawVerts, (int)(numDrawVerts*sizeof(drawVerts[0])));
00345 printf ("%6i drawindexes %7i\n"
00346 ,numDrawIndexes, (int)(numDrawIndexes*sizeof(drawIndexes[0])));
00347 printf ("%6i drawsurfaces %7i\n"
00348 ,numDrawSurfaces, (int)(numDrawSurfaces*sizeof(drawSurfaces[0])));
00349
00350 printf ("%6i lightmaps %7i\n"
00351 ,numLightBytes / (LIGHTMAP_WIDTH*LIGHTMAP_HEIGHT*3), numLightBytes );
00352 printf (" visibility %7i\n"
00353 , numVisBytes );
00354 }
00355
00356
00357
00358
00359 int num_entities;
00360 entity_t entities[MAX_MAP_ENTITIES];
00361
00362 void StripTrailing( char *e ) {
00363 char *s;
00364
00365 s = e + strlen(e)-1;
00366 while (s >= e && *s <= 32)
00367 {
00368 *s = 0;
00369 s--;
00370 }
00371 }
00372
00373
00374
00375
00376
00377
00378 epair_t *ParseEpair( void ) {
00379 epair_t *e;
00380
00381 e = malloc( sizeof(epair_t) );
00382 memset( e, 0, sizeof(epair_t) );
00383
00384 if ( strlen(token) >= MAX_KEY-1 ) {
00385 Error ("ParseEpar: token too long");
00386 }
00387 e->key = copystring( token );
00388 GetToken( qfalse );
00389 if ( strlen(token) >= MAX_VALUE-1 ) {
00390 Error ("ParseEpar: token too long");
00391 }
00392 e->value = copystring( token );
00393
00394
00395
00396 StripTrailing( e->key );
00397 StripTrailing( e->value );
00398
00399 return e;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408 qboolean ParseEntity( void ) {
00409 epair_t *e;
00410 entity_t *mapent;
00411
00412 if ( !GetToken (qtrue) ) {
00413 return qfalse;
00414 }
00415
00416 if ( strcmp (token, "{") ) {
00417 Error ("ParseEntity: { not found");
00418 }
00419 if ( num_entities == MAX_MAP_ENTITIES ) {
00420 Error ("num_entities == MAX_MAP_ENTITIES");
00421 }
00422 mapent = &entities[num_entities];
00423 num_entities++;
00424
00425 do {
00426 if ( !GetToken (qtrue) ) {
00427 Error ("ParseEntity: EOF without closing brace");
00428 }
00429 if ( !strcmp (token, "}") ) {
00430 break;
00431 }
00432 e = ParseEpair ();
00433 e->next = mapent->epairs;
00434 mapent->epairs = e;
00435 } while (1);
00436
00437 return qtrue;
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447 void ParseEntities( void ) {
00448 num_entities = 0;
00449 ParseFromMemory( dentdata, entdatasize );
00450
00451 while ( ParseEntity () ) {
00452 }
00453 }
00454
00455
00456
00457
00458
00459
00460
00461
00462
00463
00464
00465 void UnparseEntities( void ) {
00466 char *buf, *end;
00467 epair_t *ep;
00468 char line[2048];
00469 int i;
00470 char key[1024], value[1024];
00471
00472 buf = dentdata;
00473 end = buf;
00474 *end = 0;
00475
00476 for (i=0 ; i<num_entities ; i++) {
00477 ep = entities[i].epairs;
00478 if ( !ep ) {
00479 continue;
00480 }
00481
00482 strcat (end,"{\n");
00483 end += 2;
00484
00485 for ( ep = entities[i].epairs ; ep ; ep=ep->next ) {
00486 strcpy (key, ep->key);
00487 StripTrailing (key);
00488 strcpy (value, ep->value);
00489 StripTrailing (value);
00490
00491 sprintf (line, "\"%s\" \"%s\"\n", key, value);
00492 strcat (end, line);
00493 end += strlen(line);
00494 }
00495 strcat (end,"}\n");
00496 end += 2;
00497
00498 if (end > buf + MAX_MAP_ENTSTRING) {
00499 Error ("Entity text too long");
00500 }
00501 }
00502 entdatasize = end - buf + 1;
00503 }
00504
00505 void PrintEntity( const entity_t *ent ) {
00506 epair_t *ep;
00507
00508 printf ("------- entity %p -------\n", ent);
00509 for (ep=ent->epairs ; ep ; ep=ep->next) {
00510 printf( "%s = %s\n", ep->key, ep->value );
00511 }
00512
00513 }
00514
00515 void SetKeyValue( entity_t *ent, const char *key, const char *value ) {
00516 epair_t *ep;
00517
00518 for ( ep=ent->epairs ; ep ; ep=ep->next ) {
00519 if ( !strcmp (ep->key, key) ) {
00520 free (ep->value);
00521 ep->value = copystring(value);
00522 return;
00523 }
00524 }
00525 ep = malloc (sizeof(*ep));
00526 ep->next = ent->epairs;
00527 ent->epairs = ep;
00528 ep->key = copystring(key);
00529 ep->value = copystring(value);
00530 }
00531
00532 const char *ValueForKey( const entity_t *ent, const char *key ) {
00533 epair_t *ep;
00534
00535 for (ep=ent->epairs ; ep ; ep=ep->next) {
00536 if (!strcmp (ep->key, key) ) {
00537 return ep->value;
00538 }
00539 }
00540 return "";
00541 }
00542
00543 vec_t FloatForKey( const entity_t *ent, const char *key ) {
00544 const char *k;
00545
00546 k = ValueForKey( ent, key );
00547 return atof(k);
00548 }
00549
00550 void GetVectorForKey( const entity_t *ent, const char *key, vec3_t vec ) {
00551 const char *k;
00552 double v1, v2, v3;
00553
00554 k = ValueForKey (ent, key);
00555
00556
00557 v1 = v2 = v3 = 0;
00558 sscanf (k, "%lf %lf %lf", &v1, &v2, &v3);
00559 vec[0] = v1;
00560 vec[1] = v2;
00561 vec[2] = v3;
00562 }
00563
00564