Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

l_bsp_q2.c (30124B)


      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 "l_cmd.h"
     24 #include "l_math.h"
     25 #include "l_mem.h"
     26 #include "l_log.h"
     27 #include "l_poly.h"
     28 #include "../botlib/l_script.h"
     29 #include "q2files.h"
     30 #include "l_bsp_q2.h"
     31 #include "l_bsp_ent.h"
     32 
     33 #define q2_dmodel_t			dmodel_t
     34 #define q2_lump_t				lump_t
     35 #define q2_dheader_t			dheader_t
     36 #define q2_dmodel_t			dmodel_t
     37 #define q2_dvertex_t			dvertex_t
     38 #define q2_dplane_t			dplane_t
     39 #define q2_dnode_t			dnode_t
     40 #define q2_texinfo_t			texinfo_t
     41 #define q2_dedge_t			dedge_t
     42 #define q2_dface_t			dface_t
     43 #define q2_dleaf_t			dleaf_t
     44 #define q2_dbrushside_t		dbrushside_t
     45 #define q2_dbrush_t			dbrush_t
     46 #define q2_dvis_t				dvis_t
     47 #define q2_dareaportal_t	dareaportal_t
     48 #define q2_darea_t			darea_t
     49 
     50 #define q2_nummodels			nummodels
     51 #define q2_dmodels			dmodels
     52 #define q2_numleafs			numleafs
     53 #define q2_dleafs				dleafs
     54 #define q2_numplanes			numplanes
     55 #define q2_dplanes			dplanes
     56 #define q2_numvertexes		numvertexes
     57 #define q2_dvertexes			dvertexes
     58 #define q2_numnodes			numnodes
     59 #define q2_dnodes				dnodes
     60 #define q2_numtexinfo		numtexinfo
     61 #define q2_texinfo			texinfo
     62 #define q2_numfaces			numfaces
     63 #define q2_dfaces				dfaces
     64 #define q2_numedges			numedges
     65 #define q2_dedges				dedges
     66 #define q2_numleaffaces		numleaffaces
     67 #define q2_dleaffaces		dleaffaces
     68 #define q2_numleafbrushes	numleafbrushes
     69 #define q2_dleafbrushes		dleafbrushes
     70 #define q2_dsurfedges		dsurfedges
     71 #define q2_numbrushes		numbrushes
     72 #define q2_dbrushes			dbrushes
     73 #define q2_numbrushsides	numbrushsides
     74 #define q2_dbrushsides		dbrushsides
     75 #define q2_numareas			numareas
     76 #define q2_dareas				dareas
     77 #define q2_numareaportals	numareaportals
     78 #define q2_dareaportals		dareaportals
     79 
     80 void GetLeafNums (void);
     81 
     82 //=============================================================================
     83 
     84 int				nummodels;
     85 dmodel_t			*dmodels;//[MAX_MAP_MODELS];
     86 
     87 int				visdatasize;
     88 byte				*dvisdata;//[MAX_MAP_VISIBILITY];
     89 dvis_t			*dvis;// = (dvis_t *)dvisdata;
     90 
     91 int				lightdatasize;
     92 byte				*dlightdata;//[MAX_MAP_LIGHTING];
     93 
     94 int				entdatasize;
     95 char				*dentdata;//[MAX_MAP_ENTSTRING];
     96 
     97 int				numleafs;
     98 dleaf_t			*dleafs;//[MAX_MAP_LEAFS];
     99 
    100 int				numplanes;
    101 dplane_t			*dplanes;//[MAX_MAP_PLANES];
    102 
    103 int				numvertexes;
    104 dvertex_t		*dvertexes;//[MAX_MAP_VERTS];
    105 
    106 int				numnodes;
    107 dnode_t			*dnodes;//[MAX_MAP_NODES];
    108 
    109 //NOTE: must be static for q2 .map to q2 .bsp
    110 int				numtexinfo;
    111 texinfo_t		texinfo[MAX_MAP_TEXINFO];
    112 
    113 int				numfaces;
    114 dface_t			*dfaces;//[MAX_MAP_FACES];
    115 
    116 int				numedges;
    117 dedge_t			*dedges;//[MAX_MAP_EDGES];
    118 
    119 int				numleaffaces;
    120 unsigned short	*dleaffaces;//[MAX_MAP_LEAFFACES];
    121 
    122 int				numleafbrushes;
    123 unsigned short	*dleafbrushes;//[MAX_MAP_LEAFBRUSHES];
    124 
    125 int				numsurfedges;
    126 int				*dsurfedges;//[MAX_MAP_SURFEDGES];
    127 
    128 int				numbrushes;
    129 dbrush_t			*dbrushes;//[MAX_MAP_BRUSHES];
    130 
    131 int				numbrushsides;
    132 dbrushside_t	*dbrushsides;//[MAX_MAP_BRUSHSIDES];
    133 
    134 int				numareas;
    135 darea_t			*dareas;//[MAX_MAP_AREAS];
    136 
    137 int				numareaportals;
    138 dareaportal_t	*dareaportals;//[MAX_MAP_AREAPORTALS];
    139 
    140 #define MAX_MAP_DPOP			256
    141 byte				dpop[MAX_MAP_DPOP];
    142 
    143 //
    144 char brushsidetextured[MAX_MAP_BRUSHSIDES];
    145 
    146 //#ifdef ME
    147 
    148 int bspallocated = false;
    149 int allocatedbspmem = 0;
    150 
    151 void Q2_AllocMaxBSP(void)
    152 {
    153 	//models
    154 	nummodels = 0;
    155 	dmodels = (dmodel_t *) GetClearedMemory(MAX_MAP_MODELS * sizeof(dmodel_t));
    156 	allocatedbspmem += MAX_MAP_MODELS * sizeof(dmodel_t);
    157 	//vis data
    158 	visdatasize = 0;
    159 	dvisdata = (byte *) GetClearedMemory(MAX_MAP_VISIBILITY * sizeof(byte));
    160 	dvis = (dvis_t *) dvisdata;
    161 	allocatedbspmem += MAX_MAP_VISIBILITY * sizeof(byte);
    162 	//light data
    163 	lightdatasize = 0;
    164 	dlightdata = (byte *) GetClearedMemory(MAX_MAP_LIGHTING * sizeof(byte));
    165 	allocatedbspmem += MAX_MAP_LIGHTING * sizeof(byte);
    166 	//entity data
    167 	entdatasize = 0;
    168 	dentdata = (char *) GetClearedMemory(MAX_MAP_ENTSTRING * sizeof(char));
    169 	allocatedbspmem += MAX_MAP_ENTSTRING * sizeof(char);
    170 	//leafs
    171 	numleafs = 0;
    172 	dleafs = (dleaf_t *) GetClearedMemory(MAX_MAP_LEAFS * sizeof(dleaf_t));
    173 	allocatedbspmem += MAX_MAP_LEAFS * sizeof(dleaf_t);
    174 	//planes
    175 	numplanes = 0;
    176 	dplanes = (dplane_t *) GetClearedMemory(MAX_MAP_PLANES * sizeof(dplane_t));
    177 	allocatedbspmem += MAX_MAP_PLANES * sizeof(dplane_t);
    178 	//vertexes
    179 	numvertexes = 0;
    180 	dvertexes = (dvertex_t *) GetClearedMemory(MAX_MAP_VERTS * sizeof(dvertex_t));
    181 	allocatedbspmem += MAX_MAP_VERTS * sizeof(dvertex_t);
    182 	//nodes
    183 	numnodes = 0;
    184 	dnodes = (dnode_t *) GetClearedMemory(MAX_MAP_NODES * sizeof(dnode_t));
    185 	allocatedbspmem += MAX_MAP_NODES * sizeof(dnode_t);
    186 	/*
    187 	//texture info
    188 	numtexinfo = 0;
    189 	texinfo = (texinfo_t *) GetClearedMemory(MAX_MAP_TEXINFO * sizeof(texinfo_t));
    190 	allocatedbspmem += MAX_MAP_TEXINFO * sizeof(texinfo_t);
    191 	//*/
    192 	//faces
    193 	numfaces = 0;
    194 	dfaces = (dface_t *) GetClearedMemory(MAX_MAP_FACES * sizeof(dface_t));
    195 	allocatedbspmem += MAX_MAP_FACES * sizeof(dface_t);
    196 	//edges
    197 	numedges = 0;
    198 	dedges = (dedge_t *) GetClearedMemory(MAX_MAP_EDGES * sizeof(dedge_t));
    199 	allocatedbspmem += MAX_MAP_EDGES * sizeof(dedge_t);
    200 	//leaf faces
    201 	numleaffaces = 0;
    202 	dleaffaces = (unsigned short *) GetClearedMemory(MAX_MAP_LEAFFACES * sizeof(unsigned short));
    203 	allocatedbspmem += MAX_MAP_LEAFFACES * sizeof(unsigned short);
    204 	//leaf brushes
    205 	numleafbrushes = 0;
    206 	dleafbrushes = (unsigned short *) GetClearedMemory(MAX_MAP_LEAFBRUSHES * sizeof(unsigned short));
    207 	allocatedbspmem += MAX_MAP_LEAFBRUSHES * sizeof(unsigned short);
    208 	//surface edges
    209 	numsurfedges = 0;
    210 	dsurfedges = (int *) GetClearedMemory(MAX_MAP_SURFEDGES * sizeof(int));
    211 	allocatedbspmem += MAX_MAP_SURFEDGES * sizeof(int);
    212 	//brushes
    213 	numbrushes = 0;
    214 	dbrushes = (dbrush_t *) GetClearedMemory(MAX_MAP_BRUSHES * sizeof(dbrush_t));
    215 	allocatedbspmem += MAX_MAP_BRUSHES * sizeof(dbrush_t);
    216 	//brushsides
    217 	numbrushsides = 0;
    218 	dbrushsides = (dbrushside_t *) GetClearedMemory(MAX_MAP_BRUSHSIDES * sizeof(dbrushside_t));
    219 	allocatedbspmem += MAX_MAP_BRUSHSIDES * sizeof(dbrushside_t);
    220 	//areas
    221 	numareas = 0;
    222 	dareas = (darea_t *) GetClearedMemory(MAX_MAP_AREAS * sizeof(darea_t));
    223 	allocatedbspmem += MAX_MAP_AREAS * sizeof(darea_t);
    224 	//area portals
    225 	numareaportals = 0;
    226 	dareaportals = (dareaportal_t *) GetClearedMemory(MAX_MAP_AREAPORTALS * sizeof(dareaportal_t));
    227 	allocatedbspmem += MAX_MAP_AREAPORTALS * sizeof(dareaportal_t);
    228 	//print allocated memory
    229 	Log_Print("allocated ");
    230 	PrintMemorySize(allocatedbspmem);
    231 	Log_Print(" of BSP memory\n");
    232 } //end of the function Q2_AllocMaxBSP
    233 
    234 void Q2_FreeMaxBSP(void)
    235 {
    236 	//models
    237 	nummodels = 0;
    238 	FreeMemory(dmodels);
    239 	dmodels = NULL;
    240 	//vis data
    241 	visdatasize = 0;
    242 	FreeMemory(dvisdata);
    243 	dvisdata = NULL;
    244 	dvis = NULL;
    245 	//light data
    246 	lightdatasize = 0;
    247 	FreeMemory(dlightdata);
    248 	dlightdata = NULL;
    249 	//entity data
    250 	entdatasize = 0;
    251 	FreeMemory(dentdata);
    252 	dentdata = NULL;
    253 	//leafs
    254 	numleafs = 0;
    255 	FreeMemory(dleafs);
    256 	dleafs = NULL;
    257 	//planes
    258 	numplanes = 0;
    259 	FreeMemory(dplanes);
    260 	dplanes = NULL;
    261 	//vertexes
    262 	numvertexes = 0;
    263 	FreeMemory(dvertexes);
    264 	dvertexes = NULL;
    265 	//nodes
    266 	numnodes = 0;
    267 	FreeMemory(dnodes);
    268 	dnodes = NULL;
    269 	/*
    270 	//texture info
    271 	numtexinfo = 0;
    272 	FreeMemory(texinfo);
    273 	texinfo = NULL;
    274 	//*/
    275 	//faces
    276 	numfaces = 0;
    277 	FreeMemory(dfaces);
    278 	dfaces = NULL;
    279 	//edges
    280 	numedges = 0;
    281 	FreeMemory(dedges);
    282 	dedges = NULL;
    283 	//leaf faces
    284 	numleaffaces = 0;
    285 	FreeMemory(dleaffaces);
    286 	dleaffaces = NULL;
    287 	//leaf brushes
    288 	numleafbrushes = 0;
    289 	FreeMemory(dleafbrushes);
    290 	dleafbrushes = NULL;
    291 	//surface edges
    292 	numsurfedges = 0;
    293 	FreeMemory(dsurfedges);
    294 	dsurfedges = NULL;
    295 	//brushes
    296 	numbrushes = 0;
    297 	FreeMemory(dbrushes);
    298 	dbrushes = NULL;
    299 	//brushsides
    300 	numbrushsides = 0;
    301 	FreeMemory(dbrushsides);
    302 	dbrushsides = NULL;
    303 	//areas
    304 	numareas = 0;
    305 	FreeMemory(dareas);
    306 	dareas = NULL;
    307 	//area portals
    308 	numareaportals = 0;
    309 	FreeMemory(dareaportals);
    310 	dareaportals = NULL;
    311 	//
    312 	Log_Print("freed ");
    313 	PrintMemorySize(allocatedbspmem);
    314 	Log_Print(" of BSP memory\n");
    315 	allocatedbspmem = 0;
    316 } //end of the function Q2_FreeMaxBSP
    317 
    318 #define WCONVEX_EPSILON		0.5
    319 
    320 int InsideWinding(winding_t *w, vec3_t point, int planenum)
    321 {
    322 	int i;
    323 	float dist;
    324 	vec_t *v1, *v2;
    325 	vec3_t normal, edgevec;
    326 	dplane_t *plane;
    327 
    328 	for (i = 1; i <= w->numpoints; i++)
    329 	{
    330 		v1 = w->p[i % w->numpoints];
    331 		v2 = w->p[(i + 1) % w->numpoints];
    332 
    333 		VectorSubtract(v2, v1, edgevec);
    334 		plane = &dplanes[planenum];
    335 		CrossProduct(plane->normal, edgevec, normal);
    336 		VectorNormalize(normal);
    337 		dist = DotProduct(normal, v1);
    338 		//
    339 		if (DotProduct(normal, point) - dist > WCONVEX_EPSILON) return false;
    340 	} //end for
    341 	return true;
    342 } //end of the function InsideWinding
    343 
    344 int InsideFace(dface_t *face, vec3_t point)
    345 {
    346 	int i, edgenum, side;
    347 	float dist;
    348 	vec_t *v1, *v2;
    349 	vec3_t normal, edgevec;
    350 	dplane_t *plane;
    351 
    352 	for (i = 0; i < face->numedges; i++)
    353 	{
    354 		//get the first and second vertex of the edge
    355 		edgenum = dsurfedges[face->firstedge + i];
    356 		side = edgenum < 0;
    357 		v1 = dvertexes[dedges[abs(edgenum)].v[side]].point;
    358 		v2 = dvertexes[dedges[abs(edgenum)].v[!side]].point;
    359 		//create a plane through the edge vector, orthogonal to the face plane
    360 		//and with the normal vector pointing out of the face
    361 		VectorSubtract(v1, v2, edgevec);
    362 		plane = &dplanes[face->planenum];
    363 		CrossProduct(plane->normal, edgevec, normal);
    364 		VectorNormalize(normal);
    365 		dist = DotProduct(normal, v1);
    366 		//
    367 		if (DotProduct(normal, point) - dist > WCONVEX_EPSILON) return false;
    368 	} //end for
    369 	return true;
    370 } //end of the function InsideFace
    371 //===========================================================================
    372 // returns the amount the face and the winding overlap
    373 //
    374 // Parameter:				-
    375 // Returns:					-
    376 // Changes Globals:		-
    377 //===========================================================================
    378 float Q2_FaceOnWinding(q2_dface_t *face, winding_t *winding)
    379 {
    380 	int i, edgenum, side;
    381 	float dist, area;
    382 	q2_dplane_t plane;
    383 	vec_t *v1, *v2;
    384 	vec3_t normal, edgevec;
    385 	winding_t *w;
    386 
    387 	//
    388 	w = CopyWinding(winding);
    389 	memcpy(&plane, &q2_dplanes[face->planenum], sizeof(q2_dplane_t));
    390 	//check on which side of the plane the face is
    391 	if (face->side)
    392 	{
    393 		VectorNegate(plane.normal, plane.normal);
    394 		plane.dist = -plane.dist;
    395 	} //end if
    396 	for (i = 0; i < face->numedges && w; i++)
    397 	{
    398 		//get the first and second vertex of the edge
    399 		edgenum = q2_dsurfedges[face->firstedge + i];
    400 		side = edgenum > 0;
    401 		//if the face plane is flipped
    402 		v1 = q2_dvertexes[q2_dedges[abs(edgenum)].v[side]].point;
    403 		v2 = q2_dvertexes[q2_dedges[abs(edgenum)].v[!side]].point;
    404 		//create a plane through the edge vector, orthogonal to the face plane
    405 		//and with the normal vector pointing inward
    406 		VectorSubtract(v1, v2, edgevec);
    407 		CrossProduct(edgevec, plane.normal, normal);
    408 		VectorNormalize(normal);
    409 		dist = DotProduct(normal, v1);
    410 		//
    411 		ChopWindingInPlace(&w, normal, dist, -0.1); //CLIP_EPSILON
    412 	} //end for
    413 	if (w)
    414 	{
    415 		area = WindingArea(w);
    416 		FreeWinding(w);
    417 		return area;
    418 	} //end if
    419 	return 0;
    420 } //end of the function Q2_FaceOnWinding
    421 //===========================================================================
    422 // creates a winding for the given brush side on the given brush
    423 //
    424 // Parameter:				-
    425 // Returns:					-
    426 // Changes Globals:		-
    427 //===========================================================================
    428 winding_t *Q2_BrushSideWinding(dbrush_t *brush, dbrushside_t *baseside)
    429 {
    430 	int i;
    431 	dplane_t *baseplane, *plane;
    432 	winding_t *w;
    433 	dbrushside_t *side;
    434 	
    435 	//create a winding for the brush side with the given planenumber
    436 	baseplane = &dplanes[baseside->planenum];
    437 	w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
    438 	for (i = 0; i < brush->numsides && w; i++)
    439 	{
    440 		side = &dbrushsides[brush->firstside + i];
    441 		//don't chop with the base plane
    442 		if (side->planenum == baseside->planenum) continue;
    443 		//also don't use planes that are almost equal
    444 		plane = &dplanes[side->planenum];
    445 		if (DotProduct(baseplane->normal, plane->normal) > 0.999
    446 				&& fabs(baseplane->dist - plane->dist) < 0.01) continue;
    447 		//
    448 		plane = &dplanes[side->planenum^1];
    449 		ChopWindingInPlace(&w, plane->normal, plane->dist, -0.1); //CLIP_EPSILON);
    450 	} //end for
    451 	return w;
    452 } //end of the function Q2_BrushSideWinding
    453 //===========================================================================
    454 //
    455 // Parameter:				-
    456 // Returns:					-
    457 // Changes Globals:		-
    458 //===========================================================================
    459 int Q2_HintSkipBrush(dbrush_t *brush)
    460 {
    461 	int j;
    462 	dbrushside_t *brushside;
    463 
    464 	for (j = 0; j < brush->numsides; j++)
    465 	{
    466 		brushside = &dbrushsides[brush->firstside + j];
    467 		if (brushside->texinfo > 0)
    468 		{
    469 			if (texinfo[brushside->texinfo].flags & (SURF_SKIP|SURF_HINT))
    470 			{
    471 				return true;
    472 			} //end if
    473 		} //end if
    474 	} //end for
    475 	return false;
    476 } //end of the function Q2_HintSkipBrush
    477 //===========================================================================
    478 // fix screwed brush texture references
    479 //
    480 // Parameter:				-
    481 // Returns:					-
    482 // Changes Globals:		-
    483 //===========================================================================
    484 qboolean WindingIsTiny(winding_t *w);
    485 
    486 void Q2_FixTextureReferences(void)
    487 {
    488 	int i, j, k, we;
    489 	dbrushside_t *brushside;
    490 	dbrush_t *brush;
    491 	dface_t *face;
    492 	winding_t *w;
    493 
    494 	memset(brushsidetextured, false, MAX_MAP_BRUSHSIDES);
    495 	//go over all the brushes
    496    for (i = 0; i < numbrushes; i++)
    497    {
    498 		brush = &dbrushes[i];
    499 		//hint brushes are not textured
    500 		if (Q2_HintSkipBrush(brush)) continue;
    501 		//go over all the sides of the brush
    502 		for (j = 0; j < brush->numsides; j++)
    503 		{
    504 			brushside = &dbrushsides[brush->firstside + j];
    505 			//
    506 			w = Q2_BrushSideWinding(brush, brushside);
    507 			if (!w)
    508 			{
    509 				brushsidetextured[brush->firstside + j] = true;
    510 				continue;
    511 			} //end if
    512 			else
    513 			{
    514 				//RemoveEqualPoints(w, 0.2);
    515 				if (WindingIsTiny(w))
    516 				{
    517 					FreeWinding(w);
    518 					brushsidetextured[brush->firstside + j] = true;
    519 					continue;
    520 				} //end if
    521 				else
    522 				{
    523 					we = WindingError(w);
    524 					if (we == WE_NOTENOUGHPOINTS
    525 						|| we == WE_SMALLAREA
    526 						|| we == WE_POINTBOGUSRANGE
    527 //						|| we == WE_NONCONVEX
    528 						)
    529 					{
    530 						FreeWinding(w);
    531 						brushsidetextured[brush->firstside + j] = true;
    532 						continue;
    533 					} //end if
    534 				} //end else
    535 			} //end else
    536 			if (WindingArea(w) < 20)
    537 			{
    538 				brushsidetextured[brush->firstside + j] = true;
    539 			} //end if
    540 			//find a face for texturing this brush
    541 			for (k = 0; k < numfaces; k++)
    542 			{
    543 				face = &dfaces[k];
    544 				//if the face is in the same plane as the brush side
    545 				if ((face->planenum&~1) != (brushside->planenum&~1)) continue;
    546 				//if the face is partly or totally on the brush side
    547 				if (Q2_FaceOnWinding(face, w))
    548 				{
    549 					brushside->texinfo = face->texinfo;
    550 					brushsidetextured[brush->firstside + j] = true;
    551 					break;
    552 				} //end if
    553 			} //end for
    554 			FreeWinding(w);
    555 		} //end for
    556 	} //end for
    557 } //end of the function Q2_FixTextureReferences*/
    558 
    559 //#endif //ME
    560 
    561 
    562 /*
    563 ===============
    564 CompressVis
    565 
    566 ===============
    567 */
    568 int Q2_CompressVis (byte *vis, byte *dest)
    569 {
    570 	int		j;
    571 	int		rep;
    572 	int		visrow;
    573 	byte	*dest_p;
    574 	
    575 	dest_p = dest;
    576 //	visrow = (r_numvisleafs + 7)>>3;
    577 	visrow = (dvis->numclusters + 7)>>3;
    578 	
    579 	for (j=0 ; j<visrow ; j++)
    580 	{
    581 		*dest_p++ = vis[j];
    582 		if (vis[j])
    583 			continue;
    584 
    585 		rep = 1;
    586 		for ( j++; j<visrow ; j++)
    587 			if (vis[j] || rep == 255)
    588 				break;
    589 			else
    590 				rep++;
    591 		*dest_p++ = rep;
    592 		j--;
    593 	}
    594 	
    595 	return dest_p - dest;
    596 }
    597 
    598 
    599 /*
    600 ===================
    601 DecompressVis
    602 ===================
    603 */
    604 void Q2_DecompressVis (byte *in, byte *decompressed)
    605 {
    606 	int		c;
    607 	byte	*out;
    608 	int		row;
    609 
    610 //	row = (r_numvisleafs+7)>>3;	
    611 	row = (dvis->numclusters+7)>>3;	
    612 	out = decompressed;
    613 
    614 	do
    615 	{
    616 		if (*in)
    617 		{
    618 			*out++ = *in++;
    619 			continue;
    620 		}
    621 	
    622 		c = in[1];
    623 		if (!c)
    624 			Error ("DecompressVis: 0 repeat");
    625 		in += 2;
    626 		while (c)
    627 		{
    628 			*out++ = 0;
    629 			c--;
    630 		}
    631 	} while (out - decompressed < row);
    632 }
    633 
    634 //=============================================================================
    635 
    636 /*
    637 =============
    638 SwapBSPFile
    639 
    640 Byte swaps all data in a bsp file.
    641 =============
    642 */
    643 void Q2_SwapBSPFile (qboolean todisk)
    644 {
    645 	int				i, j;
    646 	dmodel_t		*d;
    647 
    648 	
    649 // models	
    650 	for (i=0 ; i<nummodels ; i++)
    651 	{
    652 		d = &dmodels[i];
    653 
    654 		d->firstface = LittleLong (d->firstface);
    655 		d->numfaces = LittleLong (d->numfaces);
    656 		d->headnode = LittleLong (d->headnode);
    657 		
    658 		for (j=0 ; j<3 ; j++)
    659 		{
    660 			d->mins[j] = LittleFloat(d->mins[j]);
    661 			d->maxs[j] = LittleFloat(d->maxs[j]);
    662 			d->origin[j] = LittleFloat(d->origin[j]);
    663 		}
    664 	}
    665 
    666 //
    667 // vertexes
    668 //
    669 	for (i=0 ; i<numvertexes ; i++)
    670 	{
    671 		for (j=0 ; j<3 ; j++)
    672 			dvertexes[i].point[j] = LittleFloat (dvertexes[i].point[j]);
    673 	}
    674 		
    675 //
    676 // planes
    677 //	
    678 	for (i=0 ; i<numplanes ; i++)
    679 	{
    680 		for (j=0 ; j<3 ; j++)
    681 			dplanes[i].normal[j] = LittleFloat (dplanes[i].normal[j]);
    682 		dplanes[i].dist = LittleFloat (dplanes[i].dist);
    683 		dplanes[i].type = LittleLong (dplanes[i].type);
    684 	}
    685 	
    686 //
    687 // texinfos
    688 //	
    689 	for (i=0 ; i<numtexinfo ; i++)
    690 	{
    691 		for (j=0 ; j<8 ; j++)
    692 			texinfo[i].vecs[0][j] = LittleFloat (texinfo[i].vecs[0][j]);
    693 		texinfo[i].flags = LittleLong (texinfo[i].flags);
    694 		texinfo[i].value = LittleLong (texinfo[i].value);
    695 		texinfo[i].nexttexinfo = LittleLong (texinfo[i].nexttexinfo);
    696 	}
    697 	
    698 //
    699 // faces
    700 //
    701 	for (i=0 ; i<numfaces ; i++)
    702 	{
    703 		dfaces[i].texinfo = LittleShort (dfaces[i].texinfo);
    704 		dfaces[i].planenum = LittleShort (dfaces[i].planenum);
    705 		dfaces[i].side = LittleShort (dfaces[i].side);
    706 		dfaces[i].lightofs = LittleLong (dfaces[i].lightofs);
    707 		dfaces[i].firstedge = LittleLong (dfaces[i].firstedge);
    708 		dfaces[i].numedges = LittleShort (dfaces[i].numedges);
    709 	}
    710 
    711 //
    712 // nodes
    713 //
    714 	for (i=0 ; i<numnodes ; i++)
    715 	{
    716 		dnodes[i].planenum = LittleLong (dnodes[i].planenum);
    717 		for (j=0 ; j<3 ; j++)
    718 		{
    719 			dnodes[i].mins[j] = LittleShort (dnodes[i].mins[j]);
    720 			dnodes[i].maxs[j] = LittleShort (dnodes[i].maxs[j]);
    721 		}
    722 		dnodes[i].children[0] = LittleLong (dnodes[i].children[0]);
    723 		dnodes[i].children[1] = LittleLong (dnodes[i].children[1]);
    724 		dnodes[i].firstface = LittleShort (dnodes[i].firstface);
    725 		dnodes[i].numfaces = LittleShort (dnodes[i].numfaces);
    726 	}
    727 
    728 //
    729 // leafs
    730 //
    731 	for (i=0 ; i<numleafs ; i++)
    732 	{
    733 		dleafs[i].contents = LittleLong (dleafs[i].contents);
    734 		dleafs[i].cluster = LittleShort (dleafs[i].cluster);
    735 		dleafs[i].area = LittleShort (dleafs[i].area);
    736 		for (j=0 ; j<3 ; j++)
    737 		{
    738 			dleafs[i].mins[j] = LittleShort (dleafs[i].mins[j]);
    739 			dleafs[i].maxs[j] = LittleShort (dleafs[i].maxs[j]);
    740 		}
    741 
    742 		dleafs[i].firstleafface = LittleShort (dleafs[i].firstleafface);
    743 		dleafs[i].numleaffaces = LittleShort (dleafs[i].numleaffaces);
    744 		dleafs[i].firstleafbrush = LittleShort (dleafs[i].firstleafbrush);
    745 		dleafs[i].numleafbrushes = LittleShort (dleafs[i].numleafbrushes);
    746 	}
    747 
    748 //
    749 // leaffaces
    750 //
    751 	for (i=0 ; i<numleaffaces ; i++)
    752 		dleaffaces[i] = LittleShort (dleaffaces[i]);
    753 
    754 //
    755 // leafbrushes
    756 //
    757 	for (i=0 ; i<numleafbrushes ; i++)
    758 		dleafbrushes[i] = LittleShort (dleafbrushes[i]);
    759 
    760 //
    761 // surfedges
    762 //
    763 	for (i=0 ; i<numsurfedges ; i++)
    764 		dsurfedges[i] = LittleLong (dsurfedges[i]);
    765 
    766 //
    767 // edges
    768 //
    769 	for (i=0 ; i<numedges ; i++)
    770 	{
    771 		dedges[i].v[0] = LittleShort (dedges[i].v[0]);
    772 		dedges[i].v[1] = LittleShort (dedges[i].v[1]);
    773 	}
    774 
    775 //
    776 // brushes
    777 //
    778 	for (i=0 ; i<numbrushes ; i++)
    779 	{
    780 		dbrushes[i].firstside = LittleLong (dbrushes[i].firstside);
    781 		dbrushes[i].numsides = LittleLong (dbrushes[i].numsides);
    782 		dbrushes[i].contents = LittleLong (dbrushes[i].contents);
    783 	}
    784 
    785 //
    786 // areas
    787 //
    788 	for (i=0 ; i<numareas ; i++)
    789 	{
    790 		dareas[i].numareaportals = LittleLong (dareas[i].numareaportals);
    791 		dareas[i].firstareaportal = LittleLong (dareas[i].firstareaportal);
    792 	}
    793 
    794 //
    795 // areasportals
    796 //
    797 	for (i=0 ; i<numareaportals ; i++)
    798 	{
    799 		dareaportals[i].portalnum = LittleLong (dareaportals[i].portalnum);
    800 		dareaportals[i].otherarea = LittleLong (dareaportals[i].otherarea);
    801 	}
    802 
    803 //
    804 // brushsides
    805 //
    806 	for (i=0 ; i<numbrushsides ; i++)
    807 	{
    808 		dbrushsides[i].planenum = LittleShort (dbrushsides[i].planenum);
    809 		dbrushsides[i].texinfo = LittleShort (dbrushsides[i].texinfo);
    810 	}
    811 
    812 //
    813 // visibility
    814 //
    815 	if (todisk)
    816 		j = dvis->numclusters;
    817 	else
    818 		j = LittleLong(dvis->numclusters);
    819 	dvis->numclusters = LittleLong (dvis->numclusters);
    820 	for (i=0 ; i<j ; i++)
    821 	{
    822 		dvis->bitofs[i][0] = LittleLong (dvis->bitofs[i][0]);
    823 		dvis->bitofs[i][1] = LittleLong (dvis->bitofs[i][1]);
    824 	}
    825 } //end of the function Q2_SwapBSPFile
    826 
    827 
    828 dheader_t	*header;
    829 
    830 int Q2_CopyLump (int lump, void *dest, int size, int maxsize)
    831 {
    832 	int		length, ofs;
    833 
    834 	length = header->lumps[lump].filelen;
    835 	ofs = header->lumps[lump].fileofs;
    836 	
    837 	if (length % size)
    838 		Error ("LoadBSPFile: odd lump size");
    839 
    840    if ((length/size) > maxsize)
    841       Error ("Q2_LoadBSPFile: exceeded max size for lump %d size %d > maxsize %d\n", lump, (length/size), maxsize);
    842 
    843 	memcpy (dest, (byte *)header + ofs, length);
    844 
    845 	return length / size;
    846 } //end of the function Q2_CopyLump
    847 
    848 /*
    849 =============
    850 LoadBSPFile
    851 =============
    852 */
    853 void Q2_LoadBSPFile(char *filename, int offset, int length)
    854 {
    855 	int			i;
    856 	
    857 //
    858 // load the file header
    859 //
    860 	LoadFile (filename, (void **)&header, offset, length);
    861 
    862 // swap the header
    863 	for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
    864 		((int *)header)[i] = LittleLong ( ((int *)header)[i]);
    865 
    866 	if (header->ident != IDBSPHEADER)
    867 		Error ("%s is not a IBSP file", filename);
    868 	if (header->version != BSPVERSION)
    869 		Error ("%s is version %i, not %i", filename, header->version, BSPVERSION);
    870 
    871 	nummodels = Q2_CopyLump (LUMP_MODELS, dmodels, sizeof(dmodel_t), MAX_MAP_MODELS);
    872 	numvertexes = Q2_CopyLump (LUMP_VERTEXES, dvertexes, sizeof(dvertex_t), MAX_MAP_VERTS);
    873 	numplanes = Q2_CopyLump (LUMP_PLANES, dplanes, sizeof(dplane_t), MAX_MAP_PLANES);
    874 	numleafs = Q2_CopyLump (LUMP_LEAFS, dleafs, sizeof(dleaf_t), MAX_MAP_LEAFS);
    875 	numnodes = Q2_CopyLump (LUMP_NODES, dnodes, sizeof(dnode_t), MAX_MAP_NODES);
    876 	numtexinfo = Q2_CopyLump (LUMP_TEXINFO, texinfo, sizeof(texinfo_t), MAX_MAP_TEXINFO);
    877 	numfaces = Q2_CopyLump (LUMP_FACES, dfaces, sizeof(dface_t), MAX_MAP_FACES);
    878 	numleaffaces = Q2_CopyLump (LUMP_LEAFFACES, dleaffaces, sizeof(dleaffaces[0]), MAX_MAP_LEAFFACES);
    879 	numleafbrushes = Q2_CopyLump (LUMP_LEAFBRUSHES, dleafbrushes, sizeof(dleafbrushes[0]), MAX_MAP_LEAFBRUSHES);
    880 	numsurfedges = Q2_CopyLump (LUMP_SURFEDGES, dsurfedges, sizeof(dsurfedges[0]), MAX_MAP_SURFEDGES);
    881 	numedges = Q2_CopyLump (LUMP_EDGES, dedges, sizeof(dedge_t), MAX_MAP_EDGES);
    882 	numbrushes = Q2_CopyLump (LUMP_BRUSHES, dbrushes, sizeof(dbrush_t), MAX_MAP_BRUSHES);
    883 	numbrushsides = Q2_CopyLump (LUMP_BRUSHSIDES, dbrushsides, sizeof(dbrushside_t), MAX_MAP_BRUSHSIDES);
    884 	numareas = Q2_CopyLump (LUMP_AREAS, dareas, sizeof(darea_t), MAX_MAP_AREAS);
    885 	numareaportals = Q2_CopyLump (LUMP_AREAPORTALS, dareaportals, sizeof(dareaportal_t), MAX_MAP_AREAPORTALS);
    886 
    887 	visdatasize = Q2_CopyLump (LUMP_VISIBILITY, dvisdata, 1, MAX_MAP_VISIBILITY);
    888 	lightdatasize = Q2_CopyLump (LUMP_LIGHTING, dlightdata, 1, MAX_MAP_LIGHTING);
    889 	entdatasize = Q2_CopyLump (LUMP_ENTITIES, dentdata, 1, MAX_MAP_ENTSTRING);
    890 
    891 	Q2_CopyLump (LUMP_POP, dpop, 1, MAX_MAP_DPOP);
    892 
    893 	FreeMemory(header);		// everything has been copied out
    894 		
    895 //
    896 // swap everything
    897 //	
    898 	Q2_SwapBSPFile (false);
    899 
    900 	Q2_FixTextureReferences();
    901 } //end of the function Q2_LoadBSPFile
    902 
    903 
    904 /*
    905 =============
    906 LoadBSPFileTexinfo
    907 
    908 Only loads the texinfo lump, so qdata can scan for textures
    909 =============
    910 */
    911 void	Q2_LoadBSPFileTexinfo (char *filename)
    912 {
    913 	int			i;
    914 	FILE		*f;
    915 	int		length, ofs;
    916 
    917 	header = GetMemory(sizeof(dheader_t));
    918 
    919 	f = fopen (filename, "rb");
    920 	fread (header, sizeof(dheader_t), 1, f);
    921 
    922 // swap the header
    923 	for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
    924 		((int *)header)[i] = LittleLong ( ((int *)header)[i]);
    925 
    926 	if (header->ident != IDBSPHEADER)
    927 		Error ("%s is not a IBSP file", filename);
    928 	if (header->version != BSPVERSION)
    929 		Error ("%s is version %i, not %i", filename, header->version, BSPVERSION);
    930 
    931 
    932 	length = header->lumps[LUMP_TEXINFO].filelen;
    933 	ofs = header->lumps[LUMP_TEXINFO].fileofs;
    934 
    935 	fseek (f, ofs, SEEK_SET);
    936 	fread (texinfo, length, 1, f);
    937 	fclose (f);
    938 
    939 	numtexinfo = length / sizeof(texinfo_t);
    940 
    941 	FreeMemory(header);		// everything has been copied out
    942 		
    943 	Q2_SwapBSPFile (false);
    944 } //end of the function Q2_LoadBSPFileTexinfo
    945 
    946 
    947 //============================================================================
    948 
    949 FILE		*wadfile;
    950 dheader_t	outheader;
    951 
    952 void Q2_AddLump (int lumpnum, void *data, int len)
    953 {
    954 	lump_t *lump;
    955 
    956 	lump = &header->lumps[lumpnum];
    957 	
    958 	lump->fileofs = LittleLong( ftell(wadfile) );
    959 	lump->filelen = LittleLong(len);
    960 	SafeWrite (wadfile, data, (len+3)&~3);
    961 } //end of the function Q2_AddLump
    962 
    963 /*
    964 =============
    965 WriteBSPFile
    966 
    967 Swaps the bsp file in place, so it should not be referenced again
    968 =============
    969 */
    970 void	Q2_WriteBSPFile (char *filename)
    971 {		
    972 	header = &outheader;
    973 	memset (header, 0, sizeof(dheader_t));
    974 	
    975 	Q2_SwapBSPFile (true);
    976 
    977 	header->ident = LittleLong (IDBSPHEADER);
    978 	header->version = LittleLong (BSPVERSION);
    979 	
    980 	wadfile = SafeOpenWrite (filename);
    981 	SafeWrite (wadfile, header, sizeof(dheader_t));	// overwritten later
    982 
    983 	Q2_AddLump (LUMP_PLANES, dplanes, numplanes*sizeof(dplane_t));
    984 	Q2_AddLump (LUMP_LEAFS, dleafs, numleafs*sizeof(dleaf_t));
    985 	Q2_AddLump (LUMP_VERTEXES, dvertexes, numvertexes*sizeof(dvertex_t));
    986 	Q2_AddLump (LUMP_NODES, dnodes, numnodes*sizeof(dnode_t));
    987 	Q2_AddLump (LUMP_TEXINFO, texinfo, numtexinfo*sizeof(texinfo_t));
    988 	Q2_AddLump (LUMP_FACES, dfaces, numfaces*sizeof(dface_t));
    989 	Q2_AddLump (LUMP_BRUSHES, dbrushes, numbrushes*sizeof(dbrush_t));
    990 	Q2_AddLump (LUMP_BRUSHSIDES, dbrushsides, numbrushsides*sizeof(dbrushside_t));
    991 	Q2_AddLump (LUMP_LEAFFACES, dleaffaces, numleaffaces*sizeof(dleaffaces[0]));
    992 	Q2_AddLump (LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes*sizeof(dleafbrushes[0]));
    993 	Q2_AddLump (LUMP_SURFEDGES, dsurfedges, numsurfedges*sizeof(dsurfedges[0]));
    994 	Q2_AddLump (LUMP_EDGES, dedges, numedges*sizeof(dedge_t));
    995 	Q2_AddLump (LUMP_MODELS, dmodels, nummodels*sizeof(dmodel_t));
    996 	Q2_AddLump (LUMP_AREAS, dareas, numareas*sizeof(darea_t));
    997 	Q2_AddLump (LUMP_AREAPORTALS, dareaportals, numareaportals*sizeof(dareaportal_t));
    998 
    999 	Q2_AddLump (LUMP_LIGHTING, dlightdata, lightdatasize);
   1000 	Q2_AddLump (LUMP_VISIBILITY, dvisdata, visdatasize);
   1001 	Q2_AddLump (LUMP_ENTITIES, dentdata, entdatasize);
   1002 	Q2_AddLump (LUMP_POP, dpop, sizeof(dpop));
   1003 	
   1004 	fseek (wadfile, 0, SEEK_SET);
   1005 	SafeWrite (wadfile, header, sizeof(dheader_t));
   1006 	fclose (wadfile);	
   1007 } //end of the function Q2_WriteBSPFile
   1008 
   1009 //============================================================================
   1010 
   1011 /*
   1012 =============
   1013 PrintBSPFileSizes
   1014 
   1015 Dumps info about current file
   1016 =============
   1017 */
   1018 void Q2_PrintBSPFileSizes (void)
   1019 {
   1020 	if (!num_entities)
   1021 		Q2_ParseEntities();
   1022 
   1023 	printf ("%6i models       %7i\n"
   1024 		,nummodels, (int)(nummodels*sizeof(dmodel_t)));
   1025 	printf ("%6i brushes      %7i\n"
   1026 		,numbrushes, (int)(numbrushes*sizeof(dbrush_t)));
   1027 	printf ("%6i brushsides   %7i\n"
   1028 		,numbrushsides, (int)(numbrushsides*sizeof(dbrushside_t)));
   1029 	printf ("%6i planes       %7i\n"
   1030 		,numplanes, (int)(numplanes*sizeof(dplane_t)));
   1031 	printf ("%6i texinfo      %7i\n"
   1032 		,numtexinfo, (int)(numtexinfo*sizeof(texinfo_t)));
   1033 	printf ("%6i entdata      %7i\n", num_entities, entdatasize);
   1034 
   1035 	printf ("\n");
   1036 
   1037 	printf ("%6i vertexes     %7i\n"
   1038 		,numvertexes, (int)(numvertexes*sizeof(dvertex_t)));
   1039 	printf ("%6i nodes        %7i\n"
   1040 		,numnodes, (int)(numnodes*sizeof(dnode_t)));
   1041 	printf ("%6i faces        %7i\n"
   1042 		,numfaces, (int)(numfaces*sizeof(dface_t)));
   1043 	printf ("%6i leafs        %7i\n"
   1044 		,numleafs, (int)(numleafs*sizeof(dleaf_t)));
   1045 	printf ("%6i leaffaces    %7i\n"
   1046 		,numleaffaces, (int)(numleaffaces*sizeof(dleaffaces[0])));
   1047 	printf ("%6i leafbrushes  %7i\n"
   1048 		,numleafbrushes, (int)(numleafbrushes*sizeof(dleafbrushes[0])));
   1049 	printf ("%6i surfedges    %7i\n"
   1050 		,numsurfedges, (int)(numsurfedges*sizeof(dsurfedges[0])));
   1051 	printf ("%6i edges        %7i\n"
   1052 		,numedges, (int)(numedges*sizeof(dedge_t)));
   1053 //NEW
   1054 	printf ("%6i areas        %7i\n"
   1055 		,numareas, (int)(numareas*sizeof(darea_t)));
   1056 	printf ("%6i areaportals  %7i\n"
   1057 		,numareaportals, (int)(numareaportals*sizeof(dareaportal_t)));
   1058 //ENDNEW
   1059 	printf ("      lightdata    %7i\n", lightdatasize);
   1060 	printf ("      visdata      %7i\n", visdatasize);
   1061 } //end of the function Q2_PrintBSPFileSizes
   1062 
   1063 /*
   1064 ================
   1065 ParseEntities
   1066 
   1067 Parses the dentdata string into entities
   1068 ================
   1069 */
   1070 void Q2_ParseEntities (void)
   1071 {
   1072 	script_t *script;
   1073 
   1074 	num_entities = 0;
   1075 	script = LoadScriptMemory(dentdata, entdatasize, "*Quake2 bsp file");
   1076 	SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
   1077 									SCFL_NOSTRINGESCAPECHARS);
   1078 
   1079 	while(ParseEntity(script))
   1080 	{
   1081 	} //end while
   1082 
   1083 	FreeScript(script);
   1084 } //end of the function Q2_ParseEntities
   1085 
   1086 
   1087 /*
   1088 ================
   1089 UnparseEntities
   1090 
   1091 Generates the dentdata string from all the entities
   1092 ================
   1093 */
   1094 void Q2_UnparseEntities (void)
   1095 {
   1096 	char	*buf, *end;
   1097 	epair_t	*ep;
   1098 	char	line[2048];
   1099 	int		i;
   1100 	char	key[1024], value[1024];
   1101 
   1102 	buf = dentdata;
   1103 	end = buf;
   1104 	*end = 0;
   1105 	
   1106 	for (i=0 ; i<num_entities ; i++)
   1107 	{
   1108 		ep = entities[i].epairs;
   1109 		if (!ep)
   1110 			continue;	// ent got removed
   1111 		
   1112 		strcat (end,"{\n");
   1113 		end += 2;
   1114 				
   1115 		for (ep = entities[i].epairs ; ep ; ep=ep->next)
   1116 		{
   1117 			strcpy (key, ep->key);
   1118 			StripTrailing (key);
   1119 			strcpy (value, ep->value);
   1120 			StripTrailing (value);
   1121 				
   1122 			sprintf (line, "\"%s\" \"%s\"\n", key, value);
   1123 			strcat (end, line);
   1124 			end += strlen(line);
   1125 		}
   1126 		strcat (end,"}\n");
   1127 		end += 2;
   1128 
   1129 		if (end > buf + MAX_MAP_ENTSTRING)
   1130 			Error ("Entity text too long");
   1131 	}
   1132 	entdatasize = end - buf + 1;
   1133 } //end of the function Q2_UnparseEntities
   1134