aas_file.c (21783B)
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 "qbsp.h" 24 #include "../botlib/aasfile.h" 25 #include "aas_file.h" 26 #include "aas_store.h" 27 #include "aas_create.h" 28 29 #define AAS_Error Error 30 31 //=========================================================================== 32 // 33 // Parameter: - 34 // Returns: - 35 // Changes Globals: - 36 //=========================================================================== 37 void AAS_SwapAASData(void) 38 { 39 int i, j; 40 //bounding boxes 41 for (i = 0; i < aasworld.numbboxes; i++) 42 { 43 aasworld.bboxes[i].presencetype = LittleLong(aasworld.bboxes[i].presencetype); 44 aasworld.bboxes[i].flags = LittleLong(aasworld.bboxes[i].flags); 45 for (j = 0; j < 3; j++) 46 { 47 aasworld.bboxes[i].mins[j] = LittleLong(aasworld.bboxes[i].mins[j]); 48 aasworld.bboxes[i].maxs[j] = LittleLong(aasworld.bboxes[i].maxs[j]); 49 } //end for 50 } //end for 51 //vertexes 52 for (i = 0; i < aasworld.numvertexes; i++) 53 { 54 for (j = 0; j < 3; j++) 55 aasworld.vertexes[i][j] = LittleFloat(aasworld.vertexes[i][j]); 56 } //end for 57 //planes 58 for (i = 0; i < aasworld.numplanes; i++) 59 { 60 for (j = 0; j < 3; j++) 61 aasworld.planes[i].normal[j] = LittleFloat(aasworld.planes[i].normal[j]); 62 aasworld.planes[i].dist = LittleFloat(aasworld.planes[i].dist); 63 aasworld.planes[i].type = LittleLong(aasworld.planes[i].type); 64 } //end for 65 //edges 66 for (i = 0; i < aasworld.numedges; i++) 67 { 68 aasworld.edges[i].v[0] = LittleLong(aasworld.edges[i].v[0]); 69 aasworld.edges[i].v[1] = LittleLong(aasworld.edges[i].v[1]); 70 } //end for 71 //edgeindex 72 for (i = 0; i < aasworld.edgeindexsize; i++) 73 { 74 aasworld.edgeindex[i] = LittleLong(aasworld.edgeindex[i]); 75 } //end for 76 //faces 77 for (i = 0; i < aasworld.numfaces; i++) 78 { 79 aasworld.faces[i].planenum = LittleLong(aasworld.faces[i].planenum); 80 aasworld.faces[i].faceflags = LittleLong(aasworld.faces[i].faceflags); 81 aasworld.faces[i].numedges = LittleLong(aasworld.faces[i].numedges); 82 aasworld.faces[i].firstedge = LittleLong(aasworld.faces[i].firstedge); 83 aasworld.faces[i].frontarea = LittleLong(aasworld.faces[i].frontarea); 84 aasworld.faces[i].backarea = LittleLong(aasworld.faces[i].backarea); 85 } //end for 86 //face index 87 for (i = 0; i < aasworld.faceindexsize; i++) 88 { 89 aasworld.faceindex[i] = LittleLong(aasworld.faceindex[i]); 90 } //end for 91 //convex areas 92 for (i = 0; i < aasworld.numareas; i++) 93 { 94 aasworld.areas[i].areanum = LittleLong(aasworld.areas[i].areanum); 95 aasworld.areas[i].numfaces = LittleLong(aasworld.areas[i].numfaces); 96 aasworld.areas[i].firstface = LittleLong(aasworld.areas[i].firstface); 97 for (j = 0; j < 3; j++) 98 { 99 aasworld.areas[i].mins[j] = LittleFloat(aasworld.areas[i].mins[j]); 100 aasworld.areas[i].maxs[j] = LittleFloat(aasworld.areas[i].maxs[j]); 101 aasworld.areas[i].center[j] = LittleFloat(aasworld.areas[i].center[j]); 102 } //end for 103 } //end for 104 //area settings 105 for (i = 0; i < aasworld.numareasettings; i++) 106 { 107 aasworld.areasettings[i].contents = LittleLong(aasworld.areasettings[i].contents); 108 aasworld.areasettings[i].areaflags = LittleLong(aasworld.areasettings[i].areaflags); 109 aasworld.areasettings[i].presencetype = LittleLong(aasworld.areasettings[i].presencetype); 110 aasworld.areasettings[i].cluster = LittleLong(aasworld.areasettings[i].cluster); 111 aasworld.areasettings[i].clusterareanum = LittleLong(aasworld.areasettings[i].clusterareanum); 112 aasworld.areasettings[i].numreachableareas = LittleLong(aasworld.areasettings[i].numreachableareas); 113 aasworld.areasettings[i].firstreachablearea = LittleLong(aasworld.areasettings[i].firstreachablearea); 114 } //end for 115 //area reachability 116 for (i = 0; i < aasworld.reachabilitysize; i++) 117 { 118 aasworld.reachability[i].areanum = LittleLong(aasworld.reachability[i].areanum); 119 aasworld.reachability[i].facenum = LittleLong(aasworld.reachability[i].facenum); 120 aasworld.reachability[i].edgenum = LittleLong(aasworld.reachability[i].edgenum); 121 for (j = 0; j < 3; j++) 122 { 123 aasworld.reachability[i].start[j] = LittleFloat(aasworld.reachability[i].start[j]); 124 aasworld.reachability[i].end[j] = LittleFloat(aasworld.reachability[i].end[j]); 125 } //end for 126 aasworld.reachability[i].traveltype = LittleLong(aasworld.reachability[i].traveltype); 127 aasworld.reachability[i].traveltime = LittleShort(aasworld.reachability[i].traveltime); 128 } //end for 129 //nodes 130 for (i = 0; i < aasworld.numnodes; i++) 131 { 132 aasworld.nodes[i].planenum = LittleLong(aasworld.nodes[i].planenum); 133 aasworld.nodes[i].children[0] = LittleLong(aasworld.nodes[i].children[0]); 134 aasworld.nodes[i].children[1] = LittleLong(aasworld.nodes[i].children[1]); 135 } //end for 136 //cluster portals 137 for (i = 0; i < aasworld.numportals; i++) 138 { 139 aasworld.portals[i].areanum = LittleLong(aasworld.portals[i].areanum); 140 aasworld.portals[i].frontcluster = LittleLong(aasworld.portals[i].frontcluster); 141 aasworld.portals[i].backcluster = LittleLong(aasworld.portals[i].backcluster); 142 aasworld.portals[i].clusterareanum[0] = LittleLong(aasworld.portals[i].clusterareanum[0]); 143 aasworld.portals[i].clusterareanum[1] = LittleLong(aasworld.portals[i].clusterareanum[1]); 144 } //end for 145 //cluster portal index 146 for (i = 0; i < aasworld.portalindexsize; i++) 147 { 148 aasworld.portalindex[i] = LittleLong(aasworld.portalindex[i]); 149 } //end for 150 //cluster 151 for (i = 0; i < aasworld.numclusters; i++) 152 { 153 aasworld.clusters[i].numareas = LittleLong(aasworld.clusters[i].numareas); 154 aasworld.clusters[i].numportals = LittleLong(aasworld.clusters[i].numportals); 155 aasworld.clusters[i].firstportal = LittleLong(aasworld.clusters[i].firstportal); 156 } //end for 157 } //end of the function AAS_SwapAASData 158 //=========================================================================== 159 // dump the current loaded aas file 160 // 161 // Parameter: - 162 // Returns: - 163 // Changes Globals: - 164 //=========================================================================== 165 void AAS_DumpAASData(void) 166 { 167 /* 168 if (aasworld.vertexes) FreeMemory(aasworld.vertexes); 169 aasworld.vertexes = NULL; 170 if (aasworld.planes) FreeMemory(aasworld.planes); 171 aasworld.planes = NULL; 172 if (aasworld.edges) FreeMemory(aasworld.edges); 173 aasworld.edges = NULL; 174 if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex); 175 aasworld.edgeindex = NULL; 176 if (aasworld.faces) FreeMemory(aasworld.faces); 177 aasworld.faces = NULL; 178 if (aasworld.faceindex) FreeMemory(aasworld.faceindex); 179 aasworld.faceindex = NULL; 180 if (aasworld.areas) FreeMemory(aasworld.areas); 181 aasworld.areas = NULL; 182 if (aasworld.areasettings) FreeMemory(aasworld.areasettings); 183 aasworld.areasettings = NULL; 184 if (aasworld.reachability) FreeMemory(aasworld.reachability); 185 aasworld.reachability = NULL; 186 */ 187 aasworld.loaded = false; 188 } //end of the function AAS_DumpAASData 189 //=========================================================================== 190 // allocate memory and read a lump of a AAS file 191 // 192 // Parameter: - 193 // Returns: - 194 // Changes Globals: - 195 //=========================================================================== 196 char *AAS_LoadAASLump(FILE *fp, int offset, int length, void *buf) 197 { 198 if (!length) 199 { 200 printf("lump size 0\n"); 201 return buf; 202 } //end if 203 //seek to the data 204 if (fseek(fp, offset, SEEK_SET)) 205 { 206 AAS_Error("can't seek to lump\n"); 207 AAS_DumpAASData(); 208 fclose(fp); 209 return 0; 210 } //end if 211 //allocate memory 212 if (!buf) buf = (void *) GetClearedMemory(length); 213 //read the data 214 if (fread((char *) buf, 1, length, fp) != length) 215 { 216 AAS_Error("can't read lump\n"); 217 FreeMemory(buf); 218 AAS_DumpAASData(); 219 fclose(fp); 220 return NULL; 221 } //end if 222 return buf; 223 } //end of the function AAS_LoadAASLump 224 //=========================================================================== 225 // 226 // Parameter: - 227 // Returns: - 228 // Changes Globals: - 229 //=========================================================================== 230 void AAS_DData(unsigned char *data, int size) 231 { 232 int i; 233 234 for (i = 0; i < size; i++) 235 { 236 data[i] ^= (unsigned char) i * 119; 237 } //end for 238 } //end of the function AAS_DData 239 //=========================================================================== 240 // load an aas file 241 // 242 // Parameter: - 243 // Returns: - 244 // Changes Globals: - 245 //=========================================================================== 246 qboolean AAS_LoadAASFile(char *filename, int fpoffset, int fplength) 247 { 248 FILE *fp; 249 aas_header_t header; 250 int offset, length; 251 252 //dump current loaded aas file 253 AAS_DumpAASData(); 254 //open the file 255 fp = fopen(filename, "rb"); 256 if (!fp) 257 { 258 AAS_Error("can't open %s\n", filename); 259 return false; 260 } //end if 261 //seek to the correct position (in the pak file) 262 if (fseek(fp, fpoffset, SEEK_SET)) 263 { 264 AAS_Error("can't seek to file %s\n"); 265 fclose(fp); 266 return false; 267 } //end if 268 //read the header 269 if (fread(&header, sizeof(aas_header_t), 1, fp) != 1) 270 { 271 AAS_Error("can't read header of file %s\n", filename); 272 fclose(fp); 273 return false; 274 } //end if 275 //check header identification 276 header.ident = LittleLong(header.ident); 277 if (header.ident != AASID) 278 { 279 AAS_Error("%s is not an AAS file\n", filename); 280 fclose(fp); 281 return false; 282 } //end if 283 //check the version 284 header.version = LittleLong(header.version); 285 if (header.version != AASVERSION_OLD && header.version != AASVERSION) 286 { 287 AAS_Error("%s is version %i, not %i\n", filename, header.version, AASVERSION); 288 fclose(fp); 289 return false; 290 } //end if 291 // 292 if (header.version == AASVERSION) 293 { 294 AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8); 295 } //end if 296 aasworld.bspchecksum = LittleLong(header.bspchecksum); 297 //load the lumps: 298 //bounding boxes 299 offset = fpoffset + LittleLong(header.lumps[AASLUMP_BBOXES].fileofs); 300 length = LittleLong(header.lumps[AASLUMP_BBOXES].filelen); 301 aasworld.bboxes = (aas_bbox_t *) AAS_LoadAASLump(fp, offset, length, aasworld.bboxes); 302 if (!aasworld.bboxes) return false; 303 aasworld.numbboxes = length / sizeof(aas_bbox_t); 304 //vertexes 305 offset = fpoffset + LittleLong(header.lumps[AASLUMP_VERTEXES].fileofs); 306 length = LittleLong(header.lumps[AASLUMP_VERTEXES].filelen); 307 aasworld.vertexes = (aas_vertex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.vertexes); 308 if (!aasworld.vertexes) return false; 309 aasworld.numvertexes = length / sizeof(aas_vertex_t); 310 //planes 311 offset = fpoffset + LittleLong(header.lumps[AASLUMP_PLANES].fileofs); 312 length = LittleLong(header.lumps[AASLUMP_PLANES].filelen); 313 aasworld.planes = (aas_plane_t *) AAS_LoadAASLump(fp, offset, length, aasworld.planes); 314 if (!aasworld.planes) return false; 315 aasworld.numplanes = length / sizeof(aas_plane_t); 316 //edges 317 offset = fpoffset + LittleLong(header.lumps[AASLUMP_EDGES].fileofs); 318 length = LittleLong(header.lumps[AASLUMP_EDGES].filelen); 319 aasworld.edges = (aas_edge_t *) AAS_LoadAASLump(fp, offset, length, aasworld.edges); 320 if (!aasworld.edges) return false; 321 aasworld.numedges = length / sizeof(aas_edge_t); 322 //edgeindex 323 offset = fpoffset + LittleLong(header.lumps[AASLUMP_EDGEINDEX].fileofs); 324 length = LittleLong(header.lumps[AASLUMP_EDGEINDEX].filelen); 325 aasworld.edgeindex = (aas_edgeindex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.edgeindex); 326 if (!aasworld.edgeindex) return false; 327 aasworld.edgeindexsize = length / sizeof(aas_edgeindex_t); 328 //faces 329 offset = fpoffset + LittleLong(header.lumps[AASLUMP_FACES].fileofs); 330 length = LittleLong(header.lumps[AASLUMP_FACES].filelen); 331 aasworld.faces = (aas_face_t *) AAS_LoadAASLump(fp, offset, length, aasworld.faces); 332 if (!aasworld.faces) return false; 333 aasworld.numfaces = length / sizeof(aas_face_t); 334 //faceindex 335 offset = fpoffset + LittleLong(header.lumps[AASLUMP_FACEINDEX].fileofs); 336 length = LittleLong(header.lumps[AASLUMP_FACEINDEX].filelen); 337 aasworld.faceindex = (aas_faceindex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.faceindex); 338 if (!aasworld.faceindex) return false; 339 aasworld.faceindexsize = length / sizeof(int); 340 //convex areas 341 offset = fpoffset + LittleLong(header.lumps[AASLUMP_AREAS].fileofs); 342 length = LittleLong(header.lumps[AASLUMP_AREAS].filelen); 343 aasworld.areas = (aas_area_t *) AAS_LoadAASLump(fp, offset, length, aasworld.areas); 344 if (!aasworld.areas) return false; 345 aasworld.numareas = length / sizeof(aas_area_t); 346 //area settings 347 offset = fpoffset + LittleLong(header.lumps[AASLUMP_AREASETTINGS].fileofs); 348 length = LittleLong(header.lumps[AASLUMP_AREASETTINGS].filelen); 349 aasworld.areasettings = (aas_areasettings_t *) AAS_LoadAASLump(fp, offset, length, aasworld.areasettings); 350 if (!aasworld.areasettings) return false; 351 aasworld.numareasettings = length / sizeof(aas_areasettings_t); 352 //reachability list 353 offset = fpoffset + LittleLong(header.lumps[AASLUMP_REACHABILITY].fileofs); 354 length = LittleLong(header.lumps[AASLUMP_REACHABILITY].filelen); 355 aasworld.reachability = (aas_reachability_t *) AAS_LoadAASLump(fp, offset, length, aasworld.reachability); 356 if (length && !aasworld.reachability) return false; 357 aasworld.reachabilitysize = length / sizeof(aas_reachability_t); 358 //nodes 359 offset = fpoffset + LittleLong(header.lumps[AASLUMP_NODES].fileofs); 360 length = LittleLong(header.lumps[AASLUMP_NODES].filelen); 361 aasworld.nodes = (aas_node_t *) AAS_LoadAASLump(fp, offset, length, aasworld.nodes); 362 if (!aasworld.nodes) return false; 363 aasworld.numnodes = length / sizeof(aas_node_t); 364 //cluster portals 365 offset = fpoffset + LittleLong(header.lumps[AASLUMP_PORTALS].fileofs); 366 length = LittleLong(header.lumps[AASLUMP_PORTALS].filelen); 367 aasworld.portals = (aas_portal_t *) AAS_LoadAASLump(fp, offset, length, aasworld.portals); 368 if (length && !aasworld.portals) return false; 369 aasworld.numportals = length / sizeof(aas_portal_t); 370 //cluster portal index 371 offset = fpoffset + LittleLong(header.lumps[AASLUMP_PORTALINDEX].fileofs); 372 length = LittleLong(header.lumps[AASLUMP_PORTALINDEX].filelen); 373 aasworld.portalindex = (aas_portalindex_t *) AAS_LoadAASLump(fp, offset, length, aasworld.portalindex); 374 if (length && !aasworld.portalindex) return false; 375 aasworld.portalindexsize = length / sizeof(aas_portalindex_t); 376 //clusters 377 offset = fpoffset + LittleLong(header.lumps[AASLUMP_CLUSTERS].fileofs); 378 length = LittleLong(header.lumps[AASLUMP_CLUSTERS].filelen); 379 aasworld.clusters = (aas_cluster_t *) AAS_LoadAASLump(fp, offset, length, aasworld.clusters); 380 if (length && !aasworld.clusters) return false; 381 aasworld.numclusters = length / sizeof(aas_cluster_t); 382 //swap everything 383 AAS_SwapAASData(); 384 //aas file is loaded 385 aasworld.loaded = true; 386 //close the file 387 fclose(fp); 388 return true; 389 } //end of the function AAS_LoadAASFile 390 //=========================================================================== 391 // 392 // Parameter: - 393 // Returns: - 394 // Changes Globals: - 395 //=========================================================================== 396 int AAS_WriteAASLump(FILE *fp, aas_header_t *h, int lumpnum, void *data, int length) 397 { 398 aas_lump_t *lump; 399 400 lump = &h->lumps[lumpnum]; 401 402 lump->fileofs = LittleLong(ftell(fp)); 403 lump->filelen = LittleLong(length); 404 405 if (length > 0) 406 { 407 if (fwrite(data, length, 1, fp) < 1) 408 { 409 Log_Print("error writing lump %s\n", lumpnum); 410 fclose(fp); 411 return false; 412 } //end if 413 } //end if 414 return true; 415 } //end of the function AAS_WriteAASLump 416 //=========================================================================== 417 // 418 // Parameter: - 419 // Returns: - 420 // Changes Globals: - 421 //=========================================================================== 422 void AAS_ShowNumReachabilities(int tt, char *name) 423 { 424 int i, num; 425 426 num = 0; 427 for (i = 0; i < aasworld.reachabilitysize; i++) 428 { 429 if ((aasworld.reachability[i].traveltype & TRAVELTYPE_MASK) == tt) 430 num++; 431 } //end for 432 Log_Print("%6d %s\n", num, name); 433 } //end of the function AAS_ShowNumReachabilities 434 //=========================================================================== 435 // 436 // Parameter: - 437 // Returns: - 438 // Changes Globals: - 439 //=========================================================================== 440 void AAS_ShowTotals(void) 441 { 442 Log_Print("numvertexes = %d\r\n", aasworld.numvertexes); 443 Log_Print("numplanes = %d\r\n", aasworld.numplanes); 444 Log_Print("numedges = %d\r\n", aasworld.numedges); 445 Log_Print("edgeindexsize = %d\r\n", aasworld.edgeindexsize); 446 Log_Print("numfaces = %d\r\n", aasworld.numfaces); 447 Log_Print("faceindexsize = %d\r\n", aasworld.faceindexsize); 448 Log_Print("numareas = %d\r\n", aasworld.numareas); 449 Log_Print("numareasettings = %d\r\n", aasworld.numareasettings); 450 Log_Print("reachabilitysize = %d\r\n", aasworld.reachabilitysize); 451 Log_Print("numnodes = %d\r\n", aasworld.numnodes); 452 Log_Print("numportals = %d\r\n", aasworld.numportals); 453 Log_Print("portalindexsize = %d\r\n", aasworld.portalindexsize); 454 Log_Print("numclusters = %d\r\n", aasworld.numclusters); 455 AAS_ShowNumReachabilities(TRAVEL_WALK, "walk"); 456 AAS_ShowNumReachabilities(TRAVEL_CROUCH, "crouch"); 457 AAS_ShowNumReachabilities(TRAVEL_BARRIERJUMP, "barrier jump"); 458 AAS_ShowNumReachabilities(TRAVEL_JUMP, "jump"); 459 AAS_ShowNumReachabilities(TRAVEL_LADDER, "ladder"); 460 AAS_ShowNumReachabilities(TRAVEL_WALKOFFLEDGE, "walk off ledge"); 461 AAS_ShowNumReachabilities(TRAVEL_SWIM, "swim"); 462 AAS_ShowNumReachabilities(TRAVEL_WATERJUMP, "water jump"); 463 AAS_ShowNumReachabilities(TRAVEL_TELEPORT, "teleport"); 464 AAS_ShowNumReachabilities(TRAVEL_ELEVATOR, "elevator"); 465 AAS_ShowNumReachabilities(TRAVEL_ROCKETJUMP, "rocket jump"); 466 AAS_ShowNumReachabilities(TRAVEL_BFGJUMP, "bfg jump"); 467 AAS_ShowNumReachabilities(TRAVEL_GRAPPLEHOOK, "grapple hook"); 468 AAS_ShowNumReachabilities(TRAVEL_DOUBLEJUMP, "double jump"); 469 AAS_ShowNumReachabilities(TRAVEL_RAMPJUMP, "ramp jump"); 470 AAS_ShowNumReachabilities(TRAVEL_STRAFEJUMP, "strafe jump"); 471 AAS_ShowNumReachabilities(TRAVEL_JUMPPAD, "jump pad"); 472 AAS_ShowNumReachabilities(TRAVEL_FUNCBOB, "func bob"); 473 } //end of the function AAS_ShowTotals 474 //=========================================================================== 475 // aas data is useless after writing to file because it is byte swapped 476 // 477 // Parameter: - 478 // Returns: - 479 // Changes Globals: - 480 //=========================================================================== 481 qboolean AAS_WriteAASFile(char *filename) 482 { 483 aas_header_t header; 484 FILE *fp; 485 486 Log_Print("writing %s\n", filename); 487 AAS_ShowTotals(); 488 //swap the aas data 489 AAS_SwapAASData(); 490 //initialize the file header 491 memset(&header, 0, sizeof(aas_header_t)); 492 header.ident = LittleLong(AASID); 493 header.version = LittleLong(AASVERSION); 494 header.bspchecksum = LittleLong(aasworld.bspchecksum); 495 //open a new file 496 fp = fopen(filename, "wb"); 497 if (!fp) 498 { 499 Log_Print("error opening %s\n", filename); 500 return false; 501 } //end if 502 //write the header 503 if (fwrite(&header, sizeof(aas_header_t), 1, fp) < 1) 504 { 505 fclose(fp); 506 return false; 507 } //end if 508 //add the data lumps to the file 509 if (!AAS_WriteAASLump(fp, &header, AASLUMP_BBOXES, aasworld.bboxes, 510 aasworld.numbboxes * sizeof(aas_bbox_t))) return false; 511 if (!AAS_WriteAASLump(fp, &header, AASLUMP_VERTEXES, aasworld.vertexes, 512 aasworld.numvertexes * sizeof(aas_vertex_t))) return false; 513 if (!AAS_WriteAASLump(fp, &header, AASLUMP_PLANES, aasworld.planes, 514 aasworld.numplanes * sizeof(aas_plane_t))) return false; 515 if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGES, aasworld.edges, 516 aasworld.numedges * sizeof(aas_edge_t))) return false; 517 if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGEINDEX, aasworld.edgeindex, 518 aasworld.edgeindexsize * sizeof(aas_edgeindex_t))) return false; 519 if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACES, aasworld.faces, 520 aasworld.numfaces * sizeof(aas_face_t))) return false; 521 if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACEINDEX, aasworld.faceindex, 522 aasworld.faceindexsize * sizeof(aas_faceindex_t))) return false; 523 if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREAS, aasworld.areas, 524 aasworld.numareas * sizeof(aas_area_t))) return false; 525 if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREASETTINGS, aasworld.areasettings, 526 aasworld.numareasettings * sizeof(aas_areasettings_t))) return false; 527 if (!AAS_WriteAASLump(fp, &header, AASLUMP_REACHABILITY, aasworld.reachability, 528 aasworld.reachabilitysize * sizeof(aas_reachability_t))) return false; 529 if (!AAS_WriteAASLump(fp, &header, AASLUMP_NODES, aasworld.nodes, 530 aasworld.numnodes * sizeof(aas_node_t))) return false; 531 if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALS, aasworld.portals, 532 aasworld.numportals * sizeof(aas_portal_t))) return false; 533 if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALINDEX, aasworld.portalindex, 534 aasworld.portalindexsize * sizeof(aas_portalindex_t))) return false; 535 if (!AAS_WriteAASLump(fp, &header, AASLUMP_CLUSTERS, aasworld.clusters, 536 aasworld.numclusters * sizeof(aas_cluster_t))) return false; 537 //rewrite the header with the added lumps 538 fseek(fp, 0, SEEK_SET); 539 AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8); 540 if (fwrite(&header, sizeof(aas_header_t), 1, fp) < 1) 541 { 542 fclose(fp); 543 return false; 544 } //end if 545 //close the file 546 fclose(fp); 547 return true; 548 } //end of the function AAS_WriteAASFile 549