1 /****************************************************************************************/
\r
4 /* Author: John Pollard */
\r
5 /* Description: Loads a BSP */
\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
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
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
21 /****************************************************************************************/
\r
22 #include <Windows.h>
\r
25 #include "DCommon.h"
\r
26 #include "GBSPFile.h"
\r
30 //========================================================================================
\r
32 //========================================================================================
\r
33 GBSP_Header GBSPHeader; // Header
\r
34 GFX_SkyData GFXSkyData;
\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
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
52 GFX_Texture *GFXTextures; // Textures
\r
53 GFX_TexInfo *GFXTexInfo; // TexInfo
\r
54 uint8 *GFXTexData; // TexData
\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
66 int32 NumGFXClusters; // CHANGE: CLUSTER
\r
68 int32 NumGFXAreaPortals;
\r
71 int32 NumGFXLeafFaces;
\r
72 int32 NumGFXLeafSides;
\r
74 int32 NumGFXVertIndexList;
\r
75 int32 NumGFXRGBVerts;
\r
77 int32 NumGFXEntData;
\r
78 int32 NumGFXTextures;
\r
79 int32 NumGFXTexInfo;
\r
80 int32 NumGFXTexData;
\r
82 int32 NumGFXLightData;
\r
83 int32 NumGFXVisData;
\r
84 int32 NumGFXPortals;
\r
85 int32 NumGFXPalettes;
\r
86 int32 NumGFXMotionBytes;
\r
88 //#define DEBUGCHUNKS
\r
90 static char *ChunkNames[] =
\r
92 "GBSP_CHUNK_HEADER",
\r
93 "GBSP_CHUNK_MODELS",
\r
95 "GBSP_CHUNK_BNODES",
\r
97 "GBSP_CHUNK_CLUSTERS",
\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
119 //========================================================================================
\r
121 //========================================================================================
\r
122 geBoolean WriteChunk(GBSP_Chunk *Chunk, void *Data, geVFile *f)
\r
124 if (geVFile_Write(f, Chunk, sizeof(GBSP_Chunk)) != GE_TRUE)
\r
126 //Hook.Error("WriteChunk: There was an error writing the chunk (Duh...).\n");
\r
131 if (Chunk->Type != GBSP_CHUNK_END)
\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
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
147 if (Chunk->Size * Chunk->Elements > 0)
\r
152 if (geVFile_Write(f, Data, Chunk->Size * Chunk->Elements) != GE_TRUE)
\r
154 //Hook.Error("WriteChunk: There was an error writing the chunk data.\n");
\r
162 //========================================================================================
\r
164 //========================================================================================
\r
165 geBoolean ReadChunkData(GBSP_Chunk *Chunk, void *Data, geVFile *f)
\r
167 if (geVFile_Read(f, Data, Chunk->Size * Chunk->Elements) != GE_TRUE)
\r
173 //========================================================================================
\r
175 //========================================================================================
\r
176 geBoolean ReadChunk(GBSP_Chunk *Chunk, geVFile *f)
\r
178 if (geVFile_Read(f, Chunk, sizeof(GBSP_Chunk)) != GE_TRUE)
\r
184 if (Chunk->Type != GBSP_CHUNK_END)
\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
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
201 switch(Chunk->Type)
\r
203 case GBSP_CHUNK_HEADER:
\r
205 if (!ReadChunkData(Chunk, (void*)&GBSPHeader, f))
\r
207 if (strcmp(GBSPHeader.TAG, "GBSP"))
\r
209 if (GBSPHeader.Version != GBSP_VERSION)
\r
214 case GBSP_CHUNK_MODELS:
\r
216 NumGFXModels = Chunk->Elements;
\r
217 GFXModels = GE_RAM_ALLOCATE_ARRAY(GFX_Model, NumGFXModels);
\r
218 if (!ReadChunkData(Chunk, GFXModels, f))
\r
222 case GBSP_CHUNK_NODES:
\r
224 NumGFXNodes = Chunk->Elements;
\r
225 GFXNodes = GE_RAM_ALLOCATE_ARRAY(GFX_Node,NumGFXNodes);
\r
226 if (!ReadChunkData(Chunk, GFXNodes, f))
\r
230 case GBSP_CHUNK_BNODES:
\r
232 NumGFXBNodes = Chunk->Elements;
\r
233 GFXBNodes = GE_RAM_ALLOCATE_ARRAY(GFX_BNode,NumGFXBNodes);
\r
234 if (!ReadChunkData(Chunk, GFXBNodes, f))
\r
238 case GBSP_CHUNK_LEAFS:
\r
240 NumGFXLeafs = Chunk->Elements;
\r
241 GFXLeafs = GE_RAM_ALLOCATE_ARRAY(GFX_Leaf,NumGFXLeafs);
\r
242 if (!ReadChunkData(Chunk, GFXLeafs, f))
\r
246 case GBSP_CHUNK_CLUSTERS:
\r
248 NumGFXClusters = Chunk->Elements;
\r
250 GFXClusters = GE_RAM_ALLOCATE_ARRAY(GFX_Cluster,NumGFXClusters);
\r
251 if (!ReadChunkData(Chunk, GFXClusters, f))
\r
255 case GBSP_CHUNK_AREAS:
\r
257 NumGFXAreas = Chunk->Elements;
\r
258 GFXAreas = GE_RAM_ALLOCATE_ARRAY(GFX_Area,NumGFXAreas);
\r
259 if (!ReadChunkData(Chunk, GFXAreas, f))
\r
263 case GBSP_CHUNK_AREA_PORTALS:
\r
265 NumGFXAreaPortals = Chunk->Elements;
\r
266 GFXAreaPortals = GE_RAM_ALLOCATE_ARRAY(GFX_AreaPortal,NumGFXAreaPortals);
\r
267 if (!ReadChunkData(Chunk, GFXAreaPortals, f))
\r
271 case GBSP_CHUNK_PORTALS:
\r
273 NumGFXPortals = Chunk->Elements;
\r
274 GFXPortals = GE_RAM_ALLOCATE_ARRAY(GFX_Portal,NumGFXPortals);
\r
275 if (!ReadChunkData(Chunk, GFXPortals, f))
\r
279 case GBSP_CHUNK_PLANES:
\r
281 NumGFXPlanes = Chunk->Elements;
\r
282 GFXPlanes = GE_RAM_ALLOCATE_ARRAY(GFX_Plane,NumGFXPlanes);
\r
283 if (!ReadChunkData(Chunk, GFXPlanes, f))
\r
287 case GBSP_CHUNK_FACES:
\r
289 NumGFXFaces = Chunk->Elements;
\r
290 GFXFaces = GE_RAM_ALLOCATE_ARRAY(GFX_Face,NumGFXFaces);
\r
291 if (!ReadChunkData(Chunk, GFXFaces, f))
\r
295 case GBSP_CHUNK_LEAF_FACES:
\r
297 NumGFXLeafFaces = Chunk->Elements;
\r
298 GFXLeafFaces = GE_RAM_ALLOCATE_ARRAY(int32,NumGFXLeafFaces);
\r
299 if (!ReadChunkData(Chunk, GFXLeafFaces, f))
\r
303 case GBSP_CHUNK_LEAF_SIDES:
\r
305 NumGFXLeafSides = Chunk->Elements;
\r
307 GFXLeafSides = GE_RAM_ALLOCATE_ARRAY(GFX_LeafSide,NumGFXLeafSides);
\r
308 if (!ReadChunkData(Chunk, GFXLeafSides, f))
\r
312 case GBSP_CHUNK_VERTS:
\r
314 NumGFXVerts = Chunk->Elements;
\r
315 GFXVerts = GE_RAM_ALLOCATE_ARRAY(geVec3d,NumGFXVerts);
\r
316 if (!ReadChunkData(Chunk, GFXVerts, f))
\r
320 case GBSP_CHUNK_VERT_INDEX:
\r
322 NumGFXVertIndexList = Chunk->Elements;
\r
323 GFXVertIndexList = GE_RAM_ALLOCATE_ARRAY(int32,NumGFXVertIndexList);
\r
324 if (!ReadChunkData(Chunk, GFXVertIndexList, f))
\r
329 case GBSP_CHUNK_RGB_VERTS:
\r
331 NumGFXRGBVerts = Chunk->Elements;
\r
332 GFXRGBVerts = GE_RAM_ALLOCATE_ARRAY(geVec3d,NumGFXRGBVerts);
\r
333 if (!ReadChunkData(Chunk, GFXRGBVerts, f))
\r
338 case GBSP_CHUNK_TEXINFO:
\r
340 NumGFXTexInfo = Chunk->Elements;
\r
341 GFXTexInfo = GE_RAM_ALLOCATE_ARRAY(GFX_TexInfo,NumGFXTexInfo);
\r
342 if (!ReadChunkData(Chunk, GFXTexInfo, f))
\r
347 case GBSP_CHUNK_TEXTURES:
\r
349 NumGFXTextures = Chunk->Elements;
\r
350 GFXTextures = GE_RAM_ALLOCATE_ARRAY(GFX_Texture,NumGFXTextures);
\r
351 if (!ReadChunkData(Chunk, GFXTextures, f))
\r
356 case GBSP_CHUNK_TEXDATA:
\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
365 case GBSP_CHUNK_ENTDATA:
\r
367 NumGFXEntData = Chunk->Elements;
\r
368 GFXEntData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXEntData);
\r
369 if (!ReadChunkData(Chunk, GFXEntData, f))
\r
373 case GBSP_CHUNK_LIGHTDATA:
\r
375 NumGFXLightData = Chunk->Elements;
\r
376 GFXLightData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXLightData);
\r
377 if (!ReadChunkData(Chunk, GFXLightData, f))
\r
381 case GBSP_CHUNK_VISDATA:
\r
383 NumGFXVisData = Chunk->Elements;
\r
384 GFXVisData = GE_RAM_ALLOCATE_ARRAY(uint8,NumGFXVisData);
\r
385 if (!ReadChunkData(Chunk, GFXVisData, f))
\r
389 case GBSP_CHUNK_SKYDATA:
\r
391 if (!ReadChunkData(Chunk, &GFXSkyData, f))
\r
395 case GBSP_CHUNK_PALETTES:
\r
397 NumGFXPalettes = Chunk->Elements;
\r
398 GFXPalettes = GE_RAM_ALLOCATE_ARRAY(DRV_Palette,NumGFXPalettes);
\r
401 if (!ReadChunkData(Chunk, GFXPalettes, f))
\r
405 case GBSP_CHUNK_MOTIONS:
\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
414 case GBSP_CHUNK_END:
\r
425 //========================================================================================
\r
427 //========================================================================================
\r
428 geBoolean LoadGBSPFile(char *FileName)
\r
433 f = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_DOS, FileName, NULL, GE_VFILE_OPEN_READONLY);
\r
440 if (!ReadChunk(&Chunk, f))
\r
443 if (Chunk.Type == GBSP_CHUNK_END)
\r
450 //========================================================================================
\r
452 //========================================================================================
\r
453 geBoolean FreeGBSPFile(void)
\r
456 geRam_Free(GFXModels);
\r
458 geRam_Free(GFXNodes);
\r
460 geRam_Free(GFXBNodes);
\r
462 geRam_Free(GFXLeafs);
\r
463 if (GFXClusters) // CHANGE: CLUSTER
\r
464 geRam_Free(GFXClusters);
\r
466 geRam_Free(GFXAreas);
\r
468 geRam_Free(GFXPortals);
\r
470 geRam_Free(GFXPlanes);
\r
472 geRam_Free(GFXFaces);
\r
474 geRam_Free(GFXLeafFaces);
\r
476 geRam_Free(GFXLeafSides);
\r
478 geRam_Free(GFXVerts);
\r
479 if (GFXVertIndexList)
\r
480 geRam_Free(GFXVertIndexList);
\r
482 geRam_Free(GFXRGBVerts);
\r
484 geRam_Free(GFXTextures);
\r
486 geRam_Free(GFXTexInfo);
\r
488 geRam_Free(GFXTexData);
\r
490 geRam_Free(GFXEntData);
\r
492 geRam_Free(GFXLightData);
\r
494 geRam_Free(GFXVisData);
\r
496 geRam_Free(GFXPalettes);
\r
498 geRam_Free(GFXMotionData);
\r
504 GFXClusters = NULL; // CHANGE: CLUSTER
\r
508 GFXLeafFaces = NULL;
\r
509 GFXLeafSides = NULL;
\r
511 GFXVertIndexList = NULL;
\r
512 GFXRGBVerts = NULL;
\r
515 GFXTextures = NULL;
\r
518 GFXPalettes = NULL;
\r
519 GFXMotionData = NULL;
\r
521 GFXLightData = NULL;
\r
529 NumGFXClusters = 0; // CHANGE: CLUSTER
\r
533 NumGFXLeafFaces = 0;
\r
534 NumGFXLeafSides = 0;
\r
536 NumGFXVertIndexList = 0;
\r
537 NumGFXRGBVerts = 0;
\r
541 NumGFXTextures = 0;
\r
543 NumGFXPalettes = 0;
\r
545 NumGFXMotionBytes = 0;
\r
547 NumGFXLightData = 0;
\r
554 //================================================================================
\r
556 //================================================================================
\r
557 geBoolean WriteChunks(GBSP_ChunkData *Data, int32 NumChunkData, geVFile *f)
\r
562 for (i=0; i< NumChunkData; i++)
\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
574 //================================================================================
\r
576 //================================================================================
\r
577 geBoolean SaveGBSPFile(char *FileName)
\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
610 f = geVFile_OpenNewSystem(NULL, GE_VFILE_TYPE_DOS, FileName, NULL, GE_VFILE_OPEN_CREATE);
\r
615 if (!WriteChunks(CurrentChunkData, sizeof(CurrentChunkData) / sizeof(CurrentChunkData[0]), f))
\r