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 }