Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

l_bsp_hl.c (24472B)


      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 #include "l_cmd.h"
     23 #include "l_math.h"
     24 #include "l_mem.h"
     25 #include "l_log.h"
     26 #include "../botlib/l_script.h"
     27 #include "l_bsp_hl.h"
     28 #include "l_bsp_ent.h"
     29 
     30 //=============================================================================
     31 
     32 int				hl_nummodels;
     33 hl_dmodel_t		*hl_dmodels;//[HL_MAX_MAP_MODELS];
     34 int				hl_dmodels_checksum;
     35 
     36 int				hl_visdatasize;
     37 byte				*hl_dvisdata;//[HL_MAX_MAP_VISIBILITY];
     38 int				hl_dvisdata_checksum;
     39 
     40 int				hl_lightdatasize;
     41 byte				*hl_dlightdata;//[HL_MAX_MAP_LIGHTING];
     42 int				hl_dlightdata_checksum;
     43 
     44 int				hl_texdatasize;
     45 byte				*hl_dtexdata;//[HL_MAX_MAP_MIPTEX]; // (dmiptexlump_t)
     46 int				hl_dtexdata_checksum;
     47 
     48 int				hl_entdatasize;
     49 char				*hl_dentdata;//[HL_MAX_MAP_ENTSTRING];
     50 int				hl_dentdata_checksum;
     51 
     52 int				hl_numleafs;
     53 hl_dleaf_t		*hl_dleafs;//[HL_MAX_MAP_LEAFS];
     54 int				hl_dleafs_checksum;
     55 
     56 int				hl_numplanes;
     57 hl_dplane_t		*hl_dplanes;//[HL_MAX_MAP_PLANES];
     58 int				hl_dplanes_checksum;
     59 
     60 int				hl_numvertexes;
     61 hl_dvertex_t	*hl_dvertexes;//[HL_MAX_MAP_VERTS];
     62 int				hl_dvertexes_checksum;
     63 
     64 int				hl_numnodes;
     65 hl_dnode_t		*hl_dnodes;//[HL_MAX_MAP_NODES];
     66 int				hl_dnodes_checksum;
     67 
     68 int				hl_numtexinfo;
     69 hl_texinfo_t	*hl_texinfo;//[HL_MAX_MAP_TEXINFO];
     70 int				hl_texinfo_checksum;
     71 
     72 int				hl_numfaces;
     73 hl_dface_t		*hl_dfaces;//[HL_MAX_MAP_FACES];
     74 int				hl_dfaces_checksum;
     75 
     76 int				hl_numclipnodes;
     77 hl_dclipnode_t	*hl_dclipnodes;//[HL_MAX_MAP_CLIPNODES];
     78 int				hl_dclipnodes_checksum;
     79 
     80 int				hl_numedges;
     81 hl_dedge_t		*hl_dedges;//[HL_MAX_MAP_EDGES];
     82 int				hl_dedges_checksum;
     83 
     84 int				hl_nummarksurfaces;
     85 unsigned short	*hl_dmarksurfaces;//[HL_MAX_MAP_MARKSURFACES];
     86 int				hl_dmarksurfaces_checksum;
     87 
     88 int				hl_numsurfedges;
     89 int				*hl_dsurfedges;//[HL_MAX_MAP_SURFEDGES];
     90 int				hl_dsurfedges_checksum;
     91 
     92 //int				num_entities;
     93 //entity_t			entities[HL_MAX_MAP_ENTITIES];
     94 
     95 
     96 //#ifdef //ME
     97 
     98 int hl_bspallocated = false;
     99 int hl_allocatedbspmem = 0;
    100 
    101 void HL_AllocMaxBSP(void)
    102 {
    103 	//models
    104 	hl_nummodels = 0;
    105 	hl_dmodels = (hl_dmodel_t *) GetMemory(HL_MAX_MAP_MODELS * sizeof(hl_dmodel_t));
    106 	hl_allocatedbspmem = HL_MAX_MAP_MODELS * sizeof(hl_dmodel_t);
    107 	//visibility
    108 	hl_visdatasize = 0;
    109 	hl_dvisdata = (byte *) GetMemory(HL_MAX_MAP_VISIBILITY * sizeof(byte));
    110 	hl_allocatedbspmem += HL_MAX_MAP_VISIBILITY * sizeof(byte);
    111 	//light data
    112 	hl_lightdatasize = 0;
    113 	hl_dlightdata = (byte *) GetMemory(HL_MAX_MAP_LIGHTING * sizeof(byte));
    114 	hl_allocatedbspmem += HL_MAX_MAP_LIGHTING * sizeof(byte);
    115 	//texture data
    116 	hl_texdatasize = 0;
    117 	hl_dtexdata = (byte *) GetMemory(HL_MAX_MAP_MIPTEX * sizeof(byte)); // (dmiptexlump_t)
    118 	hl_allocatedbspmem += HL_MAX_MAP_MIPTEX * sizeof(byte);
    119 	//entities
    120 	hl_entdatasize = 0;
    121 	hl_dentdata = (char *) GetMemory(HL_MAX_MAP_ENTSTRING * sizeof(char));
    122 	hl_allocatedbspmem += HL_MAX_MAP_ENTSTRING * sizeof(char);
    123 	//leaves
    124 	hl_numleafs = 0;
    125 	hl_dleafs = (hl_dleaf_t *) GetMemory(HL_MAX_MAP_LEAFS * sizeof(hl_dleaf_t));
    126 	hl_allocatedbspmem += HL_MAX_MAP_LEAFS * sizeof(hl_dleaf_t);
    127 	//planes
    128 	hl_numplanes = 0;
    129 	hl_dplanes = (hl_dplane_t *) GetMemory(HL_MAX_MAP_PLANES * sizeof(hl_dplane_t));
    130 	hl_allocatedbspmem += HL_MAX_MAP_PLANES * sizeof(hl_dplane_t);
    131 	//vertexes
    132 	hl_numvertexes = 0;
    133 	hl_dvertexes = (hl_dvertex_t *) GetMemory(HL_MAX_MAP_VERTS * sizeof(hl_dvertex_t));
    134 	hl_allocatedbspmem += HL_MAX_MAP_VERTS * sizeof(hl_dvertex_t);
    135 	//nodes
    136 	hl_numnodes = 0;
    137 	hl_dnodes = (hl_dnode_t *) GetMemory(HL_MAX_MAP_NODES * sizeof(hl_dnode_t));
    138 	hl_allocatedbspmem += HL_MAX_MAP_NODES * sizeof(hl_dnode_t);
    139 	//texture info
    140 	hl_numtexinfo = 0;
    141 	hl_texinfo = (hl_texinfo_t *) GetMemory(HL_MAX_MAP_TEXINFO * sizeof(hl_texinfo_t));
    142 	hl_allocatedbspmem += HL_MAX_MAP_TEXINFO * sizeof(hl_texinfo_t);
    143 	//faces
    144 	hl_numfaces = 0;
    145 	hl_dfaces = (hl_dface_t *) GetMemory(HL_MAX_MAP_FACES * sizeof(hl_dface_t));
    146 	hl_allocatedbspmem += HL_MAX_MAP_FACES * sizeof(hl_dface_t);
    147 	//clip nodes
    148 	hl_numclipnodes = 0;
    149 	hl_dclipnodes = (hl_dclipnode_t *) GetMemory(HL_MAX_MAP_CLIPNODES * sizeof(hl_dclipnode_t));
    150 	hl_allocatedbspmem += HL_MAX_MAP_CLIPNODES * sizeof(hl_dclipnode_t);
    151 	//edges
    152 	hl_numedges = 0;
    153 	hl_dedges = (hl_dedge_t *) GetMemory(HL_MAX_MAP_EDGES * sizeof(hl_dedge_t));
    154 	hl_allocatedbspmem += HL_MAX_MAP_EDGES, sizeof(hl_dedge_t);
    155 	//mark surfaces
    156 	hl_nummarksurfaces = 0;
    157 	hl_dmarksurfaces = (unsigned short *) GetMemory(HL_MAX_MAP_MARKSURFACES * sizeof(unsigned short));
    158 	hl_allocatedbspmem += HL_MAX_MAP_MARKSURFACES * sizeof(unsigned short);
    159 	//surface edges
    160 	hl_numsurfedges = 0;
    161 	hl_dsurfedges = (int *) GetMemory(HL_MAX_MAP_SURFEDGES * sizeof(int));
    162 	hl_allocatedbspmem += HL_MAX_MAP_SURFEDGES * sizeof(int);
    163 	//print allocated memory
    164 	Log_Print("allocated ");
    165 	PrintMemorySize(hl_allocatedbspmem);
    166 	Log_Print(" of BSP memory\n");
    167 } //end of the function HL_AllocMaxBSP
    168 
    169 void HL_FreeMaxBSP(void)
    170 {
    171 	//models
    172 	hl_nummodels = 0;
    173 	FreeMemory(hl_dmodels);
    174 	hl_dmodels = NULL;
    175 	//visibility
    176 	hl_visdatasize = 0;
    177 	FreeMemory(hl_dvisdata);
    178 	hl_dvisdata = NULL;
    179 	//light data
    180 	hl_lightdatasize = 0;
    181 	FreeMemory(hl_dlightdata);
    182 	hl_dlightdata = NULL;
    183 	//texture data
    184 	hl_texdatasize = 0;
    185 	FreeMemory(hl_dtexdata);
    186 	hl_dtexdata = NULL;
    187 	//entities
    188 	hl_entdatasize = 0;
    189 	FreeMemory(hl_dentdata);
    190 	hl_dentdata = NULL;
    191 	//leaves
    192 	hl_numleafs = 0;
    193 	FreeMemory(hl_dleafs);
    194 	hl_dleafs = NULL;
    195 	//planes
    196 	hl_numplanes = 0;
    197 	FreeMemory(hl_dplanes);
    198 	hl_dplanes = NULL;
    199 	//vertexes
    200 	hl_numvertexes = 0;
    201 	FreeMemory(hl_dvertexes);
    202 	hl_dvertexes = NULL;
    203 	//nodes
    204 	hl_numnodes = 0;
    205 	FreeMemory(hl_dnodes);
    206 	hl_dnodes = NULL;
    207 	//texture info
    208 	hl_numtexinfo = 0;
    209 	FreeMemory(hl_texinfo);
    210 	hl_texinfo = NULL;
    211 	//faces
    212 	hl_numfaces = 0;
    213 	FreeMemory(hl_dfaces);
    214 	hl_dfaces = NULL;
    215 	//clip nodes
    216 	hl_numclipnodes = 0;
    217 	FreeMemory(hl_dclipnodes);
    218 	hl_dclipnodes = NULL;
    219 	//edges
    220 	hl_numedges = 0;
    221 	FreeMemory(hl_dedges);
    222 	hl_dedges = NULL;
    223 	//mark surfaces
    224 	hl_nummarksurfaces = 0;
    225 	FreeMemory(hl_dmarksurfaces);
    226 	hl_dmarksurfaces = NULL;
    227 	//surface edges
    228 	hl_numsurfedges = 0;
    229 	FreeMemory(hl_dsurfedges);
    230 	hl_dsurfedges = NULL;
    231 	//
    232 	Log_Print("freed ");
    233 	PrintMemorySize(hl_allocatedbspmem);
    234 	Log_Print(" of BSP memory\n");
    235 	hl_allocatedbspmem = 0;
    236 } //end of the function HL_FreeMaxBSP
    237 //#endif //ME
    238 
    239 /*
    240 ===============
    241 FastChecksum
    242 ===============
    243 */
    244 
    245 int FastChecksum(void *buffer, int bytes)
    246 {
    247 	int	checksum = 0;
    248 
    249 	while( bytes-- )  
    250 		checksum = (checksum << 4) ^ *((char *)buffer)++;
    251 
    252 	return checksum;
    253 }
    254 
    255 /*
    256 ===============
    257 HL_CompressVis
    258 ===============
    259 */
    260 int HL_CompressVis(byte *vis, byte *dest)
    261 {
    262 	int		j;
    263 	int		rep;
    264 	int		visrow;
    265 	byte	*dest_p;
    266 	
    267 	dest_p = dest;
    268 	visrow = (hl_numleafs + 7)>>3;
    269 	
    270 	for (j=0 ; j<visrow ; j++)
    271 	{
    272 		*dest_p++ = vis[j];
    273 		if (vis[j])
    274 			continue;
    275 
    276 		rep = 1;
    277 		for ( j++; j<visrow ; j++)
    278 			if (vis[j] || rep == 255)
    279 				break;
    280 			else
    281 				rep++;
    282 		*dest_p++ = rep;
    283 		j--;
    284 	}
    285 	
    286 	return dest_p - dest;
    287 }
    288 
    289 
    290 /*
    291 ===================
    292 HL_DecompressVis
    293 ===================
    294 */
    295 void HL_DecompressVis (byte *in, byte *decompressed)
    296 {
    297 	int		c;
    298 	byte	*out;
    299 	int		row;
    300 
    301 	row = (hl_numleafs+7)>>3;	
    302 	out = decompressed;
    303 
    304 	do
    305 	{
    306 		if (*in)
    307 		{
    308 			*out++ = *in++;
    309 			continue;
    310 		}
    311 	
    312 		c = in[1];
    313 		in += 2;
    314 		while (c)
    315 		{
    316 			*out++ = 0;
    317 			c--;
    318 		}
    319 	} while (out - decompressed < row);
    320 }
    321 
    322 //=============================================================================
    323 
    324 /*
    325 =============
    326 HL_SwapBSPFile
    327 
    328 Byte swaps all data in a bsp file.
    329 =============
    330 */
    331 void HL_SwapBSPFile (qboolean todisk)
    332 {
    333 	int i, j, c;
    334 	hl_dmodel_t *d;
    335 	hl_dmiptexlump_t *mtl;
    336 
    337 	
    338 // models	
    339 	for (i = 0; i < hl_nummodels; i++)
    340 	{
    341 		d = &hl_dmodels[i];
    342 
    343 		for (j = 0; j < HL_MAX_MAP_HULLS; j++)
    344 			d->headnode[j] = LittleLong(d->headnode[j]);
    345 
    346 		d->visleafs = LittleLong(d->visleafs);
    347 		d->firstface = LittleLong(d->firstface);
    348 		d->numfaces = LittleLong(d->numfaces);
    349 		
    350 		for (j = 0; j < 3; j++)
    351 		{
    352 			d->mins[j] = LittleFloat(d->mins[j]);
    353 			d->maxs[j] = LittleFloat(d->maxs[j]);
    354 			d->origin[j] = LittleFloat(d->origin[j]);
    355 		}
    356 	}
    357 
    358 //
    359 // vertexes
    360 //
    361 	for (i = 0; i < hl_numvertexes; i++)
    362 	{
    363 		for (j = 0; j < 3; j++)
    364 			hl_dvertexes[i].point[j] = LittleFloat (hl_dvertexes[i].point[j]);
    365 	}
    366 		
    367 //
    368 // planes
    369 //	
    370 	for (i=0 ; i<hl_numplanes ; i++)
    371 	{
    372 		for (j=0 ; j<3 ; j++)
    373 			hl_dplanes[i].normal[j] = LittleFloat (hl_dplanes[i].normal[j]);
    374 		hl_dplanes[i].dist = LittleFloat (hl_dplanes[i].dist);
    375 		hl_dplanes[i].type = LittleLong (hl_dplanes[i].type);
    376 	}
    377 	
    378 //
    379 // texinfos
    380 //	
    381 	for (i=0 ; i<hl_numtexinfo ; i++)
    382 	{
    383 		for (j=0 ; j<8 ; j++)
    384 			hl_texinfo[i].vecs[0][j] = LittleFloat (hl_texinfo[i].vecs[0][j]);
    385 		hl_texinfo[i].miptex = LittleLong (hl_texinfo[i].miptex);
    386 		hl_texinfo[i].flags = LittleLong (hl_texinfo[i].flags);
    387 	}
    388 	
    389 //
    390 // faces
    391 //
    392 	for (i=0 ; i<hl_numfaces ; i++)
    393 	{
    394 		hl_dfaces[i].texinfo = LittleShort (hl_dfaces[i].texinfo);
    395 		hl_dfaces[i].planenum = LittleShort (hl_dfaces[i].planenum);
    396 		hl_dfaces[i].side = LittleShort (hl_dfaces[i].side);
    397 		hl_dfaces[i].lightofs = LittleLong (hl_dfaces[i].lightofs);
    398 		hl_dfaces[i].firstedge = LittleLong (hl_dfaces[i].firstedge);
    399 		hl_dfaces[i].numedges = LittleShort (hl_dfaces[i].numedges);
    400 	}
    401 
    402 //
    403 // nodes
    404 //
    405 	for (i=0 ; i<hl_numnodes ; i++)
    406 	{
    407 		hl_dnodes[i].planenum = LittleLong (hl_dnodes[i].planenum);
    408 		for (j=0 ; j<3 ; j++)
    409 		{
    410 			hl_dnodes[i].mins[j] = LittleShort (hl_dnodes[i].mins[j]);
    411 			hl_dnodes[i].maxs[j] = LittleShort (hl_dnodes[i].maxs[j]);
    412 		}
    413 		hl_dnodes[i].children[0] = LittleShort (hl_dnodes[i].children[0]);
    414 		hl_dnodes[i].children[1] = LittleShort (hl_dnodes[i].children[1]);
    415 		hl_dnodes[i].firstface = LittleShort (hl_dnodes[i].firstface);
    416 		hl_dnodes[i].numfaces = LittleShort (hl_dnodes[i].numfaces);
    417 	}
    418 
    419 //
    420 // leafs
    421 //
    422 	for (i=0 ; i<hl_numleafs ; i++)
    423 	{
    424 		hl_dleafs[i].contents = LittleLong (hl_dleafs[i].contents);
    425 		for (j=0 ; j<3 ; j++)
    426 		{
    427 			hl_dleafs[i].mins[j] = LittleShort (hl_dleafs[i].mins[j]);
    428 			hl_dleafs[i].maxs[j] = LittleShort (hl_dleafs[i].maxs[j]);
    429 		}
    430 
    431 		hl_dleafs[i].firstmarksurface = LittleShort (hl_dleafs[i].firstmarksurface);
    432 		hl_dleafs[i].nummarksurfaces = LittleShort (hl_dleafs[i].nummarksurfaces);
    433 		hl_dleafs[i].visofs = LittleLong (hl_dleafs[i].visofs);
    434 	}
    435 
    436 //
    437 // clipnodes
    438 //
    439 	for (i=0 ; i<hl_numclipnodes ; i++)
    440 	{
    441 		hl_dclipnodes[i].planenum = LittleLong (hl_dclipnodes[i].planenum);
    442 		hl_dclipnodes[i].children[0] = LittleShort (hl_dclipnodes[i].children[0]);
    443 		hl_dclipnodes[i].children[1] = LittleShort (hl_dclipnodes[i].children[1]);
    444 	}
    445 
    446 //
    447 // miptex
    448 //
    449 	if (hl_texdatasize)
    450 	{
    451 		mtl = (hl_dmiptexlump_t *)hl_dtexdata;
    452 		if (todisk)
    453 			c = mtl->nummiptex;
    454 		else
    455 			c = LittleLong(mtl->nummiptex);
    456 		mtl->nummiptex = LittleLong (mtl->nummiptex);
    457 		for (i=0 ; i<c ; i++)
    458 			mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
    459 	}
    460 	
    461 //
    462 // marksurfaces
    463 //
    464 	for (i=0 ; i<hl_nummarksurfaces ; i++)
    465 		hl_dmarksurfaces[i] = LittleShort (hl_dmarksurfaces[i]);
    466 
    467 //
    468 // surfedges
    469 //
    470 	for (i=0 ; i<hl_numsurfedges ; i++)
    471 		hl_dsurfedges[i] = LittleLong (hl_dsurfedges[i]);
    472 
    473 //
    474 // edges
    475 //
    476 	for (i=0 ; i<hl_numedges ; i++)
    477 	{
    478 		hl_dedges[i].v[0] = LittleShort (hl_dedges[i].v[0]);
    479 		hl_dedges[i].v[1] = LittleShort (hl_dedges[i].v[1]);
    480 	}
    481 } //end of the function HL_SwapBSPFile
    482 
    483 
    484 hl_dheader_t	*hl_header;
    485 int				hl_fileLength;
    486 
    487 int HL_CopyLump (int lump, void *dest, int size, int maxsize)
    488 {
    489 	int		length, ofs;
    490 
    491 	length = hl_header->lumps[lump].filelen;
    492 	ofs = hl_header->lumps[lump].fileofs;
    493 	
    494 	if (length % size) {
    495 		Error ("LoadBSPFile: odd lump size");
    496 	}
    497 	// somehow things got out of range
    498 	if ((length/size) > maxsize) {
    499 		printf("WARNING: exceeded max size for lump %d size %d > maxsize %d\n", lump, (length/size), maxsize);
    500 		length = maxsize * size;
    501 	}
    502 	if ( ofs + length > hl_fileLength ) {
    503 		printf("WARNING: exceeded file length for lump %d\n", lump);
    504 		length = hl_fileLength - ofs;
    505 		if ( length <= 0 ) {
    506 			return 0;
    507 		}
    508 	}
    509 
    510 	memcpy (dest, (byte *)hl_header + ofs, length);
    511 
    512 	return length / size;
    513 }
    514 
    515 /*
    516 =============
    517 HL_LoadBSPFile
    518 =============
    519 */
    520 void	HL_LoadBSPFile (char *filename, int offset, int length)
    521 {
    522 	int			i;
    523 	
    524 //
    525 // load the file header
    526 //
    527 	hl_fileLength = LoadFile (filename, (void **)&hl_header, offset, length);
    528 
    529 // swap the header
    530 	for (i=0 ; i< sizeof(hl_dheader_t)/4 ; i++)
    531 		((int *)hl_header)[i] = LittleLong ( ((int *)hl_header)[i]);
    532 
    533 	if (hl_header->version != HL_BSPVERSION)
    534 		Error ("%s is version %i, not %i", filename, hl_header->version, HL_BSPVERSION);
    535 
    536 	hl_nummodels = HL_CopyLump (HL_LUMP_MODELS, hl_dmodels, sizeof(hl_dmodel_t), HL_MAX_MAP_MODELS );
    537 	hl_numvertexes = HL_CopyLump (HL_LUMP_VERTEXES, hl_dvertexes, sizeof(hl_dvertex_t), HL_MAX_MAP_VERTS );
    538 	hl_numplanes = HL_CopyLump (HL_LUMP_PLANES, hl_dplanes, sizeof(hl_dplane_t), HL_MAX_MAP_PLANES );
    539 	hl_numleafs = HL_CopyLump (HL_LUMP_LEAFS, hl_dleafs, sizeof(hl_dleaf_t), HL_MAX_MAP_LEAFS );
    540 	hl_numnodes = HL_CopyLump (HL_LUMP_NODES, hl_dnodes, sizeof(hl_dnode_t), HL_MAX_MAP_NODES );
    541 	hl_numtexinfo = HL_CopyLump (HL_LUMP_TEXINFO, hl_texinfo, sizeof(hl_texinfo_t), HL_MAX_MAP_TEXINFO );
    542 	hl_numclipnodes = HL_CopyLump (HL_LUMP_CLIPNODES, hl_dclipnodes, sizeof(hl_dclipnode_t), HL_MAX_MAP_CLIPNODES );
    543 	hl_numfaces = HL_CopyLump (HL_LUMP_FACES, hl_dfaces, sizeof(hl_dface_t), HL_MAX_MAP_FACES );
    544 	hl_nummarksurfaces = HL_CopyLump (HL_LUMP_MARKSURFACES, hl_dmarksurfaces, sizeof(hl_dmarksurfaces[0]), HL_MAX_MAP_MARKSURFACES );
    545 	hl_numsurfedges = HL_CopyLump (HL_LUMP_SURFEDGES, hl_dsurfedges, sizeof(hl_dsurfedges[0]), HL_MAX_MAP_SURFEDGES );
    546 	hl_numedges = HL_CopyLump (HL_LUMP_EDGES, hl_dedges, sizeof(hl_dedge_t), HL_MAX_MAP_EDGES );
    547 
    548 	hl_texdatasize = HL_CopyLump (HL_LUMP_TEXTURES, hl_dtexdata, 1, HL_MAX_MAP_MIPTEX );
    549 	hl_visdatasize = HL_CopyLump (HL_LUMP_VISIBILITY, hl_dvisdata, 1, HL_MAX_MAP_VISIBILITY );
    550 	hl_lightdatasize = HL_CopyLump (HL_LUMP_LIGHTING, hl_dlightdata, 1, HL_MAX_MAP_LIGHTING );
    551 	hl_entdatasize = HL_CopyLump (HL_LUMP_ENTITIES, hl_dentdata, 1, HL_MAX_MAP_ENTSTRING );
    552 
    553 	FreeMemory(hl_header);		// everything has been copied out
    554 		
    555 //
    556 // swap everything
    557 //	
    558 	HL_SwapBSPFile (false);
    559 
    560 	hl_dmodels_checksum = FastChecksum( hl_dmodels, hl_nummodels*sizeof(hl_dmodels[0]) );
    561 	hl_dvertexes_checksum = FastChecksum( hl_dvertexes, hl_numvertexes*sizeof(hl_dvertexes[0]) );
    562 	hl_dplanes_checksum = FastChecksum( hl_dplanes, hl_numplanes*sizeof(hl_dplanes[0]) );
    563 	hl_dleafs_checksum = FastChecksum( hl_dleafs, hl_numleafs*sizeof(hl_dleafs[0]) );
    564 	hl_dnodes_checksum = FastChecksum( hl_dnodes, hl_numnodes*sizeof(hl_dnodes[0]) );
    565 	hl_texinfo_checksum = FastChecksum( hl_texinfo, hl_numtexinfo*sizeof(hl_texinfo[0]) );
    566 	hl_dclipnodes_checksum = FastChecksum( hl_dclipnodes, hl_numclipnodes*sizeof(hl_dclipnodes[0]) );
    567 	hl_dfaces_checksum = FastChecksum( hl_dfaces, hl_numfaces*sizeof(hl_dfaces[0]) );
    568 	hl_dmarksurfaces_checksum = FastChecksum( hl_dmarksurfaces, hl_nummarksurfaces*sizeof(hl_dmarksurfaces[0]) );
    569 	hl_dsurfedges_checksum = FastChecksum( hl_dsurfedges, hl_numsurfedges*sizeof(hl_dsurfedges[0]) );
    570 	hl_dedges_checksum = FastChecksum( hl_dedges, hl_numedges*sizeof(hl_dedges[0]) );
    571 	hl_dtexdata_checksum = FastChecksum( hl_dtexdata, hl_numedges*sizeof(hl_dtexdata[0]) );
    572 	hl_dvisdata_checksum = FastChecksum( hl_dvisdata, hl_visdatasize*sizeof(hl_dvisdata[0]) );
    573 	hl_dlightdata_checksum = FastChecksum( hl_dlightdata, hl_lightdatasize*sizeof(hl_dlightdata[0]) );
    574 	hl_dentdata_checksum = FastChecksum( hl_dentdata, hl_entdatasize*sizeof(hl_dentdata[0]) );
    575 
    576 }
    577 
    578 //============================================================================
    579 
    580 FILE		*wadfile;
    581 hl_dheader_t	outheader;
    582 
    583 void HL_AddLump (int lumpnum, void *data, int len)
    584 {
    585 	hl_lump_t *lump;
    586 
    587 	lump = &hl_header->lumps[lumpnum];
    588 	
    589 	lump->fileofs = LittleLong( ftell(wadfile) );
    590 	lump->filelen = LittleLong(len);
    591 	SafeWrite (wadfile, data, (len+3)&~3);
    592 }
    593 
    594 /*
    595 =============
    596 HL_WriteBSPFile
    597 
    598 Swaps the bsp file in place, so it should not be referenced again
    599 =============
    600 */
    601 void HL_WriteBSPFile (char *filename)
    602 {		
    603 	hl_header = &outheader;
    604 	memset (hl_header, 0, sizeof(hl_dheader_t));
    605 	
    606 	HL_SwapBSPFile (true);
    607 
    608 	hl_header->version = LittleLong (HL_BSPVERSION);
    609 	
    610 	wadfile = SafeOpenWrite (filename);
    611 	SafeWrite (wadfile, hl_header, sizeof(hl_dheader_t));	// overwritten later
    612 
    613 	HL_AddLump (HL_LUMP_PLANES, hl_dplanes, hl_numplanes*sizeof(hl_dplane_t));
    614 	HL_AddLump (HL_LUMP_LEAFS, hl_dleafs, hl_numleafs*sizeof(hl_dleaf_t));
    615 	HL_AddLump (HL_LUMP_VERTEXES, hl_dvertexes, hl_numvertexes*sizeof(hl_dvertex_t));
    616 	HL_AddLump (HL_LUMP_NODES, hl_dnodes, hl_numnodes*sizeof(hl_dnode_t));
    617 	HL_AddLump (HL_LUMP_TEXINFO, hl_texinfo, hl_numtexinfo*sizeof(hl_texinfo_t));
    618 	HL_AddLump (HL_LUMP_FACES, hl_dfaces, hl_numfaces*sizeof(hl_dface_t));
    619 	HL_AddLump (HL_LUMP_CLIPNODES, hl_dclipnodes, hl_numclipnodes*sizeof(hl_dclipnode_t));
    620 	HL_AddLump (HL_LUMP_MARKSURFACES, hl_dmarksurfaces, hl_nummarksurfaces*sizeof(hl_dmarksurfaces[0]));
    621 	HL_AddLump (HL_LUMP_SURFEDGES, hl_dsurfedges, hl_numsurfedges*sizeof(hl_dsurfedges[0]));
    622 	HL_AddLump (HL_LUMP_EDGES, hl_dedges, hl_numedges*sizeof(hl_dedge_t));
    623 	HL_AddLump (HL_LUMP_MODELS, hl_dmodels, hl_nummodels*sizeof(hl_dmodel_t));
    624 
    625 	HL_AddLump (HL_LUMP_LIGHTING, hl_dlightdata, hl_lightdatasize);
    626 	HL_AddLump (HL_LUMP_VISIBILITY, hl_dvisdata, hl_visdatasize);
    627 	HL_AddLump (HL_LUMP_ENTITIES, hl_dentdata, hl_entdatasize);
    628 	HL_AddLump (HL_LUMP_TEXTURES, hl_dtexdata, hl_texdatasize);
    629 	
    630 	fseek (wadfile, 0, SEEK_SET);
    631 	SafeWrite (wadfile, hl_header, sizeof(hl_dheader_t));
    632 	fclose (wadfile);	
    633 }
    634 
    635 //============================================================================
    636 
    637 #define ENTRIES(a)		(sizeof(a)/sizeof(*(a)))
    638 #define ENTRYSIZE(a)	(sizeof(*(a)))
    639 
    640 ArrayUsage( char *szItem, int items, int maxitems, int itemsize )
    641 {
    642 	float	percentage = maxitems ? items * 100.0 / maxitems : 0.0;
    643 
    644    qprintf("%-12s  %7i/%-7i  %7i/%-7i  (%4.1f%%)", 
    645 				szItem, items, maxitems, items * itemsize, maxitems * itemsize, percentage );
    646 	if ( percentage > 80.0 )
    647 		qprintf( "VERY FULL!\n" );
    648 	else if ( percentage > 95.0 )
    649 		qprintf( "SIZE DANGER!\n" );
    650 	else if ( percentage > 99.9 )
    651 		qprintf( "SIZE OVERFLOW!!!\n" );
    652 	else
    653 		qprintf( "\n" );
    654 	return items * itemsize;
    655 }
    656 
    657 GlobUsage( char *szItem, int itemstorage, int maxstorage )
    658 {
    659 	float	percentage = maxstorage ? itemstorage * 100.0 / maxstorage : 0.0;
    660 
    661 	qprintf("%-12s     [variable]    %7i/%-7i  (%4.1f%%)", 
    662 				szItem, itemstorage, maxstorage, percentage );
    663 	if ( percentage > 80.0 )
    664 		qprintf( "VERY FULL!\n" );
    665 	else if ( percentage > 95.0 )
    666 		qprintf( "SIZE DANGER!\n" );
    667 	else if ( percentage > 99.9 )
    668 		qprintf( "SIZE OVERFLOW!!!\n" );
    669 	else
    670 		qprintf( "\n" );
    671 	return itemstorage;
    672 }
    673 
    674 /*
    675 =============
    676 HL_PrintBSPFileSizes
    677 
    678 Dumps info about current file
    679 =============
    680 */
    681 void HL_PrintBSPFileSizes(void)
    682 {
    683 	int	numtextures = hl_texdatasize ? ((hl_dmiptexlump_t*)hl_dtexdata)->nummiptex : 0;
    684 	int	totalmemory = 0;
    685 
    686 	qprintf("\n");
    687 	qprintf("Object names  Objects/Maxobjs  Memory / Maxmem  Fullness\n" );
    688 	qprintf("------------  ---------------  ---------------  --------\n" );
    689 
    690 	totalmemory += ArrayUsage( "models",		hl_nummodels,		ENTRIES(hl_dmodels),		ENTRYSIZE(hl_dmodels) );
    691 	totalmemory += ArrayUsage( "planes",		hl_numplanes,		ENTRIES(hl_dplanes),		ENTRYSIZE(hl_dplanes) );
    692 	totalmemory += ArrayUsage( "vertexes",		hl_numvertexes,	ENTRIES(hl_dvertexes),	ENTRYSIZE(hl_dvertexes) );
    693 	totalmemory += ArrayUsage( "nodes",			hl_numnodes,		ENTRIES(hl_dnodes),		ENTRYSIZE(hl_dnodes) );
    694 	totalmemory += ArrayUsage( "texinfos",		hl_numtexinfo,		ENTRIES(hl_texinfo),		ENTRYSIZE(hl_texinfo) );
    695 	totalmemory += ArrayUsage( "faces",			hl_numfaces,		ENTRIES(hl_dfaces),		ENTRYSIZE(hl_dfaces) );
    696 	totalmemory += ArrayUsage( "clipnodes",	hl_numclipnodes,	ENTRIES(hl_dclipnodes),	ENTRYSIZE(hl_dclipnodes) );
    697 	totalmemory += ArrayUsage( "leaves",		hl_numleafs,		ENTRIES(hl_dleafs),		ENTRYSIZE(hl_dleafs) );
    698 	totalmemory += ArrayUsage( "marksurfaces",hl_nummarksurfaces,ENTRIES(hl_dmarksurfaces),ENTRYSIZE(hl_dmarksurfaces) );
    699 	totalmemory += ArrayUsage( "surfedges",	hl_numsurfedges,	ENTRIES(hl_dsurfedges),	ENTRYSIZE(hl_dsurfedges) );
    700 	totalmemory += ArrayUsage( "edges",			hl_numedges,		ENTRIES(hl_dedges),		ENTRYSIZE(hl_dedges) );
    701 
    702 	totalmemory += GlobUsage( "texdata",		hl_texdatasize,	sizeof(hl_dtexdata) );
    703 	totalmemory += GlobUsage( "lightdata",		hl_lightdatasize,	sizeof(hl_dlightdata) );
    704 	totalmemory += GlobUsage( "visdata",		hl_visdatasize,	sizeof(hl_dvisdata) );
    705 	totalmemory += GlobUsage( "entdata",		hl_entdatasize,	sizeof(hl_dentdata) );
    706 
    707 	qprintf( "=== Total BSP file data space used: %d bytes ===\n\n", totalmemory );
    708 }
    709 
    710 
    711 
    712 /*
    713 =================
    714 ParseEpair
    715 =================
    716 * /
    717 epair_t *ParseEpair (void)
    718 {
    719 	epair_t	*e;
    720 	
    721 	e = malloc (sizeof(epair_t));
    722 	memset (e, 0, sizeof(epair_t));
    723 	
    724 	if (strlen(token) >= MAX_KEY-1)
    725 		Error ("ParseEpar: token too long");
    726 	e->key = copystring(token);
    727 	GetToken (false);
    728 	if (strlen(token) >= MAX_VALUE-1)
    729 		Error ("ParseEpar: token too long");
    730 	e->value = copystring(token);
    731 
    732 	return e;
    733 } //*/
    734 
    735 
    736 /*
    737 ================
    738 ParseEntity
    739 ================
    740 * /
    741 qboolean	ParseEntity (void)
    742 {
    743 	epair_t		*e;
    744 	entity_t	*mapent;
    745 
    746 	if (!GetToken (true))
    747 		return false;
    748 
    749 	if (strcmp (token, "{") )
    750 		Error ("ParseEntity: { not found");
    751 	
    752 	if (num_entities == HL_MAX_MAP_ENTITIES)
    753 		Error ("num_entities == HL_MAX_MAP_ENTITIES");
    754 
    755 	mapent = &entities[num_entities];
    756 	num_entities++;
    757 
    758 	do
    759 	{
    760 		if (!GetToken (true))
    761 			Error ("ParseEntity: EOF without closing brace");
    762 		if (!strcmp (token, "}") )
    763 			break;
    764 		e = ParseEpair ();
    765 		e->next = mapent->epairs;
    766 		mapent->epairs = e;
    767 	} while (1);
    768 	
    769 	return true;
    770 } //*/
    771 
    772 /*
    773 ================
    774 ParseEntities
    775 
    776 Parses the dentdata string into entities
    777 ================
    778 */
    779 void HL_ParseEntities (void)
    780 {
    781 	script_t *script;
    782 
    783 	num_entities = 0;
    784 	script = LoadScriptMemory(hl_dentdata, hl_entdatasize, "*Half-Life bsp file");
    785 	SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
    786 									SCFL_NOSTRINGESCAPECHARS);
    787 
    788 	while(ParseEntity(script))
    789 	{
    790 	} //end while
    791 
    792 	FreeScript(script);
    793 } //end of the function HL_ParseEntities
    794 
    795 
    796 /*
    797 ================
    798 UnparseEntities
    799 
    800 Generates the dentdata string from all the entities
    801 ================
    802 */
    803 void HL_UnparseEntities (void)
    804 {
    805 	char *buf, *end;
    806 	epair_t *ep;
    807 	char line[2048];
    808 	int i;
    809 	
    810 	buf = hl_dentdata;
    811 	end = buf;
    812 	*end = 0;
    813 	
    814 	for (i=0 ; i<num_entities ; i++)
    815 	{
    816 		ep = entities[i].epairs;
    817 		if (!ep)
    818 			continue;	// ent got removed
    819 		
    820 		strcat (end,"{\n");
    821 		end += 2;
    822 				
    823 		for (ep = entities[i].epairs ; ep ; ep=ep->next)
    824 		{
    825 			sprintf (line, "\"%s\" \"%s\"\n", ep->key, ep->value);
    826 			strcat (end, line);
    827 			end += strlen(line);
    828 		}
    829 		strcat (end,"}\n");
    830 		end += 2;
    831 
    832 		if (end > buf + HL_MAX_MAP_ENTSTRING)
    833 			Error ("Entity text too long");
    834 	}
    835 	hl_entdatasize = end - buf + 1;
    836 } //end of the function HL_UnparseEntities
    837 
    838 
    839 /*
    840 void 	SetKeyValue (entity_t *ent, char *key, char *value)
    841 {
    842 	epair_t	*ep;
    843 	
    844 	for (ep=ent->epairs ; ep ; ep=ep->next)
    845 		if (!strcmp (ep->key, key) )
    846 		{
    847 			free (ep->value);
    848 			ep->value = copystring(value);
    849 			return;
    850 		}
    851 	ep = malloc (sizeof(*ep));
    852 	ep->next = ent->epairs;
    853 	ent->epairs = ep;
    854 	ep->key = copystring(key);
    855 	ep->value = copystring(value);
    856 }
    857 
    858 char 	*ValueForKey (entity_t *ent, char *key)
    859 {
    860 	epair_t	*ep;
    861 	
    862 	for (ep=ent->epairs ; ep ; ep=ep->next)
    863 		if (!strcmp (ep->key, key) )
    864 			return ep->value;
    865 	return "";
    866 }
    867 
    868 vec_t	FloatForKey (entity_t *ent, char *key)
    869 {
    870 	char	*k;
    871 	
    872 	k = ValueForKey (ent, key);
    873 	return atof(k);
    874 }
    875 
    876 void 	GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
    877 {
    878 	char	*k;
    879 	double	v1, v2, v3;
    880 
    881 	k = ValueForKey (ent, key);
    882 // scanf into doubles, then assign, so it is vec_t size independent
    883 	v1 = v2 = v3 = 0;
    884 	sscanf (k, "%lf %lf %lf", &v1, &v2, &v3);
    885 	vec[0] = v1;
    886 	vec[1] = v2;
    887 	vec[2] = v3;
    888 } //*/