summaryrefslogtreecommitdiff
path: root/source/r_bsp.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/r_bsp.c')
-rw-r--r--source/r_bsp.c664
1 files changed, 0 insertions, 664 deletions
diff --git a/source/r_bsp.c b/source/r_bsp.c
deleted file mode 100644
index b1a499b..0000000
--- a/source/r_bsp.c
+++ /dev/null
@@ -1,664 +0,0 @@
-/*
-Copyright (C) 2003-2006 Andrey Nazarov
-
-This program is free software; you can redistribute it and/or
-modify it under the terms of the GNU General Public License
-as published by the Free Software Foundation; either version 2
-of the License, or (at your option) any later version.
-
-This program is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-
-See the GNU General Public License for more details.
-
-You should have received a copy of the GNU General Public License
-along with this program; if not, write to the Free Software
-Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
-*/
-
-//
-// r_bsp.c -- map loading functions common for both renderers
-//
-
-#include <config.h>
-#include "q_shared.h"
-#include "com_public.h"
-#include "q_files.h"
-#include "q_list.h"
-#include "r_shared.h"
-
-bspModel_t r_world;
-
-bspLeaf_t *Bsp_FindLeaf( vec3_t origin ) {
- bspNode_t *node;
- cplane_t *plane;
- vec_t dot;
-
- node = r_world.nodes;
- do {
- plane = node->plane;
- dot = DotProduct( plane->normal, origin ) - plane->dist;
- if( dot >= 0 ) {
- node = node->children[0];
- } else {
- node = node->children[1];
- }
- } while( node->plane );
-
- return ( bspLeaf_t * )node;
-}
-
-byte *Bsp_ClusterPVS( int clusterNum ) {
- if( !r_world.vis || clusterNum == -1 ) {
- return NULL;
- }
-
- return r_world.vis + clusterNum * r_world.rowsize;
-}
-
-
-/* ========================================================================= */
-
-#define Bsp_Malloc( size ) sys.HunkAlloc( &r_world.pool, size )
-
-static byte *loadData;
-
-static void Bsp_DecompressVis( byte *src, byte *dst, unsigned rowsize ) {
- unsigned count;
-
- do {
- if( *src ) {
- *dst++ = *src++;
- rowsize--;
- } else {
- src++; count = *src++;
- if( count > rowsize ) {
- Com_WPrintf( "Bsp_DecompressVis: overrun\n" );
- count = rowsize;
- }
- rowsize -= count;
- while( count-- ) {
- *dst++ = 0;
- }
- }
- } while( rowsize );
-}
-
-static void Bsp_LoadVis( lump_t *lump ) {
- dvis_t *src_vis;
- byte *dst, *src;
- uint32_t numClusters, rowsize;
- uint32_t offset;
- int i;
-
- if( !lump->filelen ) {
- r_world.vis = NULL;
- r_world.numClusters = 0;
- return;
- }
-
- src_vis = ( dvis_t * )( loadData + lump->fileofs );
- numClusters = LittleLong( src_vis->numclusters );
- if( !numClusters ) {
- r_world.vis = 0;
- r_world.numClusters = 0;
- return; // it is OK to have a map without vis
- }
- if( numClusters > MAX_MAP_LEAFS/8 ) {
- Com_Error( ERR_DROP, "%s: too many clusters", __func__ );
- }
-
- rowsize = ( numClusters + 7 ) >> 3;
- r_world.numClusters = numClusters;
- r_world.rowsize = rowsize;
- r_world.vis = Bsp_Malloc( numClusters * rowsize );
-
- dst = r_world.vis;
- for( i = 0; i < numClusters; i++ ) {
- offset = LittleLong( src_vis->bitofs[i][DVIS_PVS] );
- if( offset >= lump->filelen ) {
- Com_Error( ERR_DROP, "%s: bad offset", __func__ );
- }
-
- src = ( byte * )src_vis + offset;
- Bsp_DecompressVis( src, dst, rowsize );
- dst += rowsize;
- }
-}
-
-static void Bsp_LoadVertices( lump_t *lump ) {
- int i, count;
- dvertex_t *src, *dst;
-
- count = lump->filelen / sizeof( *src );
- if( lump->filelen % sizeof( *src ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.vertices = Bsp_Malloc( ( count + EXTRA_VERTICES ) * sizeof( *dst ) );
- r_world.numVertices = count;
-
- src = ( dvertex_t * )( loadData + lump->fileofs );
- dst = r_world.vertices;
- for( i = 0; i < count; i++ ) {
- dst->point[0] = LittleFloat( src->point[0] );
- dst->point[1] = LittleFloat( src->point[1] );
- dst->point[2] = LittleFloat( src->point[2] );
-
- src++; dst++;
- }
-}
-
-static void Bsp_LoadEdges( lump_t *lump ) {
- int i, count;
- dedge_t *src, *dst;
-
- count = lump->filelen / sizeof( *src );
- if( lump->filelen % sizeof( *src ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.edges = Bsp_Malloc( ( count + EXTRA_EDGES ) * sizeof( *dst ) );
- r_world.numEdges = count;
-
- src = ( dedge_t * )( loadData + lump->fileofs );
- dst = r_world.edges;
- for( i = 0; i < count; i++ ) {
- dst->v[0] = LittleShort( src->v[0] );
- dst->v[1] = LittleShort( src->v[1] );
-
- src++; dst++;
- }
-}
-
-static void Bsp_LoadSurfEdges( lump_t *lump ) {
- int i, count;
- int *src, *dst;
-
- count = lump->filelen / sizeof( *src );
- if( lump->filelen % sizeof( *src ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.surfEdges = Bsp_Malloc( ( count + EXTRA_SURFEDGES ) * sizeof( *dst ) );
- r_world.numSurfEdges = count;
-
- src = ( int * )( loadData + lump->fileofs );
- dst = r_world.surfEdges;
- for( i = 0; i < count; i++ ) {
- *dst++ = LittleLong( *src++ );
- }
-}
-
-static void Bsp_LoadTexinfo( lump_t *lump ) {
- int i, count;
- texinfo_t *src;
- bspTexinfo_t *dst, *tex;
- image_t *texture;
- char path[MAX_QPATH];
- int animNext;
-
- count = lump->filelen / sizeof( *src );
- if( lump->filelen % sizeof( *src ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.numTexinfos = count;
- r_world.texinfos = Bsp_Malloc( sizeof( *dst ) * count );
-
- src = ( texinfo_t * )( loadData + lump->fileofs );
- dst = r_world.texinfos;
- for( i = 0; i < count; i++ ) {
- Q_strncpyz( dst->name, src->texture, sizeof( dst->name ) );
- dst->flags = LittleLong( src->flags );
-
- dst->axis[0][0] = LittleFloat( src->vecs[0][0] );
- dst->axis[0][1] = LittleFloat( src->vecs[0][1] );
- dst->axis[0][2] = LittleFloat( src->vecs[0][2] );
-
- dst->axis[1][0] = LittleFloat( src->vecs[1][0] );
- dst->axis[1][1] = LittleFloat( src->vecs[1][1] );
- dst->axis[1][2] = LittleFloat( src->vecs[1][2] );
-
- dst->offset[0] = LittleFloat( src->vecs[0][3] );
- dst->offset[1] = LittleFloat( src->vecs[1][3] );
-
-#ifdef OPENGL_RENDERER
- upload_texinfo = dst;
-#endif
-
- animNext = LittleLong( src->nexttexinfo );
- if( animNext > 0 ) {
- if( animNext >= count ) {
- Com_Error( ERR_DROP, "%s: bad anim chain", __func__ );
- }
- dst->animNext = r_world.texinfos + animNext;
- } else {
- dst->animNext = NULL;
- }
-
- Q_concat( path, sizeof( path ), "textures/", dst->name, ".wal", NULL );
- texture = R_FindImage( path, it_wall );
- if( texture ) {
- dst->image = texture;
- } else {
- dst->image = r_notexture;
- }
-
-#ifdef OPENGL_RENDERER
- upload_texinfo = NULL;
-#endif
-
- src++; dst++;
- }
-
- dst = r_world.texinfos;
- for( i = 0; i < count; i++ ) {
- dst->numFrames = 1;
- for( tex = dst->animNext; tex && tex != dst; tex = tex->animNext ) {
- dst->numFrames++;
- }
- dst++;
- }
-}
-
-static void Bsp_LoadFaces( lump_t *lump ) {
- dface_t *src_face;
- bspSurface_t *dst_face;
- int i, j, count;
- uint16_t texinfoNum;
- uint32_t lightmapOffset;
- uint32_t firstEdge;
- uint16_t numEdges;
- uint16_t planeNum;
-
- count = lump->filelen / sizeof( *src_face );
- if( lump->filelen % sizeof( *src_face ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.surfaces = Bsp_Malloc( ( count + EXTRA_SURFACES ) * sizeof( *dst_face ) );
- r_world.numSurfaces = count;
-
- src_face = ( dface_t * )( loadData + lump->fileofs );
- dst_face = r_world.surfaces;
- for( i = 0; i < count; i++ ) {
- firstEdge = LittleLong( src_face->firstedge );
- numEdges = LittleShort( src_face->numedges );
- if( numEdges < 3 ) {
- Com_Error( ERR_DROP, "%s: bad surfedges", __func__ );
- }
- if( firstEdge + numEdges > r_world.numSurfEdges ) {
- Com_Error( ERR_DROP, "%s: surfedges out of bounds", __func__ );
- }
-
- planeNum = LittleShort( src_face->planenum );
- if( planeNum >= r_world.numPlanes ) {
- Com_Error( ERR_DROP, "%s: bad planenum", __func__ );
- }
-
- texinfoNum = LittleShort( src_face->texinfo );
- if( texinfoNum >= r_world.numTexinfos ) {
- Com_Error( ERR_DROP, "%s: bad texinfo", __func__ );
- }
-
- lightmapOffset = LittleLong( src_face->lightofs );
- if( lightmapOffset == ( uint32_t )-1 || r_world.lightmapSize == 0 ) {
- dst_face->lightmap = NULL;
- } else {
- if( lightmapOffset >= r_world.lightmapSize ) {
- Com_Error( ERR_DROP, "%s: bad lightofs", __func__ );
- }
- dst_face->lightmap = r_world.lightmap + lightmapOffset;
- }
-
- dst_face->texinfo = r_world.texinfos + texinfoNum;
- j = LittleShort( src_face->side );
- dst_face->side = j & 1;
- dst_face->index = i;
- dst_face->type = DSURF_POLY;
- dst_face->plane = r_world.planes + planeNum;
- dst_face->firstSurfEdge = r_world.surfEdges + firstEdge;
- dst_face->numSurfEdges = numEdges;
-
- src_face++; dst_face++;
- }
-}
-
-static void Bsp_LoadLeafFaces( lump_t *lump ) {
- int i, count;
- uint32_t faceNum;
- uint16_t *src;
- bspSurface_t **dst;
-
- count = lump->filelen / sizeof( *src );
- if( lump->filelen % sizeof( *src ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.numLeafFaces = count;
- r_world.leafFaces = Bsp_Malloc( sizeof( *dst ) * count );
-
- src = ( uint16_t * )( loadData + lump->fileofs );
- dst = r_world.leafFaces;
- for( i = 0; i < count; i++ ) {
- faceNum = LittleShort( *src );
- if( faceNum >= r_world.numSurfaces ) {
- Com_Error( ERR_DROP, "%s: bad face index\n", __func__ );
- }
- *dst = r_world.surfaces + faceNum;
-
- src++; dst++;
- }
-}
-
-static void Bsp_LoadLeafs( lump_t *lump ) {
- int i, count;
- uint16_t cluster, area;
- uint16_t firstLeafFace, numLeafFaces;
- dleaf_t *src;
- bspLeaf_t *dst;
-
- count = lump->filelen / sizeof( *src );
- if( lump->filelen % sizeof( *src ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.numLeafs = count;
- r_world.leafs = Bsp_Malloc( sizeof( *dst ) * count );
-
- src = ( dleaf_t * )( loadData + lump->fileofs );
- dst = r_world.leafs;
- for( i = 0; i < count; i++ ) {
- dst->index = i;
- dst->plane = NULL;
- dst->parent = NULL;
- dst->visframe = -1;
-
- area = LittleShort( src->area );
- if( area >= MAX_MAP_AREAS ) {
- Com_Error( ERR_DROP, "%s: bad area num", __func__ );
- }
- dst->area = area;
- dst->contents = LittleLong( src->contents );
-
- cluster = LittleShort( src->cluster );
- if( cluster == ( uint16_t )-1 || r_world.numClusters == 0 ) {
- dst->cluster = -1;
- } else {
- if( cluster >= r_world.numClusters ) {
- Com_Error( ERR_DROP, "%s: bad cluster num", __func__ );
- }
- dst->cluster = cluster;
- }
-
- firstLeafFace = LittleShort( src->firstleafface );
- numLeafFaces = LittleShort( src->numleaffaces );
-
- if( firstLeafFace + numLeafFaces > r_world.numLeafFaces ) {
- Com_Error( ERR_DROP, "%s: bad leafface", __func__ );
- }
-
- dst->firstLeafFace = r_world.leafFaces + firstLeafFace;
- dst->numLeafFaces = numLeafFaces;
-
- LSV( mins );
- LSV( maxs );
-
- src++; dst++;
- }
-}
-
-static void Bsp_LoadPlanes( lump_t *lump ) {
- int i, count;
- dplane_t *src;
- cplane_t *dst;
-
- count = lump->filelen / sizeof( *src );
- if( lump->filelen % sizeof( *src ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.numPlanes = count;
- r_world.planes = Bsp_Malloc( sizeof( *dst ) * count );
-
- src = ( dplane_t * )( loadData + lump->fileofs );
- dst = r_world.planes;
- for( i = 0; i < count; i++ ) {
- LV( normal );
- LF( dist );
- SetPlaneType( dst );
- SetPlaneSignbits( dst );
-
- src++; dst++;
- }
-}
-
-static void Bsp_LoadNodes( lump_t *lump ) {
- int i, j, count;
- uint32_t planenum;
- uint32_t child;
- dnode_t *src;
- bspNode_t *dst;
- uint16_t firstFace, numFaces;
-
- count = lump->filelen / sizeof( *src );
- if( lump->filelen % sizeof( *src ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.numNodes = count;
- r_world.nodes = Bsp_Malloc( sizeof( *dst ) * count );
-
- src = ( dnode_t * )( loadData + lump->fileofs );
- dst = r_world.nodes;
- for( i = 0; i < count; i++ ) {
- dst->index = i;
- dst->parent = NULL;
- dst->visframe = -1;
-
- // load splitting plane index
- planenum = LittleLong( src->planenum );
- if( planenum >= r_world.numPlanes ) {
- Com_Error( ERR_DROP, "%s: bad planenum for node %d", __func__, i );
- }
- dst->plane = r_world.planes + planenum;
-
- // load children indices
- for( j = 0; j < 2; j++ ) {
- child = LittleLong( src->children[j] );
- if( child & 0x80000000 ) {
- // leaf index
- child = ~child;
- if( child >= r_world.numLeafs ) {
- Com_Error( ERR_DROP, "%s: bad leafnum for node %d", __func__, i );
- }
- dst->children[j] = ( bspNode_t * )( r_world.leafs + child );
- } else {
- // node index
- if( child >= count ) {
- Com_Error( ERR_DROP, "%s: bad nodenum for node %d", __func__, i );
- }
- dst->children[j] = r_world.nodes + child;
- }
- }
-
- firstFace = LittleShort( src->firstface );
- numFaces = LittleShort( src->numfaces );
-
- if( firstFace + numFaces > r_world.numSurfaces ) {
- Com_Error( ERR_DROP, "%s: bad faces for node %d", __func__, i );
- }
-
- dst->firstFace = r_world.surfaces + firstFace;
- dst->numFaces = numFaces;
-
- LSV( mins );
- LSV( maxs );
-
- src++; dst++;
- }
-}
-
-static void Bsp_LoadLightMap( lump_t *lump ) {
- if( !lump->filelen ) {
- return;
- }
-
- r_world.lightmap = Bsp_Malloc( lump->filelen );
- memcpy( r_world.lightmap, loadData + lump->fileofs, lump->filelen );
- r_world.lightmapSize = lump->filelen;
-}
-
-static void Bsp_LoadSubmodels( lump_t *lump ) {
- int i, count;
- dmodel_t *src;
- bspSubmodel_t *dst;
- uint32_t firstFace, numFaces;
- uint32_t headnode;
-
- count = lump->filelen / sizeof( *src );
- if( lump->filelen % sizeof( *src ) ) {
- Com_Error( ERR_DROP, "%s: bad lump size", __func__ );
- }
-
- r_world.numSubmodels = count;
- r_world.submodels = Bsp_Malloc( sizeof( *dst ) * count );
-
- src = ( dmodel_t * )( loadData + lump->fileofs );
- dst = r_world.submodels;
- for( i = 0; i < count; i++ ) {
- firstFace = LittleLong( src->firstface );
- numFaces = LittleLong( src->numfaces );
- if( firstFace + numFaces > r_world.numSurfaces ) {
- Com_Error( ERR_DROP, "%s: bad faces for model %d", __func__, i );
- }
-
- headnode = LittleLong( src->headnode );
- if( headnode >= r_world.numNodes ) {
- // FIXME: headnode may be garbage for some models
- Com_DPrintf( "%s: bad headnode for model %d", __func__, i );
- dst->headnode = NULL;
- } else {
- dst->headnode = r_world.nodes + headnode;
- }
-
- dst->type = MODEL_BSP;
- dst->firstFace = r_world.surfaces + firstFace;
- dst->numFaces = numFaces;
-
- LV( mins );
- LV( maxs );
- LV( origin );
-
- dst->radius = RadiusFromBounds( dst->mins, dst->maxs );
-
- src++; dst++;
- }
-}
-
-
-static void Bsp_SetParent( bspNode_t *node ) {
- bspNode_t *child;
-
- while( node->plane ) {
- child = node->children[0];
- child->parent = node;
- Bsp_SetParent( child );
-
- child = node->children[1];
- child->parent = node;
- node = child;
- }
-
-}
-
-void Bsp_FreeWorld( void ) {
- if( r_world.name[0] ) {
- sys.HunkFree( &r_world.pool );
- memset( &r_world, 0, sizeof( r_world ) );
- }
-}
-
-void Bsp_LoadWorld( const char *path ) {
- dheader_t header;
- lump_t *lump;
- int i;
- byte *data;
- size_t length, endpos;
-
- length = fs.LoadFile( path, ( void ** )&data );
- if( !data ) {
- Com_Error( ERR_DROP, "%s: couldn't load %s", __func__, path );
- }
-
- if( length < sizeof( header ) ) {
- Com_Error( ERR_DROP, "%s: %s is too small", __func__, path );
- }
-
- // byte swap and validate the header
- header = *( dheader_t * )data;
- header.ident = LittleLong( header.ident );
- header.version = LittleLong( header.version );
- if( header.ident != IDBSPHEADER ) {
- Com_Error( ERR_DROP, "%s: %s is not an IBSP file", __func__, path );
- }
- if( header.version != BSPVERSION ) {
- Com_Error( ERR_DROP, "%s: %s has wrong IBSP version", __func__, path );
- }
-
- // byte swap and validate lumps
- for( i = 0, lump = header.lumps; i < HEADER_LUMPS; i++, lump++ ) {
- lump->fileofs = LittleLong( lump->fileofs );
- lump->filelen = LittleLong( lump->filelen );
- endpos = lump->fileofs + lump->filelen;
- if( endpos < lump->fileofs || endpos > length ) {
- Com_Error( ERR_DROP, "%s: %s has lump #%d out of bounds\n",
- __func__, path, i );
- }
- }
-
- loadData = data;
-
- // reserve 16 MB of virtual memory
- sys.HunkBegin( &r_world.pool, 0x1000000 );
-
-#ifdef OPENGL_RENDERER
- GL_BeginPostProcessing();
-#endif
-
-#define LOAD( Func, Lump ) do { \
- Bsp_Load##Func( &header.lumps[LUMP_##Lump] ); \
- } while( 0 )
-
- LOAD( Vis, VISIBILITY );
- LOAD( Vertices, VERTEXES );
- LOAD( Edges, EDGES );
- LOAD( SurfEdges, SURFEDGES );
- LOAD( Texinfo, TEXINFO );
- LOAD( LightMap, LIGHTING );
- LOAD( Planes, PLANES );
- LOAD( Faces, FACES );
- LOAD( LeafFaces, LEAFFACES );
- LOAD( Leafs, LEAFS );
- LOAD( Nodes, NODES );
- LOAD( Submodels, MODELS );
-
-#undef LOAD
-
-#ifdef OPENGL_RENDERER
- GL_EndPostProcessing();
-#endif
-
- fs.FreeFile( data );
-
- sys.HunkEnd( &r_world.pool );
-
- Bsp_SetParent( r_world.nodes );
-
- strcpy( r_world.name, path );
-}
-
-