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