Quake-III-Arena

Quake III Arena GPL Source Release
Log | Files | Refs

l_bsp_sin.c (37344B)


      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 "l_bsp_ent.h"
     30 #include "l_bsp_sin.h"
     31 
     32 void GetLeafNums (void);
     33 
     34 //=============================================================================
     35 
     36 int					sin_nummodels;
     37 sin_dmodel_t		*sin_dmodels;//[SIN_MAX_MAP_MODELS];
     38 
     39 int					sin_visdatasize;
     40 byte				*sin_dvisdata;//[SIN_MAX_MAP_VISIBILITY];
     41 sin_dvis_t			*sin_dvis;// = (sin_dvis_t *)sin_sin_dvisdata;
     42 
     43 int					sin_lightdatasize;
     44 byte				*sin_dlightdata;//[SIN_MAX_MAP_LIGHTING];
     45 
     46 int					sin_entdatasize;
     47 char				*sin_dentdata;//[SIN_MAX_MAP_ENTSTRING];
     48 
     49 int					sin_numleafs;
     50 sin_dleaf_t			*sin_dleafs;//[SIN_MAX_MAP_LEAFS];
     51 
     52 int					sin_numplanes;
     53 sin_dplane_t		*sin_dplanes;//[SIN_MAX_MAP_PLANES];
     54 
     55 int					sin_numvertexes;
     56 sin_dvertex_t		*sin_dvertexes;//[SIN_MAX_MAP_VERTS];
     57 
     58 int					sin_numnodes;
     59 sin_dnode_t			*sin_dnodes;//[SIN_MAX_MAP_NODES];
     60 
     61 int					sin_numtexinfo;
     62 sin_texinfo_t		*sin_texinfo;//[SIN_MAX_MAP_sin_texinfo];
     63 
     64 int					sin_numfaces;
     65 sin_dface_t			*sin_dfaces;//[SIN_MAX_MAP_FACES];
     66 
     67 int					sin_numedges;
     68 sin_dedge_t			*sin_dedges;//[SIN_MAX_MAP_EDGES];
     69 
     70 int					sin_numleaffaces;
     71 unsigned short		*sin_dleaffaces;//[SIN_MAX_MAP_LEAFFACES];
     72 
     73 int					sin_numleafbrushes;
     74 unsigned short		*sin_dleafbrushes;//[SIN_MAX_MAP_LEAFBRUSHES];
     75 
     76 int					sin_numsurfedges;
     77 int					*sin_dsurfedges;//[SIN_MAX_MAP_SURFEDGES];
     78 
     79 int					sin_numbrushes;
     80 sin_dbrush_t		*sin_dbrushes;//[SIN_MAX_MAP_BRUSHES];
     81 
     82 int					sin_numbrushsides;
     83 sin_dbrushside_t	*sin_dbrushsides;//[SIN_MAX_MAP_BRUSHSIDES];
     84 
     85 int					sin_numareas;
     86 sin_darea_t			*sin_dareas;//[SIN_MAX_MAP_AREAS];
     87 
     88 int					sin_numareaportals;
     89 sin_dareaportal_t	*sin_dareaportals;//[SIN_MAX_MAP_AREAPORTALS];
     90 
     91 int					sin_numlightinfo;
     92 sin_lightvalue_t	*sin_lightinfo;//[SIN_MAX_MAP_LIGHTINFO];
     93 
     94 byte				sin_dpop[256];
     95 
     96 char				sin_dbrushsidetextured[SIN_MAX_MAP_BRUSHSIDES];
     97 
     98 int sin_bspallocated = false;
     99 int sin_allocatedbspmem = 0;
    100 
    101 void Sin_AllocMaxBSP(void)
    102 {
    103 	//models
    104 	sin_nummodels = 0;
    105 	sin_dmodels = (sin_dmodel_t *) GetClearedMemory(SIN_MAX_MAP_MODELS * sizeof(sin_dmodel_t));
    106 	sin_allocatedbspmem += SIN_MAX_MAP_MODELS * sizeof(sin_dmodel_t);
    107 	//vis data
    108 	sin_visdatasize = 0;
    109 	sin_dvisdata = (byte *) GetClearedMemory(SIN_MAX_MAP_VISIBILITY * sizeof(byte));
    110 	sin_dvis = (sin_dvis_t *) sin_dvisdata;
    111 	sin_allocatedbspmem += SIN_MAX_MAP_VISIBILITY * sizeof(byte);
    112 	//light data
    113 	sin_lightdatasize = 0;
    114 	sin_dlightdata = (byte *) GetClearedMemory(SIN_MAX_MAP_LIGHTING * sizeof(byte));
    115 	sin_allocatedbspmem += SIN_MAX_MAP_LIGHTING * sizeof(byte);
    116 	//entity data
    117 	sin_entdatasize = 0;
    118 	sin_dentdata = (char *) GetClearedMemory(SIN_MAX_MAP_ENTSTRING * sizeof(char));
    119 	sin_allocatedbspmem += SIN_MAX_MAP_ENTSTRING * sizeof(char);
    120 	//leafs
    121 	sin_numleafs = 0;
    122 	sin_dleafs = (sin_dleaf_t *) GetClearedMemory(SIN_MAX_MAP_LEAFS * sizeof(sin_dleaf_t));
    123 	sin_allocatedbspmem += SIN_MAX_MAP_LEAFS * sizeof(sin_dleaf_t);
    124 	//planes
    125 	sin_numplanes = 0;
    126 	sin_dplanes = (sin_dplane_t *) GetClearedMemory(SIN_MAX_MAP_PLANES * sizeof(sin_dplane_t));
    127 	sin_allocatedbspmem += SIN_MAX_MAP_PLANES * sizeof(sin_dplane_t);
    128 	//vertexes
    129 	sin_numvertexes = 0;
    130 	sin_dvertexes = (sin_dvertex_t *) GetClearedMemory(SIN_MAX_MAP_VERTS * sizeof(sin_dvertex_t));
    131 	sin_allocatedbspmem += SIN_MAX_MAP_VERTS * sizeof(sin_dvertex_t);
    132 	//nodes
    133 	sin_numnodes = 0;
    134 	sin_dnodes = (sin_dnode_t *) GetClearedMemory(SIN_MAX_MAP_NODES * sizeof(sin_dnode_t));
    135 	sin_allocatedbspmem += SIN_MAX_MAP_NODES * sizeof(sin_dnode_t);
    136 	//texture info
    137 	sin_numtexinfo = 0;
    138 	sin_texinfo = (sin_texinfo_t *) GetClearedMemory(SIN_MAX_MAP_TEXINFO * sizeof(sin_texinfo_t));
    139 	sin_allocatedbspmem += SIN_MAX_MAP_TEXINFO * sizeof(sin_texinfo_t);
    140 	//faces
    141 	sin_numfaces = 0;
    142 	sin_dfaces = (sin_dface_t *) GetClearedMemory(SIN_MAX_MAP_FACES * sizeof(sin_dface_t));
    143 	sin_allocatedbspmem += SIN_MAX_MAP_FACES * sizeof(sin_dface_t);
    144 	//edges
    145 	sin_numedges = 0;
    146 	sin_dedges = (sin_dedge_t *) GetClearedMemory(SIN_MAX_MAP_EDGES * sizeof(sin_dedge_t));
    147 	sin_allocatedbspmem += SIN_MAX_MAP_EDGES * sizeof(sin_dedge_t);
    148 	//leaf faces
    149 	sin_numleaffaces = 0;
    150 	sin_dleaffaces = (unsigned short *) GetClearedMemory(SIN_MAX_MAP_LEAFFACES * sizeof(unsigned short));
    151 	sin_allocatedbspmem += SIN_MAX_MAP_LEAFFACES * sizeof(unsigned short);
    152 	//leaf brushes
    153 	sin_numleafbrushes = 0;
    154 	sin_dleafbrushes = (unsigned short *) GetClearedMemory(SIN_MAX_MAP_LEAFBRUSHES * sizeof(unsigned short));
    155 	sin_allocatedbspmem += SIN_MAX_MAP_LEAFBRUSHES * sizeof(unsigned short);
    156 	//surface edges
    157 	sin_numsurfedges = 0;
    158 	sin_dsurfedges = (int *) GetClearedMemory(SIN_MAX_MAP_SURFEDGES * sizeof(int));
    159 	sin_allocatedbspmem += SIN_MAX_MAP_SURFEDGES * sizeof(int);
    160 	//brushes
    161 	sin_numbrushes = 0;
    162 	sin_dbrushes = (sin_dbrush_t *) GetClearedMemory(SIN_MAX_MAP_BRUSHES * sizeof(sin_dbrush_t));
    163 	sin_allocatedbspmem += SIN_MAX_MAP_BRUSHES * sizeof(sin_dbrush_t);
    164 	//brushsides
    165 	sin_numbrushsides = 0;
    166 	sin_dbrushsides = (sin_dbrushside_t *) GetClearedMemory(SIN_MAX_MAP_BRUSHSIDES * sizeof(sin_dbrushside_t));
    167 	sin_allocatedbspmem += SIN_MAX_MAP_BRUSHSIDES * sizeof(sin_dbrushside_t);
    168 	//areas
    169 	sin_numareas = 0;
    170 	sin_dareas = (sin_darea_t *) GetClearedMemory(SIN_MAX_MAP_AREAS * sizeof(sin_darea_t));
    171 	sin_allocatedbspmem += SIN_MAX_MAP_AREAS * sizeof(sin_darea_t);
    172 	//area portals
    173 	sin_numareaportals = 0;
    174 	sin_dareaportals = (sin_dareaportal_t *) GetClearedMemory(SIN_MAX_MAP_AREAPORTALS * sizeof(sin_dareaportal_t));
    175 	sin_allocatedbspmem += SIN_MAX_MAP_AREAPORTALS * sizeof(sin_dareaportal_t);
    176 	//light info
    177 	sin_numlightinfo = 0;
    178 	sin_lightinfo = (sin_lightvalue_t *) GetClearedMemory(SIN_MAX_MAP_LIGHTINFO * sizeof(sin_lightvalue_t));
    179 	sin_allocatedbspmem += SIN_MAX_MAP_LIGHTINFO * sizeof(sin_lightvalue_t);
    180 	//print allocated memory
    181 	Log_Print("allocated ");
    182 	PrintMemorySize(sin_allocatedbspmem);
    183 	Log_Print(" of BSP memory\n");
    184 } //end of the function Sin_AllocMaxBSP
    185 
    186 void Sin_FreeMaxBSP(void)
    187 {
    188 	//models
    189 	sin_nummodels = 0;
    190 	FreeMemory(sin_dmodels);
    191 	sin_dmodels = NULL;
    192 	//vis data
    193 	sin_visdatasize = 0;
    194 	FreeMemory(sin_dvisdata);
    195 	sin_dvisdata = NULL;
    196 	sin_dvis = NULL;
    197 	//light data
    198 	sin_lightdatasize = 0;
    199 	FreeMemory(sin_dlightdata);
    200 	sin_dlightdata = NULL;
    201 	//entity data
    202 	sin_entdatasize = 0;
    203 	FreeMemory(sin_dentdata);
    204 	sin_dentdata = NULL;
    205 	//leafs
    206 	sin_numleafs = 0;
    207 	FreeMemory(sin_dleafs);
    208 	sin_dleafs = NULL;
    209 	//planes
    210 	sin_numplanes = 0;
    211 	FreeMemory(sin_dplanes);
    212 	sin_dplanes = NULL;
    213 	//vertexes
    214 	sin_numvertexes = 0;
    215 	FreeMemory(sin_dvertexes);
    216 	sin_dvertexes = NULL;
    217 	//nodes
    218 	sin_numnodes = 0;
    219 	FreeMemory(sin_dnodes);
    220 	sin_dnodes = NULL;
    221 	//texture info
    222 	sin_numtexinfo = 0;
    223 	FreeMemory(sin_texinfo);
    224 	sin_texinfo = NULL;
    225 	//faces
    226 	sin_numfaces = 0;
    227 	FreeMemory(sin_dfaces);
    228 	sin_dfaces = NULL;
    229 	//edges
    230 	sin_numedges = 0;
    231 	FreeMemory(sin_dedges);
    232 	sin_dedges = NULL;
    233 	//leaf faces
    234 	sin_numleaffaces = 0;
    235 	FreeMemory(sin_dleaffaces);
    236 	sin_dleaffaces = NULL;
    237 	//leaf brushes
    238 	sin_numleafbrushes = 0;
    239 	FreeMemory(sin_dleafbrushes);
    240 	sin_dleafbrushes = NULL;
    241 	//surface edges
    242 	sin_numsurfedges = 0;
    243 	FreeMemory(sin_dsurfedges);
    244 	sin_dsurfedges = NULL;
    245 	//brushes
    246 	sin_numbrushes = 0;
    247 	FreeMemory(sin_dbrushes);
    248 	sin_dbrushes = NULL;
    249 	//brushsides
    250 	sin_numbrushsides = 0;
    251 	FreeMemory(sin_dbrushsides);
    252 	sin_dbrushsides = NULL;
    253 	//areas
    254 	sin_numareas = 0;
    255 	FreeMemory(sin_dareas);
    256 	sin_dareas = NULL;
    257 	//area portals
    258 	sin_numareaportals = 0;
    259 	FreeMemory(sin_dareaportals);
    260 	sin_dareaportals = NULL;
    261 	//light info
    262 	sin_numlightinfo = 0;
    263 	FreeMemory(sin_lightinfo);
    264 	sin_lightinfo = NULL;
    265 	//
    266 	Log_Print("freed ");
    267 	PrintMemorySize(sin_allocatedbspmem);
    268 	Log_Print(" of BSP memory\n");
    269 	sin_allocatedbspmem = 0;
    270 } //end of the function Sin_FreeMaxBSP
    271 
    272 #define WCONVEX_EPSILON		0.5
    273 
    274 //===========================================================================
    275 // returns the amount the face and the winding overlap
    276 //
    277 // Parameter:				-
    278 // Returns:					-
    279 // Changes Globals:		-
    280 //===========================================================================
    281 float Sin_FaceOnWinding(sin_dface_t *face, winding_t *winding)
    282 {
    283 	int i, edgenum, side;
    284 	float dist, area;
    285 	sin_dplane_t plane;
    286 	vec_t *v1, *v2;
    287 	vec3_t normal, edgevec;
    288 	winding_t *w;
    289 
    290 	//
    291 	w = CopyWinding(winding);
    292 	memcpy(&plane, &sin_dplanes[face->planenum], sizeof(sin_dplane_t));
    293 	//check on which side of the plane the face is
    294 	if (face->side)
    295 	{
    296 		VectorNegate(plane.normal, plane.normal);
    297 		plane.dist = -plane.dist;
    298 	} //end if
    299 	for (i = 0; i < face->numedges && w; i++)
    300 	{
    301 		//get the first and second vertex of the edge
    302 		edgenum = sin_dsurfedges[face->firstedge + i];
    303 		side = edgenum > 0;
    304 		//if the face plane is flipped
    305 		v1 = sin_dvertexes[sin_dedges[abs(edgenum)].v[side]].point;
    306 		v2 = sin_dvertexes[sin_dedges[abs(edgenum)].v[!side]].point;
    307 		//create a plane through the edge vector, orthogonal to the face plane
    308 		//and with the normal vector pointing out of the face
    309 		VectorSubtract(v1, v2, edgevec);
    310 		CrossProduct(edgevec, plane.normal, normal);
    311 		VectorNormalize(normal);
    312 		dist = DotProduct(normal, v1);
    313 		//
    314 		ChopWindingInPlace(&w, normal, dist, 0.9); //CLIP_EPSILON
    315 	} //end for
    316 	if (w)
    317 	{
    318 		area = WindingArea(w);
    319 		FreeWinding(w);
    320 		return area;
    321 	} //end if
    322 	return 0;
    323 } //end of the function Sin_FaceOnWinding
    324 //===========================================================================
    325 // creates a winding for the given brush side on the given brush
    326 //
    327 // Parameter:				-
    328 // Returns:					-
    329 // Changes Globals:		-
    330 //===========================================================================
    331 winding_t *Sin_BrushSideWinding(sin_dbrush_t *brush, sin_dbrushside_t *baseside)
    332 {
    333 	int i;
    334 	sin_dplane_t *baseplane, *plane;
    335 	sin_dbrushside_t *side;
    336 	winding_t *w;
    337 	
    338 	//create a winding for the brush side with the given planenumber
    339 	baseplane = &sin_dplanes[baseside->planenum];
    340 	w = BaseWindingForPlane(baseplane->normal, baseplane->dist);
    341 	for (i = 0; i < brush->numsides && w; i++)
    342 	{
    343 		side = &sin_dbrushsides[brush->firstside + i];
    344 		//don't chop with the base plane
    345 		if (side->planenum == baseside->planenum) continue;
    346 		//also don't use planes that are almost equal
    347 		plane = &sin_dplanes[side->planenum];
    348 		if (DotProduct(baseplane->normal, plane->normal) > 0.999
    349 				&& fabs(baseplane->dist - plane->dist) < 0.01) continue;
    350 		//
    351 		plane = &sin_dplanes[side->planenum^1];
    352 		ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
    353 	} //end for
    354 	return w;
    355 } //end of the function Sin_BrushSideWinding
    356 //===========================================================================
    357 //
    358 // Parameter:				-
    359 // Returns:					-
    360 // Changes Globals:		-
    361 //===========================================================================
    362 int Sin_HintSkipBrush(sin_dbrush_t *brush)
    363 {
    364 	int j;
    365 	sin_dbrushside_t *brushside;
    366 
    367 	for (j = 0; j < brush->numsides; j++)
    368 	{
    369 		brushside = &sin_dbrushsides[brush->firstside + j];
    370 		if (brushside->texinfo > 0)
    371 		{
    372 			if (sin_texinfo[brushside->texinfo].flags & (SURF_SKIP|SURF_HINT))
    373 			{
    374 				return true;
    375 			} //end if
    376 		} //end if
    377 	} //end for
    378 	return false;
    379 } //end of the function Sin_HintSkipBrush
    380 //===========================================================================
    381 // fix screwed brush texture references
    382 //
    383 // Parameter:				-
    384 // Returns:					-
    385 // Changes Globals:		-
    386 //===========================================================================
    387 qboolean WindingIsTiny(winding_t *w);
    388 
    389 void Sin_FixTextureReferences(void)
    390 {
    391 	int i, j, k, we;
    392 	sin_dbrushside_t *brushside;
    393 	sin_dbrush_t *brush;
    394 	sin_dface_t *face;
    395 	winding_t *w;
    396 
    397 	memset(sin_dbrushsidetextured, false, SIN_MAX_MAP_BRUSHSIDES);
    398 	//go over all the brushes
    399    for (i = 0; i < sin_numbrushes; i++)
    400    {
    401 		brush = &sin_dbrushes[i];
    402 		//hint brushes are not textured
    403 		if (Sin_HintSkipBrush(brush)) continue;
    404 		//go over all the sides of the brush
    405 		for (j = 0; j < brush->numsides; j++)
    406 		{
    407 			brushside = &sin_dbrushsides[brush->firstside + j];
    408 			//
    409 			w = Sin_BrushSideWinding(brush, brushside);
    410 			if (!w)
    411 			{
    412 				sin_dbrushsidetextured[brush->firstside + j] = true;
    413 				continue;
    414 			} //end if
    415 			else
    416 			{
    417 				//RemoveEqualPoints(w, 0.2);
    418 				if (WindingIsTiny(w))
    419 				{
    420 					FreeWinding(w);
    421 					sin_dbrushsidetextured[brush->firstside + j] = true;
    422 					continue;
    423 				} //end if
    424 				else
    425 				{
    426 					we = WindingError(w);
    427 					if (we == WE_NOTENOUGHPOINTS
    428 						|| we == WE_SMALLAREA
    429 						|| we == WE_POINTBOGUSRANGE
    430 //						|| we == WE_NONCONVEX
    431 						)
    432 					{
    433 						FreeWinding(w);
    434 						sin_dbrushsidetextured[brush->firstside + j] = true;
    435 						continue;
    436 					} //end if
    437 				} //end else
    438 			} //end else
    439 			if (WindingArea(w) < 20)
    440 			{
    441 				sin_dbrushsidetextured[brush->firstside + j] = true;
    442 			} //end if
    443 			//find a face for texturing this brush
    444 			for (k = 0; k < sin_numfaces; k++)
    445 			{
    446 				face = &sin_dfaces[k];
    447 				//if the face is in the same plane as the brush side
    448 				if ((face->planenum&~1) != (brushside->planenum&~1)) continue;
    449 				//if the face is partly or totally on the brush side
    450 				if (Sin_FaceOnWinding(face, w))
    451 				{
    452 					brushside->texinfo = face->texinfo;
    453 					sin_dbrushsidetextured[brush->firstside + j] = true;
    454 					break;
    455 				} //end if
    456 			} //end for
    457 			FreeWinding(w);
    458 		} //end for
    459 	} //end for
    460 } //end of the function Sin_FixTextureReferences*/
    461 
    462 /*
    463 ===============
    464 CompressVis
    465 
    466 ===============
    467 */
    468 int Sin_CompressVis (byte *vis, byte *dest)
    469 {
    470 	int		j;
    471 	int		rep;
    472 	int		visrow;
    473 	byte	*dest_p;
    474 	
    475 	dest_p = dest;
    476 //	visrow = (r_numvisleafs + 7)>>3;
    477 	visrow = (sin_dvis->numclusters + 7)>>3;
    478 	
    479 	for (j=0 ; j<visrow ; j++)
    480 	{
    481 		*dest_p++ = vis[j];
    482 		if (vis[j])
    483 			continue;
    484 
    485 		rep = 1;
    486 		for ( j++; j<visrow ; j++)
    487 			if (vis[j] || rep == 255)
    488 				break;
    489 			else
    490 				rep++;
    491 		*dest_p++ = rep;
    492 		j--;
    493 	}
    494 	
    495 	return dest_p - dest;
    496 } //end of the function Sin_CompressVis
    497 
    498 
    499 /*
    500 ===================
    501 DecompressVis
    502 ===================
    503 */
    504 void Sin_DecompressVis (byte *in, byte *decompressed)
    505 {
    506 	int		c;
    507 	byte	*out;
    508 	int		row;
    509 
    510 //	row = (r_numvisleafs+7)>>3;	
    511 	row = (sin_dvis->numclusters+7)>>3;	
    512 	out = decompressed;
    513 
    514 	do
    515 	{
    516 		if (*in)
    517 		{
    518 			*out++ = *in++;
    519 			continue;
    520 		}
    521 	
    522 		c = in[1];
    523 		if (!c)
    524 			Error ("DecompressVis: 0 repeat");
    525 		in += 2;
    526 		while (c)
    527 		{
    528 			*out++ = 0;
    529 			c--;
    530 		}
    531 	} while (out - decompressed < row);
    532 } //end of the function Sin_DecompressVis
    533 
    534 //=============================================================================
    535 
    536 /*
    537 =============
    538 Sin_SwapBSPFile
    539 
    540 Byte swaps all data in a bsp file.
    541 =============
    542 */
    543 void Sin_SwapBSPFile (qboolean todisk)
    544 {
    545 	int				i, j;
    546 	sin_dmodel_t		*d;
    547 
    548 	
    549 // models	
    550 	for (i=0 ; i<sin_nummodels ; i++)
    551 	{
    552 		d = &sin_dmodels[i];
    553 
    554 		d->firstface = LittleLong (d->firstface);
    555 		d->numfaces = LittleLong (d->numfaces);
    556 		d->headnode = LittleLong (d->headnode);
    557 		
    558 		for (j=0 ; j<3 ; j++)
    559 		{
    560 			d->mins[j] = LittleFloat(d->mins[j]);
    561 			d->maxs[j] = LittleFloat(d->maxs[j]);
    562 			d->origin[j] = LittleFloat(d->origin[j]);
    563 		}
    564 	}
    565 
    566 //
    567 // vertexes
    568 //
    569 	for (i=0 ; i<sin_numvertexes ; i++)
    570 	{
    571 		for (j=0 ; j<3 ; j++)
    572 			sin_dvertexes[i].point[j] = LittleFloat (sin_dvertexes[i].point[j]);
    573 	}
    574 		
    575 //
    576 // planes
    577 //	
    578 	for (i=0 ; i<sin_numplanes ; i++)
    579 	{
    580 		for (j=0 ; j<3 ; j++)
    581 			sin_dplanes[i].normal[j] = LittleFloat (sin_dplanes[i].normal[j]);
    582 		sin_dplanes[i].dist = LittleFloat (sin_dplanes[i].dist);
    583 		sin_dplanes[i].type = LittleLong (sin_dplanes[i].type);
    584 	}
    585 	
    586 //
    587 // sin_texinfos
    588 //	
    589 	for (i = 0; i < sin_numtexinfo; i++)
    590 	{
    591 		for (j=0 ; j<8 ; j++)
    592 			sin_texinfo[i].vecs[0][j] = LittleFloat (sin_texinfo[i].vecs[0][j]);
    593 #ifdef SIN
    594       sin_texinfo[i].trans_mag = LittleFloat( sin_texinfo[i].trans_mag );     
    595       sin_texinfo[i].trans_angle = LittleLong( sin_texinfo[i].trans_angle );     
    596       sin_texinfo[i].animtime = LittleFloat( sin_texinfo[i].animtime );     
    597       sin_texinfo[i].nonlit = LittleFloat( sin_texinfo[i].nonlit );     
    598       sin_texinfo[i].translucence = LittleFloat( sin_texinfo[i].translucence );     
    599       sin_texinfo[i].friction = LittleFloat( sin_texinfo[i].friction );     
    600       sin_texinfo[i].restitution = LittleFloat( sin_texinfo[i].restitution );     
    601 		sin_texinfo[i].flags = LittleUnsigned (sin_texinfo[i].flags);
    602 #else
    603 		sin_texinfo[i].value = LittleLong (sin_texinfo[i].value);
    604 		sin_texinfo[i].flags = LittleLong (sin_texinfo[i].flags);
    605 #endif
    606 		sin_texinfo[i].nexttexinfo = LittleLong (sin_texinfo[i].nexttexinfo);
    607 	}
    608 
    609 #ifdef SIN
    610 //
    611 // lightinfos
    612 //	
    613 	for (i = 0; i < sin_numlightinfo; i++)
    614 	{
    615 		for (j=0 ; j<3 ; j++)
    616          {
    617 			sin_lightinfo[i].color[j] = LittleFloat (sin_lightinfo[i].color[j]);
    618          }
    619 		sin_lightinfo[i].value = LittleLong (sin_lightinfo[i].value);
    620       sin_lightinfo[i].direct = LittleFloat( sin_lightinfo[i].direct );     
    621       sin_lightinfo[i].directangle = LittleFloat( sin_lightinfo[i].directangle );     
    622       sin_lightinfo[i].directstyle = LittleFloat( sin_lightinfo[i].directstyle );     
    623 	}
    624 #endif
    625 	
    626 //
    627 // faces
    628 //
    629 	for (i=0 ; i<sin_numfaces ; i++)
    630 	{
    631 		sin_dfaces[i].texinfo = LittleShort (sin_dfaces[i].texinfo);
    632 #ifdef SIN
    633 		sin_dfaces[i].lightinfo = LittleLong (sin_dfaces[i].lightinfo);
    634 		sin_dfaces[i].planenum = LittleUnsignedShort (sin_dfaces[i].planenum);
    635 #else
    636 		sin_dfaces[i].planenum = LittleShort (sin_dfaces[i].planenum);
    637 #endif
    638 		sin_dfaces[i].side = LittleShort (sin_dfaces[i].side);
    639 		sin_dfaces[i].lightofs = LittleLong (sin_dfaces[i].lightofs);
    640 		sin_dfaces[i].firstedge = LittleLong (sin_dfaces[i].firstedge);
    641 		sin_dfaces[i].numedges = LittleShort (sin_dfaces[i].numedges);
    642 	}
    643 
    644 //
    645 // nodes
    646 //
    647 	for (i=0 ; i<sin_numnodes ; i++)
    648 	{
    649 		sin_dnodes[i].planenum = LittleLong (sin_dnodes[i].planenum);
    650 		for (j=0 ; j<3 ; j++)
    651 		{
    652 			sin_dnodes[i].mins[j] = LittleShort (sin_dnodes[i].mins[j]);
    653 			sin_dnodes[i].maxs[j] = LittleShort (sin_dnodes[i].maxs[j]);
    654 		}
    655 		sin_dnodes[i].children[0] = LittleLong (sin_dnodes[i].children[0]);
    656 		sin_dnodes[i].children[1] = LittleLong (sin_dnodes[i].children[1]);
    657 #ifdef SIN
    658 		sin_dnodes[i].firstface = LittleUnsignedShort (sin_dnodes[i].firstface);
    659 		sin_dnodes[i].numfaces = LittleUnsignedShort (sin_dnodes[i].numfaces);
    660 #else
    661 		sin_dnodes[i].firstface = LittleShort (sin_dnodes[i].firstface);
    662 		sin_dnodes[i].numfaces = LittleShort (sin_dnodes[i].numfaces);
    663 #endif
    664 	}
    665 
    666 //
    667 // leafs
    668 //
    669 	for (i=0 ; i<sin_numleafs ; i++)
    670 	{
    671 		sin_dleafs[i].contents = LittleLong (sin_dleafs[i].contents);
    672 		sin_dleafs[i].cluster = LittleShort (sin_dleafs[i].cluster);
    673 		sin_dleafs[i].area = LittleShort (sin_dleafs[i].area);
    674 		for (j=0 ; j<3 ; j++)
    675 		{
    676 			sin_dleafs[i].mins[j] = LittleShort (sin_dleafs[i].mins[j]);
    677 			sin_dleafs[i].maxs[j] = LittleShort (sin_dleafs[i].maxs[j]);
    678 		}
    679 #ifdef SIN
    680 		sin_dleafs[i].firstleafface = LittleUnsignedShort (sin_dleafs[i].firstleafface);
    681 		sin_dleafs[i].numleaffaces = LittleUnsignedShort (sin_dleafs[i].numleaffaces);
    682 		sin_dleafs[i].firstleafbrush = LittleUnsignedShort (sin_dleafs[i].firstleafbrush);
    683 		sin_dleafs[i].numleafbrushes = LittleUnsignedShort (sin_dleafs[i].numleafbrushes);
    684 #else
    685 		sin_dleafs[i].firstleafface = LittleShort (sin_dleafs[i].firstleafface);
    686 		sin_dleafs[i].numleaffaces = LittleShort (sin_dleafs[i].numleaffaces);
    687 		sin_dleafs[i].firstleafbrush = LittleShort (sin_dleafs[i].firstleafbrush);
    688 		sin_dleafs[i].numleafbrushes = LittleShort (sin_dleafs[i].numleafbrushes);
    689 #endif
    690 	}
    691 
    692 //
    693 // leaffaces
    694 //
    695 	for (i=0 ; i<sin_numleaffaces ; i++)
    696 		sin_dleaffaces[i] = LittleShort (sin_dleaffaces[i]);
    697 
    698 //
    699 // leafbrushes
    700 //
    701 	for (i=0 ; i<sin_numleafbrushes ; i++)
    702 		sin_dleafbrushes[i] = LittleShort (sin_dleafbrushes[i]);
    703 
    704 //
    705 // surfedges
    706 //
    707 	for (i=0 ; i<sin_numsurfedges ; i++)
    708 		sin_dsurfedges[i] = LittleLong (sin_dsurfedges[i]);
    709 
    710 //
    711 // edges
    712 //
    713 	for (i=0 ; i<sin_numedges ; i++)
    714 	{
    715 #ifdef SIN
    716 		sin_dedges[i].v[0] = LittleUnsignedShort (sin_dedges[i].v[0]);
    717 		sin_dedges[i].v[1] = LittleUnsignedShort (sin_dedges[i].v[1]);
    718 #else
    719 		sin_dedges[i].v[0] = LittleShort (sin_dedges[i].v[0]);
    720 		sin_dedges[i].v[1] = LittleShort (sin_dedges[i].v[1]);
    721 #endif
    722 	}
    723 
    724 //
    725 // brushes
    726 //
    727 	for (i=0 ; i<sin_numbrushes ; i++)
    728 	{
    729 		sin_dbrushes[i].firstside = LittleLong (sin_dbrushes[i].firstside);
    730 		sin_dbrushes[i].numsides = LittleLong (sin_dbrushes[i].numsides);
    731 		sin_dbrushes[i].contents = LittleLong (sin_dbrushes[i].contents);
    732 	}
    733 
    734 //
    735 // areas
    736 //
    737 	for (i=0 ; i<sin_numareas ; i++)
    738 	{
    739 		sin_dareas[i].numareaportals = LittleLong (sin_dareas[i].numareaportals);
    740 		sin_dareas[i].firstareaportal = LittleLong (sin_dareas[i].firstareaportal);
    741 	}
    742 
    743 //
    744 // areasportals
    745 //
    746 	for (i=0 ; i<sin_numareaportals ; i++)
    747 	{
    748 		sin_dareaportals[i].portalnum = LittleLong (sin_dareaportals[i].portalnum);
    749 		sin_dareaportals[i].otherarea = LittleLong (sin_dareaportals[i].otherarea);
    750 	}
    751 
    752 //
    753 // brushsides
    754 //
    755 	for (i=0 ; i<sin_numbrushsides ; i++)
    756 	{
    757 #ifdef SIN
    758 		sin_dbrushsides[i].planenum = LittleUnsignedShort (sin_dbrushsides[i].planenum);
    759 #else
    760 		sin_dbrushsides[i].planenum = LittleShort (sin_dbrushsides[i].planenum);
    761 #endif
    762 		sin_dbrushsides[i].texinfo = LittleShort (sin_dbrushsides[i].texinfo);
    763 #ifdef SIN
    764 		sin_dbrushsides[i].lightinfo = LittleLong (sin_dbrushsides[i].lightinfo);
    765 #endif
    766 	}
    767 
    768 //
    769 // visibility
    770 //
    771 	if (todisk)
    772 		j = sin_dvis->numclusters;
    773 	else
    774 		j = LittleLong(sin_dvis->numclusters);
    775 	sin_dvis->numclusters = LittleLong (sin_dvis->numclusters);
    776 	for (i=0 ; i<j ; i++)
    777 	{
    778 		sin_dvis->bitofs[i][0] = LittleLong (sin_dvis->bitofs[i][0]);
    779 		sin_dvis->bitofs[i][1] = LittleLong (sin_dvis->bitofs[i][1]);
    780 	}
    781 } //end of the function Sin_SwapBSPFile
    782 
    783 
    784 sin_dheader_t	*header;
    785 #ifdef SIN
    786 int Sin_CopyLump (int lump, void *dest, int size, int maxsize)
    787 {
    788 	int		length, ofs;
    789 
    790 	length = header->lumps[lump].filelen;
    791 	ofs = header->lumps[lump].fileofs;
    792 	
    793 	if (length % size)
    794 		Error ("Sin_LoadBSPFile: odd lump size");
    795 
    796    if ((length/size) > maxsize)
    797       Error ("Sin_LoadBSPFile: exceeded max size for lump %d size %d > maxsize %d\n", lump, (length/size), maxsize );
    798 	
    799 	memcpy (dest, (byte *)header + ofs, length);
    800 
    801 	return length / size;
    802 }
    803 #else
    804 int Sin_CopyLump (int lump, void *dest, int size)
    805 {
    806 	int		length, ofs;
    807 
    808 	length = header->lumps[lump].filelen;
    809 	ofs = header->lumps[lump].fileofs;
    810 	
    811 	if (length % size)
    812 		Error ("Sin_LoadBSPFile: odd lump size");
    813 	
    814 	memcpy (dest, (byte *)header + ofs, length);
    815 
    816 	return length / size;
    817 }
    818 #endif
    819 
    820 /*
    821 =============
    822 Sin_LoadBSPFile
    823 =============
    824 */
    825 void	Sin_LoadBSPFile(char *filename, int offset, int length)
    826 {
    827 	int			i;
    828 	
    829 //
    830 // load the file header
    831 //
    832 	LoadFile (filename, (void **)&header, offset, length);
    833 
    834 // swap the header
    835 	for (i=0 ; i< sizeof(sin_dheader_t)/4 ; i++)
    836 		((int *)header)[i] = LittleLong ( ((int *)header)[i]);
    837 
    838 	if (header->ident != SIN_BSPHEADER && header->ident != SINGAME_BSPHEADER)
    839 		Error ("%s is not a IBSP file", filename);
    840 	if (header->version != SIN_BSPVERSION && header->version != SINGAME_BSPVERSION)
    841 		Error ("%s is version %i, not %i", filename, header->version, SIN_BSPVERSION);
    842 
    843 #ifdef SIN
    844 	sin_nummodels = Sin_CopyLump (SIN_LUMP_MODELS, sin_dmodels, sizeof(sin_dmodel_t), SIN_MAX_MAP_MODELS);
    845 	sin_numvertexes = Sin_CopyLump (SIN_LUMP_VERTEXES, sin_dvertexes, sizeof(sin_dvertex_t), SIN_MAX_MAP_VERTS);
    846 	sin_numplanes = Sin_CopyLump (SIN_LUMP_PLANES, sin_dplanes, sizeof(sin_dplane_t), SIN_MAX_MAP_PLANES);
    847 	sin_numleafs = Sin_CopyLump (SIN_LUMP_LEAFS, sin_dleafs, sizeof(sin_dleaf_t), SIN_MAX_MAP_LEAFS);
    848 	sin_numnodes = Sin_CopyLump (SIN_LUMP_NODES, sin_dnodes, sizeof(sin_dnode_t), SIN_MAX_MAP_NODES);
    849 	sin_numtexinfo = Sin_CopyLump (SIN_LUMP_TEXINFO, sin_texinfo, sizeof(sin_texinfo_t), SIN_MAX_MAP_TEXINFO);
    850 	sin_numfaces = Sin_CopyLump (SIN_LUMP_FACES, sin_dfaces, sizeof(sin_dface_t), SIN_MAX_MAP_FACES);
    851 	sin_numleaffaces = Sin_CopyLump (SIN_LUMP_LEAFFACES, sin_dleaffaces, sizeof(sin_dleaffaces[0]), SIN_MAX_MAP_LEAFFACES);
    852 	sin_numleafbrushes = Sin_CopyLump (SIN_LUMP_LEAFBRUSHES, sin_dleafbrushes, sizeof(sin_dleafbrushes[0]), SIN_MAX_MAP_LEAFBRUSHES);
    853 	sin_numsurfedges = Sin_CopyLump (SIN_LUMP_SURFEDGES, sin_dsurfedges, sizeof(sin_dsurfedges[0]), SIN_MAX_MAP_SURFEDGES);
    854 	sin_numedges = Sin_CopyLump (SIN_LUMP_EDGES, sin_dedges, sizeof(sin_dedge_t), SIN_MAX_MAP_EDGES);
    855 	sin_numbrushes = Sin_CopyLump (SIN_LUMP_BRUSHES, sin_dbrushes, sizeof(sin_dbrush_t), SIN_MAX_MAP_BRUSHES);
    856 	sin_numbrushsides = Sin_CopyLump (SIN_LUMP_BRUSHSIDES, sin_dbrushsides, sizeof(sin_dbrushside_t), SIN_MAX_MAP_BRUSHSIDES);
    857 	sin_numareas = Sin_CopyLump (SIN_LUMP_AREAS, sin_dareas, sizeof(sin_darea_t), SIN_MAX_MAP_AREAS);
    858 	sin_numareaportals = Sin_CopyLump (SIN_LUMP_AREAPORTALS, sin_dareaportals, sizeof(sin_dareaportal_t), SIN_MAX_MAP_AREAPORTALS);
    859 	sin_numlightinfo = Sin_CopyLump (SIN_LUMP_LIGHTINFO, sin_lightinfo, sizeof(sin_lightvalue_t), SIN_MAX_MAP_LIGHTINFO);
    860 
    861 	sin_visdatasize = Sin_CopyLump (SIN_LUMP_VISIBILITY, sin_dvisdata, 1, SIN_MAX_MAP_VISIBILITY);
    862 	sin_lightdatasize = Sin_CopyLump (SIN_LUMP_LIGHTING, sin_dlightdata, 1, SIN_MAX_MAP_LIGHTING);
    863 	sin_entdatasize = Sin_CopyLump (SIN_LUMP_ENTITIES, sin_dentdata, 1, SIN_MAX_MAP_ENTSTRING);
    864 
    865 	Sin_CopyLump (SIN_LUMP_POP, sin_dpop, 1, sizeof(sin_dpop));
    866 #else
    867 	sin_nummodels = Sin_CopyLump (SIN_LUMP_MODELS, sin_dmodels, sizeof(sin_dmodel_t));
    868 	sin_numvertexes = Sin_CopyLump (SIN_LUMP_VERTEXES, sin_dvertexes, sizeof(sin_dvertex_t));
    869 	sin_numplanes = Sin_CopyLump (SIN_LUMP_PLANES, sin_dplanes, sizeof(sin_dplane_t));
    870 	sin_numleafs = Sin_CopyLump (SIN_LUMP_LEAFS, sin_dleafs, sizeof(sin_dleaf_t));
    871 	sin_numnodes = Sin_CopyLump (SIN_LUMP_NODES, sin_dnodes, sizeof(sin_dnode_t));
    872 	sin_numtexinfo = Sin_CopyLump (SIN_LUMP_TEXINFO, sin_texinfo, sizeof(sin_texinfo_t));
    873 	sin_numfaces = Sin_CopyLump (SIN_LUMP_FACES, sin_dfaces, sizeof(sin_dface_t));
    874 	sin_numleaffaces = Sin_CopyLump (SIN_LUMP_LEAFFACES, sin_dleaffaces, sizeof(sin_dleaffaces[0]));
    875 	sin_numleafbrushes = Sin_CopyLump (SIN_LUMP_LEAFBRUSHES, sin_dleafbrushes, sizeof(sin_dleafbrushes[0]));
    876 	sin_numsurfedges = Sin_CopyLump (SIN_LUMP_SURFEDGES, sin_dsurfedges, sizeof(sin_dsurfedges[0]));
    877 	sin_numedges = Sin_CopyLump (SIN_LUMP_EDGES, sin_dedges, sizeof(sin_dedge_t));
    878 	sin_numbrushes = Sin_CopyLump (SIN_LUMP_BRUSHES, sin_dbrushes, sizeof(sin_dbrush_t));
    879 	sin_numbrushsides = Sin_CopyLump (SIN_LUMP_BRUSHSIDES, sin_dbrushsides, sizeof(sin_dbrushside_t));
    880 	sin_numareas = Sin_CopyLump (SIN_LUMP_AREAS, sin_dareas, sizeof(sin_darea_t));
    881 	sin_numareaportals = Sin_CopyLump (SIN_LUMP_AREAPORTALS, sin_dareaportals, sizeof(sin_dareaportal_t));
    882 
    883 	sin_visdatasize = Sin_CopyLump (SIN_LUMP_VISIBILITY, sin_dvisdata, 1);
    884 	sin_lightdatasize = Sin_CopyLump (SIN_LUMP_LIGHTING, sin_dlightdata, 1);
    885 	sin_entdatasize = Sin_CopyLump (SIN_LUMP_ENTITIES, sin_dentdata, 1);
    886 
    887 	Sin_CopyLump (SIN_LUMP_POP, sin_dpop, 1);
    888 #endif
    889 
    890 	FreeMemory(header);		// everything has been copied out
    891 		
    892 //
    893 // swap everything
    894 //	
    895 	Sin_SwapBSPFile (false);
    896 } //end of the function Sin_LoadBSPFile
    897 
    898 /*
    899 =============
    900 Sin_LoadBSPFilesTexinfo
    901 
    902 Only loads the sin_texinfo lump, so qdata can scan for textures
    903 =============
    904 */
    905 void	Sin_LoadBSPFileTexinfo (char *filename)
    906 {
    907 	int			i;
    908 	FILE		*f;
    909 	int		length, ofs;
    910 
    911 	header = GetMemory(sizeof(sin_dheader_t));
    912 
    913 	f = fopen (filename, "rb");
    914 	fread (header, sizeof(sin_dheader_t), 1, f);
    915 
    916 // swap the header
    917 	for (i=0 ; i< sizeof(sin_dheader_t)/4 ; i++)
    918 		((int *)header)[i] = LittleLong ( ((int *)header)[i]);
    919 
    920 	if (header->ident != SIN_BSPHEADER && header->ident != SINGAME_BSPHEADER)
    921 		Error ("%s is not a IBSP file", filename);
    922 	if (header->version != SIN_BSPVERSION && header->version != SINGAME_BSPVERSION)
    923 		Error ("%s is version %i, not %i", filename, header->version, SIN_BSPVERSION);
    924 
    925 
    926 	length = header->lumps[SIN_LUMP_TEXINFO].filelen;
    927 	ofs = header->lumps[SIN_LUMP_TEXINFO].fileofs;
    928 
    929 	fseek (f, ofs, SEEK_SET);
    930 	fread (sin_texinfo, length, 1, f);
    931 	fclose (f);
    932 
    933 	sin_numtexinfo = length / sizeof(sin_texinfo_t);
    934 
    935 	FreeMemory(header);		// everything has been copied out
    936 		
    937 	Sin_SwapBSPFile (false);
    938 } //end of the function Sin_LoadBSPFilesTexinfo
    939 
    940 
    941 //============================================================================
    942 
    943 FILE		*wadfile;
    944 sin_dheader_t	outheader;
    945 
    946 #ifdef SIN
    947 void Sin_AddLump (int lumpnum, void *data, int len, int size, int maxsize)
    948 {
    949 	sin_lump_t *lump;
    950 	int totallength;
    951 
    952 	totallength = len*size;
    953 
    954 	if (len > maxsize)
    955 		Error ("Sin_WriteBSPFile: exceeded max size for lump %d size %d > maxsize %d\n", lumpnum, len, maxsize );
    956 
    957 	lump = &header->lumps[lumpnum];
    958 	
    959 	lump->fileofs = LittleLong( ftell(wadfile) );
    960 	lump->filelen = LittleLong(totallength);
    961 	SafeWrite (wadfile, data, (totallength+3)&~3);
    962 }
    963 #else
    964 void Sin_AddLump (int lumpnum, void *data, int len)
    965 {
    966 	sin_lump_t *lump;
    967 
    968 	lump = &header->lumps[lumpnum];
    969 	
    970 	lump->fileofs = LittleLong( ftell(wadfile) );
    971 	lump->filelen = LittleLong(len);
    972 	SafeWrite (wadfile, data, (len+3)&~3);
    973 }
    974 #endif
    975 /*
    976 =============
    977 Sin_WriteBSPFile
    978 
    979 Swaps the bsp file in place, so it should not be referenced again
    980 =============
    981 */
    982 void	Sin_WriteBSPFile (char *filename)
    983 {		
    984 	header = &outheader;
    985 	memset (header, 0, sizeof(sin_dheader_t));
    986 	
    987 	Sin_SwapBSPFile (true);
    988 
    989 	header->ident = LittleLong (SIN_BSPHEADER);
    990 	header->version = LittleLong (SIN_BSPVERSION);
    991 	
    992 	wadfile = SafeOpenWrite (filename);
    993 	SafeWrite (wadfile, header, sizeof(sin_dheader_t));	// overwritten later
    994 
    995 #ifdef SIN
    996 	Sin_AddLump (SIN_LUMP_PLANES, sin_dplanes, sin_numplanes, sizeof(sin_dplane_t), SIN_MAX_MAP_PLANES);
    997 	Sin_AddLump (SIN_LUMP_LEAFS, sin_dleafs, sin_numleafs, sizeof(sin_dleaf_t), SIN_MAX_MAP_LEAFS);
    998 	Sin_AddLump (SIN_LUMP_VERTEXES, sin_dvertexes, sin_numvertexes, sizeof(sin_dvertex_t), SIN_MAX_MAP_VERTS);
    999 	Sin_AddLump (SIN_LUMP_NODES, sin_dnodes, sin_numnodes, sizeof(sin_dnode_t), SIN_MAX_MAP_NODES);
   1000 	Sin_AddLump (SIN_LUMP_TEXINFO, sin_texinfo, sin_numtexinfo, sizeof(sin_texinfo_t), SIN_MAX_MAP_TEXINFO);
   1001 	Sin_AddLump (SIN_LUMP_FACES, sin_dfaces, sin_numfaces, sizeof(sin_dface_t), SIN_MAX_MAP_FACES);
   1002 	Sin_AddLump (SIN_LUMP_BRUSHES, sin_dbrushes, sin_numbrushes, sizeof(sin_dbrush_t), SIN_MAX_MAP_BRUSHES);
   1003 	Sin_AddLump (SIN_LUMP_BRUSHSIDES, sin_dbrushsides, sin_numbrushsides, sizeof(sin_dbrushside_t), SIN_MAX_MAP_BRUSHSIDES);
   1004 	Sin_AddLump (SIN_LUMP_LEAFFACES, sin_dleaffaces, sin_numleaffaces, sizeof(sin_dleaffaces[0]), SIN_MAX_MAP_LEAFFACES);
   1005 	Sin_AddLump (SIN_LUMP_LEAFBRUSHES, sin_dleafbrushes, sin_numleafbrushes, sizeof(sin_dleafbrushes[0]), SIN_MAX_MAP_LEAFBRUSHES);
   1006 	Sin_AddLump (SIN_LUMP_SURFEDGES, sin_dsurfedges, sin_numsurfedges, sizeof(sin_dsurfedges[0]), SIN_MAX_MAP_SURFEDGES);
   1007 	Sin_AddLump (SIN_LUMP_EDGES, sin_dedges, sin_numedges, sizeof(sin_dedge_t), SIN_MAX_MAP_EDGES);
   1008 	Sin_AddLump (SIN_LUMP_MODELS, sin_dmodels, sin_nummodels, sizeof(sin_dmodel_t), SIN_MAX_MAP_MODELS);
   1009 	Sin_AddLump (SIN_LUMP_AREAS, sin_dareas, sin_numareas, sizeof(sin_darea_t), SIN_MAX_MAP_AREAS);
   1010 	Sin_AddLump (SIN_LUMP_AREAPORTALS, sin_dareaportals, sin_numareaportals, sizeof(sin_dareaportal_t), SIN_MAX_MAP_AREAPORTALS);
   1011 	Sin_AddLump (SIN_LUMP_LIGHTINFO, sin_lightinfo, sin_numlightinfo, sizeof(sin_lightvalue_t), SIN_MAX_MAP_LIGHTINFO);
   1012 
   1013 	Sin_AddLump (SIN_LUMP_LIGHTING, sin_dlightdata, sin_lightdatasize, 1, SIN_MAX_MAP_LIGHTING);
   1014 	Sin_AddLump (SIN_LUMP_VISIBILITY, sin_dvisdata, sin_visdatasize, 1, SIN_MAX_MAP_VISIBILITY);
   1015 	Sin_AddLump (SIN_LUMP_ENTITIES, sin_dentdata, sin_entdatasize, 1, SIN_MAX_MAP_ENTSTRING);
   1016 	Sin_AddLump (SIN_LUMP_POP, sin_dpop, sizeof(sin_dpop), 1, sizeof(sin_dpop));
   1017 #else
   1018 	Sin_AddLump (SIN_LUMP_PLANES, sin_dplanes, sin_numplanes*sizeof(sin_dplane_t));
   1019 	Sin_AddLump (SIN_LUMP_LEAFS, sin_dleafs, sin_numleafs*sizeof(sin_dleaf_t));
   1020 	Sin_AddLump (SIN_LUMP_VERTEXES, sin_dvertexes, sin_numvertexes*sizeof(sin_dvertex_t));
   1021 	Sin_AddLump (SIN_LUMP_NODES, sin_dnodes, sin_numnodes*sizeof(sin_dnode_t));
   1022 	Sin_AddLump (SIN_LUMP_TEXINFO, sin_texinfo, sin_numtexinfo*sizeof(sin_texinfo_t));
   1023 	Sin_AddLump (SIN_LUMP_FACES, sin_dfaces, sin_numfaces*sizeof(sin_dface_t));
   1024 	Sin_AddLump (SIN_LUMP_BRUSHES, sin_dbrushes, sin_numbrushes*sizeof(sin_dbrush_t));
   1025 	Sin_AddLump (SIN_LUMP_BRUSHSIDES, sin_dbrushsides, sin_numbrushsides*sizeof(sin_dbrushside_t));
   1026 	Sin_AddLump (SIN_LUMP_LEAFFACES, sin_dleaffaces, sin_numleaffaces*sizeof(sin_dleaffaces[0]));
   1027 	Sin_AddLump (SIN_LUMP_LEAFBRUSHES, sin_dleafbrushes, sin_numleafbrushes*sizeof(sin_dleafbrushes[0]));
   1028 	Sin_AddLump (SIN_LUMP_SURFEDGES, sin_dsurfedges, sin_numsurfedges*sizeof(sin_dsurfedges[0]));
   1029 	Sin_AddLump (SIN_LUMP_EDGES, sin_dedges, sin_numedges*sizeof(sin_dedge_t));
   1030 	Sin_AddLump (SIN_LUMP_MODELS, sin_dmodels, sin_nummodels*sizeof(sin_dmodel_t));
   1031 	Sin_AddLump (SIN_LUMP_AREAS, sin_dareas, sin_numareas*sizeof(sin_darea_t));
   1032 	Sin_AddLump (SIN_LUMP_AREAPORTALS, sin_dareaportals, sin_numareaportals*sizeof(sin_dareaportal_t));
   1033 
   1034 	Sin_AddLump (SIN_LUMP_LIGHTING, sin_dlightdata, sin_lightdatasize);
   1035 	Sin_AddLump (SIN_LUMP_VISIBILITY, sin_dvisdata, sin_visdatasize);
   1036 	Sin_AddLump (SIN_LUMP_ENTITIES, sin_dentdata, sin_entdatasize);
   1037 	Sin_AddLump (SIN_LUMP_POP, sin_dpop, sizeof(sin_dpop));
   1038 #endif
   1039 	
   1040 	fseek (wadfile, 0, SEEK_SET);
   1041 	SafeWrite (wadfile, header, sizeof(sin_dheader_t));
   1042 	fclose (wadfile);	
   1043 }
   1044 
   1045 //============================================================================
   1046 
   1047 
   1048 //============================================
   1049 
   1050 /*
   1051 ================
   1052 ParseEntities
   1053 
   1054 Parses the sin_dentdata string into entities
   1055 ================
   1056 */
   1057 void Sin_ParseEntities (void)
   1058 {
   1059 	script_t *script;
   1060 
   1061 	num_entities = 0;
   1062 	script = LoadScriptMemory(sin_dentdata, sin_entdatasize, "*sin bsp file");
   1063 	SetScriptFlags(script, SCFL_NOSTRINGWHITESPACES |
   1064 									SCFL_NOSTRINGESCAPECHARS);
   1065 
   1066 	while(ParseEntity(script))
   1067 	{
   1068 	} //end while
   1069 
   1070 	FreeScript(script);
   1071 } //end of the function Sin_ParseEntities
   1072 
   1073 
   1074 /*
   1075 ================
   1076 UnparseEntities
   1077 
   1078 Generates the sin_dentdata string from all the entities
   1079 ================
   1080 */
   1081 void Sin_UnparseEntities (void)
   1082 {
   1083 	char	*buf, *end;
   1084 	epair_t	*ep;
   1085 	char	line[2048];
   1086 	int		i;
   1087 	char	key[1024], value[1024];
   1088 
   1089 	buf = sin_dentdata;
   1090 	end = buf;
   1091 	*end = 0;
   1092 	
   1093 	for (i=0 ; i<num_entities ; i++)
   1094 	{
   1095 		ep = entities[i].epairs;
   1096 		if (!ep)
   1097 			continue;	// ent got removed
   1098 		
   1099 		strcat (end,"{\n");
   1100 		end += 2;
   1101 				
   1102 		for (ep = entities[i].epairs ; ep ; ep=ep->next)
   1103 		{
   1104 			strcpy (key, ep->key);
   1105 			StripTrailing (key);
   1106 			strcpy (value, ep->value);
   1107 			StripTrailing (value);
   1108 				
   1109 			sprintf (line, "\"%s\" \"%s\"\n", key, value);
   1110 			strcat (end, line);
   1111 			end += strlen(line);
   1112 		}
   1113 		strcat (end,"}\n");
   1114 		end += 2;
   1115 
   1116 		if (end > buf + SIN_MAX_MAP_ENTSTRING)
   1117 			Error ("Entity text too long");
   1118 	}
   1119 	sin_entdatasize = end - buf + 1;
   1120 } //end of the function Sin_UnparseEntities
   1121 
   1122 #ifdef SIN
   1123 void  FreeValueKeys(entity_t *ent)
   1124 {
   1125 	epair_t	*ep,*next;
   1126 
   1127 	for (ep=ent->epairs ; ep ; ep=next)
   1128 	{
   1129 		next = ep->next;
   1130 		FreeMemory(ep->value);
   1131 		FreeMemory(ep->key);
   1132 		FreeMemory(ep);
   1133 	}
   1134 	ent->epairs = NULL;
   1135 }
   1136 #endif
   1137 
   1138 /*
   1139 =============
   1140 Sin_PrintBSPFileSizes
   1141 
   1142 Dumps info about current file
   1143 =============
   1144 */
   1145 void Sin_PrintBSPFileSizes (void)
   1146 {
   1147 	if (!num_entities)
   1148 		Sin_ParseEntities ();
   1149 
   1150 	Log_Print("%6i models       %7i\n"
   1151 		,sin_nummodels, (int)(sin_nummodels*sizeof(sin_dmodel_t)));
   1152 	Log_Print("%6i brushes      %7i\n"
   1153 		,sin_numbrushes, (int)(sin_numbrushes*sizeof(sin_dbrush_t)));
   1154 	Log_Print("%6i brushsides   %7i\n"
   1155 		,sin_numbrushsides, (int)(sin_numbrushsides*sizeof(sin_dbrushside_t)));
   1156 	Log_Print("%6i planes       %7i\n"
   1157 		,sin_numplanes, (int)(sin_numplanes*sizeof(sin_dplane_t)));
   1158 	Log_Print("%6i texinfo      %7i\n"
   1159 		,sin_numtexinfo, (int)(sin_numtexinfo*sizeof(sin_texinfo_t)));
   1160 #ifdef SIN
   1161 	Log_Print("%6i lightinfo    %7i\n"
   1162 		,sin_numlightinfo, (int)(sin_numlightinfo*sizeof(sin_lightvalue_t)));
   1163 #endif
   1164 	Log_Print("%6i entdata      %7i\n", num_entities, sin_entdatasize);
   1165 
   1166 	Log_Print("\n");
   1167 
   1168 	Log_Print("%6i vertexes     %7i\n"
   1169 		,sin_numvertexes, (int)(sin_numvertexes*sizeof(sin_dvertex_t)));
   1170 	Log_Print("%6i nodes        %7i\n"
   1171 		,sin_numnodes, (int)(sin_numnodes*sizeof(sin_dnode_t)));
   1172 	Log_Print("%6i faces        %7i\n"
   1173 		,sin_numfaces, (int)(sin_numfaces*sizeof(sin_dface_t)));
   1174 	Log_Print("%6i leafs        %7i\n"
   1175 		,sin_numleafs, (int)(sin_numleafs*sizeof(sin_dleaf_t)));
   1176 	Log_Print("%6i leaffaces    %7i\n"
   1177 		,sin_numleaffaces, (int)(sin_numleaffaces*sizeof(sin_dleaffaces[0])));
   1178 	Log_Print("%6i leafbrushes  %7i\n"
   1179 		,sin_numleafbrushes, (int)(sin_numleafbrushes*sizeof(sin_dleafbrushes[0])));
   1180 	Log_Print("%6i surfedges    %7i\n"
   1181 		,sin_numsurfedges, (int)(sin_numsurfedges*sizeof(sin_dsurfedges[0])));
   1182 	Log_Print("%6i edges        %7i\n"
   1183 		,sin_numedges, (int)(sin_numedges*sizeof(sin_dedge_t)));
   1184 	Log_Print("       lightdata    %7i\n", sin_lightdatasize);
   1185 	Log_Print("       visdata      %7i\n", sin_visdatasize);
   1186 }