00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "../game/q_shared.h"
00033 #include "l_memory.h"
00034 #include "l_script.h"
00035 #include "l_precomp.h"
00036 #include "l_struct.h"
00037 #include "l_libvar.h"
00038 #include "l_utils.h"
00039 #include "aasfile.h"
00040 #include "../game/botlib.h"
00041 #include "../game/be_aas.h"
00042 #include "be_aas_funcs.h"
00043 #include "be_interface.h"
00044 #include "be_aas_def.h"
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 void AAS_SwapAASData(void)
00055 {
00056 int i, j;
00057
00058 for (i = 0; i < aasworld.numbboxes; i++)
00059 {
00060 aasworld.bboxes[i].presencetype = LittleLong(aasworld.bboxes[i].presencetype);
00061 aasworld.bboxes[i].flags = LittleLong(aasworld.bboxes[i].flags);
00062 for (j = 0; j < 3; j++)
00063 {
00064 aasworld.bboxes[i].mins[j] = LittleLong(aasworld.bboxes[i].mins[j]);
00065 aasworld.bboxes[i].maxs[j] = LittleLong(aasworld.bboxes[i].maxs[j]);
00066 }
00067 }
00068
00069 for (i = 0; i < aasworld.numvertexes; i++)
00070 {
00071 for (j = 0; j < 3; j++)
00072 aasworld.vertexes[i][j] = LittleFloat(aasworld.vertexes[i][j]);
00073 }
00074
00075 for (i = 0; i < aasworld.numplanes; i++)
00076 {
00077 for (j = 0; j < 3; j++)
00078 aasworld.planes[i].normal[j] = LittleFloat(aasworld.planes[i].normal[j]);
00079 aasworld.planes[i].dist = LittleFloat(aasworld.planes[i].dist);
00080 aasworld.planes[i].type = LittleLong(aasworld.planes[i].type);
00081 }
00082
00083 for (i = 0; i < aasworld.numedges; i++)
00084 {
00085 aasworld.edges[i].v[0] = LittleLong(aasworld.edges[i].v[0]);
00086 aasworld.edges[i].v[1] = LittleLong(aasworld.edges[i].v[1]);
00087 }
00088
00089 for (i = 0; i < aasworld.edgeindexsize; i++)
00090 {
00091 aasworld.edgeindex[i] = LittleLong(aasworld.edgeindex[i]);
00092 }
00093
00094 for (i = 0; i < aasworld.numfaces; i++)
00095 {
00096 aasworld.faces[i].planenum = LittleLong(aasworld.faces[i].planenum);
00097 aasworld.faces[i].faceflags = LittleLong(aasworld.faces[i].faceflags);
00098 aasworld.faces[i].numedges = LittleLong(aasworld.faces[i].numedges);
00099 aasworld.faces[i].firstedge = LittleLong(aasworld.faces[i].firstedge);
00100 aasworld.faces[i].frontarea = LittleLong(aasworld.faces[i].frontarea);
00101 aasworld.faces[i].backarea = LittleLong(aasworld.faces[i].backarea);
00102 }
00103
00104 for (i = 0; i < aasworld.faceindexsize; i++)
00105 {
00106 aasworld.faceindex[i] = LittleLong(aasworld.faceindex[i]);
00107 }
00108
00109 for (i = 0; i < aasworld.numareas; i++)
00110 {
00111 aasworld.areas[i].areanum = LittleLong(aasworld.areas[i].areanum);
00112 aasworld.areas[i].numfaces = LittleLong(aasworld.areas[i].numfaces);
00113 aasworld.areas[i].firstface = LittleLong(aasworld.areas[i].firstface);
00114 for (j = 0; j < 3; j++)
00115 {
00116 aasworld.areas[i].mins[j] = LittleFloat(aasworld.areas[i].mins[j]);
00117 aasworld.areas[i].maxs[j] = LittleFloat(aasworld.areas[i].maxs[j]);
00118 aasworld.areas[i].center[j] = LittleFloat(aasworld.areas[i].center[j]);
00119 }
00120 }
00121
00122 for (i = 0; i < aasworld.numareasettings; i++)
00123 {
00124 aasworld.areasettings[i].contents = LittleLong(aasworld.areasettings[i].contents);
00125 aasworld.areasettings[i].areaflags = LittleLong(aasworld.areasettings[i].areaflags);
00126 aasworld.areasettings[i].presencetype = LittleLong(aasworld.areasettings[i].presencetype);
00127 aasworld.areasettings[i].cluster = LittleLong(aasworld.areasettings[i].cluster);
00128 aasworld.areasettings[i].clusterareanum = LittleLong(aasworld.areasettings[i].clusterareanum);
00129 aasworld.areasettings[i].numreachableareas = LittleLong(aasworld.areasettings[i].numreachableareas);
00130 aasworld.areasettings[i].firstreachablearea = LittleLong(aasworld.areasettings[i].firstreachablearea);
00131 }
00132
00133 for (i = 0; i < aasworld.reachabilitysize; i++)
00134 {
00135 aasworld.reachability[i].areanum = LittleLong(aasworld.reachability[i].areanum);
00136 aasworld.reachability[i].facenum = LittleLong(aasworld.reachability[i].facenum);
00137 aasworld.reachability[i].edgenum = LittleLong(aasworld.reachability[i].edgenum);
00138 for (j = 0; j < 3; j++)
00139 {
00140 aasworld.reachability[i].start[j] = LittleFloat(aasworld.reachability[i].start[j]);
00141 aasworld.reachability[i].end[j] = LittleFloat(aasworld.reachability[i].end[j]);
00142 }
00143 aasworld.reachability[i].traveltype = LittleLong(aasworld.reachability[i].traveltype);
00144 aasworld.reachability[i].traveltime = LittleShort(aasworld.reachability[i].traveltime);
00145 }
00146
00147 for (i = 0; i < aasworld.numnodes; i++)
00148 {
00149 aasworld.nodes[i].planenum = LittleLong(aasworld.nodes[i].planenum);
00150 aasworld.nodes[i].children[0] = LittleLong(aasworld.nodes[i].children[0]);
00151 aasworld.nodes[i].children[1] = LittleLong(aasworld.nodes[i].children[1]);
00152 }
00153
00154 for (i = 0; i < aasworld.numportals; i++)
00155 {
00156 aasworld.portals[i].areanum = LittleLong(aasworld.portals[i].areanum);
00157 aasworld.portals[i].frontcluster = LittleLong(aasworld.portals[i].frontcluster);
00158 aasworld.portals[i].backcluster = LittleLong(aasworld.portals[i].backcluster);
00159 aasworld.portals[i].clusterareanum[0] = LittleLong(aasworld.portals[i].clusterareanum[0]);
00160 aasworld.portals[i].clusterareanum[1] = LittleLong(aasworld.portals[i].clusterareanum[1]);
00161 }
00162
00163 for (i = 0; i < aasworld.portalindexsize; i++)
00164 {
00165 aasworld.portalindex[i] = LittleLong(aasworld.portalindex[i]);
00166 }
00167
00168 for (i = 0; i < aasworld.numclusters; i++)
00169 {
00170 aasworld.clusters[i].numareas = LittleLong(aasworld.clusters[i].numareas);
00171 aasworld.clusters[i].numreachabilityareas = LittleLong(aasworld.clusters[i].numreachabilityareas);
00172 aasworld.clusters[i].numportals = LittleLong(aasworld.clusters[i].numportals);
00173 aasworld.clusters[i].firstportal = LittleLong(aasworld.clusters[i].firstportal);
00174 }
00175 }
00176
00177
00178
00179
00180
00181
00182
00183 void AAS_DumpAASData(void)
00184 {
00185 aasworld.numbboxes = 0;
00186 if (aasworld.bboxes) FreeMemory(aasworld.bboxes);
00187 aasworld.bboxes = NULL;
00188 aasworld.numvertexes = 0;
00189 if (aasworld.vertexes) FreeMemory(aasworld.vertexes);
00190 aasworld.vertexes = NULL;
00191 aasworld.numplanes = 0;
00192 if (aasworld.planes) FreeMemory(aasworld.planes);
00193 aasworld.planes = NULL;
00194 aasworld.numedges = 0;
00195 if (aasworld.edges) FreeMemory(aasworld.edges);
00196 aasworld.edges = NULL;
00197 aasworld.edgeindexsize = 0;
00198 if (aasworld.edgeindex) FreeMemory(aasworld.edgeindex);
00199 aasworld.edgeindex = NULL;
00200 aasworld.numfaces = 0;
00201 if (aasworld.faces) FreeMemory(aasworld.faces);
00202 aasworld.faces = NULL;
00203 aasworld.faceindexsize = 0;
00204 if (aasworld.faceindex) FreeMemory(aasworld.faceindex);
00205 aasworld.faceindex = NULL;
00206 aasworld.numareas = 0;
00207 if (aasworld.areas) FreeMemory(aasworld.areas);
00208 aasworld.areas = NULL;
00209 aasworld.numareasettings = 0;
00210 if (aasworld.areasettings) FreeMemory(aasworld.areasettings);
00211 aasworld.areasettings = NULL;
00212 aasworld.reachabilitysize = 0;
00213 if (aasworld.reachability) FreeMemory(aasworld.reachability);
00214 aasworld.reachability = NULL;
00215 aasworld.numnodes = 0;
00216 if (aasworld.nodes) FreeMemory(aasworld.nodes);
00217 aasworld.nodes = NULL;
00218 aasworld.numportals = 0;
00219 if (aasworld.portals) FreeMemory(aasworld.portals);
00220 aasworld.portals = NULL;
00221 aasworld.numportals = 0;
00222 if (aasworld.portalindex) FreeMemory(aasworld.portalindex);
00223 aasworld.portalindex = NULL;
00224 aasworld.portalindexsize = 0;
00225 if (aasworld.clusters) FreeMemory(aasworld.clusters);
00226 aasworld.clusters = NULL;
00227 aasworld.numclusters = 0;
00228
00229 aasworld.loaded = qfalse;
00230 aasworld.initialized = qfalse;
00231 aasworld.savefile = qfalse;
00232 }
00233
00234
00235
00236
00237
00238
00239 #ifdef AASFILEDEBUG
00240 void AAS_FileInfo(void)
00241 {
00242 int i, n, optimized;
00243
00244 botimport.Print(PRT_MESSAGE, "version = %d\n", AASVERSION);
00245 botimport.Print(PRT_MESSAGE, "numvertexes = %d\n", aasworld.numvertexes);
00246 botimport.Print(PRT_MESSAGE, "numplanes = %d\n", aasworld.numplanes);
00247 botimport.Print(PRT_MESSAGE, "numedges = %d\n", aasworld.numedges);
00248 botimport.Print(PRT_MESSAGE, "edgeindexsize = %d\n", aasworld.edgeindexsize);
00249 botimport.Print(PRT_MESSAGE, "numfaces = %d\n", aasworld.numfaces);
00250 botimport.Print(PRT_MESSAGE, "faceindexsize = %d\n", aasworld.faceindexsize);
00251 botimport.Print(PRT_MESSAGE, "numareas = %d\n", aasworld.numareas);
00252 botimport.Print(PRT_MESSAGE, "numareasettings = %d\n", aasworld.numareasettings);
00253 botimport.Print(PRT_MESSAGE, "reachabilitysize = %d\n", aasworld.reachabilitysize);
00254 botimport.Print(PRT_MESSAGE, "numnodes = %d\n", aasworld.numnodes);
00255 botimport.Print(PRT_MESSAGE, "numportals = %d\n", aasworld.numportals);
00256 botimport.Print(PRT_MESSAGE, "portalindexsize = %d\n", aasworld.portalindexsize);
00257 botimport.Print(PRT_MESSAGE, "numclusters = %d\n", aasworld.numclusters);
00258
00259 for (n = 0, i = 0; i < aasworld.numareasettings; i++)
00260 {
00261 if (aasworld.areasettings[i].areaflags & AREA_GROUNDED) n++;
00262 }
00263 botimport.Print(PRT_MESSAGE, "num grounded areas = %d\n", n);
00264
00265 botimport.Print(PRT_MESSAGE, "planes size %d bytes\n", aasworld.numplanes * sizeof(aas_plane_t));
00266 botimport.Print(PRT_MESSAGE, "areas size %d bytes\n", aasworld.numareas * sizeof(aas_area_t));
00267 botimport.Print(PRT_MESSAGE, "areasettings size %d bytes\n", aasworld.numareasettings * sizeof(aas_areasettings_t));
00268 botimport.Print(PRT_MESSAGE, "nodes size %d bytes\n", aasworld.numnodes * sizeof(aas_node_t));
00269 botimport.Print(PRT_MESSAGE, "reachability size %d bytes\n", aasworld.reachabilitysize * sizeof(aas_reachability_t));
00270 botimport.Print(PRT_MESSAGE, "portals size %d bytes\n", aasworld.numportals * sizeof(aas_portal_t));
00271 botimport.Print(PRT_MESSAGE, "clusters size %d bytes\n", aasworld.numclusters * sizeof(aas_cluster_t));
00272
00273 optimized = aasworld.numplanes * sizeof(aas_plane_t) +
00274 aasworld.numareas * sizeof(aas_area_t) +
00275 aasworld.numareasettings * sizeof(aas_areasettings_t) +
00276 aasworld.numnodes * sizeof(aas_node_t) +
00277 aasworld.reachabilitysize * sizeof(aas_reachability_t) +
00278 aasworld.numportals * sizeof(aas_portal_t) +
00279 aasworld.numclusters * sizeof(aas_cluster_t);
00280 botimport.Print(PRT_MESSAGE, "optimzed size %d KB\n", optimized >> 10);
00281 }
00282 #endif //AASFILEDEBUG
00283
00284
00285
00286
00287
00288
00289
00290 char *AAS_LoadAASLump(fileHandle_t fp, int offset, int length, int *lastoffset, int size)
00291 {
00292 char *buf;
00293
00294 if (!length)
00295 {
00296
00297 return (char *) GetClearedHunkMemory(size+1);
00298 }
00299
00300 if (offset != *lastoffset)
00301 {
00302 botimport.Print(PRT_WARNING, "AAS file not sequentially read\n");
00303 if (botimport.FS_Seek(fp, offset, FS_SEEK_SET))
00304 {
00305 AAS_Error("can't seek to aas lump\n");
00306 AAS_DumpAASData();
00307 botimport.FS_FCloseFile(fp);
00308 return 0;
00309 }
00310 }
00311
00312 buf = (char *) GetClearedHunkMemory(length+1);
00313
00314 if (length)
00315 {
00316 botimport.FS_Read(buf, length, fp );
00317 *lastoffset += length;
00318 }
00319 return buf;
00320 }
00321
00322
00323
00324
00325
00326
00327 void AAS_DData(unsigned char *data, int size)
00328 {
00329 int i;
00330
00331 for (i = 0; i < size; i++)
00332 {
00333 data[i] ^= (unsigned char) i * 119;
00334 }
00335 }
00336
00337
00338
00339
00340
00341
00342
00343 int AAS_LoadAASFile(char *filename)
00344 {
00345 fileHandle_t fp;
00346 aas_header_t header;
00347 int offset, length, lastoffset;
00348
00349 botimport.Print(PRT_MESSAGE, "trying to load %s\n", filename);
00350
00351 AAS_DumpAASData();
00352
00353 botimport.FS_FOpenFile( filename, &fp, FS_READ );
00354 if (!fp)
00355 {
00356 AAS_Error("can't open %s\n", filename);
00357 return BLERR_CANNOTOPENAASFILE;
00358 }
00359
00360 botimport.FS_Read(&header, sizeof(aas_header_t), fp );
00361 lastoffset = sizeof(aas_header_t);
00362
00363 header.ident = LittleLong(header.ident);
00364 if (header.ident != AASID)
00365 {
00366 AAS_Error("%s is not an AAS file\n", filename);
00367 botimport.FS_FCloseFile(fp);
00368 return BLERR_WRONGAASFILEID;
00369 }
00370
00371 header.version = LittleLong(header.version);
00372
00373 if (header.version != AASVERSION_OLD && header.version != AASVERSION)
00374 {
00375 AAS_Error("aas file %s is version %i, not %i\n", filename, header.version, AASVERSION);
00376 botimport.FS_FCloseFile(fp);
00377 return BLERR_WRONGAASFILEVERSION;
00378 }
00379
00380 if (header.version == AASVERSION)
00381 {
00382 AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8);
00383 }
00384
00385 aasworld.bspchecksum = atoi(LibVarGetString( "sv_mapChecksum"));
00386 if (LittleLong(header.bspchecksum) != aasworld.bspchecksum)
00387 {
00388 AAS_Error("aas file %s is out of date\n", filename);
00389 botimport.FS_FCloseFile(fp);
00390 return BLERR_WRONGAASFILEVERSION;
00391 }
00392
00393
00394 offset = LittleLong(header.lumps[AASLUMP_BBOXES].fileofs);
00395 length = LittleLong(header.lumps[AASLUMP_BBOXES].filelen);
00396 aasworld.bboxes = (aas_bbox_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_bbox_t));
00397 aasworld.numbboxes = length / sizeof(aas_bbox_t);
00398 if (aasworld.numbboxes && !aasworld.bboxes) return BLERR_CANNOTREADAASLUMP;
00399
00400 offset = LittleLong(header.lumps[AASLUMP_VERTEXES].fileofs);
00401 length = LittleLong(header.lumps[AASLUMP_VERTEXES].filelen);
00402 aasworld.vertexes = (aas_vertex_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_vertex_t));
00403 aasworld.numvertexes = length / sizeof(aas_vertex_t);
00404 if (aasworld.numvertexes && !aasworld.vertexes) return BLERR_CANNOTREADAASLUMP;
00405
00406 offset = LittleLong(header.lumps[AASLUMP_PLANES].fileofs);
00407 length = LittleLong(header.lumps[AASLUMP_PLANES].filelen);
00408 aasworld.planes = (aas_plane_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_plane_t));
00409 aasworld.numplanes = length / sizeof(aas_plane_t);
00410 if (aasworld.numplanes && !aasworld.planes) return BLERR_CANNOTREADAASLUMP;
00411
00412 offset = LittleLong(header.lumps[AASLUMP_EDGES].fileofs);
00413 length = LittleLong(header.lumps[AASLUMP_EDGES].filelen);
00414 aasworld.edges = (aas_edge_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_edge_t));
00415 aasworld.numedges = length / sizeof(aas_edge_t);
00416 if (aasworld.numedges && !aasworld.edges) return BLERR_CANNOTREADAASLUMP;
00417
00418 offset = LittleLong(header.lumps[AASLUMP_EDGEINDEX].fileofs);
00419 length = LittleLong(header.lumps[AASLUMP_EDGEINDEX].filelen);
00420 aasworld.edgeindex = (aas_edgeindex_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_edgeindex_t));
00421 aasworld.edgeindexsize = length / sizeof(aas_edgeindex_t);
00422 if (aasworld.edgeindexsize && !aasworld.edgeindex) return BLERR_CANNOTREADAASLUMP;
00423
00424 offset = LittleLong(header.lumps[AASLUMP_FACES].fileofs);
00425 length = LittleLong(header.lumps[AASLUMP_FACES].filelen);
00426 aasworld.faces = (aas_face_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_face_t));
00427 aasworld.numfaces = length / sizeof(aas_face_t);
00428 if (aasworld.numfaces && !aasworld.faces) return BLERR_CANNOTREADAASLUMP;
00429
00430 offset = LittleLong(header.lumps[AASLUMP_FACEINDEX].fileofs);
00431 length = LittleLong(header.lumps[AASLUMP_FACEINDEX].filelen);
00432 aasworld.faceindex = (aas_faceindex_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_faceindex_t));
00433 aasworld.faceindexsize = length / sizeof(aas_faceindex_t);
00434 if (aasworld.faceindexsize && !aasworld.faceindex) return BLERR_CANNOTREADAASLUMP;
00435
00436 offset = LittleLong(header.lumps[AASLUMP_AREAS].fileofs);
00437 length = LittleLong(header.lumps[AASLUMP_AREAS].filelen);
00438 aasworld.areas = (aas_area_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_area_t));
00439 aasworld.numareas = length / sizeof(aas_area_t);
00440 if (aasworld.numareas && !aasworld.areas) return BLERR_CANNOTREADAASLUMP;
00441
00442 offset = LittleLong(header.lumps[AASLUMP_AREASETTINGS].fileofs);
00443 length = LittleLong(header.lumps[AASLUMP_AREASETTINGS].filelen);
00444 aasworld.areasettings = (aas_areasettings_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_areasettings_t));
00445 aasworld.numareasettings = length / sizeof(aas_areasettings_t);
00446 if (aasworld.numareasettings && !aasworld.areasettings) return BLERR_CANNOTREADAASLUMP;
00447
00448 offset = LittleLong(header.lumps[AASLUMP_REACHABILITY].fileofs);
00449 length = LittleLong(header.lumps[AASLUMP_REACHABILITY].filelen);
00450 aasworld.reachability = (aas_reachability_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_reachability_t));
00451 aasworld.reachabilitysize = length / sizeof(aas_reachability_t);
00452 if (aasworld.reachabilitysize && !aasworld.reachability) return BLERR_CANNOTREADAASLUMP;
00453
00454 offset = LittleLong(header.lumps[AASLUMP_NODES].fileofs);
00455 length = LittleLong(header.lumps[AASLUMP_NODES].filelen);
00456 aasworld.nodes = (aas_node_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_node_t));
00457 aasworld.numnodes = length / sizeof(aas_node_t);
00458 if (aasworld.numnodes && !aasworld.nodes) return BLERR_CANNOTREADAASLUMP;
00459
00460 offset = LittleLong(header.lumps[AASLUMP_PORTALS].fileofs);
00461 length = LittleLong(header.lumps[AASLUMP_PORTALS].filelen);
00462 aasworld.portals = (aas_portal_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_portal_t));
00463 aasworld.numportals = length / sizeof(aas_portal_t);
00464 if (aasworld.numportals && !aasworld.portals) return BLERR_CANNOTREADAASLUMP;
00465
00466 offset = LittleLong(header.lumps[AASLUMP_PORTALINDEX].fileofs);
00467 length = LittleLong(header.lumps[AASLUMP_PORTALINDEX].filelen);
00468 aasworld.portalindex = (aas_portalindex_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_portalindex_t));
00469 aasworld.portalindexsize = length / sizeof(aas_portalindex_t);
00470 if (aasworld.portalindexsize && !aasworld.portalindex) return BLERR_CANNOTREADAASLUMP;
00471
00472 offset = LittleLong(header.lumps[AASLUMP_CLUSTERS].fileofs);
00473 length = LittleLong(header.lumps[AASLUMP_CLUSTERS].filelen);
00474 aasworld.clusters = (aas_cluster_t *) AAS_LoadAASLump(fp, offset, length, &lastoffset, sizeof(aas_cluster_t));
00475 aasworld.numclusters = length / sizeof(aas_cluster_t);
00476 if (aasworld.numclusters && !aasworld.clusters) return BLERR_CANNOTREADAASLUMP;
00477
00478 AAS_SwapAASData();
00479
00480 aasworld.loaded = qtrue;
00481
00482 botimport.FS_FCloseFile(fp);
00483
00484 #ifdef AASFILEDEBUG
00485 AAS_FileInfo();
00486 #endif //AASFILEDEBUG
00487
00488 return BLERR_NOERROR;
00489 }
00490
00491
00492
00493
00494
00495
00496 static int AAS_WriteAASLump_offset;
00497
00498 int AAS_WriteAASLump(fileHandle_t fp, aas_header_t *h, int lumpnum, void *data, int length)
00499 {
00500 aas_lump_t *lump;
00501
00502 lump = &h->lumps[lumpnum];
00503
00504 lump->fileofs = LittleLong(AAS_WriteAASLump_offset);
00505 lump->filelen = LittleLong(length);
00506
00507 if (length > 0)
00508 {
00509 botimport.FS_Write(data, length, fp );
00510 }
00511
00512 AAS_WriteAASLump_offset += length;
00513
00514 return qtrue;
00515 }
00516
00517
00518
00519
00520
00521
00522
00523 qboolean AAS_WriteAASFile(char *filename)
00524 {
00525 aas_header_t header;
00526 fileHandle_t fp;
00527
00528 botimport.Print(PRT_MESSAGE, "writing %s\n", filename);
00529
00530 AAS_SwapAASData();
00531
00532 Com_Memset(&header, 0, sizeof(aas_header_t));
00533 header.ident = LittleLong(AASID);
00534 header.version = LittleLong(AASVERSION);
00535 header.bspchecksum = LittleLong(aasworld.bspchecksum);
00536
00537 botimport.FS_FOpenFile( filename, &fp, FS_WRITE );
00538 if (!fp)
00539 {
00540 botimport.Print(PRT_ERROR, "error opening %s\n", filename);
00541 return qfalse;
00542 }
00543
00544 botimport.FS_Write(&header, sizeof(aas_header_t), fp);
00545 AAS_WriteAASLump_offset = sizeof(aas_header_t);
00546
00547 if (!AAS_WriteAASLump(fp, &header, AASLUMP_BBOXES, aasworld.bboxes,
00548 aasworld.numbboxes * sizeof(aas_bbox_t))) return qfalse;
00549 if (!AAS_WriteAASLump(fp, &header, AASLUMP_VERTEXES, aasworld.vertexes,
00550 aasworld.numvertexes * sizeof(aas_vertex_t))) return qfalse;
00551 if (!AAS_WriteAASLump(fp, &header, AASLUMP_PLANES, aasworld.planes,
00552 aasworld.numplanes * sizeof(aas_plane_t))) return qfalse;
00553 if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGES, aasworld.edges,
00554 aasworld.numedges * sizeof(aas_edge_t))) return qfalse;
00555 if (!AAS_WriteAASLump(fp, &header, AASLUMP_EDGEINDEX, aasworld.edgeindex,
00556 aasworld.edgeindexsize * sizeof(aas_edgeindex_t))) return qfalse;
00557 if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACES, aasworld.faces,
00558 aasworld.numfaces * sizeof(aas_face_t))) return qfalse;
00559 if (!AAS_WriteAASLump(fp, &header, AASLUMP_FACEINDEX, aasworld.faceindex,
00560 aasworld.faceindexsize * sizeof(aas_faceindex_t))) return qfalse;
00561 if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREAS, aasworld.areas,
00562 aasworld.numareas * sizeof(aas_area_t))) return qfalse;
00563 if (!AAS_WriteAASLump(fp, &header, AASLUMP_AREASETTINGS, aasworld.areasettings,
00564 aasworld.numareasettings * sizeof(aas_areasettings_t))) return qfalse;
00565 if (!AAS_WriteAASLump(fp, &header, AASLUMP_REACHABILITY, aasworld.reachability,
00566 aasworld.reachabilitysize * sizeof(aas_reachability_t))) return qfalse;
00567 if (!AAS_WriteAASLump(fp, &header, AASLUMP_NODES, aasworld.nodes,
00568 aasworld.numnodes * sizeof(aas_node_t))) return qfalse;
00569 if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALS, aasworld.portals,
00570 aasworld.numportals * sizeof(aas_portal_t))) return qfalse;
00571 if (!AAS_WriteAASLump(fp, &header, AASLUMP_PORTALINDEX, aasworld.portalindex,
00572 aasworld.portalindexsize * sizeof(aas_portalindex_t))) return qfalse;
00573 if (!AAS_WriteAASLump(fp, &header, AASLUMP_CLUSTERS, aasworld.clusters,
00574 aasworld.numclusters * sizeof(aas_cluster_t))) return qfalse;
00575
00576 botimport.FS_Seek(fp, 0, FS_SEEK_SET);
00577 AAS_DData((unsigned char *) &header + 8, sizeof(aas_header_t) - 8);
00578 botimport.FS_Write(&header, sizeof(aas_header_t), fp);
00579
00580 botimport.FS_FCloseFile(fp);
00581 return qtrue;
00582 }