📄 q3bsp.cpp
字号:
// ==========================================================================================================
//
// BREW v2.0+ OPENGLES MICROENGINE
//
// ----------------------------------------
//
// Written by Vander Nunes
//
// ==========================================================================================================
#include "q3bsp.h"
#include <stdio.h>
#include <string.h>
//
//
//
CQ3BSP::CQ3BSP(CEngine* pEngine)
{
m_pEngine = pEngine;
m_pVfs = new CVfs();
VectorSet(m_Origin, 0,0,0); // player default start position
m_iAngle = ITOX(270); // player default angle
Unload();
}
//
//
//
CQ3BSP::~CQ3BSP()
{
DeletePtr(m_pVfs);
Unload();
}
//
//
//
void CQ3BSP::Unload()
{
DeletePtrArray(m_pTextures);
DeletePtrArray(m_pSurfaces);
DeletePtrArray(m_pPlanes);
DeletePtrArray(m_pNodes);
DeletePtrArray(m_pLeafs);
DeletePtrArray(m_pLeafFaces);
DeletePtrArray(m_pLeafBrushes);
DeletePtrArray(m_pModels);
DeletePtrArray(m_pBrushes);
DeletePtrArray(m_pBrushSides);
DeletePtrArray(m_pVertices);
DeletePtrArray(m_pMeshVerts);
DeletePtrArray(m_pEffects);
DeletePtrArray(m_pFaces);
DeletePtrArray(m_pLightmaps);
DeletePtrArray(m_pLightmapTextures);
DeletePtrArray(m_pLightvols);
DeletePtrArray(m_Visdata.pjVecs);
if (m_FastBSP.pFaces)
{
for (DWORD f=0; f<m_dwFaceCount; f++) DeletePtrArray(m_FastBSP.pFaces[f].pTris);
DeletePtrArray(m_FastBSP.pFaces);
}
DeletePtrArray(m_FastBSP.pVertices);
DeletePtrArray(m_FastBSP.pTexCoords);
DeletePtrArray(m_FastBSP.pLitCoords);
DeletePtrArray(m_FastBSP.pColValues);
m_dwFrame = 0;
m_wTexCount = 0;
m_dwPlaneCount = 0;
m_dwNodeCount = 0;
m_dwLeafCount = 0;
m_dwLeafFaceCount = 0;
m_dwLeafBrushCount = 0;
m_dwModelCount = 0;
m_dwBrushCount = 0;
m_dwBrushSideCount = 0;
m_dwVertexCount = 0;
m_dwMeshVertCount = 0;
m_dwEffectCount = 0;
m_dwFaceCount = 0;
m_dwLightmapCount = 0;
m_dwLightvolCount = 0;
m_dwVisdataCount = 0;
VectorSet(m_Origin, 0,0,0); // player default start position
m_iAngle = ITOX(270); // player default angle
}
//
//
//
boolean CQ3BSP::Load(char* szFile)
{
if (!m_pVfs->Unpack("game.dat", szFile, m_pEngine->Applet()))
return FALSE;
// read bsp header
header sHeader;
m_pVfs->Read(&sHeader, sizeof(header));
// check signature and version
if (STRNCMP(sHeader.szMagic, "IBSP", 4)) return FALSE;
if (sHeader.iVersion != 46) return FALSE;
// load map information
LoadEntities(&sHeader.sEntries[0]);
// load textures
LoadTextures(&sHeader.sEntries[1]);
// load planes
LoadPlanes(&sHeader.sEntries[2]);
// load nodes
LoadNodes(&sHeader.sEntries[3]);
// load leafs
LoadLeafs(&sHeader.sEntries[4]);
// load leaffaces
LoadLeafFaces(&sHeader.sEntries[5]);
// load leafbrushes
LoadLeafBrushes(&sHeader.sEntries[6]);
// load models
LoadModels(&sHeader.sEntries[7]);
// load brushes
LoadBrushes(&sHeader.sEntries[8]);
// load brushes
LoadBrushSides(&sHeader.sEntries[9]);
// load vertices
LoadVertices(&sHeader.sEntries[10]);
// load meshverts
LoadMeshVerts(&sHeader.sEntries[11]);
// load effects
LoadEffects(&sHeader.sEntries[12]);
// load faces
LoadFaces(&sHeader.sEntries[13]);
// load lightmaps
LoadLightmaps(&sHeader.sEntries[14]);
// load lightvols
LoadLightvols(&sHeader.sEntries[15]);
// load visdata
LoadVisdata(&sHeader.sEntries[16]);
ConvertToFast();
m_pVfs->Finish();
return TRUE;
}
//
// Load map information
//
boolean CQ3BSP::LoadEntities(direntry* pEntry)
{
char* szMapInfo = new char[pEntry->iLength];
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(szMapInfo, pEntry->iLength);
ParseMapInfo(szMapInfo);
DeletePtrArray(szMapInfo);
return TRUE;
}
//
// Load map textures
//
boolean CQ3BSP::LoadTextures(direntry* pEntry)
{
m_wTexCount = pEntry->iLength / sizeof(texture_lump);
m_pTextures = new texture_lump[m_wTexCount];
m_pSurfaces = new CTexture[m_wTexCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
for (WORD x=0; x<m_wTexCount; x++)
{
m_pVfs->Read(&m_pTextures[x], sizeof(texture_lump));
char szFile[128];
STRCPY(szFile, m_pTextures[x].szName);
STRCAT(szFile, ".tga");
m_pSurfaces[x].Load(m_pEngine->Applet(), "game.dat", szFile);
}
return TRUE;
}
//
// Load planes
//
boolean CQ3BSP::LoadPlanes(direntry* pEntry)
{
m_dwPlaneCount = pEntry->iLength / sizeof(plane_lump);
m_pPlanes = new plane_lump[m_dwPlaneCount];
// read all planes
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pPlanes, sizeof(plane_lump) * m_dwPlaneCount);
return TRUE;
}
//
// Load nodes
//
boolean CQ3BSP::LoadNodes(direntry* pEntry)
{
m_dwNodeCount = pEntry->iLength / sizeof(node_lump);
m_pNodes = new node_lump[m_dwNodeCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
for (DWORD x=0; x<m_dwNodeCount; x++)
{
m_pVfs->Read(&m_pNodes[x], sizeof(node_lump));
// convert bbox
int iTmp;
m_pNodes[x].iMin[0] = ITOX(m_pNodes[x].iMin[0]);
iTmp = ITOX(m_pNodes[x].iMin[1]);
m_pNodes[x].iMin[1] = ITOX(m_pNodes[x].iMin[2]);
m_pNodes[x].iMin[2] = -iTmp;
m_pNodes[x].iMax[0] = ITOX(m_pNodes[x].iMax[0]);
iTmp = ITOX(m_pNodes[x].iMax[1]);
m_pNodes[x].iMax[1] = ITOX(m_pNodes[x].iMax[2]);
m_pNodes[x].iMax[2] = -iTmp;
}
return TRUE;
}
//
// Load leafs
//
boolean CQ3BSP::LoadLeafs(direntry* pEntry)
{
m_dwLeafCount = pEntry->iLength / sizeof(leaf_lump);
m_pLeafs = new leaf_lump[m_dwLeafCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
for (DWORD x=0; x<m_dwNodeCount; x++)
{
m_pVfs->Read(&m_pLeafs[x], sizeof(leaf_lump));
// convert bbox
int iTmp;
m_pLeafs[x].iMin[0] = ITOX(m_pLeafs[x].iMin[0]);
iTmp = ITOX(m_pLeafs[x].iMin[1]);
m_pLeafs[x].iMin[1] = ITOX(m_pLeafs[x].iMin[2]);
m_pLeafs[x].iMin[2] = -iTmp;
m_pLeafs[x].iMax[0] = ITOX(m_pLeafs[x].iMax[0]);
iTmp = ITOX(m_pLeafs[x].iMax[1]);
m_pLeafs[x].iMax[1] = ITOX(m_pLeafs[x].iMax[2]);
m_pLeafs[x].iMax[2] = -iTmp;
}
return TRUE;
}
//
// Load leaffaces
//
boolean CQ3BSP::LoadLeafFaces(direntry* pEntry)
{
m_dwLeafFaceCount = pEntry->iLength / sizeof(leafface_lump);
m_pLeafFaces = new leafface_lump[m_dwLeafFaceCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pLeafFaces, sizeof(leafface_lump) * m_dwLeafFaceCount);
return TRUE;
}
//
// Load leafbrushes
//
boolean CQ3BSP::LoadLeafBrushes(direntry* pEntry)
{
m_dwLeafBrushCount = pEntry->iLength / sizeof(leafbrush_lump);
m_pLeafBrushes = new leafbrush_lump[m_dwLeafBrushCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pLeafBrushes, sizeof(leafbrush_lump) * m_dwLeafBrushCount);
return TRUE;
}
//
// Load models
//
boolean CQ3BSP::LoadModels(direntry* pEntry)
{
m_dwModelCount = pEntry->iLength / sizeof(model_lump);
m_pModels = new model_lump[m_dwModelCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pModels, sizeof(model_lump) * m_dwModelCount);
return TRUE;
}
//
// Load brushes
//
boolean CQ3BSP::LoadBrushes(direntry* pEntry)
{
m_dwBrushCount = pEntry->iLength / sizeof(brush_lump);
m_pBrushes = new brush_lump[m_dwBrushCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pBrushes, sizeof(brush_lump) * m_dwBrushCount);
return TRUE;
}
//
// Load brushsides
//
boolean CQ3BSP::LoadBrushSides(direntry* pEntry)
{
m_dwBrushSideCount = pEntry->iLength / sizeof(brushside_lump);
m_pBrushSides = new brushside_lump[m_dwBrushSideCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pBrushSides, sizeof(brushside_lump) * m_dwBrushSideCount);
return TRUE;
}
//
// Load vertices
//
boolean CQ3BSP::LoadVertices(direntry* pEntry)
{
m_dwVertexCount = pEntry->iLength / sizeof(vertex_lump);
m_pVertices = new vertex_lump[m_dwVertexCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pVertices, sizeof(vertex_lump) * m_dwVertexCount);
return TRUE;
}
//
// Load meshverts
//
boolean CQ3BSP::LoadMeshVerts(direntry* pEntry)
{
m_dwMeshVertCount = pEntry->iLength / sizeof(meshvert_lump);
m_pMeshVerts = new meshvert_lump[m_dwMeshVertCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pMeshVerts, sizeof(meshvert_lump) * m_dwMeshVertCount);
return TRUE;
}
//
// Load effects
//
boolean CQ3BSP::LoadEffects(direntry* pEntry)
{
m_dwEffectCount = pEntry->iLength / sizeof(effect_lump);
m_pEffects = new effect_lump[m_dwEffectCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pEffects, sizeof(effect_lump) * m_dwEffectCount);
return TRUE;
}
//
// Load faces
//
boolean CQ3BSP::LoadFaces(direntry* pEntry)
{
m_dwFaceCount = pEntry->iLength / sizeof(face_lump);
m_pFaces = new face_lump[m_dwFaceCount];
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
m_pVfs->Read(m_pFaces, sizeof(face_lump) * m_dwFaceCount);
return TRUE;
}
//
// Load lightmaps
//
boolean CQ3BSP::LoadLightmaps(direntry* pEntry)
{
m_dwLightmapCount = pEntry->iLength / sizeof(lightmap_lump);
m_pLightmaps = new lightmap_lump[m_dwLightmapCount];
m_pLightmapTextures = new CTexture[m_dwLightmapCount];
CTGA* pTga = new CTGA();
// read the lump
m_pVfs->SeekTo(pEntry->iOffset);
for (DWORD x=0; x<m_dwLightmapCount; x++)
{
m_pVfs->Read(&m_pLightmaps[x], sizeof(lightmap_lump));
// overbright lightmap
#if 1
BYTE* pLm = (BYTE*)m_pLightmaps[x].jLm;
for (DWORD y=0; y<128*128*3; y++)
pLm[y] = (BYTE)clamp((WORD)pLm[y]*2.0f, 0, 255);
#endif
pTga->Set(128, 128, 24, (BYTE*)&m_pLightmaps[x]);
m_pLightmapTextures[x].LoadFromMemory(pTga);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -