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