summaryrefslogtreecommitdiff
path: root/source/cmodel.c
diff options
context:
space:
mode:
Diffstat (limited to 'source/cmodel.c')
-rw-r--r--source/cmodel.c948
1 files changed, 87 insertions, 861 deletions
diff --git a/source/cmodel.c b/source/cmodel.c
index c2c1aa3..de0c01c 100644
--- a/source/cmodel.c
+++ b/source/cmodel.c
@@ -20,13 +20,15 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
// cmodel.c -- model loading
#include "com_local.h"
+#include "q_list.h"
+#include "files.h"
+#include "sys_public.h"
+#include "bsp.h"
+#include "cmodel.h"
-#define CM_Malloc( size ) Z_TagMalloc( size, TAG_CMODEL )
-#define CM_Mallocz( size ) Z_TagMallocz( size, TAG_CMODEL )
-#define CM_Free( ptr ) Z_Free( ptr )
+mtexinfo_t nulltexinfo;
-static mapsurface_t nullsurface;
-static cleaf_t nullleaf;
+static mleaf_t nullleaf;
static int floodvalid;
static int checkcount;
@@ -36,513 +38,20 @@ static cvar_t *map_override;
void CM_FloodAreaConnections( cm_t *cm );
-typedef struct {
- void *base;
- size_t count;
-} cmlump_t;
-
-typedef struct {
- size_t size;
- size_t mincount;
- size_t maxcount;
- const char *name;
-} lump_info_t;
-
-static const lump_info_t lump_info[HEADER_LUMPS] = {
- { 1, 0, MAX_MAP_ENTSTRING, "entities" },
- { sizeof( dplane_t ), 1, MAX_MAP_PLANES, "planes" },
- { sizeof( dvertex_t ), 0, MAX_MAP_VERTS, "verts" },
- { 1, 0, MAX_MAP_VISIBILITY, "visibility" },
- { sizeof( dnode_t ), 1, MAX_MAP_NODES, "nodes" },
- { sizeof( texinfo_t ), 1, MAX_MAP_TEXINFO, "texinfo" },
- { sizeof( dface_t ), 0, MAX_MAP_FACES, "faces" },
- { 1, 0, MAX_MAP_LIGHTING, "lighting" },
- { sizeof( dleaf_t ), 1, MAX_MAP_LEAFS, "leafs" },
- { sizeof( uint16_t ), 0, MAX_MAP_LEAFFACES, "leaf faces" },
- { sizeof( uint16_t ), 1, MAX_MAP_LEAFBRUSHES, "leaf brushes" },
- { sizeof( dedge_t ), 0, MAX_MAP_EDGES, "edges" },
- { sizeof( uint32_t ), 0, MAX_MAP_SURFEDGES, "surf edges" },
- { sizeof( dmodel_t ), 1, MAX_MAP_MODELS, "models" },
- { sizeof( dbrush_t ), 1, MAX_MAP_BRUSHES, "brushes" },
- { sizeof( dbrushside_t ), 1, MAX_MAP_BRUSHSIDES, "brush sides" },
- { 0, 0, 0, NULL },
- { sizeof( darea_t ), 0, MAX_MAP_AREAS, "areas" },
- { sizeof( dareaportal_t ), 0, MAX_MAP_AREAPORTALS, "area portals" }
-};
-
-/*
-===============================================================================
-
- MAP LOADING
-
-===============================================================================
-*/
-
-#define CM_FUNC( Func ) \
- static qboolean CM_Load##Func( cmcache_t *cache, cmlump_t *l )
-
-/*
-=================
-CM_LoadSubmodels
-=================
-*/
-CM_FUNC( Submodels ) {
- dmodel_t *in;
- cmodel_t *out;
- int i, j;
- unsigned headnode;
-
- cache->cmodels = CM_Malloc( sizeof( *out ) * l->count );
- cache->numcmodels = l->count;
-
- in = l->base;
- out = cache->cmodels;
- for( i = 0; i < l->count; i++, in++, out++ ) {
- for( j = 0; j < 3; j++ ) {
- // spread the mins / maxs by a pixel
- out->mins[j] = LittleFloat (in->mins[j]) - 1;
- out->maxs[j] = LittleFloat (in->maxs[j]) + 1;
- out->origin[j] = LittleFloat (in->origin[j]);
- }
- headnode = LittleLong (in->headnode);
- if( headnode >= cache->numnodes ) {
- // FIXME: headnode may be garbage for some models
- Com_DPrintf( "%s: bad headnode for model %d\n", __func__, i );
- out->headnode = NULL;
- } else {
- out->headnode = cache->nodes + headnode;
- }
- }
- return qtrue;
-}
-
-
-/*
-=================
-CM_LoadSurfaces
-=================
-*/
-CM_FUNC( Surfaces ) {
- texinfo_t *in;
- mapsurface_t *out;
- int i;
-
- cache->numtexinfo = l->count;
- cache->surfaces = CM_Malloc( sizeof( *out ) * l->count );
-
- in = l->base;
- out = cache->surfaces;
- for( i = 0; i < l->count; i++, in++, out++ ) {
- memcpy( out->c.name, in->texture, sizeof( out->c.name ) );
- out->c.name[ sizeof( out->c.name ) - 1 ] = 0;
- memcpy( out->rname, in->texture, sizeof( out->rname ) );
- out->rname[ sizeof( out->rname ) - 1 ] = 0;
- out->c.flags = LittleLong (in->flags);
- out->c.value = LittleLong (in->value);
- }
- return qtrue;
-}
-
-
-/*
-=================
-CM_LoadNodes
-=================
-*/
-CM_FUNC( Nodes ) {
- dnode_t *in;
- uint32_t child;
- cnode_t *out;
- int i, j;
- unsigned planeNum;
-
- cache->numnodes = l->count;
- cache->nodes = CM_Malloc( sizeof( *out ) * l->count );
-
- in = l->base;
- out = cache->nodes;
- for( i = 0; i < l->count; i++, out++, in++ ) {
- planeNum = LittleLong(in->planenum);
- if( planeNum >= cache->numplanes ) {
- Com_DPrintf( "%s: bad planenum\n", __func__ );
- return qfalse;
- }
- out->plane = cache->planes + planeNum;
-
- for( j = 0; j < 2; j++ ) {
- child = LittleLong( in->children[j] );
- if( child & 0x80000000 ) {
- child = ~child;
- if( child >= cache->numleafs ) {
- Com_DPrintf( "%s: bad leafnum\n", __func__ );
- return qfalse;
- }
- out->children[j] = ( cnode_t * )( cache->leafs + child );
- } else {
- if( child >= l->count ) {
- Com_DPrintf( "%s: bad nodenum\n", __func__ );
- return qfalse;
- }
- out->children[j] = cache->nodes + child;
- }
- }
- }
- return qtrue;
-}
-
-/*
-=================
-CM_LoadBrushes
-=================
-*/
-CM_FUNC( Brushes ) {
- dbrush_t *in;
- cbrush_t *out;
- int i;
- unsigned firstSide, numSides, lastSide;
-
- cache->numbrushes = l->count;
- cache->brushes = CM_Malloc( sizeof( *out ) * l->count );
-
- in = l->base;
- out = cache->brushes;
- for( i = 0; i < l->count; i++, out++, in++ ) {
- firstSide = LittleLong(in->firstside);
- numSides = LittleLong(in->numsides);
- lastSide = firstSide + numSides;
- if( lastSide < firstSide || lastSide > cache->numbrushsides ) {
- Com_DPrintf( "%s: bad brushsides\n", __func__ );
- return qfalse;
- }
- out->firstbrushside = cache->brushsides + firstSide;
- out->numsides = numSides;
- out->contents = LittleLong(in->contents);
- out->checkcount = 0;
- }
- return qtrue;
-}
-
/*
-=================
-CM_LoadLeafs
-=================
-*/
-CM_FUNC( Leafs ) {
- cleaf_t *out;
- dleaf_t *in;
- int i;
- unsigned areaNum, firstBrush, numBrushes;
-
- cache->numleafs = l->count;
- cache->numclusters = 0;
- cache->leafs = CM_Malloc( sizeof( *out ) * l->count );
-
- in = l->base;
- out = cache->leafs;
- for( i = 0; i < l->count; i++, in++, out++ ) {
- out->plane = NULL;
- out->contents = LittleLong (in->contents);
- out->cluster = ( signed short )LittleShort (in->cluster);
- areaNum = LittleShort (in->area);
- if( areaNum >= cache->numareas ) {
- Com_DPrintf( "%s: bad areanum\n", __func__ );
- return qfalse;
- }
- out->area = areaNum;
-
- firstBrush = LittleShort (in->firstleafbrush);
- numBrushes = LittleShort (in->numleafbrushes);
- if( firstBrush + numBrushes > cache->numleafbrushes ) {
- Com_DPrintf( "%s: bad brushnum\n", __func__ );
- return qfalse;
- }
-
- out->firstleafbrush = cache->leafbrushes + firstBrush;
- out->numleafbrushes = numBrushes;
-
- if (out->cluster >= cache->numclusters)
- cache->numclusters = out->cluster + 1;
- }
-
- if (cache->leafs[0].contents != CONTENTS_SOLID) {
- Com_DPrintf( "%s: map leaf 0 is not CONTENTS_SOLID\n", __func__ );
- return qfalse;
- }
- return qtrue;
-}
-
-/*
-=================
-CM_LoadPlanes
-=================
-*/
-CM_FUNC( Planes ) {
- cplane_t *out;
- dplane_t *in;
- int i;
-
- cache->numplanes = l->count;
- cache->planes = CM_Malloc( sizeof( *out ) * l->count );
-
- in = l->base;
- out = cache->planes;
- for( i = 0; i < l->count; i++, in++, out++ ) {
- out->normal[0] = LittleFloat( in->normal[0] );
- out->normal[1] = LittleFloat( in->normal[1] );
- out->normal[2] = LittleFloat( in->normal[2] );
- out->dist = LittleFloat (in->dist);
- SetPlaneType( out );
- SetPlaneSignbits( out );
- }
- return qtrue;
-}
-
-/*
-=================
-CMLoadLeafBrushes
-=================
-*/
-CM_FUNC( LeafBrushes ) {
- cbrush_t **out;
- uint16_t *in;
- int i;
- unsigned brushNum;
-
- cache->numleafbrushes = l->count;
- cache->leafbrushes = CM_Malloc( sizeof( *out ) * l->count );
-
- in = l->base;
- out = cache->leafbrushes;
- for( i = 0; i < l->count; i++, in++, out++ ) {
- brushNum = LittleShort (*in);
- if( brushNum >= cache->numbrushes ) {
- Com_DPrintf( "%s: bad brushnum\n", __func__ );
- return qfalse;
- }
- *out = cache->brushes + brushNum;
- }
- return qtrue;
-}
-
-/*
-=================
-CM_LoadBrushSides
-=================
-*/
-CM_FUNC( BrushSides ) {
- cbrushside_t *out;
- dbrushside_t *in;
- int i;
- unsigned planeNum, texinfoNum;
-
- cache->numbrushsides = l->count;
- cache->brushsides = CM_Malloc( sizeof( *out ) * l->count );
-
- in = l->base;
- out = cache->brushsides;
- for( i = 0; i < l->count; i++, in++, out++ ) {
- planeNum = LittleShort (in->planenum);
- if( planeNum >= cache->numplanes ) {
- Com_DPrintf( "%s: bad planenum\n", __func__ );
- return qfalse;
- }
- out->plane = cache->planes + planeNum;
- texinfoNum = LittleShort (in->texinfo);
- if( texinfoNum == ( uint16_t )-1 ) {
- out->surface = &nullsurface;
- } else {
- if (texinfoNum >= cache->numtexinfo) {
- Com_DPrintf( "%s: bad texinfo\n", __func__ );
- return qfalse;
- }
- out->surface = cache->surfaces + texinfoNum;
- }
- }
- return qtrue;
-}
-
-/*
-=================
-CM_LoadAreas
-=================
-*/
-CM_FUNC( Areas ) {
- carea_t *out;
- darea_t *in;
- int i;
- unsigned numPortals, firstPortal, lastPortal;
-
- cache->numareas = l->count;
- cache->areas = CM_Malloc( sizeof( *out ) * l->count );
-
- in = l->base;
- out = cache->areas;
- for( i = 0; i < l->count; i++, in++, out++ ) {
- numPortals = LittleLong (in->numareaportals);
- firstPortal = LittleLong (in->firstareaportal);
- lastPortal = firstPortal + numPortals;
- if( lastPortal < firstPortal || lastPortal > cache->numareaportals ) {
- Com_DPrintf( "%s: bad areaportals\n", __func__ );
- return qfalse;
- }
- out->numareaportals = numPortals;
- out->firstareaportal = firstPortal;
- out->floodvalid = 0;
- }
- return qtrue;
-}
-
-/*
-=================
-CM_LoadAreaPortals
-=================
-*/
-CM_FUNC( AreaPortals ) {
- careaportal_t *out;
- dareaportal_t *in;
- int i;
- unsigned portalNum, otherArea;
-
- cache->numareaportals = l->count;
- cache->areaportals = CM_Malloc( sizeof( *out ) * l->count );
-
- in = l->base;
- out = cache->areaportals;
- for( i = 0; i < l->count; i++, in++, out++ ) {
- portalNum = LittleLong (in->portalnum);
- if( portalNum >= MAX_MAP_AREAPORTALS ) {
- Com_DPrintf( "%s: bad portalnum\n", __func__ );
- }
- out->portalnum = portalNum;
- otherArea = LittleLong (in->otherarea);
- if( otherArea >= MAX_MAP_AREAS ) {
- Com_DPrintf( "%s: bad otherarea\n", __func__ );
- }
- out->otherarea = otherArea;
- }
- return qtrue;
-}
-
-/*
-=================
-CM_LoadVisibility
-=================
-*/
-CM_FUNC( Visibility ) {
- unsigned numClusters;
- int i;
-
- if( !l->count ) {
- cache->numvisibility = cache->visrowsize = 0;
- return qtrue;
- }
-
- cache->numvisibility = l->count;
- cache->vis = CM_Malloc( l->count );
- memcpy( cache->vis, l->base, l->count );
-
- numClusters = LittleLong( cache->vis->numclusters );
- cache->vis->numclusters = numClusters;
- for( i = 0; i < numClusters; i++ ) {
- cache->vis->bitofs[i][0] = LittleLong( cache->vis->bitofs[i][0] );
- cache->vis->bitofs[i][1] = LittleLong( cache->vis->bitofs[i][1] );
- }
-
- cache->visrowsize = ( numClusters + 7 ) >> 3;
- return qtrue;
-}
-
-
-/*
-=================
-CM_LoadEntityString
-=================
+==================
+CM_FreeMap
+==================
*/
-CM_FUNC( EntityString ) {
- cache->numEntityChars = l->count;
- cache->entitystring = CM_Malloc( l->count + 1 );
- memcpy( cache->entitystring, l->base, l->count );
- cache->entitystring[l->count] = 0;
- return qtrue;
-}
-
-#define CM_CACHESIZE 16
-
-static cmcache_t cm_cache[CM_CACHESIZE];
-
-static void CM_FreeCache( cmcache_t *cache ) {
-#define CM_FREE( f ) if( cache->f ) CM_Free( cache->f )
-
- CM_FREE( vis );
- CM_FREE( surfaces );
- CM_FREE( planes );
- CM_FREE( brushsides );
- CM_FREE( brushes );
- CM_FREE( leafbrushes );
- CM_FREE( areaportals );
- CM_FREE( areas );
- CM_FREE( leafs );
- CM_FREE( nodes );
- CM_FREE( cmodels );
- CM_FREE( entitystring );
-
- memset( cache, 0, sizeof( *cache ) );
-}
-
void CM_FreeMap( cm_t *cm ) {
- cmcache_t *cache;
-
if( cm->floodnums ) {
Z_Free( cm->floodnums );
}
-
- cache = cm->cache;
- if( cache ) {
- if( cache->refcount <= 0 ) {
- Com_Error( ERR_FATAL, "CM_FreeMap: negative refcount" );
- }
- if( --cache->refcount == 0 ) {
- CM_FreeCache( cache );
- }
- }
+ BSP_Free( cm->cache );
memset( cm, 0, sizeof( *cm ) );
}
-static void CM_AllocPortals( cm_t *cm, int flags ) {
- if( flags & CM_LOAD_CLIENT ) {
- cm->floodnums = NULL;
- cm->portalopen = NULL;
- return;
- }
- cm->floodnums = CM_Mallocz( sizeof( int ) * cm->cache->numareas +
- sizeof( qboolean ) * cm->cache->numareaportals );
- cm->portalopen = ( qboolean * )( cm->floodnums + cm->cache->numareas );
- CM_FloodAreaConnections( cm );
-}
-
-typedef struct {
- qboolean (*func)( cmcache_t *, cmlump_t * );
- int lump;
-} lump_load_t;
-
-#define CM_LOAD( Func, Lump ) { CM_Load##Func, LUMP_##Lump }
-
-static const lump_load_t lump_load[] = {
- CM_LOAD( Visibility, VISIBILITY ),
- CM_LOAD( Surfaces, TEXINFO ),
- CM_LOAD( Planes, PLANES ),
- CM_LOAD( BrushSides, BRUSHSIDES ),
- CM_LOAD( Brushes, BRUSHES ),
- CM_LOAD( LeafBrushes, LEAFBRUSHES ),
- CM_LOAD( AreaPortals, AREAPORTALS ),
- CM_LOAD( Areas, AREAS ),
- CM_LOAD( Leafs, LEAFS ),
- CM_LOAD( Nodes, NODES ),
- CM_LOAD( Submodels, MODELS ),
- { NULL }
-};
-
/*
==================
CM_LoadMap
@@ -550,216 +59,30 @@ CM_LoadMap
Loads in the map and all submodels
==================
*/
-const char *CM_LoadMapEx( cm_t *cm, const char *name, int flags, uint32_t *checksum ) {
- cmcache_t *cache;
- byte *buf;
- int i;
- dheader_t *header;
- lump_t *in;
- cmlump_t lumps[HEADER_LUMPS];
- cmlump_t *out;
- const lump_info_t *info;
- const lump_load_t *load;
- size_t length, endpos, fileofs, filelen;
- char *error;
-
- if( !name || !name[0] ) {
- Com_Error( ERR_FATAL, "CM_LoadMap: NULL name" );
- }
-
- memset( cm, 0, sizeof( *cm ) );
+qboolean CM_LoadMap( cm_t *cm, const char *name ) {
+ bsp_t *cache;
- for( i = 0, cache = cm_cache; i < CM_CACHESIZE; i++, cache++ ) {
- if( !cache->name[0] ) {
- continue;
- }
- if( strcmp( cache->name, name ) ) {
- continue;
- }
- //if( !( cache->flags & CM_LOAD_VISONLY ) || ( flags & CM_LOAD_VISONLY ) )
- {
- cm->cache = cache;
- if( checksum ) {
- *checksum = cache->checksum;
- }
- CM_AllocPortals( cm, flags );
- cache->refcount++;
- return NULL; // still have the right version
- }
- break;
- }
-
- // find a free slot
- for( i = 0, cache = cm_cache; i < CM_CACHESIZE; i++, cache++ ) {
- if( !cache->name[0] ) {
- break;
- }
- }
- if( i == CM_CACHESIZE ) {
- return "out of cache slots";
- }
-
- //
- // load the file
- //
- length = FS_LoadFile( name, (void **)&buf );
- if( !buf ) {
- return "file not found";
- }
-
- cache->checksum = LittleLong( Com_BlockChecksum( buf, length ) );
- if( checksum ) {
- *checksum = cache->checksum;
- }
-
- // byte swap and validate the header
- header = ( dheader_t * )buf;
- if( LittleLong( header->ident ) != IDBSPHEADER ) {
- error = "not an IBSP file";
- goto fail;
- }
- if( LittleLong( header->version ) != BSPVERSION ) {
- error = "wrong IBSP version";
- goto fail;
- }
-
- // byte swap and validate lumps
- in = header->lumps;
- out = lumps;
- info = lump_info;
- for( i = 0; i < HEADER_LUMPS; i++, in++, out++, info++ ) {
- if( !info->size ) {
- continue;
- }
- fileofs = LittleLong( in->fileofs );
- filelen = LittleLong( in->filelen );
- endpos = fileofs + filelen;
- if( endpos < fileofs || endpos > length ) {
- error = va( "%s lump is out of bounds", info->name );
- goto fail;
- }
- out->base = buf + fileofs;
- if( filelen % info->size ) {
- error = va( "%s lump has funny size", info->name );
- goto fail;
- }
- out->count = filelen / info->size;
- if( out->count < info->mincount || out->count > info->maxcount ) {
- error = va( "%s lump has bad number of elements", info->name );
- goto fail;
- }
- }
-
-
- // load into heap
- if( !( flags & CM_LOAD_ENTONLY ) ) {
- for( load = lump_load; load->func; load++ ) {
- if( !load->func( cache, &lumps[load->lump] ) ) {
- error = va( "%s lump has invalid structure", lump_info[load->lump].name );
- goto fail;
- }
- }
- }
-
- // optionally load the entity string from external source
- if( map_override->integer && !( flags & CM_LOAD_CLIENT ) ) {
- char *entstring;
- char buffer[MAX_QPATH];
-
- COM_StripExtension( name, buffer, sizeof( buffer ) );
- Q_strcat( buffer, sizeof( buffer ), ".ent" );
- length = FS_LoadFileEx( buffer, ( void ** )&entstring, 0, TAG_CMODEL );
- if( entstring ) {
- Com_DPrintf( "Loaded entity string from %s\n", buffer );
- cache->entitystring = entstring;
- cache->numEntityChars = length;
- } else {
- CM_LoadEntityString( cache, &lumps[LUMP_ENTITIES] );
- }
- } else {
- CM_LoadEntityString( cache, &lumps[LUMP_ENTITIES] );
+ if( !( cache = BSP_Load( name ) ) ) {
+ return qfalse;
}
- FS_FreeFile( buf );
-
- Q_strncpyz( cache->name, name, sizeof( cache->name ) );
-
- cache->refcount = 1;
cm->cache = cache;
+ cm->floodnums = Z_TagMallocz( sizeof( int ) * cm->cache->numareas +
+ sizeof( qboolean ) * cm->cache->numareaportals, TAG_CMODEL );
+ cm->portalopen = ( qboolean * )( cm->floodnums + cm->cache->numareas );
+ CM_FloodAreaConnections( cm );
- CM_AllocPortals( cm, flags );
-
- return NULL;
-
-fail:
- FS_FreeFile( buf );
- CM_FreeCache( cache );
- return error;
-}
-
-void CM_LoadMap( cm_t *cm, const char *name, int flags, uint32_t *checksum ) {
- const char *error = CM_LoadMapEx( cm, name, flags, checksum );
-
- if( error ) {
- Com_Error( ERR_DROP, "Couldn't load %s: %s", name, error );
- }
-}
-
-/*
-==================
-CM_InlineModel
-==================
-*/
-cmodel_t *CM_InlineModel( cm_t *cm, const char *name ) {
- int num;
- cmodel_t *cmodel;
-
- if( !name || name[0] != '*' ) {
- Com_Error( ERR_DROP, "%s: bad name: %s", __func__, name );
- }
- if( !cm->cache ) {
- Com_Error( ERR_DROP, "%s: NULL cache", __func__ );
- }
- num = atoi( name + 1 );
- if( num < 1 || num >= cm->cache->numcmodels ) {
- Com_Error ( ERR_DROP, "%s: bad number: %d", __func__, num );
- }
-
- cmodel = &cm->cache->cmodels[num];
-
- return cmodel;
-}
-
-int CM_NumClusters( cm_t *cm ) {
- if( !cm->cache ) {
- return 0;
- }
- return cm->cache->numclusters;
+ return qtrue;
}
-int CM_NumInlineModels( cm_t *cm ) {
- if( !cm->cache ) {
- return 0;
- }
- return cm->cache->numcmodels;
-}
-char *CM_EntityString( cm_t *cm ) {
- if( !cm->cache ) {
- return "";
- }
- if( !cm->cache->entitystring ) {
- return "";
- }
- return cm->cache->entitystring;
-}
-cnode_t *CM_NodeNum( cm_t *cm, int number ) {
+mnode_t *CM_NodeNum( cm_t *cm, int number ) {
if( !cm->cache ) {
Com_Error( ERR_DROP, "%s: NULL cache", __func__ );
}
if( number == -1 ) {
- return ( cnode_t * )cm->cache->leafs; // special case for solid leaf
+ return ( mnode_t * )cm->cache->leafs; // special case for solid leaf
}
if( number < 0 || number >= cm->cache->numnodes ) {
Com_Error( ERR_DROP, "%s: bad number: %d", __func__, number );
@@ -767,7 +90,7 @@ cnode_t *CM_NodeNum( cm_t *cm, int number ) {
return cm->cache->nodes + number;
}
-cleaf_t *CM_LeafNum( cm_t *cm, int number ) {
+mleaf_t *CM_LeafNum( cm_t *cm, int number ) {
if( !cm->cache ) {
Com_Error( ERR_DROP, "%s: NULL cache", __func__ );
}
@@ -780,13 +103,13 @@ cleaf_t *CM_LeafNum( cm_t *cm, int number ) {
//=======================================================================
static cplane_t box_planes[12];
-static cnode_t box_nodes[6];
-static cnode_t *box_headnode;
-static cbrush_t box_brush;
-static cbrush_t *box_leafbrush;
-static cbrushside_t box_brushsides[6];
-static cleaf_t box_leaf;
-static cleaf_t box_emptyleaf;
+static mnode_t box_nodes[6];
+static mnode_t *box_headnode;
+static mbrush_t box_brush;
+static mbrush_t *box_leafbrush;
+static mbrushside_t box_brushsides[6];
+static mleaf_t box_leaf;
+static mleaf_t box_emptyleaf;
/*
===================
@@ -799,9 +122,9 @@ can just be stored out and get a proper clipping hull structure.
static void CM_InitBoxHull( void ) {
int i;
int side;
- cnode_t *c;
+ mnode_t *c;
cplane_t *p;
- cbrushside_t *s;
+ mbrushside_t *s;
box_headnode = &box_nodes[0];
@@ -821,16 +144,16 @@ static void CM_InitBoxHull( void ) {
// brush sides
s = &box_brushsides[i];
s->plane = &box_planes[i*2+side];
- s->surface = &nullsurface;
+ s->texinfo = &nulltexinfo;
// nodes
c = &box_nodes[i];
c->plane = &box_planes[i*2];
- c->children[side] = ( cnode_t * )&box_emptyleaf;
+ c->children[side] = ( mnode_t * )&box_emptyleaf;
if( i != 5 )
c->children[side^1] = &box_nodes[i + 1];
else
- c->children[side^1] = ( cnode_t * )&box_leaf;
+ c->children[side^1] = ( mnode_t * )&box_leaf;
// planes
p = &box_planes[i*2];
@@ -856,7 +179,7 @@ To keep everything totally uniform, bounding boxes are turned into small
BSP trees instead of being compared directly.
===================
*/
-cnode_t *CM_HeadnodeForBox( vec3_t mins, vec3_t maxs ) {
+mnode_t *CM_HeadnodeForBox( vec3_t mins, vec3_t maxs ) {
box_planes[0].dist = maxs[0];
box_planes[1].dist = -maxs[0];
box_planes[2].dist = mins[0];
@@ -874,34 +197,13 @@ cnode_t *CM_HeadnodeForBox( vec3_t mins, vec3_t maxs ) {
}
-/*
-==================
-CM_PointLeaf_r
-
-==================
-*/
-static cleaf_t *CM_PointLeaf_r( vec3_t p, cnode_t *node ) {
- float d;
-
- while( node->plane ) {
- d = PlaneDiffFast( p, node->plane );
- if( d < 0 )
- node = node->children[1];
- else
- node = node->children[0];
- }
-
- return ( cleaf_t * )node;
-}
-
-cleaf_t *CM_PointLeaf( cm_t *cm, vec3_t p ) {
+mleaf_t *CM_PointLeaf( cm_t *cm, vec3_t p ) {
if( !cm->cache ) {
return &nullleaf; // server may call this without map loaded
}
- return CM_PointLeaf_r( p, cm->cache->nodes );
+ return BSP_PointLeaf( cm->cache->nodes, p );
}
-
/*
=============
CM_BoxLeafnums
@@ -910,11 +212,11 @@ Fills in a list of all the leafs touched
=============
*/
static int leaf_count, leaf_maxcount;
-static cleaf_t **leaf_list;
+static mleaf_t **leaf_list;
static float *leaf_mins, *leaf_maxs;
-static cnode_t *leaf_topnode;
+static mnode_t *leaf_topnode;
-static void CM_BoxLeafs_r( cnode_t *node ) {
+static void CM_BoxLeafs_r( mnode_t *node ) {
int s;
while( node->plane ) {
@@ -934,12 +236,12 @@ static void CM_BoxLeafs_r( cnode_t *node ) {
}
if( leaf_count < leaf_maxcount ) {
- leaf_list[leaf_count++] = ( cleaf_t * )node;
+ leaf_list[leaf_count++] = ( mleaf_t * )node;
}
}
-static int CM_BoxLeafs_headnode( vec3_t mins, vec3_t maxs, cleaf_t **list, int listsize,
- cnode_t *headnode, cnode_t **topnode )
+static int CM_BoxLeafs_headnode( vec3_t mins, vec3_t maxs, mleaf_t **list, int listsize,
+ mnode_t *headnode, mnode_t **topnode )
{
leaf_list = list;
leaf_count = 0;
@@ -957,7 +259,7 @@ static int CM_BoxLeafs_headnode( vec3_t mins, vec3_t maxs, cleaf_t **list, int l
return leaf_count;
}
-int CM_BoxLeafs( cm_t *cm, vec3_t mins, vec3_t maxs, cleaf_t **list, int listsize, cnode_t **topnode ) {
+int CM_BoxLeafs( cm_t *cm, vec3_t mins, vec3_t maxs, mleaf_t **list, int listsize, mnode_t **topnode ) {
if( !cm->cache ) // map not loaded
return 0;
return CM_BoxLeafs_headnode( mins, maxs, list,
@@ -972,14 +274,14 @@ CM_PointContents
==================
*/
-int CM_PointContents( vec3_t p, cnode_t *headnode ) {
- cleaf_t *leaf;
+int CM_PointContents( vec3_t p, mnode_t *headnode ) {
+ mleaf_t *leaf;
if( !headnode ) {
return 0;
}
- leaf = CM_PointLeaf_r( p, headnode );
+ leaf = BSP_PointLeaf( headnode, p );
return leaf->contents;
}
@@ -992,11 +294,11 @@ Handles offseting and rotation of the end points for moving and
rotating entities
==================
*/
-int CM_TransformedPointContents( vec3_t p, cnode_t *headnode, vec3_t origin, vec3_t angles ) {
+int CM_TransformedPointContents( vec3_t p, mnode_t *headnode, vec3_t origin, vec3_t angles ) {
vec3_t p_l;
vec3_t temp;
vec3_t forward, right, up;
- cleaf_t *leaf;
+ mleaf_t *leaf;
if( !headnode ) {
return 0;
@@ -1017,7 +319,7 @@ int CM_TransformedPointContents( vec3_t p, cnode_t *headnode, vec3_t origin, vec
p_l[2] = DotProduct (temp, up);
}
- leaf = CM_PointLeaf_r( p_l, headnode );
+ leaf = BSP_PointLeaf( headnode, p_l );
return leaf->contents;
}
@@ -1048,7 +350,7 @@ CM_ClipBoxToBrush
================
*/
static void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
- trace_t *trace, cbrush_t *brush)
+ trace_t *trace, mbrush_t *brush)
{
int i, j;
cplane_t *plane, *clipplane;
@@ -1058,7 +360,7 @@ static void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
float d1, d2;
qboolean getout, startout;
float f;
- cbrushside_t *side, *leadside;
+ mbrushside_t *side, *leadside;
enterfrac = -1;
leavefrac = 1;
@@ -1149,7 +451,7 @@ static void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2,
enterfrac = 0;
trace->fraction = enterfrac;
trace->plane = *clipplane;
- trace->surface = &(leadside->surface->c);
+ trace->surface = &(leadside->texinfo->c);
trace->contents = brush->contents;
}
}
@@ -1161,14 +463,14 @@ CM_TestBoxInBrush
================
*/
static void CM_TestBoxInBrush (vec3_t mins, vec3_t maxs, vec3_t p1,
- trace_t *trace, cbrush_t *brush)
+ trace_t *trace, mbrush_t *brush)
{
int i, j;
cplane_t *plane;
float dist;
vec3_t ofs;
float d1;
- cbrushside_t *side;
+ mbrushside_t *side;
if (!brush->numsides)
return;
@@ -1215,10 +517,10 @@ static void CM_TestBoxInBrush (vec3_t mins, vec3_t maxs, vec3_t p1,
CM_TraceToLeaf
================
*/
-static void CM_TraceToLeaf ( cleaf_t *leaf )
+static void CM_TraceToLeaf ( mleaf_t *leaf )
{
int k;
- cbrush_t *b, **leafbrush;
+ mbrush_t *b, **leafbrush;
if( !( leaf->contents & trace_contents ) )
return;
@@ -1246,10 +548,10 @@ static void CM_TraceToLeaf ( cleaf_t *leaf )
CM_TestInLeaf
================
*/
-static void CM_TestInLeaf ( cleaf_t *leaf )
+static void CM_TestInLeaf ( mleaf_t *leaf )
{
int k;
- cbrush_t *b, **leafbrush;
+ mbrush_t *b, **leafbrush;
if( !( leaf->contents & trace_contents ) )
return;
@@ -1278,7 +580,7 @@ CM_RecursiveHullCheck
==================
*/
-static void CM_RecursiveHullCheck ( cnode_t *node, float p1f, float p2f, vec3_t p1, vec3_t p2)
+static void CM_RecursiveHullCheck ( mnode_t *node, float p1f, float p2f, vec3_t p1, vec3_t p2)
{
cplane_t *plane;
float t1, t2, offset;
@@ -1296,7 +598,7 @@ recheck:
// if plane is NULL, we are in a leaf node
plane = node->plane;
if (!plane) {
- CM_TraceToLeaf ( ( cleaf_t * )node );
+ CM_TraceToLeaf ( ( mleaf_t * )node );
return;
}
@@ -1393,7 +695,7 @@ CM_BoxTrace
*/
void CM_BoxTrace( trace_t *trace, vec3_t start, vec3_t end,
vec3_t mins, vec3_t maxs,
- cnode_t *headnode, int brushmask )
+ mnode_t *headnode, int brushmask )
{
int i;
@@ -1403,7 +705,7 @@ void CM_BoxTrace( trace_t *trace, vec3_t start, vec3_t end,
trace_trace = trace;
memset (trace_trace, 0, sizeof( *trace_trace ));
trace_trace->fraction = 1;
- trace_trace->surface = &(nullsurface.c);
+ trace_trace->surface = &(nulltexinfo.c);
if( !headnode ) {
return;
@@ -1420,7 +722,7 @@ void CM_BoxTrace( trace_t *trace, vec3_t start, vec3_t end,
//
if (start[0] == end[0] && start[1] == end[1] && start[2] == end[2])
{
- cleaf_t *leafs[1024];
+ mleaf_t *leafs[1024];
int i, numleafs;
vec3_t c1, c2;
@@ -1488,7 +790,7 @@ rotating entities
*/
void CM_TransformedBoxTrace ( trace_t *trace, vec3_t start, vec3_t end,
vec3_t mins, vec3_t maxs,
- cnode_t *headnode, int brushmask,
+ mnode_t *headnode, int brushmask,
vec3_t origin, vec3_t angles)
{
vec3_t start_l, end_l;
@@ -1561,80 +863,6 @@ void CM_ClipEntity( trace_t *dst, trace_t *src, struct edict_s *ent ) {
/*
===============================================================================
-PVS / PHS
-
-===============================================================================
-*/
-
-static byte pvsrow[MAX_MAP_LEAFS/8];
-static byte phsrow[MAX_MAP_LEAFS/8];
-
-/*
-===================
-CM_DecompressVis
-===================
-*/
-static void CM_DecompressVis( byte *in, byte *out, int rowsize ) {
- int c;
- byte *out_p;
-
- out_p = out;
- do {
- if( *in ) {
- *out_p++ = *in++;
- continue;
- }
-
- c = in[1];
- in += 2;
- if( ( out_p - out ) + c > rowsize ) {
- c = rowsize - ( out_p - out );
- Com_WPrintf( "CM_DecompressVis: overrun\n" );
- }
- while( c ) {
- *out_p++ = 0;
- c--;
- }
- } while( out_p - out < rowsize );
-}
-
-byte *CM_ClusterPVS( cm_t *cm, int cluster ) {
- cmcache_t *cache = cm->cache;
-
- if( !cache || !cache->vis ) {
- memset( pvsrow, 0xff, sizeof( pvsrow ) );
- } else if( cluster == -1 ) {
- memset( pvsrow, 0, cache->visrowsize );
- } else {
- if( cluster < 0 || cluster >= cache->vis->numclusters ) {
- Com_Error( ERR_DROP, "CM_ClusterPVS: bad cluster" );
- }
- CM_DecompressVis( ( byte * )cache->vis + cache->vis->bitofs[cluster][DVIS_PVS],
- pvsrow, cache->visrowsize );
- }
- return pvsrow;
-}
-
-byte *CM_ClusterPHS( cm_t *cm, int cluster ) {
- cmcache_t *cache = cm->cache;
-
- if( !cache || !cache->vis ) {
- memset( phsrow, 0xff, sizeof( phsrow ) );
- } else if( cluster == -1 ) {
- memset( phsrow, 0, cache->visrowsize );
- } else {
- if( cluster < 0 || cluster >= cache->vis->numclusters ) {
- Com_Error( ERR_DROP, "CM_ClusterPVS: bad cluster" );
- }
- CM_DecompressVis( ( byte * )cache->vis + cache->vis->bitofs[cluster][DVIS_PHS],
- phsrow, cache->visrowsize );
- }
- return phsrow;
-}
-
-/*
-===============================================================================
-
AREAPORTALS
===============================================================================
@@ -1642,8 +870,8 @@ AREAPORTALS
static void FloodArea_r( cm_t *cm, int number, int floodnum ) {
int i;
- careaportal_t *p;
- carea_t *area;
+ mareaportal_t *p;
+ marea_t *area;
area = &cm->cache->areas[number];
if( area->floodvalid == floodvalid ) {
@@ -1668,7 +896,7 @@ CM_FloodAreaConnections
*/
void CM_FloodAreaConnections( cm_t *cm ) {
int i;
- carea_t *area;
+ marea_t *area;
int floodnum;
// all current floods are now invalid
@@ -1695,7 +923,7 @@ void CM_SetAreaPortalState( cm_t *cm, int portalnum, qboolean open ) {
}
qboolean CM_AreasConnected( cm_t *cm, int area1, int area2 ) {
- cmcache_t *cache = cm->cache;
+ bsp_t *cache = cm->cache;
if( !cache ) {
return qfalse;
@@ -1728,7 +956,7 @@ This is used by the client refreshes to cull visibility
=================
*/
int CM_WriteAreaBits( cm_t *cm, byte *buffer, int area ) {
- cmcache_t *cache = cm->cache;
+ bsp_t *cache = cm->cache;
int i;
int floodnum;
int bytes;
@@ -1811,8 +1039,8 @@ Returns qtrue if any leaf under headnode has a cluster that
is potentially visible
=============
*/
-qboolean CM_HeadnodeVisible( cnode_t *node, byte *visbits ) {
- cleaf_t *leaf;
+qboolean CM_HeadnodeVisible( mnode_t *node, byte *visbits ) {
+ mleaf_t *leaf;
int cluster;
while( node->plane ) {
@@ -1821,7 +1049,7 @@ qboolean CM_HeadnodeVisible( cnode_t *node, byte *visbits ) {
node = node->children[1];
}
- leaf = ( cleaf_t * )node;
+ leaf = ( mleaf_t * )node;
cluster = leaf->cluster;
if( cluster == -1 )
return qfalse;
@@ -1839,18 +1067,20 @@ The client will interpolate the view position,
so we can't use a single PVS point
===========
*/
-byte *CM_FatPVS( cm_t *cm, const vec3_t org ) {
- static byte fatpvs[MAX_MAP_LEAFS/8];
- cleaf_t *leafs[64];
+byte *CM_FatPVS( cm_t *cm, byte *mask, const vec3_t org ) {
+ byte temp[MAX_MAP_VIS];
+ mleaf_t *leafs[64];
int clusters[64];
int i, j, count;
int longs;
uint32_t *src, *dst;
vec3_t mins, maxs;
-
+
if( !cm->cache ) { // map not loaded
- memset( fatpvs, 0, sizeof( fatpvs ) );
- return fatpvs;
+ return memset( mask, 0, MAX_MAP_VIS );
+ }
+ if( !cm->cache->vis ) {
+ return memset( mask, 0xff, MAX_MAP_VIS );
}
for( i = 0; i < 3; i++ ) {
@@ -1861,18 +1091,14 @@ byte *CM_FatPVS( cm_t *cm, const vec3_t org ) {
count = CM_BoxLeafs( cm, mins, maxs, leafs, 64, NULL );
if( count < 1 )
Com_Error( ERR_DROP, "CM_FatPVS: leaf count < 1" );
- longs = ( cm->cache->numclusters + 31 ) >> 5;
+ longs = ( cm->cache->vis->numclusters + 31 ) >> 5;
// convert leafs to clusters
for( i = 0 ; i < count; i++ ) {
clusters[i] = leafs[i]->cluster;
}
- src = ( uint32_t * )CM_ClusterPVS( cm, clusters[0] );
- dst = ( uint32_t * )fatpvs;
- for( j = 0; j < longs; j++ ) {
- *dst++ = *src++;
- }
+ BSP_ClusterVis( cm->cache, mask, clusters[0], DVIS_PVS );
// or in all the other leaf bits
for( i = 1; i < count; i++ ) {
@@ -1881,8 +1107,8 @@ byte *CM_FatPVS( cm_t *cm, const vec3_t org ) {
goto nextleaf; // already have the cluster we want
}
}
- src = ( uint32_t * )CM_ClusterPVS( cm, clusters[i] );
- dst = ( uint32_t * )fatpvs;
+ src = ( uint32_t * )BSP_ClusterVis( cm->cache, temp, clusters[i], DVIS_PVS );
+ dst = ( uint32_t * )mask;
for( j = 0; j < longs; j++ ) {
*dst++ |= *src++;
}
@@ -1890,7 +1116,7 @@ byte *CM_FatPVS( cm_t *cm, const vec3_t org ) {
nextleaf:;
}
- return fatpvs;
+ return mask;
}
/*