diff options
author | Andrey Nazarov <skuller@skuller.net> | 2008-08-16 10:19:42 +0000 |
---|---|---|
committer | Andrey Nazarov <skuller@skuller.net> | 2008-08-16 10:19:42 +0000 |
commit | 1526e22e4ff29153e9c127081e8ea8d9e2f33b8c (patch) | |
tree | b361766433d4a7b4a111865afd52803e2bbf7754 /source/cmodel.c | |
parent | e826e5f176f21cd18b3bbc22887a266835ada57c (diff) |
Split some monolithic include files into smaller ones.
Use single BSP models cache for refresh and collision subsystems.
Refresh libraries may not longer be dynamically loaded.
Made gi.TagMalloc use separate tag namespace to avoid
conflicts with engine reserverd tags.
Fixed listing order of MVD channels in chooser menu.
A lot of misc changes... MSVC build is definitely broken now.
Diffstat (limited to 'source/cmodel.c')
-rw-r--r-- | source/cmodel.c | 948 |
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; } /* |