#include
<stdio.h>
// fopen(..), fclose(..)
#include
<assert.h> //
assert(..)
#define
SZ_FILE_BSP "test_level.bsp"
// Quake 3 BSP Level File
//----------------------- Various BSP Lump Data
Types-----------------------------//
enum
BSP_TYPES
{
enEntities=0,
enTextures,
enPlanes,
enNodes,
enLeaves,
enLeafFaces,
enLeafBrushes,
enModels,
enBrushes,
enBrushSides,
enVertices,
enMeshIndices,
enEffect,
enFaces,
enLightmaps,
enLightVols,
enVisData
};
char
szBSPTYPES [17][20] = {
"Entities",
"Textures",
"Planes",
"Nodes",
"Leaves",
"LeafFaces",
"LeafBrushes",
"Models",
"Brushes",
"BrushSides",
"Vertices",
"MeshIndices",
"Effect",
"Faces",
"Lightmaps",
"LightVols",
"VisData"
};
//------------------------- Various Structure Definitions
------------------------//
struct
stLump
{
int nFileofs;
// Offset to start of lump, relative to beginning
of file.
int nFileLen;
// Length of lump. Always a multiple of 4.
};
struct
stHeader
{
char cMagic[4];
int nVersion;
stLump Lumps[17];
};
//----------------------------- Lump Definitions
---------------------------------//
typedef
float Vector2[2];
typedef
float Vector3[3];
typedef
float Vector4[4];
typedef
float TexCoord[2];
typedef
int nBBox[6];
// Integer bounding box (mins, maxs)
typedef
float fBBox[6];
// Float bounding box
//Lump 0
//Entities
char
*entities; // A pointer to text
//Lump 1
//Shader Texture Info
struct
stShaderRef
{
char Name[64];
// Texture name
int nSurfaceFlags;
// Type of surface (See Surface Flags below)
int nContentFlags;
// Leaf content (See Content Flags below)
};
//Lump 2
//Planes
struct
stPlane
{
Vector3 Normal; // Normal vector for
plane
float fDist;
// Distance from plane to origin
};
//Lump 3
//Nodes
struct
stNode
{
int nPlane;
// Space partitioning plane
int nChildren[2];
// Back and front child nodes
nBBox BBoxI; // Bounding box of
node
};
//Lump 4
//Leaves
struct
stLeaf
{
int nCluster;
// Visibility cluster number
int nArea;
// Volume of the leaf
nBBox BBoxI; // Bounding box of
leaf
int nFirstFace,
NumFaces; // Lookup for
the face list (indexes
// are
for faces)
int nFirstBrush,
NumBrushes; // Lookup for
the brush list (indexes
// are
for brushes)
};
//Lump 5
//Leaf Faces
int
*pFaces; // a pointer to a
series of indexes to
// a
face list
//Lump 6
//Leaf Brushes
int
*pBrushes; // a pointer to a
series of indexes to
// a
brush list
//Lump 7
//Models
struct
stModel
{
fBBox BBoxF; // Bounding box of
model
int nFirstFace,
// First face for model
NumFaces; // Number of
faces for model
int nFirstBrush,
// First brush for model
NumBrushes; // Number of
brushes for model
};
//Lump 8
//Brushes
struct
stBrush
{
int nFirstSide,
// First brushside for brush
NumSides; // Number of
brushsides for brush
int nIndex;
// Texture index
};
//Lump 9
//Brush Sides
struct
stBrushSide
{
int PlaneNum;
// Lookup for plane
int nIndex;
// Texture index
};
//Lump 10
//Vertices
struct
stVertex
{
Vector3 vPoint; // Vertex Position
TexCoord Tex; // Texture
coordinates
TexCoord LightTexCoord; // Light Map texture
coordinates
Vector3 vNormal; // Normal vector (used for
lighting ?)
unsigned int
RGBA; // Vertex color. RGBA
};
//Lump 11
//MeshVert
int
nOffset; // Vertex index
offset, relative to first
//
vertex of corresponding face.
//Lump 12
//Effect
struct
stEffect
{
char cName[64];
// Effect shader.
int nBrush;
// Brush that generated this effect.
int Unknown;
// Always 5, except in q3dm8, which has
// one
effect with -1.
};
//Lump 13
//Faces
#pragma
pack(1)
struct
stFace // size 24*4
{
int nShader;
// Refers to a shader
int nEffect;
// Index into lump 12 (Effects), or -1
int nFaceType;
// Face type. 1=polygon, 2=patch, 3=mesh,
4=billboard
int FirstVert,
NumVerts; // Reference
to vertices
int nFirstMeshVerts,
// Index of first meshvert
// Every
three meshverts describe a triangle
NumMeshVerts; // Number of
meshverts
int LMIndex;
// Lightmap index.
int LMStart[2];
// X,Y Corner of this face's lightmap image in
lightmap.
int LMSize[2];
// Size of lightmap
float LMOrigin[3];
// World space origin of lightmap.
float LMVects[2][3];
// World space lightmap s and t unit vectors.
Vector3 vNormal; // Face normal
int nSize[2];
// Patch dimensions.
};
#pragma
pack()
//Lump 14
//Lightmaps
unsigned
char pMap[128][128][3];
// Lightmap color data. RGB.
//Lump 15
//Light Grid
//Unknown
//Lump 16
//Visibility Lists
struct
stVisibility
{
int NumVectors;
// Number of vectors.
int nSizeVector;
// Size of each vector, in bytes
unsigned char
*pData; // [NumVectors * nSizeVector];
//
Visibility data. One bit per cluster per vector
};
//Lump 17
//Number of Lumps
//Unknown
//-----------------------Write Debug Feedback
Information-------------------------//
void
abc(char *str)
{
FILE *fp = fopen("dbg.txt", "a+");
fprintf(fp, "%s", str);
fclose(fp);
}
//-------------------------- Program Entry Point
---------------------------------//
void
main()
{
abc("<->Opening
File\n\n");
// Open BSP File
FILE * fp = fopen(SZ_FILE_BSP, "rb");
// Temporary Buffer
stHeader Data;
fread(&Data, //
Buffer
sizeof(stHeader),
// Size
1, //
Number of times
fp);
// File Pointer
// Temp string buffer
char buf[100];
sprintf(buf, "<?>stHeader:cMagic = %c%c%c%c\n",
Data.cMagic[0], // 'I'
Data.cMagic[1], // 'B'
Data.cMagic[2], // 'S'
Data.cMagic[3]); // 'P'
abc(buf);
sprintf(buf, "<?>stHeader:ver = 0x%X\n\n",
Data.nVersion); // 0x2E
for Quake3
abc(buf);
// Get the pointer to our array of lumps
stLump * pLumps = Data.Lumps;
// Display all the different types of Lumps
for(int i=0;
i<17; i++)
{
sprintf(buf, "<?>\tLump:(%d):%s"
"FileOffset: 0x%X"
"Length: 0x%X\n",
i+1,
szBSPTYPES[i],
pLumps[i].nFileofs,
pLumps[i].nFileLen);
abc(buf);
}
//------------------------------------Vertices------------------------------------//
stLump * pLump = &pLumps[enVertices];
fseek( fp,
pLump->nFileofs,
SEEK_SET );
char * pVData = new
char[pLump->nFileLen];
assert(pVData);
fread( pVData, //
Buffer
1, //
Size
pLump->nFileLen, // Number of
times
fp ); // File
Pointer
stVertex * pVerts = 0;
pVerts = (stVertex*)pVData;
int nNumVerts = pLump->nFileLen /
sizeof(stVertex);
sprintf(buf, "\n<?>Num Vertices: %d\n", nNumVerts);
abc(buf);
for(i=0; i<nNumVerts; i++)
{
// We will only display some of the
information
sprintf(buf,"<?>Point:(%.2f,%.2f,%.2f) "
"Normal(%.2f,%.2f,%.2f) "
"RGBA(0x%X)\n",
pVerts[i].vPoint[0],
// x
pVerts[i].vPoint[1],
// y
pVerts[i].vPoint[2],
// z
pVerts[i].vNormal[0],//
nx
pVerts[i].vNormal[1],//
ny
pVerts[i].vNormal[2],//
nz
pVerts[i].RGBA );
// rgba
abc(buf);
}//End
for i
delete[] pVData;
//------------------------------------ Faces
-------------------------------------//
pLump = &pLumps[enFaces];
fseek( fp,
pLump->nFileofs,
SEEK_SET );
char * pFData = new
char[pLump->nFileLen];
assert(pFData);
fread( pFData, //
Buffer
pLump->nFileLen, // Size
1, //
Number of times
fp ); // File
Pointer
stFace * pFaces = 0;
pFaces = (stFace*)pFData;
int nNumFaces = pLump->nFileLen /
sizeof(stFace);
// Display Information
sprintf(buf, "\n<?>Num Faces: %d\n", nNumFaces);
abc(buf);
for(i=0; i<nNumFaces; i++)
{
// We will only display some of the
information
sprintf(buf,"<?>FirstVert(%d) "
"NumVerts(%d) "
"FirstMeshVert(%d) "
"NumMeshVerts(%d) \n",
pFaces[i].FirstVert,
pFaces[i].NumVerts,
pFaces[i].nFirstMeshVerts,
pFaces[i].NumMeshVerts);
abc(buf);
}//End
for i
delete[] pFData;
abc("\n<->Closing
File\n");
// Close BSP File
fclose(fp);
}//End
main()
|