Main Page | Class Hierarchy | Alphabetical List | Data Structures | Directories | File List | Data Fields | Globals

bspfile.c

Go to the documentation of this file.
00001 /*
00002 ===========================================================================
00003 Copyright (C) 1999-2005 Id Software, Inc.
00004 
00005 This file is part of Quake III Arena source code.
00006 
00007 Quake III Arena source code is free software; you can redistribute it
00008 and/or modify it under the terms of the GNU General Public License as
00009 published by the Free Software Foundation; either version 2 of the License,
00010 or (at your option) any later version.
00011 
00012 Quake III Arena source code is distributed in the hope that it will be
00013 useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 GNU General Public License for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Foobar; if not, write to the Free Software
00019 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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 SwapBlock
00088 
00089 If all values are 32 bits, this can be used to swap everything
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 SwapBSPFile
00104 
00105 Byte swaps all data in a bsp file.
00106 =============
00107 */
00108 void SwapBSPFile( void ) {
00109     int             i;
00110     
00111     // models   
00112     SwapBlock( (int *)dmodels, nummodels * sizeof( dmodels[0] ) );
00113 
00114     // shaders (don't swap the name)
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     // planes
00121     SwapBlock( (int *)dplanes, numplanes * sizeof( dplanes[0] ) );
00122     
00123     // nodes
00124     SwapBlock( (int *)dnodes, numnodes * sizeof( dnodes[0] ) );
00125 
00126     // leafs
00127     SwapBlock( (int *)dleafs, numleafs * sizeof( dleafs[0] ) );
00128 
00129     // leaffaces
00130     SwapBlock( (int *)dleafsurfaces, numleafsurfaces * sizeof( dleafsurfaces[0] ) );
00131 
00132     // leafbrushes
00133     SwapBlock( (int *)dleafbrushes, numleafbrushes * sizeof( dleafbrushes[0] ) );
00134 
00135     // brushes
00136     SwapBlock( (int *)dbrushes, numbrushes * sizeof( dbrushes[0] ) );
00137 
00138     // brushsides
00139     SwapBlock( (int *)dbrushsides, numbrushsides * sizeof( dbrushsides[0] ) );
00140 
00141     // vis
00142     ((int *)&visBytes)[0] = LittleLong( ((int *)&visBytes)[0] );
00143     ((int *)&visBytes)[1] = LittleLong( ((int *)&visBytes)[1] );
00144 
00145     // drawverts (don't swap colors )
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     // drawindexes
00160     SwapBlock( (int *)drawIndexes, numDrawIndexes * sizeof( drawIndexes[0] ) );
00161 
00162     // drawsurfs
00163     SwapBlock( (int *)drawSurfaces, numDrawSurfaces * sizeof( drawSurfaces[0] ) );
00164 
00165     // fogs
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 CopyLump
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 LoadBSPFile
00197 =============
00198 */
00199 void    LoadBSPFile( const char *filename ) {
00200     dheader_t   *header;
00201 
00202     // load the file header
00203     LoadFile (filename, (void **)&header);
00204 
00205     // swap the header
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 );     // everything has been copied out
00237         
00238     // swap everything
00239     SwapBSPFile();
00240 }
00241 
00242 
00243 //============================================================================
00244 
00245 /*
00246 =============
00247 AddLump
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 WriteBSPFile
00263 
00264 Swaps the bsp file in place, so it should not be referenced again
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) );    // overwritten later
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 PrintBSPFileSizes
00310 
00311 Dumps info about current file
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 ParseEpair
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     // strip trailing spaces that sometimes get accidentally
00395     // added in the editor
00396     StripTrailing( e->key );
00397     StripTrailing( e->value );
00398 
00399     return e;
00400 }
00401 
00402 
00403 /*
00404 ================
00405 ParseEntity
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 ParseEntities
00443 
00444 Parses the dentdata string into entities
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 UnparseEntities
00459 
00460 Generates the dentdata string from all the entities
00461 This allows the utilities to add or remove key/value pairs
00462 to the data created by the map editor.
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;   // ent got removed
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     // scanf into doubles, then assign, so it is vec_t size independent
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 

Generated on Thu Aug 25 12:38:07 2005 for Quake III Arena by  doxygen 1.3.9.1