Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

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