bspfile.c (14767B)
1 /* 2 =========================================================================== 3 Copyright (C) 1999-2005 Id Software, Inc. 4 5 This file is part of Quake III Arena source code. 6 7 Quake III Arena source code is free software; you can redistribute it 8 and/or modify it under the terms of the GNU General Public License as 9 published by the Free Software Foundation; either version 2 of the License, 10 or (at your option) any later version. 11 12 Quake III Arena source code is distributed in the hope that it will be 13 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU General Public License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with Foobar; if not, write to the Free Software 19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 20 =========================================================================== 21 */ 22 23 #include "cmdlib.h" 24 #include "mathlib.h" 25 #include "bspfile.h" 26 #include "scriplib.h" 27 28 void GetLeafNums (void); 29 30 //============================================================================= 31 32 int nummodels; 33 dmodel_t dmodels[MAX_MAP_MODELS]; 34 35 int numShaders; 36 dshader_t dshaders[MAX_MAP_SHADERS]; 37 38 int entdatasize; 39 char dentdata[MAX_MAP_ENTSTRING]; 40 41 int numleafs; 42 dleaf_t dleafs[MAX_MAP_LEAFS]; 43 44 int numplanes; 45 dplane_t dplanes[MAX_MAP_PLANES]; 46 47 int numnodes; 48 dnode_t dnodes[MAX_MAP_NODES]; 49 50 int numleafsurfaces; 51 int dleafsurfaces[MAX_MAP_LEAFFACES]; 52 53 int numleafbrushes; 54 int dleafbrushes[MAX_MAP_LEAFBRUSHES]; 55 56 int numbrushes; 57 dbrush_t dbrushes[MAX_MAP_BRUSHES]; 58 59 int numbrushsides; 60 dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES]; 61 62 int numLightBytes; 63 byte lightBytes[MAX_MAP_LIGHTING]; 64 65 int numGridPoints; 66 byte gridData[MAX_MAP_LIGHTGRID]; 67 68 int numVisBytes; 69 byte visBytes[MAX_MAP_VISIBILITY]; 70 71 int numDrawVerts; 72 drawVert_t drawVerts[MAX_MAP_DRAW_VERTS]; 73 74 int numDrawIndexes; 75 int drawIndexes[MAX_MAP_DRAW_INDEXES]; 76 77 int numDrawSurfaces; 78 dsurface_t drawSurfaces[MAX_MAP_DRAW_SURFS]; 79 80 int numFogs; 81 dfog_t dfogs[MAX_MAP_FOGS]; 82 83 //============================================================================= 84 85 /* 86 ============= 87 SwapBlock 88 89 If all values are 32 bits, this can be used to swap everything 90 ============= 91 */ 92 void SwapBlock( int *block, int sizeOfBlock ) { 93 int i; 94 95 sizeOfBlock >>= 2; 96 for ( i = 0 ; i < sizeOfBlock ; i++ ) { 97 block[i] = LittleLong( block[i] ); 98 } 99 } 100 101 /* 102 ============= 103 SwapBSPFile 104 105 Byte swaps all data in a bsp file. 106 ============= 107 */ 108 void SwapBSPFile( void ) { 109 int i; 110 111 // models 112 SwapBlock( (int *)dmodels, nummodels * sizeof( dmodels[0] ) ); 113 114 // shaders (don't swap the name) 115 for ( i = 0 ; i < numShaders ; i++ ) { 116 dshaders[i].contentFlags = LittleLong( dshaders[i].contentFlags ); 117 dshaders[i].surfaceFlags = LittleLong( dshaders[i].surfaceFlags ); 118 } 119 120 // planes 121 SwapBlock( (int *)dplanes, numplanes * sizeof( dplanes[0] ) ); 122 123 // nodes 124 SwapBlock( (int *)dnodes, numnodes * sizeof( dnodes[0] ) ); 125 126 // leafs 127 SwapBlock( (int *)dleafs, numleafs * sizeof( dleafs[0] ) ); 128 129 // leaffaces 130 SwapBlock( (int *)dleafsurfaces, numleafsurfaces * sizeof( dleafsurfaces[0] ) ); 131 132 // leafbrushes 133 SwapBlock( (int *)dleafbrushes, numleafbrushes * sizeof( dleafbrushes[0] ) ); 134 135 // brushes 136 SwapBlock( (int *)dbrushes, numbrushes * sizeof( dbrushes[0] ) ); 137 138 // brushsides 139 SwapBlock( (int *)dbrushsides, numbrushsides * sizeof( dbrushsides[0] ) ); 140 141 // vis 142 ((int *)&visBytes)[0] = LittleLong( ((int *)&visBytes)[0] ); 143 ((int *)&visBytes)[1] = LittleLong( ((int *)&visBytes)[1] ); 144 145 // drawverts (don't swap colors ) 146 for ( i = 0 ; i < numDrawVerts ; i++ ) { 147 drawVerts[i].lightmap[0] = LittleFloat( drawVerts[i].lightmap[0] ); 148 drawVerts[i].lightmap[1] = LittleFloat( drawVerts[i].lightmap[1] ); 149 drawVerts[i].st[0] = LittleFloat( drawVerts[i].st[0] ); 150 drawVerts[i].st[1] = LittleFloat( drawVerts[i].st[1] ); 151 drawVerts[i].xyz[0] = LittleFloat( drawVerts[i].xyz[0] ); 152 drawVerts[i].xyz[1] = LittleFloat( drawVerts[i].xyz[1] ); 153 drawVerts[i].xyz[2] = LittleFloat( drawVerts[i].xyz[2] ); 154 drawVerts[i].normal[0] = LittleFloat( drawVerts[i].normal[0] ); 155 drawVerts[i].normal[1] = LittleFloat( drawVerts[i].normal[1] ); 156 drawVerts[i].normal[2] = LittleFloat( drawVerts[i].normal[2] ); 157 } 158 159 // drawindexes 160 SwapBlock( (int *)drawIndexes, numDrawIndexes * sizeof( drawIndexes[0] ) ); 161 162 // drawsurfs 163 SwapBlock( (int *)drawSurfaces, numDrawSurfaces * sizeof( drawSurfaces[0] ) ); 164 165 // fogs 166 for ( i = 0 ; i < numFogs ; i++ ) { 167 dfogs[i].brushNum = LittleLong( dfogs[i].brushNum ); 168 dfogs[i].visibleSide = LittleLong( dfogs[i].visibleSide ); 169 } 170 } 171 172 173 174 /* 175 ============= 176 CopyLump 177 ============= 178 */ 179 int CopyLump( dheader_t *header, int lump, void *dest, int size ) { 180 int length, ofs; 181 182 length = header->lumps[lump].filelen; 183 ofs = header->lumps[lump].fileofs; 184 185 if ( length % size ) { 186 Error ("LoadBSPFile: odd lump size"); 187 } 188 189 memcpy( dest, (byte *)header + ofs, length ); 190 191 return length / size; 192 } 193 194 /* 195 ============= 196 LoadBSPFile 197 ============= 198 */ 199 void LoadBSPFile( const char *filename ) { 200 dheader_t *header; 201 202 // load the file header 203 LoadFile (filename, (void **)&header); 204 205 // swap the header 206 SwapBlock( (int *)header, sizeof(*header) ); 207 208 if ( header->ident != BSP_IDENT ) { 209 Error( "%s is not a IBSP file", filename ); 210 } 211 if ( header->version != BSP_VERSION ) { 212 Error( "%s is version %i, not %i", filename, header->version, BSP_VERSION ); 213 } 214 215 numShaders = CopyLump( header, LUMP_SHADERS, dshaders, sizeof(dshader_t) ); 216 nummodels = CopyLump( header, LUMP_MODELS, dmodels, sizeof(dmodel_t) ); 217 numplanes = CopyLump( header, LUMP_PLANES, dplanes, sizeof(dplane_t) ); 218 numleafs = CopyLump( header, LUMP_LEAFS, dleafs, sizeof(dleaf_t) ); 219 numnodes = CopyLump( header, LUMP_NODES, dnodes, sizeof(dnode_t) ); 220 numleafsurfaces = CopyLump( header, LUMP_LEAFSURFACES, dleafsurfaces, sizeof(dleafsurfaces[0]) ); 221 numleafbrushes = CopyLump( header, LUMP_LEAFBRUSHES, dleafbrushes, sizeof(dleafbrushes[0]) ); 222 numbrushes = CopyLump( header, LUMP_BRUSHES, dbrushes, sizeof(dbrush_t) ); 223 numbrushsides = CopyLump( header, LUMP_BRUSHSIDES, dbrushsides, sizeof(dbrushside_t) ); 224 numDrawVerts = CopyLump( header, LUMP_DRAWVERTS, drawVerts, sizeof(drawVert_t) ); 225 numDrawSurfaces = CopyLump( header, LUMP_SURFACES, drawSurfaces, sizeof(dsurface_t) ); 226 numFogs = CopyLump( header, LUMP_FOGS, dfogs, sizeof(dfog_t) ); 227 numDrawIndexes = CopyLump( header, LUMP_DRAWINDEXES, drawIndexes, sizeof(drawIndexes[0]) ); 228 229 numVisBytes = CopyLump( header, LUMP_VISIBILITY, visBytes, 1 ); 230 numLightBytes = CopyLump( header, LUMP_LIGHTMAPS, lightBytes, 1 ); 231 entdatasize = CopyLump( header, LUMP_ENTITIES, dentdata, 1); 232 233 numGridPoints = CopyLump( header, LUMP_LIGHTGRID, gridData, 8 ); 234 235 236 free( header ); // everything has been copied out 237 238 // swap everything 239 SwapBSPFile(); 240 } 241 242 243 //============================================================================ 244 245 /* 246 ============= 247 AddLump 248 ============= 249 */ 250 void AddLump( FILE *bspfile, dheader_t *header, int lumpnum, const void *data, int len ) { 251 lump_t *lump; 252 253 lump = &header->lumps[lumpnum]; 254 255 lump->fileofs = LittleLong( ftell(bspfile) ); 256 lump->filelen = LittleLong( len ); 257 SafeWrite( bspfile, data, (len+3)&~3 ); 258 } 259 260 /* 261 ============= 262 WriteBSPFile 263 264 Swaps the bsp file in place, so it should not be referenced again 265 ============= 266 */ 267 void WriteBSPFile( const char *filename ) { 268 dheader_t outheader, *header; 269 FILE *bspfile; 270 271 header = &outheader; 272 memset( header, 0, sizeof(dheader_t) ); 273 274 SwapBSPFile(); 275 276 header->ident = LittleLong( BSP_IDENT ); 277 header->version = LittleLong( BSP_VERSION ); 278 279 bspfile = SafeOpenWrite( filename ); 280 SafeWrite( bspfile, header, sizeof(dheader_t) ); // overwritten later 281 282 AddLump( bspfile, header, LUMP_SHADERS, dshaders, numShaders*sizeof(dshader_t) ); 283 AddLump( bspfile, header, LUMP_PLANES, dplanes, numplanes*sizeof(dplane_t) ); 284 AddLump( bspfile, header, LUMP_LEAFS, dleafs, numleafs*sizeof(dleaf_t) ); 285 AddLump( bspfile, header, LUMP_NODES, dnodes, numnodes*sizeof(dnode_t) ); 286 AddLump( bspfile, header, LUMP_BRUSHES, dbrushes, numbrushes*sizeof(dbrush_t) ); 287 AddLump( bspfile, header, LUMP_BRUSHSIDES, dbrushsides, numbrushsides*sizeof(dbrushside_t) ); 288 AddLump( bspfile, header, LUMP_LEAFSURFACES, dleafsurfaces, numleafsurfaces*sizeof(dleafsurfaces[0]) ); 289 AddLump( bspfile, header, LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes*sizeof(dleafbrushes[0]) ); 290 AddLump( bspfile, header, LUMP_MODELS, dmodels, nummodels*sizeof(dmodel_t) ); 291 AddLump( bspfile, header, LUMP_DRAWVERTS, drawVerts, numDrawVerts*sizeof(drawVert_t) ); 292 AddLump( bspfile, header, LUMP_SURFACES, drawSurfaces, numDrawSurfaces*sizeof(dsurface_t) ); 293 AddLump( bspfile, header, LUMP_VISIBILITY, visBytes, numVisBytes ); 294 AddLump( bspfile, header, LUMP_LIGHTMAPS, lightBytes, numLightBytes ); 295 AddLump( bspfile, header, LUMP_LIGHTGRID, gridData, 8 * numGridPoints ); 296 AddLump( bspfile, header, LUMP_ENTITIES, dentdata, entdatasize ); 297 AddLump( bspfile, header, LUMP_FOGS, dfogs, numFogs * sizeof(dfog_t) ); 298 AddLump( bspfile, header, LUMP_DRAWINDEXES, drawIndexes, numDrawIndexes * sizeof(drawIndexes[0]) ); 299 300 fseek (bspfile, 0, SEEK_SET); 301 SafeWrite (bspfile, header, sizeof(dheader_t)); 302 fclose (bspfile); 303 } 304 305 //============================================================================ 306 307 /* 308 ============= 309 PrintBSPFileSizes 310 311 Dumps info about current file 312 ============= 313 */ 314 void PrintBSPFileSizes( void ) { 315 if ( !num_entities ) { 316 ParseEntities(); 317 } 318 319 printf ("%6i models %7i\n" 320 ,nummodels, (int)(nummodels*sizeof(dmodel_t))); 321 printf ("%6i shaders %7i\n" 322 ,numShaders, (int)(numShaders*sizeof(dshader_t))); 323 printf ("%6i brushes %7i\n" 324 ,numbrushes, (int)(numbrushes*sizeof(dbrush_t))); 325 printf ("%6i brushsides %7i\n" 326 ,numbrushsides, (int)(numbrushsides*sizeof(dbrushside_t))); 327 printf ("%6i fogs %7i\n" 328 ,numFogs, (int)(numFogs*sizeof(dfog_t))); 329 printf ("%6i planes %7i\n" 330 ,numplanes, (int)(numplanes*sizeof(dplane_t))); 331 printf ("%6i entdata %7i\n", num_entities, entdatasize); 332 333 printf ("\n"); 334 335 printf ("%6i nodes %7i\n" 336 ,numnodes, (int)(numnodes*sizeof(dnode_t))); 337 printf ("%6i leafs %7i\n" 338 ,numleafs, (int)(numleafs*sizeof(dleaf_t))); 339 printf ("%6i leafsurfaces %7i\n" 340 ,numleafsurfaces, (int)(numleafsurfaces*sizeof(dleafsurfaces[0]))); 341 printf ("%6i leafbrushes %7i\n" 342 ,numleafbrushes, (int)(numleafbrushes*sizeof(dleafbrushes[0]))); 343 printf ("%6i drawverts %7i\n" 344 ,numDrawVerts, (int)(numDrawVerts*sizeof(drawVerts[0]))); 345 printf ("%6i drawindexes %7i\n" 346 ,numDrawIndexes, (int)(numDrawIndexes*sizeof(drawIndexes[0]))); 347 printf ("%6i drawsurfaces %7i\n" 348 ,numDrawSurfaces, (int)(numDrawSurfaces*sizeof(drawSurfaces[0]))); 349 350 printf ("%6i lightmaps %7i\n" 351 ,numLightBytes / (LIGHTMAP_WIDTH*LIGHTMAP_HEIGHT*3), numLightBytes ); 352 printf (" visibility %7i\n" 353 , numVisBytes ); 354 } 355 356 357 //============================================ 358 359 int num_entities; 360 entity_t entities[MAX_MAP_ENTITIES]; 361 362 void StripTrailing( char *e ) { 363 char *s; 364 365 s = e + strlen(e)-1; 366 while (s >= e && *s <= 32) 367 { 368 *s = 0; 369 s--; 370 } 371 } 372 373 /* 374 ================= 375 ParseEpair 376 ================= 377 */ 378 epair_t *ParseEpair( void ) { 379 epair_t *e; 380 381 e = malloc( sizeof(epair_t) ); 382 memset( e, 0, sizeof(epair_t) ); 383 384 if ( strlen(token) >= MAX_KEY-1 ) { 385 Error ("ParseEpar: token too long"); 386 } 387 e->key = copystring( token ); 388 GetToken( qfalse ); 389 if ( strlen(token) >= MAX_VALUE-1 ) { 390 Error ("ParseEpar: token too long"); 391 } 392 e->value = copystring( token ); 393 394 // strip trailing spaces that sometimes get accidentally 395 // added in the editor 396 StripTrailing( e->key ); 397 StripTrailing( e->value ); 398 399 return e; 400 } 401 402 403 /* 404 ================ 405 ParseEntity 406 ================ 407 */ 408 qboolean ParseEntity( void ) { 409 epair_t *e; 410 entity_t *mapent; 411 412 if ( !GetToken (qtrue) ) { 413 return qfalse; 414 } 415 416 if ( strcmp (token, "{") ) { 417 Error ("ParseEntity: { not found"); 418 } 419 if ( num_entities == MAX_MAP_ENTITIES ) { 420 Error ("num_entities == MAX_MAP_ENTITIES"); 421 } 422 mapent = &entities[num_entities]; 423 num_entities++; 424 425 do { 426 if ( !GetToken (qtrue) ) { 427 Error ("ParseEntity: EOF without closing brace"); 428 } 429 if ( !strcmp (token, "}") ) { 430 break; 431 } 432 e = ParseEpair (); 433 e->next = mapent->epairs; 434 mapent->epairs = e; 435 } while (1); 436 437 return qtrue; 438 } 439 440 /* 441 ================ 442 ParseEntities 443 444 Parses the dentdata string into entities 445 ================ 446 */ 447 void ParseEntities( void ) { 448 num_entities = 0; 449 ParseFromMemory( dentdata, entdatasize ); 450 451 while ( ParseEntity () ) { 452 } 453 } 454 455 456 /* 457 ================ 458 UnparseEntities 459 460 Generates the dentdata string from all the entities 461 This allows the utilities to add or remove key/value pairs 462 to the data created by the map editor. 463 ================ 464 */ 465 void UnparseEntities( void ) { 466 char *buf, *end; 467 epair_t *ep; 468 char line[2048]; 469 int i; 470 char key[1024], value[1024]; 471 472 buf = dentdata; 473 end = buf; 474 *end = 0; 475 476 for (i=0 ; i<num_entities ; i++) { 477 ep = entities[i].epairs; 478 if ( !ep ) { 479 continue; // ent got removed 480 } 481 482 strcat (end,"{\n"); 483 end += 2; 484 485 for ( ep = entities[i].epairs ; ep ; ep=ep->next ) { 486 strcpy (key, ep->key); 487 StripTrailing (key); 488 strcpy (value, ep->value); 489 StripTrailing (value); 490 491 sprintf (line, "\"%s\" \"%s\"\n", key, value); 492 strcat (end, line); 493 end += strlen(line); 494 } 495 strcat (end,"}\n"); 496 end += 2; 497 498 if (end > buf + MAX_MAP_ENTSTRING) { 499 Error ("Entity text too long"); 500 } 501 } 502 entdatasize = end - buf + 1; 503 } 504 505 void PrintEntity( const entity_t *ent ) { 506 epair_t *ep; 507 508 printf ("------- entity %p -------\n", ent); 509 for (ep=ent->epairs ; ep ; ep=ep->next) { 510 printf( "%s = %s\n", ep->key, ep->value ); 511 } 512 513 } 514 515 void SetKeyValue( entity_t *ent, const char *key, const char *value ) { 516 epair_t *ep; 517 518 for ( ep=ent->epairs ; ep ; ep=ep->next ) { 519 if ( !strcmp (ep->key, key) ) { 520 free (ep->value); 521 ep->value = copystring(value); 522 return; 523 } 524 } 525 ep = malloc (sizeof(*ep)); 526 ep->next = ent->epairs; 527 ent->epairs = ep; 528 ep->key = copystring(key); 529 ep->value = copystring(value); 530 } 531 532 const char *ValueForKey( const entity_t *ent, const char *key ) { 533 epair_t *ep; 534 535 for (ep=ent->epairs ; ep ; ep=ep->next) { 536 if (!strcmp (ep->key, key) ) { 537 return ep->value; 538 } 539 } 540 return ""; 541 } 542 543 vec_t FloatForKey( const entity_t *ent, const char *key ) { 544 const char *k; 545 546 k = ValueForKey( ent, key ); 547 return atof(k); 548 } 549 550 void GetVectorForKey( const entity_t *ent, const char *key, vec3_t vec ) { 551 const char *k; 552 double v1, v2, v3; 553 554 k = ValueForKey (ent, key); 555 556 // scanf into doubles, then assign, so it is vec_t size independent 557 v1 = v2 = v3 = 0; 558 sscanf (k, "%lf %lf %lf", &v1, &v2, &v3); 559 vec[0] = v1; 560 vec[1] = v2; 561 vec[2] = v3; 562 } 563 564