- set compiler explicit to wine version
[genesis3d.git] / GBSPLib / GBSPFILE.CPP
1 /****************************************************************************************/\r
2 /*  GBSPFile.cpp                                                                        */\r
3 /*                                                                                      */\r
4 /*  Author: John Pollard                                                                */\r
5 /*  Description: Loads a BSP                                                            */\r
6 /*                                                                                      */\r
7 /*  The contents of this file are subject to the Genesis3D Public License               */\r
8 /*  Version 1.01 (the "License"); you may not use this file except in                   */\r
9 /*  compliance with the License. You may obtain a copy of the License at                */\r
10 /*  http://www.genesis3d.com                                                            */\r
11 /*                                                                                      */\r
12 /*  Software distributed under the License is distributed on an "AS IS"                 */\r
13 /*  basis, WITHOUT WARRANTY OF ANY KIND, either express or implied.  See                */\r
14 /*  the License for the specific language governing rights and limitations              */\r
15 /*  under the License.                                                                  */\r
16 /*                                                                                      */\r
17 /*  The Original Code is Genesis3D, released March 25, 1999.                            */\r
18 /*Genesis3D Version 1.1 released November 15, 1999                            */\r
19 /*  Copyright (C) 1999 WildTangent, Inc. All Rights Reserved           */\r
20 /*                                                                                      */\r
21 /****************************************************************************************/\r
22 #include <Windows.h>\r
23 #include <Stdio.h>\r
24 \r
25 #include "DCommon.h"\r
26 #include "GBSPFile.h"\r
27 #include "VFile.h"\r
28 #include "Ram.h"\r
29 \r
30 //========================================================================================\r
31 //      Globals\r
32 //========================================================================================\r
33 GBSP_Header     GBSPHeader;                                             // Header\r
34 GFX_SkyData     GFXSkyData;\r
35 \r
36 GFX_Model               *GFXModels;                                             // Model data\r
37 GFX_Node                *GFXNodes;                                              // Nodes\r
38 GFX_BNode               *GFXBNodes;                                             // Bevel Clip nodes\r
39 GFX_Leaf                *GFXLeafs;                                              // Leafs\r
40 GFX_Cluster             *GFXClusters;                                   // CHANGE: CLUSTER\r
41 GFX_Area                *GFXAreas;\r
42 GFX_AreaPortal  *GFXAreaPortals;\r
43 GFX_Plane               *GFXPlanes;                                             // Planes\r
44 GFX_Face                *GFXFaces;                                              // Faces\r
45 int32                   *GFXLeafFaces;\r
46 GFX_LeafSide    *GFXLeafSides;\r
47 geVec3d                 *GFXVerts;                                              // Verts\r
48 int32                   *GFXVertIndexList;                              // Index list\r
49 geVec3d                 *GFXRGBVerts;\r
50 \r
51 uint8                   *GFXEntData;\r
52 GFX_Texture             *GFXTextures;                                   // Textures\r
53 GFX_TexInfo             *GFXTexInfo;                                    // TexInfo\r
54 uint8                   *GFXTexData;                                    // TexData\r
55 \r
56 uint8                   *GFXLightData;                                  // Lightmap data\r
57 uint8                   *GFXVisData;                                    // Vis data\r
58 GFX_Portal              *GFXPortals;                                    // Portal data\r
59 DRV_Palette             *GFXPalettes;                                   // Texture palettes\r
60 uint8                   *GFXMotionData;                                 // Model motion keyframe data\r
61 \r
62 int32           NumGFXModels;\r
63 int32           NumGFXNodes;\r
64 int32           NumGFXBNodes;\r
65 int32           NumGFXLeafs;\r
66 int32           NumGFXClusters;         // CHANGE: CLUSTER\r
67 int32           NumGFXAreas;    \r
68 int32           NumGFXAreaPortals;\r
69 int32           NumGFXPlanes;\r
70 int32           NumGFXFaces;\r
71 int32           NumGFXLeafFaces;\r
72 int32           NumGFXLeafSides;\r
73 int32           NumGFXVerts;\r
74 int32           NumGFXVertIndexList;\r
75 int32           NumGFXRGBVerts;\r
76 \r
77 int32           NumGFXEntData;\r
78 int32           NumGFXTextures;\r
79 int32           NumGFXTexInfo;\r
80 int32           NumGFXTexData;\r
81 \r
82 int32           NumGFXLightData;\r
83 int32           NumGFXVisData;\r
84 int32           NumGFXPortals;\r
85 int32           NumGFXPalettes;\r
86 int32           NumGFXMotionBytes;\r
87 \r
88 //#define       DEBUGCHUNKS\r
89 #ifdef  DEBUGCHUNKS\r
90 static   char *ChunkNames[] =\r
91 {\r
92 "GBSP_CHUNK_HEADER",\r
93 "GBSP_CHUNK_MODELS",\r
94 "GBSP_CHUNK_NODES",\r
95 "GBSP_CHUNK_BNODES",\r
96 "GBSP_CHUNK_LEAFS",\r
97 "GBSP_CHUNK_CLUSTERS",\r
98 "GBSP_CHUNK_AREAS",\r
99 "GBSP_CHUNK_LEAF_SIDES",\r
100 "GBSP_CHUNK_PORTALS",\r
101 "GBSP_CHUNK_PLANES",\r
102 "GBSP_CHUNK_FACES",\r
103 "GBSP_CHUNK_LEAF_FACES",\r
104 "GBSP_CHUNK_VERT_INDEX",\r
105 "GBSP_CHUNK_VERTS",\r
106 "GBSP_CHUNK_RGB_VERTS",\r
107 "GBSP_CHUNK_ENTDATA",\r
108 "GBSP_CHUNK_TEXINFO",\r
109 "GBSP_CHUNK_TEXTURES",\r
110 "GBSP_CHUNK_TEXDATA",\r
111 "GBSP_CHUNK_LIGHTDATA",\r
112 "GBSP_CHUNK_VISDATA",\r
113 "GBSP_CHUNK_SKYDATA",\r
114 "GBSP_CHUNK_PALETTES",\r
115 "GBSP_CHUNK_MOTIONS",\r
116 };\r
117 #endif\r
118 \r
119 //========================================================================================\r
120 //      WriteChunk\r
121 //========================================================================================\r
122 geBoolean WriteChunk(GBSP_Chunk *Chunk, void *Data, geVFile *f)\r
123 {\r
124         if (geVFile_Write(f, Chunk, sizeof(GBSP_Chunk)) != GE_TRUE)\r
125         {\r
126                 //Hook.Error("WriteChunk:  There was an error writing the chunk (Duh...).\n");\r
127                 return GE_FALSE;\r
128         }\r
129 \r
130 #ifdef  DEBUGCHUNKS\r
131         if      (Chunk->Type != GBSP_CHUNK_END)\r
132         {\r
133                 long    Pos;\r
134 \r
135                 geVFile_Tell(f, &Pos);\r
136                 GHook.Printf(" WriteChunkData: @%08x '%s', %d elements of %d size\n", Pos,\r
137                 ChunkNames[Chunk->Type], Chunk->Elements, Chunk->Size);\r
138         }\r
139         else\r
140         {\r
141                 long    Pos;\r
142 \r
143                 geVFile_Tell(f, &Pos);\r
144                 GHook.Printf(" WriteChunk: @%08x 'GBSP_CHUNK_END', %d elements of %d size\n", Pos, Chunk->Elements, Chunk->Size);\r
145         }\r
146 #endif\r
147         if (Chunk->Size * Chunk->Elements > 0)\r
148         {\r
149                 if (!Data)\r
150                         return GE_TRUE;\r
151 \r
152                 if (geVFile_Write(f, Data, Chunk->Size * Chunk->Elements) != GE_TRUE)\r
153                 {\r
154                         //Hook.Error("WriteChunk:  There was an error writing the chunk data.\n");\r
155                         return GE_FALSE;\r
156                 }\r
157         }\r
158 \r
159         return GE_TRUE;\r
160 }\r
161 \r
162 //========================================================================================\r
163 // ReadChunkData\r
164 //========================================================================================\r
165 geBoolean ReadChunkData(GBSP_Chunk *Chunk, void *Data, geVFile *f)\r
166 {\r
167         if (geVFile_Read(f, Data, Chunk->Size * Chunk->Elements) != GE_TRUE)\r
168                 return GE_FALSE;\r
169 \r
170         return GE_TRUE;\r
171 }\r
172 \r
173 //========================================================================================\r
174 //      ReadChunk\r
175 //========================================================================================\r
176 geBoolean ReadChunk(GBSP_Chunk *Chunk, geVFile *f)\r
177 {\r
178         if (geVFile_Read(f, Chunk, sizeof(GBSP_Chunk)) != GE_TRUE)\r
179         {\r
180                 return GE_FALSE;\r
181         }\r
182 \r
183 #ifdef  DEBUGCHUNKS\r
184         if      (Chunk->Type != GBSP_CHUNK_END)\r
185         {\r
186                 long    Pos;\r
187 \r
188                 geVFile_Tell(f, &Pos);\r
189                 GHook.Printf(" ReadChunk: @%08x '%s', %d elements of %d size\n", Pos,\r
190                 ChunkNames[Chunk->Type], Chunk->Elements, Chunk->Size);\r
191         }\r
192         else\r
193         {\r
194                 long    Pos;\r
195 \r
196                 geVFile_Tell(f, &Pos);\r
197                 GHook.Printf(" ReadChunk: @%08x 'GBSP_CHUNK_END', %d elements of %d size\n", Pos, Chunk->Elements, Chunk->Size);\r
198         }\r
199 #endif\r
200 \r
201         switch(Chunk->Type)\r
202         {\r
203                 case GBSP_CHUNK_HEADER:\r
204                 {\r
205                         if (!ReadChunkData(Chunk, (void*)&GBSPHeader, f))\r
206                                 return GE_FALSE;\r
207                         if (strcmp(GBSPHeader.TAG, "GBSP"))\r
208                                 return GE_FALSE;\r
209                         if (GBSPHeader.Version != GBSP_VERSION)\r
210                                 return GE_FALSE;\r
211 \r
212                         break;\r
213                 }\r
214                 case GBSP_CHUNK_MODELS:\r
215                 {\r
216                         NumGFXModels = Chunk->Elements;\r
217                         GFXModels = GE_RAM_ALLOCATE_ARRAY(GFX_Model, NumGFXModels);\r
218                         if (!ReadChunkData(Chunk, GFXModels, f))\r
219                                 return GE_FALSE;\r
220                         break;\r
221                 }\r
222                 case GBSP_CHUNK_NODES:\r
223                 {\r
224                         NumGFXNodes = Chunk->Elements;\r
225                         GFXNodes = GE_RAM_ALLOCATE_ARRAY(GFX_Node,NumGFXNodes);\r
226                         if (!ReadChunkData(Chunk, GFXNodes, f))\r
227                                 return GE_FALSE;\r
228                         break;\r
229                 }\r
230                 case GBSP_CHUNK_BNODES:\r
231                 {\r
232                         NumGFXBNodes = Chunk->Elements;\r
233                         GFXBNodes = GE_RAM_ALLOCATE_ARRAY(GFX_BNode,NumGFXBNodes);\r
234                         if (!ReadChunkData(Chunk, GFXBNodes, f))\r
235                                 return GE_FALSE;\r
236                         break;\r
237                 }\r
238                 case GBSP_CHUNK_LEAFS:\r
239                 {\r
240                         NumGFXLeafs = Chunk->Elements;\r
241                         GFXLeafs = GE_RAM_ALLOCATE_ARRAY(GFX_Leaf,NumGFXLeafs);\r
242                         if (!ReadChunkData(Chunk, GFXLeafs, f))\r
243                                 return GE_FALSE;\r
244                         break;\r
245                 }\r
246                 case GBSP_CHUNK_CLUSTERS:\r
247                 {\r
248                         NumGFXClusters = Chunk->Elements;\r
249 \r
250                         GFXClusters = GE_RAM_ALLOCATE_ARRAY(GFX_Cluster,NumGFXClusters);\r
251                         if (!ReadChunkData(Chunk, GFXClusters, f))\r
252                                 return GE_FALSE;\r
253                         break;\r
254                 }\r
255                 case GBSP_CHUNK_AREAS:\r
256                 {\r
257                         NumGFXAreas = Chunk->Elements;\r
258                         GFXAreas = GE_RAM_ALLOCATE_ARRAY(GFX_Area,NumGFXAreas);\r
259                         if (!ReadChunkData(Chunk, GFXAreas, f))\r
260                                 return GE_FALSE;\r
261                         break;\r
262                 }\r
263                 case GBSP_CHUNK_AREA_PORTALS:\r
264                 {\r
265                         NumGFXAreaPortals = Chunk->Elements;\r
266                         GFXAreaPortals = GE_RAM_ALLOCATE_ARRAY(GFX_AreaPortal,NumGFXAreaPortals);\r
267                         if (!ReadChunkData(Chunk, GFXAreaPortals, f))\r
268                                 return GE_FALSE;\r
269                         break;\r
270                 }\r
271                 case GBSP_CHUNK_PORTALS:\r
272                 {\r
273                         NumGFXPortals = Chunk->Elements;\r
274                         GFXPortals = GE_RAM_ALLOCATE_ARRAY(GFX_Portal,NumGFXPortals);\r
275                         if (!ReadChunkData(Chunk, GFXPortals, f))\r
276                                 return GE_FALSE;\r
277                         break;\r
278                 }\r
279                 case GBSP_CHUNK_PLANES:\r
280                 {\r
281                         NumGFXPlanes = Chunk->Elements;\r
282                         GFXPlanes = GE_RAM_ALLOCATE_ARRAY(GFX_Plane,NumGFXPlanes);\r
283                         if (!ReadChunkData(Chunk, GFXPlanes, f))\r
284                                 return GE_FALSE;\r
285                         break;\r
286                 }\r
287                 case GBSP_CHUNK_FACES:\r
288                 {\r
289                         NumGFXFaces = Chunk->Elements;\r
290                         GFXFaces = GE_RAM_ALLOCATE_ARRAY(GFX_Face,NumGFXFaces);\r
291                         if (!ReadChunkData(Chunk, GFXFaces, f))\r
292                                 return GE_FALSE;\r
293                         break;\r
294                 }\r
295                 case GBSP_CHUNK_LEAF_FACES:\r
296                 {\r
297                         NumGFXLeafFaces = Chunk->Elements;\r
298                         GFXLeafFaces = GE_RAM_ALLOCATE_ARRAY(int32,NumGFXLeafFaces);\r
299                         if (!ReadChunkData(Chunk, GFXLeafFaces, f))\r
300                                 return GE_FALSE;\r
301                         break;\r
302                 }\r
303                 case GBSP_CHUNK_LEAF_SIDES:\r
304                 {\r
305                         NumGFXLeafSides = Chunk->Elements;\r
306 \r
307                         GFXLeafSides = GE_RAM_ALLOCATE_ARRAY(GFX_LeafSide,NumGFXLeafSides);\r
308                         if (!ReadChunkData(Chunk, GFXLeafSides, f))\r
309                                 return GE_FALSE;\r
310                         break;\r
311                 }\r
312                 case GBSP_CHUNK_VERTS:\r
313                 {\r
314                         NumGFXVerts = Chunk->Elements;\r
315                         GFXVerts = GE_RAM_ALLOCATE_ARRAY(geVec3d,NumGFXVerts);\r
316                         if (!ReadChunkData(Chunk, GFXVerts, f))\r
317                                 return GE_FALSE;\r
318                         break;\r
319                 }\r
320                 case GBSP_CHUNK_VERT_INDEX:\r
321                 {\r
322                         NumGFXVertIndexList = Chunk->Elements;\r
323                         GFXVertIndexList = GE_RAM_ALLOCATE_ARRAY(int32,NumGFXVertIndexList);\r
324                         if (!ReadChunkData(Chunk, GFXVertIndexList, f))\r
325                                 return GE_FALSE;\r
326                         break;\r
327                 }\r
328 \r
329                 case GBSP_CHUNK_RGB_VERTS:\r
330                 {\r
331                         NumGFXRGBVerts = Chunk->Elements;\r
332                         GFXRGBVerts = GE_RAM_ALLOCATE_ARRAY(geVec3d,NumGFXRGBVerts);\r
333                         if (!ReadChunkData(Chunk, GFXRGBVerts, f))\r
334                                 return GE_FALSE;\r
335                         break;\r
336                 }\r
337 \r
338                 case GBSP_CHUNK_TEXINFO:\r
339                 {\r
340                         NumGFXTexInfo = Chunk->Elements;\r
341                         GFXTexInfo = GE_RAM_ALLOCATE_ARRAY(GFX_TexInfo,NumGFXTexInfo);\r
342                         if (!ReadChunkData(Chunk, GFXTexInfo, f))\r
343                                 return GE_FALSE;\r
344                         break;\r
345                 }\r
346 \r
347                 case GBSP_CHUNK_TEXTURES:\r
348                 {\r
349                         NumGFXTextures = Chunk->Elements;\r
350                         GFXTextures = GE_RAM_ALLOCATE_ARRAY(GFX_Texture,NumGFXTextures);\r
351                         if (!ReadChunkData(Chunk, GFXTextures, f))\r
352                                 return GE_FALSE;\r
353                         break;\r
354                 }\r
355 \r
356                 case GBSP_CHUNK_TEXDATA:\r
357                 {\r
358 //      GHook.Printf(" Reading TEXDATA: %d bytes of %d size \n", Chunk->Elements, Chunk->Size);\r
359                         NumGFXTexData = Chunk->Elements;\r
360                         GFXTexData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXTexData);\r
361                         if (!ReadChunkData(Chunk, GFXTexData, f))\r
362                                 return GE_FALSE;\r
363                         break;\r
364                 }\r
365                 case GBSP_CHUNK_ENTDATA:\r
366                 {\r
367                         NumGFXEntData = Chunk->Elements;\r
368                         GFXEntData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXEntData);\r
369                         if (!ReadChunkData(Chunk, GFXEntData, f))\r
370                                 return GE_FALSE;\r
371                         break;\r
372                 }\r
373                 case GBSP_CHUNK_LIGHTDATA:\r
374                 {\r
375                         NumGFXLightData = Chunk->Elements;\r
376                         GFXLightData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXLightData);\r
377                         if (!ReadChunkData(Chunk, GFXLightData, f))\r
378                                 return GE_FALSE;\r
379                         break;\r
380                 }\r
381                 case GBSP_CHUNK_VISDATA:\r
382                 {\r
383                         NumGFXVisData = Chunk->Elements;\r
384                         GFXVisData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXVisData);\r
385                         if (!ReadChunkData(Chunk, GFXVisData, f))\r
386                                 return GE_FALSE;\r
387                         break;\r
388                 }\r
389                 case GBSP_CHUNK_SKYDATA:\r
390                 {\r
391                         if (!ReadChunkData(Chunk, &GFXSkyData, f))\r
392                                 return GE_FALSE;\r
393                         break;\r
394                 }\r
395                 case GBSP_CHUNK_PALETTES:\r
396                 {\r
397                         NumGFXPalettes = Chunk->Elements;\r
398                         GFXPalettes = GE_RAM_ALLOCATE_ARRAY(DRV_Palette,NumGFXPalettes);\r
399                         if (!GFXPalettes)\r
400                                 return GE_FALSE;\r
401                         if (!ReadChunkData(Chunk, GFXPalettes, f))\r
402                                 return GE_FALSE;\r
403                         break;\r
404                 }\r
405                 case GBSP_CHUNK_MOTIONS:\r
406                 {\r
407                         //      GHook.Printf(" Reading motions: %d Elements of %d size\n", Chunk->Elements, Chunk->Size);\r
408                         NumGFXMotionBytes = Chunk->Elements;\r
409                         GFXMotionData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXMotionBytes);\r
410                         if (!ReadChunkData(Chunk, GFXMotionData, f))\r
411                                 return GE_FALSE;\r
412                         break;\r
413                 }\r
414                 case GBSP_CHUNK_END:\r
415                 {\r
416                         break;\r
417                 }\r
418                 default:\r
419                         return GE_FALSE;\r
420         }\r
421 \r
422         return GE_TRUE;\r
423 }\r
424 \r
425 //========================================================================================\r
426 //      LoadGBSPFile\r
427 //========================================================================================\r
428 geBoolean LoadGBSPFile(char *FileName)\r
429 {\r
430         geVFile         *f;\r
431         GBSP_Chunk      Chunk;\r
432 \r
433         f = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_DOS, FileName, NULL, GE_VFILE_OPEN_READONLY);\r
434 \r
435         if (!f)\r
436                 return GE_FALSE;\r
437 \r
438         while (1)\r
439         {\r
440                 if (!ReadChunk(&Chunk, f))\r
441                         return GE_FALSE;\r
442                 \r
443                 if (Chunk.Type == GBSP_CHUNK_END)\r
444                         break;\r
445         }\r
446 \r
447         return GE_TRUE;\r
448 }\r
449 \r
450 //========================================================================================\r
451 //      FreeGBSPFile\r
452 //========================================================================================\r
453 geBoolean FreeGBSPFile(void)\r
454 {\r
455         if (GFXModels)\r
456                 geRam_Free(GFXModels);\r
457         if (GFXNodes)\r
458                 geRam_Free(GFXNodes);\r
459         if (GFXBNodes)\r
460                 geRam_Free(GFXBNodes);\r
461         if (GFXLeafs)\r
462                 geRam_Free(GFXLeafs);\r
463         if (GFXClusters)                        // CHANGE: CLUSTER\r
464                 geRam_Free(GFXClusters);\r
465         if (GFXAreas)\r
466                 geRam_Free(GFXAreas);\r
467         if (GFXPortals)\r
468                 geRam_Free(GFXPortals);\r
469         if (GFXPlanes)\r
470                 geRam_Free(GFXPlanes);\r
471         if (GFXFaces)\r
472                 geRam_Free(GFXFaces);\r
473         if (GFXLeafFaces)\r
474                 geRam_Free(GFXLeafFaces);\r
475         if (GFXLeafSides)\r
476                 geRam_Free(GFXLeafSides);\r
477         if (GFXVerts)\r
478                 geRam_Free(GFXVerts);\r
479         if (GFXVertIndexList)\r
480                 geRam_Free(GFXVertIndexList);\r
481         if (GFXRGBVerts)\r
482                 geRam_Free(GFXRGBVerts);\r
483         if (GFXTextures)\r
484                 geRam_Free(GFXTextures);\r
485         if (GFXTexInfo)\r
486                 geRam_Free(GFXTexInfo);\r
487         if (GFXTexData)\r
488                 geRam_Free(GFXTexData);\r
489         if (GFXEntData)\r
490                 geRam_Free(GFXEntData);\r
491         if (GFXLightData)\r
492                 geRam_Free(GFXLightData);\r
493         if (GFXVisData)\r
494                 geRam_Free(GFXVisData);\r
495         if (GFXPalettes)\r
496                 geRam_Free(GFXPalettes);\r
497         if (GFXMotionData)\r
498                 geRam_Free(GFXMotionData);\r
499 \r
500         GFXModels = NULL;\r
501         GFXNodes = NULL;\r
502         GFXBNodes = NULL;\r
503         GFXLeafs = NULL;\r
504         GFXClusters = NULL;             // CHANGE: CLUSTER\r
505         GFXAreas = NULL;\r
506         GFXPlanes = NULL;\r
507         GFXFaces = NULL;\r
508         GFXLeafFaces = NULL;\r
509         GFXLeafSides = NULL;\r
510         GFXVerts = NULL;\r
511         GFXVertIndexList = NULL;\r
512         GFXRGBVerts = NULL;\r
513         GFXEntData = NULL;\r
514         \r
515         GFXTextures = NULL;\r
516         GFXTexInfo = NULL;\r
517         GFXTexData = NULL;\r
518         GFXPalettes = NULL;\r
519         GFXMotionData = NULL;\r
520 \r
521         GFXLightData = NULL;\r
522         GFXVisData = NULL;\r
523         GFXPortals = NULL;\r
524 \r
525         NumGFXModels = 0;\r
526         NumGFXNodes = 0;\r
527         NumGFXBNodes = 0;\r
528         NumGFXLeafs = 0;\r
529         NumGFXClusters = 0;             // CHANGE: CLUSTER\r
530         NumGFXAreas = 0;\r
531         NumGFXPlanes = 0;\r
532         NumGFXFaces = 0;\r
533         NumGFXLeafFaces = 0;\r
534         NumGFXLeafSides = 0;\r
535         NumGFXVerts = 0;\r
536         NumGFXVertIndexList = 0;\r
537         NumGFXRGBVerts = 0;\r
538 \r
539         NumGFXEntData = 0;\r
540         NumGFXTexInfo = 0;\r
541         NumGFXTextures = 0;\r
542         NumGFXTexData = 0;\r
543         NumGFXPalettes = 0;\r
544 \r
545         NumGFXMotionBytes = 0;\r
546 \r
547         NumGFXLightData = 0;\r
548         NumGFXVisData = 0;\r
549         NumGFXPortals = 0;\r
550 \r
551         return GE_TRUE;\r
552 }\r
553 \r
554 //================================================================================\r
555 //      WriteChunks\r
556 //================================================================================\r
557 geBoolean WriteChunks(GBSP_ChunkData *Data, int32 NumChunkData, geVFile *f)\r
558 {\r
559         int32           i;\r
560         GBSP_Chunk      Chunk;\r
561 \r
562         for (i=0; i< NumChunkData; i++)\r
563         {\r
564                 Chunk.Type = Data[i].Type;\r
565                 Chunk.Size = Data[i].Size;\r
566                 Chunk.Elements = Data[i].Elements;\r
567                 if (!WriteChunk(&Chunk, Data[i].Data, f))\r
568                         return GE_FALSE;\r
569         }\r
570 \r
571         return GE_TRUE;\r
572 }\r
573 \r
574 //================================================================================\r
575 //      SaveGBSPFile\r
576 //================================================================================\r
577 geBoolean SaveGBSPFile(char *FileName)\r
578 {\r
579         GBSP_ChunkData  CurrentChunkData[] = {\r
580                 { GBSP_CHUNK_HEADER                     , sizeof(GBSP_Header)   ,1                                      , &GBSPHeader},\r
581                 { GBSP_CHUNK_MODELS                     , sizeof(GFX_Model)             ,NumGFXModels           , GFXModels },\r
582                 { GBSP_CHUNK_NODES                      , sizeof(GFX_Node)              ,NumGFXNodes            , GFXNodes  },\r
583                 { GBSP_CHUNK_PORTALS            , sizeof(GFX_Portal)    ,NumGFXPortals          , GFXPortals},\r
584                 { GBSP_CHUNK_BNODES                     , sizeof(GFX_BNode)             ,NumGFXBNodes           , GFXBNodes },\r
585                 { GBSP_CHUNK_PLANES                     , sizeof(GFX_Plane)             ,NumGFXPlanes           , GFXPlanes },\r
586                 { GBSP_CHUNK_FACES                      , sizeof(GFX_Face)              ,NumGFXFaces            , GFXFaces  },\r
587                 { GBSP_CHUNK_AREAS                      , sizeof(GFX_Area)              ,NumGFXAreas            , GFXAreas  },\r
588                 { GBSP_CHUNK_AREA_PORTALS       , sizeof(GFX_AreaPortal),NumGFXAreaPortals      , GFXAreaPortals  },\r
589                 { GBSP_CHUNK_LEAF_FACES         , sizeof(int32)                 ,NumGFXLeafFaces        , GFXLeafFaces  },\r
590                 { GBSP_CHUNK_LEAF_SIDES         , sizeof(GFX_LeafSide)  ,NumGFXLeafSides        , GFXLeafSides  },\r
591                 { GBSP_CHUNK_VERTS                      , sizeof(geVec3d)               ,NumGFXVerts            , GFXVerts  },\r
592                 { GBSP_CHUNK_VERT_INDEX         , sizeof(int32)                 ,NumGFXVertIndexList , GFXVertIndexList},\r
593                 { GBSP_CHUNK_RGB_VERTS          , sizeof(geVec3d)               ,NumGFXRGBVerts         , GFXRGBVerts  },\r
594                 { GBSP_CHUNK_ENTDATA            , sizeof(uint8)                 ,NumGFXEntData          , GFXEntData},\r
595                 { GBSP_CHUNK_TEXTURES           , sizeof(GFX_Texture)   ,NumGFXTextures         , GFXTextures},\r
596                 { GBSP_CHUNK_TEXINFO            , sizeof(GFX_TexInfo)   ,NumGFXTexInfo          , GFXTexInfo},\r
597                 { GBSP_CHUNK_TEXDATA            , sizeof(uint8)                 ,NumGFXTexData          , GFXTexData},\r
598                 { GBSP_CHUNK_LIGHTDATA          , sizeof(uint8)                 ,NumGFXLightData        , GFXLightData},\r
599                 { GBSP_CHUNK_LEAFS                      , sizeof(GFX_Leaf)              ,NumGFXLeafs            , GFXLeafs  },\r
600                 { GBSP_CHUNK_CLUSTERS           , sizeof(GFX_Cluster)   ,NumGFXClusters         , GFXClusters},\r
601                 { GBSP_CHUNK_VISDATA            , sizeof(uint8)                 ,NumGFXVisData          , GFXVisData},\r
602                 { GBSP_CHUNK_SKYDATA            , sizeof(GFX_SkyData)   ,1                                      , &GFXSkyData},\r
603                 { GBSP_CHUNK_PALETTES           , sizeof(DRV_Palette)   ,NumGFXPalettes         , GFXPalettes},\r
604                 { GBSP_CHUNK_MOTIONS            , sizeof(uint8)                 ,NumGFXMotionBytes      , GFXMotionData},\r
605                 { GBSP_CHUNK_END                        , 0                                             ,0                                      ,NULL },\r
606         };\r
607 \r
608         geVFile *f;\r
609 \r
610         f = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_DOS, FileName, NULL, GE_VFILE_OPEN_CREATE);\r
611 \r
612         if (!f)\r
613                 return GE_FALSE;\r
614 \r
615         if (!WriteChunks(CurrentChunkData, sizeof(CurrentChunkData) / sizeof(CurrentChunkData[0]), f))\r
616         {\r
617                 geVFile_Close(f);\r
618                 return GE_FALSE;\r
619         }\r
620 \r
621         geVFile_Close(f);\r
622 \r
623         return GE_TRUE;\r
624 }\r
625 \r