|
//
// BSPFile.cpp
//
// Class to facilitate opening a HL BSP file from disk and loading data lumps into memory
//
// Copyright 2005 Paul Higinbotham
//
#include "stdafx.h"
#include "BSPFile.h"
#include "..\..\collections\String.h"
using namespace ZGraphics;
void BSPFile::Open(const char * pszFilename)
{
Close();
m_pBSPFile = fopen(pszFilename, "rb");
assert (m_pBSPFile);
if (!m_pBSPFile)
{
String<char> szMessage = "Error: Unable to open scene file: ";
szMessage += pszFilename;
throw szMessage;
}
}
void BSPFile::Close()
{
if (m_pBSPFile)
fclose(m_pBSPFile);
m_pBSPFile = 0;
}
//
// Data lumps
//
DataLump<bspf_plane> * BSPFile::LoadPlanes()
{
int cByteLength;
bspf_plane * pData = reinterpret_cast<bspf_plane *>(_readLump(LUMP_PLANES, cByteLength));
int cSize = cByteLength / sizeof(bspf_plane);
assert(cByteLength % cSize == 0);
return new DataLump<bspf_plane>(pData, cSize);
}
DataLump<bspf_vertex> * BSPFile::LoadVertices()
{
int cByteLength;
bspf_vertex * pData = reinterpret_cast<bspf_vertex *>(_readLump(LUMP_VERTEXES, cByteLength));
int cSize = cByteLength / sizeof(bspf_vertex);
assert(cByteLength % cSize == 0);
return new DataLump<bspf_vertex>(pData, cSize);
}
DataLump<unsigned char> * BSPFile::LoadVisibility()
{
int cByteLength;
unsigned char * pData = _readLump(LUMP_VISIBILITY, cByteLength);
return new DataLump<unsigned char>(pData, cByteLength);
}
DataLump<bspf_node> * BSPFile::LoadBSPNodes()
{
int cByteLength;
bspf_node * pData = reinterpret_cast<bspf_node *>(_readLump(LUMP_NODES, cByteLength));
int cSize = cByteLength / sizeof(bspf_node);
assert(cByteLength % cSize == 0);
return new DataLump<bspf_node>(pData, cSize);
}
DataLump<bspf_textinfo> * BSPFile::LoadTextureInfo()
{
int cByteLength;
bspf_textinfo * pData = reinterpret_cast<bspf_textinfo *>(_readLump(LUMP_TEXINFO, cByteLength));
int cSize = cByteLength / sizeof(bspf_textinfo);
assert(cByteLength % cSize == 0);
return new DataLump<bspf_textinfo>(pData, cSize);
}
DataLump<bspf_textlump> * BSPFile::LoadTextureLump()
{
int cByteLength;
bspf_textlump * pData = reinterpret_cast<bspf_textlump *>(_readLump(LUMP_TEXTURES, cByteLength));
return new DataLump<bspf_textlump>(pData, 1);
}
DataLump<bspf_face> * BSPFile::LoadFaces()
{
int cByteLength;
bspf_face * pData = reinterpret_cast<bspf_face *>(_readLump(LUMP_FACES, cByteLength));
int cSize = cByteLength / sizeof(bspf_face);
assert(cByteLength % cSize == 0);
return new DataLump<bspf_face>(pData, cSize);
}
DataLump<unsigned char> * BSPFile::LoadLightMaps()
{
int cByteLength;
unsigned char * pData = _readLump(LUMP_LIGHTING, cByteLength);
return new DataLump<unsigned char>(pData, cByteLength);
}
DataLump<bspf_leaf> * BSPFile::LoadLeaves()
{
int cByteLength;
bspf_leaf * pData = reinterpret_cast<bspf_leaf *>(_readLump(LUMP_LEAFS, cByteLength));
int cSize = cByteLength / sizeof(bspf_leaf);
assert(cByteLength % cSize == 0);
return new DataLump<bspf_leaf>(pData, cSize);
}
DataLump<unsigned short> * BSPFile::LoadLeafFaceTable()
{
int cByteLength;
unsigned short * pData = reinterpret_cast<unsigned short *>(_readLump(LUMP_MARKSURFACES, cByteLength));
int cSize = cByteLength / sizeof(unsigned short);
assert(cByteLength % cSize == 0);
return new DataLump<unsigned short>(pData, cSize);
}
DataLump<bspf_edge> * BSPFile::LoadEdges()
{
int cByteLength;
bspf_edge * pData = reinterpret_cast<bspf_edge *>(_readLump(LUMP_EDGES, cByteLength));
int cSize = cByteLength / sizeof(bspf_edge);
assert(cByteLength % cSize == 0);
return new DataLump<bspf_edge>(pData, cSize);
}
DataLump<unsigned long> * BSPFile::LoadFaceEdgeTable()
{
int cByteLength;
unsigned long * pData = reinterpret_cast<unsigned long *>(_readLump(LUMP_SURFEDGES, cByteLength));
int cSize = cByteLength / sizeof(unsigned long);
assert(cByteLength % cSize == 0);
return new DataLump<unsigned long>(pData, cByteLength);
}
DataLump<unsigned char> * BSPFile::LoadEntities()
{
int cByteLength;
unsigned char * pData = _readLump(LUMP_ENTITIES, cByteLength);
return new DataLump<unsigned char>(pData, cByteLength);
}
DataLump<bspf_dmodel> * BSPFile::LoadModels()
{
int cByteLength;
bspf_dmodel * pData = reinterpret_cast<bspf_dmodel *>(_readLump(LUMP_MODELS, cByteLength));
int cSize = cByteLength / sizeof(bspf_dmodel);
assert(cByteLength % cSize == 0);
return new DataLump<bspf_dmodel>(pData, cByteLength);
}
//
// Private methods
//
unsigned char * BSPFile::_readLump(int nLumpIndex, int & cLength)
{
bspf_lump lumpInfo;
_checkSeek(4+nLumpIndex*sizeof(bspf_lump), SEEK_SET); // Index past the beginning version integer
_checkRead(&lumpInfo, sizeof(bspf_lump));
unsigned char * pData = new unsigned char[lumpInfo.length];
// Read data lump from file
_checkSeek(lumpInfo.offset, SEEK_SET);
_checkRead(pData, lumpInfo.length);
cLength = lumpInfo.length;
return pData;
}
inline void BSPFile::_checkSeek(long offset, int origin)
{
assert(m_pBSPFile);
if (m_pBSPFile == 0)
{
throw "Error: Scene file not open during file seek operation";
}
if (fseek(m_pBSPFile, offset, origin) != 0)
{
throw "Error: Seek failed for scene file read";
}
}
inline void BSPFile::_checkRead(void * pBuf, size_t size)
{
assert(m_pBSPFile);
if (m_pBSPFile == 0)
{
throw "Error: Scene file not open during file seek operation";
}
size_t nRead = fread(pBuf, 1, size, m_pBSPFile);
if (nRead != size)
{
throw "Error: Scene file read operation failed";
}
}
|
By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.
If a file you wish to view isn't highlighted, and is a text file (not binary), please
let us know and we'll add colourisation support for it.
I am a senior software developer currently doing contract work for Microsoft. My educational background is in electrical engineering and I hold a masters degree from the University of Washington. I have experience in hardware and systems design but have done primarily software development for the last two decades. I have worked for various small companies as well as start-up companies, and have worked as a full time employee SDE at Microsoft Corporation.