00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "Common/Directory.h"
00012 #include "Common/Console.h"
00013 #include "Bsp/BspEntity.h"
00014
00015 #include "Bsp/BspLoader.h"
00016
00017
00018 KBspLoader::KBspLoader()
00019 : KFile()
00020 {
00021 m_pShaders = NULL;
00022 m_pPlanes = NULL;
00023 m_pNodes = NULL;
00024 m_pLeaves = NULL;
00025 m_pFaceList = NULL;
00026 m_pBrushList = NULL;
00027 m_pModels = NULL;
00028 m_pBrushes = NULL;
00029 m_pBrushSides = NULL;
00030 m_pVertices = NULL;
00031 m_pMeshVerts = NULL;
00032 m_pEffects = NULL;
00033 m_pFaces = NULL;
00034 m_pLightMaps = NULL;
00035 m_pLightVols = NULL;
00036 m_pVisiList = NULL;
00037
00038 m_nShaders = 0;
00039 m_nPlanes = 0;
00040 m_nNodes = 0;
00041 m_nLeaves = 0;
00042 m_nFaceList = 0;
00043 m_nBrushList = 0;
00044 m_nModels = 0;
00045 m_nBrushes = 0;
00046 m_nBrushSides = 0;
00047 m_nVertices = 0;
00048 m_nMeshVerts = 0;
00049 m_nEffects = 0;
00050 m_nFaces = 0;
00051 m_nLightMaps = 0;
00052 m_nLightVols = 0;
00053 m_nVisiList = 0;
00054
00055
00056 m_fScale = 1.0f;
00057
00058 m_bLoaded = false;
00059 }
00060
00061
00062 KBspLoader::~KBspLoader()
00063 {
00064 }
00065
00066
00067 s32 KBspLoader::LoadBSP( const char* pFileName )
00068 {
00069 KASSERT( !m_bLoaded );
00070 KASSERT( pFileName );
00071
00072 s32 Result;
00073
00074
00075 if( !Open( pFileName, KFM_READ ) )
00076 return BSP_ERROR_OPENFILE;
00077
00078
00079 *this >> m_Header;
00080
00081 if( strncmp( m_Header.m_Magic, "IBSP", 4 ) != 0 )
00082 {
00083 Close();
00084 return BSP_ERROR_BADVERSION;
00085 }
00086
00087 if( m_Header.m_Version < 0x2E )
00088 {
00089 Close();
00090 return BSP_ERROR_BADVERSION;
00091 }
00092
00093
00094 m_nShaders = ReadLump( LUMP_SHADERS , &m_pShaders );
00095 m_nPlanes = ReadLump( LUMP_PLANES , &m_pPlanes );
00096 m_nNodes = ReadLump( LUMP_NODES , &m_pNodes );
00097
00098 m_nFaceList = ReadLump( LUMP_FACELIST , &m_pFaceList );
00099 m_nBrushList = ReadLump( LUMP_BRUSHLIST , &m_pBrushList );
00100 m_nModels = ReadLump( LUMP_MODELS , &m_pModels );
00101 m_nBrushes = ReadLump( LUMP_BRUSHES , &m_pBrushes );
00102 m_nBrushSides = ReadLump( LUMP_BRUSHSIDES , &m_pBrushSides);
00103 m_nVertices = ReadLump( LUMP_VERTICES , &m_pVertices );
00104 m_nMeshVerts = ReadLump( LUMP_MESHVERTS , &m_pMeshVerts );
00105 m_nEffects = ReadLump( LUMP_EFFECTS , &m_pEffects );
00106 m_nFaces = ReadLump( LUMP_FACES , &m_pFaces );
00107 m_nLightMaps = ReadLump( LUMP_LIGHTMAPS , &m_pLightMaps );
00108 m_nLightVols = ReadLump( LUMP_LIGHTVOLS , &m_pLightVols );
00109
00110
00111 float fScale = GetScale();
00112
00113 for( u32 Vertices = 0; Vertices < m_nVertices; Vertices ++ )
00114 {
00115 m_pVertices[Vertices].m_Position *= fScale;
00116 }
00117
00118 for( u32 Planes = 0; Planes < m_nPlanes; Planes ++ )
00119 {
00120 m_pPlanes[Planes].m_Distance *= fScale;
00121 }
00122
00123 for( u32 Nodes = 0; Nodes < m_nNodes; Nodes ++ )
00124 {
00125 m_pNodes[Nodes].m_BBMins[0] = s32( (float)m_pNodes[Nodes].m_BBMins[0] * fScale );
00126 m_pNodes[Nodes].m_BBMins[1] = s32( (float)m_pNodes[Nodes].m_BBMins[1] * fScale );
00127 m_pNodes[Nodes].m_BBMins[2] = s32( (float)m_pNodes[Nodes].m_BBMins[2] * fScale );
00128 m_pNodes[Nodes].m_BBMaxs[0] = s32( (float)m_pNodes[Nodes].m_BBMaxs[0] * fScale );
00129 m_pNodes[Nodes].m_BBMaxs[1] = s32( (float)m_pNodes[Nodes].m_BBMaxs[1] * fScale );
00130 m_pNodes[Nodes].m_BBMaxs[2] = s32( (float)m_pNodes[Nodes].m_BBMaxs[2] * fScale );
00131 }
00132
00133 KBspLeafInt* pLeavesInt = NULL;
00134 m_nLeaves = ReadLump( LUMP_LEAVES, &pLeavesInt );
00135 m_pLeaves = new KBspLeaf[m_nLeaves];
00136 for( u32 Leaves = 0; Leaves < m_nLeaves; Leaves ++ )
00137 {
00138 m_pLeaves[Leaves].m_Area = pLeavesInt[Leaves].m_Area;
00139 m_pLeaves[Leaves].m_FirstBrushId = pLeavesInt[Leaves].m_FirstBrushId;
00140 m_pLeaves[Leaves].m_FirstFaceId = pLeavesInt[Leaves].m_FirstFaceId;
00141 m_pLeaves[Leaves].m_FirstVisListId = pLeavesInt[Leaves].m_FirstVisListId;
00142 m_pLeaves[Leaves].m_NumBrushes = pLeavesInt[Leaves].m_NumBrushes;
00143 m_pLeaves[Leaves].m_NumFaces = pLeavesInt[Leaves].m_NumFaces;
00144 m_pLeaves[Leaves].m_BBMin[0] = (float)pLeavesInt[Leaves].m_BBMin[0] * fScale;
00145 m_pLeaves[Leaves].m_BBMin[1] = (float)pLeavesInt[Leaves].m_BBMin[1] * fScale;
00146 m_pLeaves[Leaves].m_BBMin[2] = (float)pLeavesInt[Leaves].m_BBMin[2] * fScale;
00147 m_pLeaves[Leaves].m_BBMax[0] = (float)pLeavesInt[Leaves].m_BBMax[0] * fScale;
00148 m_pLeaves[Leaves].m_BBMax[1] = (float)pLeavesInt[Leaves].m_BBMax[1] * fScale;
00149 m_pLeaves[Leaves].m_BBMax[2] = (float)pLeavesInt[Leaves].m_BBMax[2] * fScale;
00150 }
00151 Deletev( pLeavesInt );
00152
00153
00154 Result = LoadVisiList();
00155
00156 if( Result != BSP_OK )
00157 {
00158 Close();
00159 return Result;
00160 }
00161
00162
00163 Result = LoadEntities();
00164
00165 if( Result != BSP_OK )
00166 {
00167 Close();
00168 return Result;
00169 }
00170
00171 Close();
00172
00173 m_bLoaded = true;
00174
00175 return BSP_OK;
00176 }
00177
00178
00179 s32 KBspLoader::CloseBSP()
00180 {
00181 if( m_pShaders ) Deletev( m_pShaders );
00182 if( m_pPlanes ) Deletev( m_pPlanes );
00183 if( m_pNodes ) Deletev( m_pNodes );
00184 if( m_pLeaves ) Deletev( m_pLeaves );
00185 if( m_pFaceList ) Deletev( m_pFaceList );
00186 if( m_pBrushList ) Deletev( m_pBrushList );
00187 if( m_pModels ) Deletev( m_pModels );
00188 if( m_pBrushes ) Deletev( m_pBrushes );
00189 if( m_pBrushSides ) Deletev( m_pBrushSides);
00190 if( m_pVertices ) Deletev( m_pVertices );
00191 if( m_pMeshVerts ) Deletev( m_pMeshVerts );
00192 if( m_pEffects ) Deletev( m_pEffects );
00193 if( m_pFaces ) Deletev( m_pFaces );
00194 if( m_pLightMaps ) Deletev( m_pLightMaps );
00195 if( m_pLightVols ) Deletev( m_pLightVols );
00196 if( m_pVisiList ) Deletep( m_pVisiList );
00197
00198 m_nShaders = 0;
00199 m_nPlanes = 0;
00200 m_nNodes = 0;
00201 m_nLeaves = 0;
00202 m_nFaceList = 0;
00203 m_nBrushList = 0;
00204 m_nModels = 0;
00205 m_nBrushes = 0;
00206 m_nBrushSides = 0;
00207 m_nVertices = 0;
00208 m_nMeshVerts = 0;
00209 m_nEffects = 0;
00210 m_nFaces = 0;
00211 m_nLightMaps = 0;
00212 m_nLightVols = 0;
00213 m_nVisiList = 0;
00214
00215 DestroyVisiList();
00216 DestroyEntities();
00217
00218 m_bLoaded = false;
00219
00220 return BSP_OK;
00221 }
00222
00223
00224 u32 KBspLoader::ReadLump( enum EBspLump Lump, u8** pData, u32 Size )
00225 {
00226 u32 Number = m_Header.m_Entry[Lump].m_Size / Size;
00227
00228 Seek( m_Header.m_Entry[Lump].m_Offset, KFS_BEGIN );
00229 Read( *pData, m_Header.m_Entry[Lump].m_Size );
00230
00231 return Number;
00232 }
00233
00234
00235 s32 KBspLoader::LoadVisiList()
00236 {
00237 if( !m_Header.m_Entry[LUMP_VISILIST].m_Size )
00238 return BSP_OK;
00239
00240 Seek( m_Header.m_Entry[LUMP_VISILIST].m_Offset, KFS_BEGIN );
00241
00242 m_pVisiList = new KBspVisiList;
00243 *this >> m_pVisiList->m_NumVectors;
00244 *this >> m_pVisiList->m_SizeOfVector;
00245
00246 u32 Size = m_pVisiList->m_NumVectors * m_pVisiList->m_SizeOfVector;
00247
00248 if( Size )
00249 {
00250
00251 m_nVisiList = 1;
00252 m_pVisiList->m_VisiList = new u8[Size];
00253
00254 Read( m_pVisiList->m_VisiList, Size );
00255 }
00256 else
00257 {
00258
00259 m_nVisiList = 0;
00260 Deletep( m_pVisiList );
00261 }
00262
00263 return BSP_OK;
00264 }
00265
00266
00267 void KBspLoader::DestroyVisiList()
00268 {
00269 if( m_pVisiList )
00270 Deletep( m_pVisiList );
00271 }
00272
00273
00274 s32 KBspLoader::LoadEntities()
00275 {
00276 u32 Size = m_Header.m_Entry[LUMP_ENTITIES].m_Size;
00277 KBspEntity* pEntity = NULL;
00278 char Char;
00279 char pString[1024];
00280 char pKey[1024];
00281 char pValue[1024];
00282 u32 nString = 0;
00283 bool bKey = false;
00284 bool bReadString = false;
00285 u32 Index = 0;
00286
00287 Seek( m_Header.m_Entry[LUMP_ENTITIES].m_Offset, KFS_BEGIN );
00288
00289 for( u32 Pos = 0; Pos < Size; Pos ++ )
00290 {
00291 *this >> Char;
00292
00293 if( bReadString )
00294 {
00295 pString[nString] = Char;
00296 pString[nString + 1] = '\0';
00297 nString ++;
00298 }
00299
00300 if(( Char == '{' ) && !bReadString )
00301 {
00302 KASSERT( !pEntity );
00303
00304 pEntity = new KBspEntity();
00305 pEntity->SetIndex( Index );
00306 Index ++;
00307 }
00308
00309 if(( Char == '}' ) && !bReadString )
00310 {
00311 KASSERT( pEntity );
00312
00313
00314 m_EntityList.Add( pEntity );
00315 pEntity = NULL;
00316 }
00317
00318 if( Char == 0x0A )
00319 {
00320 bKey = true;
00321 }
00322
00323 if( Char == '"' )
00324 {
00325 KASSERT( pEntity );
00326
00327 if( bReadString )
00328 {
00329 pString[nString - 1] = '\0';
00330 if( bKey )
00331 {
00332 bKey = false;
00333 strcpy( pKey, pString );
00334 }
00335 else
00336 {
00337 bKey = true;
00338 strcpy( pValue, pString );
00339
00340 if( strcmp( pKey, "classname" ) == 0 )
00341 pEntity->SetClassName( pValue );
00342 else
00343 pEntity->AddKey( pKey, pValue );
00344 }
00345 nString = 0;
00346 }
00347
00348 bReadString = !bReadString;
00349 }
00350 }
00351
00352 return BSP_OK;
00353 }
00354
00355
00356 void KBspLoader::DestroyEntities()
00357 {
00358 for( u32 i = 0; i < m_EntityList.GetSize(); i ++ )
00359 {
00360 KBspEntity* pEntity = m_EntityList[i];
00361
00362 Deletep( pEntity );
00363 }
00364 m_EntityList.Clear();
00365 }
00366
00367
00368 KBspEntity* KBspLoader::GetNextEntity( KBspEntity* pCurrentEntity, char* pClassName )
00369 {
00370 for( u32 i = pCurrentEntity ? pCurrentEntity->GetIndex() + 1 : 0; i < m_EntityList.GetSize(); i ++ )
00371 if( stricmp( m_EntityList[i]->GetClassName(), pClassName ) == 0 )
00372 return m_EntityList[i];
00373
00374 return NULL;
00375 }
00376