From 6bf20c78f5b69d40bcc4931df93d29198435ab67 Mon Sep 17 00:00:00 2001 From: zakk Date: Fri, 26 Aug 2005 17:39:27 +0000 Subject: newlines fixed git-svn-id: svn://svn.icculus.org/quake3/trunk@6 edf5b092-35ff-0310-97b2-ce42778d08ea --- code/qcommon/cm_load.c | 1678 ++++++++++++++++++++++++------------------------ 1 file changed, 839 insertions(+), 839 deletions(-) (limited to 'code/qcommon/cm_load.c') diff --git a/code/qcommon/cm_load.c b/code/qcommon/cm_load.c index 58b4703..bc4d8bb 100755 --- a/code/qcommon/cm_load.c +++ b/code/qcommon/cm_load.c @@ -1,839 +1,839 @@ -/* -=========================================================================== -Copyright (C) 1999-2005 Id Software, Inc. - -This file is part of Quake III Arena source code. - -Quake III Arena source code 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. - -Quake III Arena source code 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 Foobar; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -// cmodel.c -- model loading - -#include "cm_local.h" - -#ifdef BSPC - -#include "../bspc/l_qfiles.h" - -void SetPlaneSignbits (cplane_t *out) { - int bits, j; - - // for fast box on planeside test - bits = 0; - for (j=0 ; j<3 ; j++) { - if (out->normal[j] < 0) { - bits |= 1<signbits = bits; -} -#endif //BSPC - -// to allow boxes to be treated as brush models, we allocate -// some extra indexes along with those needed by the map -#define BOX_BRUSHES 1 -#define BOX_SIDES 6 -#define BOX_LEAFS 2 -#define BOX_PLANES 12 - -#define LL(x) x=LittleLong(x) - - -clipMap_t cm; -int c_pointcontents; -int c_traces, c_brush_traces, c_patch_traces; - - -byte *cmod_base; - -#ifndef BSPC -cvar_t *cm_noAreas; -cvar_t *cm_noCurves; -cvar_t *cm_playerCurveClip; -#endif - -cmodel_t box_model; -cplane_t *box_planes; -cbrush_t *box_brush; - - - -void CM_InitBoxHull (void); -void CM_FloodAreaConnections (void); - - -/* -=============================================================================== - - MAP LOADING - -=============================================================================== -*/ - -/* -================= -CMod_LoadShaders -================= -*/ -void CMod_LoadShaders( lump_t *l ) { - dshader_t *in, *out; - int i, count; - - in = (void *)(cmod_base + l->fileofs); - if (l->filelen % sizeof(*in)) { - Com_Error (ERR_DROP, "CMod_LoadShaders: funny lump size"); - } - count = l->filelen / sizeof(*in); - - if (count < 1) { - Com_Error (ERR_DROP, "Map with no shaders"); - } - cm.shaders = Hunk_Alloc( count * sizeof( *cm.shaders ), h_high ); - cm.numShaders = count; - - Com_Memcpy( cm.shaders, in, count * sizeof( *cm.shaders ) ); - - out = cm.shaders; - for ( i=0 ; icontentFlags = LittleLong( out->contentFlags ); - out->surfaceFlags = LittleLong( out->surfaceFlags ); - } -} - - -/* -================= -CMod_LoadSubmodels -================= -*/ -void CMod_LoadSubmodels( lump_t *l ) { - dmodel_t *in; - cmodel_t *out; - int i, j, count; - int *indexes; - - in = (void *)(cmod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP, "CMod_LoadSubmodels: funny lump size"); - count = l->filelen / sizeof(*in); - - if (count < 1) - Com_Error (ERR_DROP, "Map with no models"); - cm.cmodels = Hunk_Alloc( count * sizeof( *cm.cmodels ), h_high ); - cm.numSubModels = count; - - if ( count > MAX_SUBMODELS ) { - Com_Error( ERR_DROP, "MAX_SUBMODELS exceeded" ); - } - - for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; - out->maxs[j] = LittleFloat (in->maxs[j]) + 1; - } - - if ( i == 0 ) { - continue; // world model doesn't need other info - } - - // make a "leaf" just to hold the model's brushes and surfaces - out->leaf.numLeafBrushes = LittleLong( in->numBrushes ); - indexes = Hunk_Alloc( out->leaf.numLeafBrushes * 4, h_high ); - out->leaf.firstLeafBrush = indexes - cm.leafbrushes; - for ( j = 0 ; j < out->leaf.numLeafBrushes ; j++ ) { - indexes[j] = LittleLong( in->firstBrush ) + j; - } - - out->leaf.numLeafSurfaces = LittleLong( in->numSurfaces ); - indexes = Hunk_Alloc( out->leaf.numLeafSurfaces * 4, h_high ); - out->leaf.firstLeafSurface = indexes - cm.leafsurfaces; - for ( j = 0 ; j < out->leaf.numLeafSurfaces ; j++ ) { - indexes[j] = LittleLong( in->firstSurface ) + j; - } - } -} - - -/* -================= -CMod_LoadNodes - -================= -*/ -void CMod_LoadNodes( lump_t *l ) { - dnode_t *in; - int child; - cNode_t *out; - int i, j, count; - - in = (void *)(cmod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); - count = l->filelen / sizeof(*in); - - if (count < 1) - Com_Error (ERR_DROP, "Map has no nodes"); - cm.nodes = Hunk_Alloc( count * sizeof( *cm.nodes ), h_high ); - cm.numNodes = count; - - out = cm.nodes; - - for (i=0 ; iplane = cm.planes + LittleLong( in->planeNum ); - for (j=0 ; j<2 ; j++) - { - child = LittleLong (in->children[j]); - out->children[j] = child; - } - } - -} - -/* -================= -CM_BoundBrush - -================= -*/ -void CM_BoundBrush( cbrush_t *b ) { - b->bounds[0][0] = -b->sides[0].plane->dist; - b->bounds[1][0] = b->sides[1].plane->dist; - - b->bounds[0][1] = -b->sides[2].plane->dist; - b->bounds[1][1] = b->sides[3].plane->dist; - - b->bounds[0][2] = -b->sides[4].plane->dist; - b->bounds[1][2] = b->sides[5].plane->dist; -} - - -/* -================= -CMod_LoadBrushes - -================= -*/ -void CMod_LoadBrushes( lump_t *l ) { - dbrush_t *in; - cbrush_t *out; - int i, count; - - in = (void *)(cmod_base + l->fileofs); - if (l->filelen % sizeof(*in)) { - Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); - } - count = l->filelen / sizeof(*in); - - cm.brushes = Hunk_Alloc( ( BOX_BRUSHES + count ) * sizeof( *cm.brushes ), h_high ); - cm.numBrushes = count; - - out = cm.brushes; - - for ( i=0 ; isides = cm.brushsides + LittleLong(in->firstSide); - out->numsides = LittleLong(in->numSides); - - out->shaderNum = LittleLong( in->shaderNum ); - if ( out->shaderNum < 0 || out->shaderNum >= cm.numShaders ) { - Com_Error( ERR_DROP, "CMod_LoadBrushes: bad shaderNum: %i", out->shaderNum ); - } - out->contents = cm.shaders[out->shaderNum].contentFlags; - - CM_BoundBrush( out ); - } - -} - -/* -================= -CMod_LoadLeafs -================= -*/ -void CMod_LoadLeafs (lump_t *l) -{ - int i; - cLeaf_t *out; - dleaf_t *in; - int count; - - in = (void *)(cmod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); - count = l->filelen / sizeof(*in); - - if (count < 1) - Com_Error (ERR_DROP, "Map with no leafs"); - - cm.leafs = Hunk_Alloc( ( BOX_LEAFS + count ) * sizeof( *cm.leafs ), h_high ); - cm.numLeafs = count; - - out = cm.leafs; - for ( i=0 ; icluster = LittleLong (in->cluster); - out->area = LittleLong (in->area); - out->firstLeafBrush = LittleLong (in->firstLeafBrush); - out->numLeafBrushes = LittleLong (in->numLeafBrushes); - out->firstLeafSurface = LittleLong (in->firstLeafSurface); - out->numLeafSurfaces = LittleLong (in->numLeafSurfaces); - - if (out->cluster >= cm.numClusters) - cm.numClusters = out->cluster + 1; - if (out->area >= cm.numAreas) - cm.numAreas = out->area + 1; - } - - cm.areas = Hunk_Alloc( cm.numAreas * sizeof( *cm.areas ), h_high ); - cm.areaPortals = Hunk_Alloc( cm.numAreas * cm.numAreas * sizeof( *cm.areaPortals ), h_high ); -} - -/* -================= -CMod_LoadPlanes -================= -*/ -void CMod_LoadPlanes (lump_t *l) -{ - int i, j; - cplane_t *out; - dplane_t *in; - int count; - int bits; - - in = (void *)(cmod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); - count = l->filelen / sizeof(*in); - - if (count < 1) - Com_Error (ERR_DROP, "Map with no planes"); - cm.planes = Hunk_Alloc( ( BOX_PLANES + count ) * sizeof( *cm.planes ), h_high ); - cm.numPlanes = count; - - out = cm.planes; - - for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); - if (out->normal[j] < 0) - bits |= 1<dist = LittleFloat (in->dist); - out->type = PlaneTypeForNormal( out->normal ); - out->signbits = bits; - } -} - -/* -================= -CMod_LoadLeafBrushes -================= -*/ -void CMod_LoadLeafBrushes (lump_t *l) -{ - int i; - int *out; - int *in; - int count; - - in = (void *)(cmod_base + l->fileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); - count = l->filelen / sizeof(*in); - - cm.leafbrushes = Hunk_Alloc( (count + BOX_BRUSHES) * sizeof( *cm.leafbrushes ), h_high ); - cm.numLeafBrushes = count; - - out = cm.leafbrushes; - - for ( i=0 ; ifileofs); - if (l->filelen % sizeof(*in)) - Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); - count = l->filelen / sizeof(*in); - - cm.leafsurfaces = Hunk_Alloc( count * sizeof( *cm.leafsurfaces ), h_high ); - cm.numLeafSurfaces = count; - - out = cm.leafsurfaces; - - for ( i=0 ; ifileofs); - if ( l->filelen % sizeof(*in) ) { - Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); - } - count = l->filelen / sizeof(*in); - - cm.brushsides = Hunk_Alloc( ( BOX_SIDES + count ) * sizeof( *cm.brushsides ), h_high ); - cm.numBrushSides = count; - - out = cm.brushsides; - - for ( i=0 ; iplaneNum ); - out->plane = &cm.planes[num]; - out->shaderNum = LittleLong( in->shaderNum ); - if ( out->shaderNum < 0 || out->shaderNum >= cm.numShaders ) { - Com_Error( ERR_DROP, "CMod_LoadBrushSides: bad shaderNum: %i", out->shaderNum ); - } - out->surfaceFlags = cm.shaders[out->shaderNum].surfaceFlags; - } -} - - -/* -================= -CMod_LoadEntityString -================= -*/ -void CMod_LoadEntityString( lump_t *l ) { - cm.entityString = Hunk_Alloc( l->filelen, h_high ); - cm.numEntityChars = l->filelen; - Com_Memcpy (cm.entityString, cmod_base + l->fileofs, l->filelen); -} - -/* -================= -CMod_LoadVisibility -================= -*/ -#define VIS_HEADER 8 -void CMod_LoadVisibility( lump_t *l ) { - int len; - byte *buf; - - len = l->filelen; - if ( !len ) { - cm.clusterBytes = ( cm.numClusters + 31 ) & ~31; - cm.visibility = Hunk_Alloc( cm.clusterBytes, h_high ); - Com_Memset( cm.visibility, 255, cm.clusterBytes ); - return; - } - buf = cmod_base + l->fileofs; - - cm.vised = qtrue; - cm.visibility = Hunk_Alloc( len, h_high ); - cm.numClusters = LittleLong( ((int *)buf)[0] ); - cm.clusterBytes = LittleLong( ((int *)buf)[1] ); - Com_Memcpy (cm.visibility, buf + VIS_HEADER, len - VIS_HEADER ); -} - -//================================================================== - - -/* -================= -CMod_LoadPatches -================= -*/ -#define MAX_PATCH_VERTS 1024 -void CMod_LoadPatches( lump_t *surfs, lump_t *verts ) { - drawVert_t *dv, *dv_p; - dsurface_t *in; - int count; - int i, j; - int c; - cPatch_t *patch; - vec3_t points[MAX_PATCH_VERTS]; - int width, height; - int shaderNum; - - in = (void *)(cmod_base + surfs->fileofs); - if (surfs->filelen % sizeof(*in)) - Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); - cm.numSurfaces = count = surfs->filelen / sizeof(*in); - cm.surfaces = Hunk_Alloc( cm.numSurfaces * sizeof( cm.surfaces[0] ), h_high ); - - dv = (void *)(cmod_base + verts->fileofs); - if (verts->filelen % sizeof(*dv)) - Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); - - // scan through all the surfaces, but only load patches, - // not planar faces - for ( i = 0 ; i < count ; i++, in++ ) { - if ( LittleLong( in->surfaceType ) != MST_PATCH ) { - continue; // ignore other surfaces - } - // FIXME: check for non-colliding patches - - cm.surfaces[ i ] = patch = Hunk_Alloc( sizeof( *patch ), h_high ); - - // load the full drawverts onto the stack - width = LittleLong( in->patchWidth ); - height = LittleLong( in->patchHeight ); - c = width * height; - if ( c > MAX_PATCH_VERTS ) { - Com_Error( ERR_DROP, "ParseMesh: MAX_PATCH_VERTS" ); - } - - dv_p = dv + LittleLong( in->firstVert ); - for ( j = 0 ; j < c ; j++, dv_p++ ) { - points[j][0] = LittleFloat( dv_p->xyz[0] ); - points[j][1] = LittleFloat( dv_p->xyz[1] ); - points[j][2] = LittleFloat( dv_p->xyz[2] ); - } - - shaderNum = LittleLong( in->shaderNum ); - patch->contents = cm.shaders[shaderNum].contentFlags; - patch->surfaceFlags = cm.shaders[shaderNum].surfaceFlags; - - // create the internal facet structure - patch->pc = CM_GeneratePatchCollide( width, height, points ); - } -} - -//================================================================== - -unsigned CM_LumpChecksum(lump_t *lump) { - return LittleLong (Com_BlockChecksum (cmod_base + lump->fileofs, lump->filelen)); -} - -unsigned CM_Checksum(dheader_t *header) { - unsigned checksums[16]; - checksums[0] = CM_LumpChecksum(&header->lumps[LUMP_SHADERS]); - checksums[1] = CM_LumpChecksum(&header->lumps[LUMP_LEAFS]); - checksums[2] = CM_LumpChecksum(&header->lumps[LUMP_LEAFBRUSHES]); - checksums[3] = CM_LumpChecksum(&header->lumps[LUMP_LEAFSURFACES]); - checksums[4] = CM_LumpChecksum(&header->lumps[LUMP_PLANES]); - checksums[5] = CM_LumpChecksum(&header->lumps[LUMP_BRUSHSIDES]); - checksums[6] = CM_LumpChecksum(&header->lumps[LUMP_BRUSHES]); - checksums[7] = CM_LumpChecksum(&header->lumps[LUMP_MODELS]); - checksums[8] = CM_LumpChecksum(&header->lumps[LUMP_NODES]); - checksums[9] = CM_LumpChecksum(&header->lumps[LUMP_SURFACES]); - checksums[10] = CM_LumpChecksum(&header->lumps[LUMP_DRAWVERTS]); - - return LittleLong(Com_BlockChecksum(checksums, 11 * 4)); -} - -/* -================== -CM_LoadMap - -Loads in the map and all submodels -================== -*/ -void CM_LoadMap( const char *name, qboolean clientload, int *checksum ) { - int *buf; - int i; - dheader_t header; - int length; - static unsigned last_checksum; - - if ( !name || !name[0] ) { - Com_Error( ERR_DROP, "CM_LoadMap: NULL name" ); - } - -#ifndef BSPC - cm_noAreas = Cvar_Get ("cm_noAreas", "0", CVAR_CHEAT); - cm_noCurves = Cvar_Get ("cm_noCurves", "0", CVAR_CHEAT); - cm_playerCurveClip = Cvar_Get ("cm_playerCurveClip", "1", CVAR_ARCHIVE|CVAR_CHEAT ); -#endif - Com_DPrintf( "CM_LoadMap( %s, %i )\n", name, clientload ); - - if ( !strcmp( cm.name, name ) && clientload ) { - *checksum = last_checksum; - return; - } - - // free old stuff - Com_Memset( &cm, 0, sizeof( cm ) ); - CM_ClearLevelPatches(); - - if ( !name[0] ) { - cm.numLeafs = 1; - cm.numClusters = 1; - cm.numAreas = 1; - cm.cmodels = Hunk_Alloc( sizeof( *cm.cmodels ), h_high ); - *checksum = 0; - return; - } - - // - // load the file - // -#ifndef BSPC - length = FS_ReadFile( name, (void **)&buf ); -#else - length = LoadQuakeFile((quakefile_t *) name, (void **)&buf); -#endif - - if ( !buf ) { - Com_Error (ERR_DROP, "Couldn't load %s", name); - } - - last_checksum = LittleLong (Com_BlockChecksum (buf, length)); - *checksum = last_checksum; - - header = *(dheader_t *)buf; - for (i=0 ; i= cm.numSubModels ) { - Com_Error (ERR_DROP, "CM_InlineModel: bad number"); - } - return index; -} - -int CM_NumClusters( void ) { - return cm.numClusters; -} - -int CM_NumInlineModels( void ) { - return cm.numSubModels; -} - -char *CM_EntityString( void ) { - return cm.entityString; -} - -int CM_LeafCluster( int leafnum ) { - if (leafnum < 0 || leafnum >= cm.numLeafs) { - Com_Error (ERR_DROP, "CM_LeafCluster: bad number"); - } - return cm.leafs[leafnum].cluster; -} - -int CM_LeafArea( int leafnum ) { - if ( leafnum < 0 || leafnum >= cm.numLeafs ) { - Com_Error (ERR_DROP, "CM_LeafArea: bad number"); - } - return cm.leafs[leafnum].area; -} - -//======================================================================= - - -/* -=================== -CM_InitBoxHull - -Set up the planes and nodes so that the six floats of a bounding box -can just be stored out and get a proper clipping hull structure. -=================== -*/ -void CM_InitBoxHull (void) -{ - int i; - int side; - cplane_t *p; - cbrushside_t *s; - - box_planes = &cm.planes[cm.numPlanes]; - - box_brush = &cm.brushes[cm.numBrushes]; - box_brush->numsides = 6; - box_brush->sides = cm.brushsides + cm.numBrushSides; - box_brush->contents = CONTENTS_BODY; - - box_model.leaf.numLeafBrushes = 1; -// box_model.leaf.firstLeafBrush = cm.numBrushes; - box_model.leaf.firstLeafBrush = cm.numLeafBrushes; - cm.leafbrushes[cm.numLeafBrushes] = cm.numBrushes; - - for (i=0 ; i<6 ; i++) - { - side = i&1; - - // brush sides - s = &cm.brushsides[cm.numBrushSides+i]; - s->plane = cm.planes + (cm.numPlanes+i*2+side); - s->surfaceFlags = 0; - - // planes - p = &box_planes[i*2]; - p->type = i>>1; - p->signbits = 0; - VectorClear (p->normal); - p->normal[i>>1] = 1; - - p = &box_planes[i*2+1]; - p->type = 3 + (i>>1); - p->signbits = 0; - VectorClear (p->normal); - p->normal[i>>1] = -1; - - SetPlaneSignbits( p ); - } -} - -/* -=================== -CM_TempBoxModel - -To keep everything totally uniform, bounding boxes are turned into small -BSP trees instead of being compared directly. -Capsules are handled differently though. -=================== -*/ -clipHandle_t CM_TempBoxModel( const vec3_t mins, const vec3_t maxs, int capsule ) { - - VectorCopy( mins, box_model.mins ); - VectorCopy( maxs, box_model.maxs ); - - if ( capsule ) { - return CAPSULE_MODEL_HANDLE; - } - - box_planes[0].dist = maxs[0]; - box_planes[1].dist = -maxs[0]; - box_planes[2].dist = mins[0]; - box_planes[3].dist = -mins[0]; - box_planes[4].dist = maxs[1]; - box_planes[5].dist = -maxs[1]; - box_planes[6].dist = mins[1]; - box_planes[7].dist = -mins[1]; - box_planes[8].dist = maxs[2]; - box_planes[9].dist = -maxs[2]; - box_planes[10].dist = mins[2]; - box_planes[11].dist = -mins[2]; - - VectorCopy( mins, box_brush->bounds[0] ); - VectorCopy( maxs, box_brush->bounds[1] ); - - return BOX_MODEL_HANDLE; -} - -/* -=================== -CM_ModelBounds -=================== -*/ -void CM_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ) { - cmodel_t *cmod; - - cmod = CM_ClipHandleToModel( model ); - VectorCopy( cmod->mins, mins ); - VectorCopy( cmod->maxs, maxs ); -} - - +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + +This file is part of Quake III Arena source code. + +Quake III Arena source code 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. + +Quake III Arena source code 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 Foobar; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ +// cmodel.c -- model loading + +#include "cm_local.h" + +#ifdef BSPC + +#include "../bspc/l_qfiles.h" + +void SetPlaneSignbits (cplane_t *out) { + int bits, j; + + // for fast box on planeside test + bits = 0; + for (j=0 ; j<3 ; j++) { + if (out->normal[j] < 0) { + bits |= 1<signbits = bits; +} +#endif //BSPC + +// to allow boxes to be treated as brush models, we allocate +// some extra indexes along with those needed by the map +#define BOX_BRUSHES 1 +#define BOX_SIDES 6 +#define BOX_LEAFS 2 +#define BOX_PLANES 12 + +#define LL(x) x=LittleLong(x) + + +clipMap_t cm; +int c_pointcontents; +int c_traces, c_brush_traces, c_patch_traces; + + +byte *cmod_base; + +#ifndef BSPC +cvar_t *cm_noAreas; +cvar_t *cm_noCurves; +cvar_t *cm_playerCurveClip; +#endif + +cmodel_t box_model; +cplane_t *box_planes; +cbrush_t *box_brush; + + + +void CM_InitBoxHull (void); +void CM_FloodAreaConnections (void); + + +/* +=============================================================================== + + MAP LOADING + +=============================================================================== +*/ + +/* +================= +CMod_LoadShaders +================= +*/ +void CMod_LoadShaders( lump_t *l ) { + dshader_t *in, *out; + int i, count; + + in = (void *)(cmod_base + l->fileofs); + if (l->filelen % sizeof(*in)) { + Com_Error (ERR_DROP, "CMod_LoadShaders: funny lump size"); + } + count = l->filelen / sizeof(*in); + + if (count < 1) { + Com_Error (ERR_DROP, "Map with no shaders"); + } + cm.shaders = Hunk_Alloc( count * sizeof( *cm.shaders ), h_high ); + cm.numShaders = count; + + Com_Memcpy( cm.shaders, in, count * sizeof( *cm.shaders ) ); + + out = cm.shaders; + for ( i=0 ; icontentFlags = LittleLong( out->contentFlags ); + out->surfaceFlags = LittleLong( out->surfaceFlags ); + } +} + + +/* +================= +CMod_LoadSubmodels +================= +*/ +void CMod_LoadSubmodels( lump_t *l ) { + dmodel_t *in; + cmodel_t *out; + int i, j, count; + int *indexes; + + in = (void *)(cmod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Com_Error (ERR_DROP, "CMod_LoadSubmodels: funny lump size"); + count = l->filelen / sizeof(*in); + + if (count < 1) + Com_Error (ERR_DROP, "Map with no models"); + cm.cmodels = Hunk_Alloc( count * sizeof( *cm.cmodels ), h_high ); + cm.numSubModels = count; + + if ( count > MAX_SUBMODELS ) { + Com_Error( ERR_DROP, "MAX_SUBMODELS exceeded" ); + } + + for ( i=0 ; imins[j] = LittleFloat (in->mins[j]) - 1; + out->maxs[j] = LittleFloat (in->maxs[j]) + 1; + } + + if ( i == 0 ) { + continue; // world model doesn't need other info + } + + // make a "leaf" just to hold the model's brushes and surfaces + out->leaf.numLeafBrushes = LittleLong( in->numBrushes ); + indexes = Hunk_Alloc( out->leaf.numLeafBrushes * 4, h_high ); + out->leaf.firstLeafBrush = indexes - cm.leafbrushes; + for ( j = 0 ; j < out->leaf.numLeafBrushes ; j++ ) { + indexes[j] = LittleLong( in->firstBrush ) + j; + } + + out->leaf.numLeafSurfaces = LittleLong( in->numSurfaces ); + indexes = Hunk_Alloc( out->leaf.numLeafSurfaces * 4, h_high ); + out->leaf.firstLeafSurface = indexes - cm.leafsurfaces; + for ( j = 0 ; j < out->leaf.numLeafSurfaces ; j++ ) { + indexes[j] = LittleLong( in->firstSurface ) + j; + } + } +} + + +/* +================= +CMod_LoadNodes + +================= +*/ +void CMod_LoadNodes( lump_t *l ) { + dnode_t *in; + int child; + cNode_t *out; + int i, j, count; + + in = (void *)(cmod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); + count = l->filelen / sizeof(*in); + + if (count < 1) + Com_Error (ERR_DROP, "Map has no nodes"); + cm.nodes = Hunk_Alloc( count * sizeof( *cm.nodes ), h_high ); + cm.numNodes = count; + + out = cm.nodes; + + for (i=0 ; iplane = cm.planes + LittleLong( in->planeNum ); + for (j=0 ; j<2 ; j++) + { + child = LittleLong (in->children[j]); + out->children[j] = child; + } + } + +} + +/* +================= +CM_BoundBrush + +================= +*/ +void CM_BoundBrush( cbrush_t *b ) { + b->bounds[0][0] = -b->sides[0].plane->dist; + b->bounds[1][0] = b->sides[1].plane->dist; + + b->bounds[0][1] = -b->sides[2].plane->dist; + b->bounds[1][1] = b->sides[3].plane->dist; + + b->bounds[0][2] = -b->sides[4].plane->dist; + b->bounds[1][2] = b->sides[5].plane->dist; +} + + +/* +================= +CMod_LoadBrushes + +================= +*/ +void CMod_LoadBrushes( lump_t *l ) { + dbrush_t *in; + cbrush_t *out; + int i, count; + + in = (void *)(cmod_base + l->fileofs); + if (l->filelen % sizeof(*in)) { + Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); + } + count = l->filelen / sizeof(*in); + + cm.brushes = Hunk_Alloc( ( BOX_BRUSHES + count ) * sizeof( *cm.brushes ), h_high ); + cm.numBrushes = count; + + out = cm.brushes; + + for ( i=0 ; isides = cm.brushsides + LittleLong(in->firstSide); + out->numsides = LittleLong(in->numSides); + + out->shaderNum = LittleLong( in->shaderNum ); + if ( out->shaderNum < 0 || out->shaderNum >= cm.numShaders ) { + Com_Error( ERR_DROP, "CMod_LoadBrushes: bad shaderNum: %i", out->shaderNum ); + } + out->contents = cm.shaders[out->shaderNum].contentFlags; + + CM_BoundBrush( out ); + } + +} + +/* +================= +CMod_LoadLeafs +================= +*/ +void CMod_LoadLeafs (lump_t *l) +{ + int i; + cLeaf_t *out; + dleaf_t *in; + int count; + + in = (void *)(cmod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); + count = l->filelen / sizeof(*in); + + if (count < 1) + Com_Error (ERR_DROP, "Map with no leafs"); + + cm.leafs = Hunk_Alloc( ( BOX_LEAFS + count ) * sizeof( *cm.leafs ), h_high ); + cm.numLeafs = count; + + out = cm.leafs; + for ( i=0 ; icluster = LittleLong (in->cluster); + out->area = LittleLong (in->area); + out->firstLeafBrush = LittleLong (in->firstLeafBrush); + out->numLeafBrushes = LittleLong (in->numLeafBrushes); + out->firstLeafSurface = LittleLong (in->firstLeafSurface); + out->numLeafSurfaces = LittleLong (in->numLeafSurfaces); + + if (out->cluster >= cm.numClusters) + cm.numClusters = out->cluster + 1; + if (out->area >= cm.numAreas) + cm.numAreas = out->area + 1; + } + + cm.areas = Hunk_Alloc( cm.numAreas * sizeof( *cm.areas ), h_high ); + cm.areaPortals = Hunk_Alloc( cm.numAreas * cm.numAreas * sizeof( *cm.areaPortals ), h_high ); +} + +/* +================= +CMod_LoadPlanes +================= +*/ +void CMod_LoadPlanes (lump_t *l) +{ + int i, j; + cplane_t *out; + dplane_t *in; + int count; + int bits; + + in = (void *)(cmod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); + count = l->filelen / sizeof(*in); + + if (count < 1) + Com_Error (ERR_DROP, "Map with no planes"); + cm.planes = Hunk_Alloc( ( BOX_PLANES + count ) * sizeof( *cm.planes ), h_high ); + cm.numPlanes = count; + + out = cm.planes; + + for ( i=0 ; inormal[j] = LittleFloat (in->normal[j]); + if (out->normal[j] < 0) + bits |= 1<dist = LittleFloat (in->dist); + out->type = PlaneTypeForNormal( out->normal ); + out->signbits = bits; + } +} + +/* +================= +CMod_LoadLeafBrushes +================= +*/ +void CMod_LoadLeafBrushes (lump_t *l) +{ + int i; + int *out; + int *in; + int count; + + in = (void *)(cmod_base + l->fileofs); + if (l->filelen % sizeof(*in)) + Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); + count = l->filelen / sizeof(*in); + + cm.leafbrushes = Hunk_Alloc( (count + BOX_BRUSHES) * sizeof( *cm.leafbrushes ), h_high ); + cm.numLeafBrushes = count; + + out = cm.leafbrushes; + + for ( i=0 ; ifileofs); + if (l->filelen % sizeof(*in)) + Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); + count = l->filelen / sizeof(*in); + + cm.leafsurfaces = Hunk_Alloc( count * sizeof( *cm.leafsurfaces ), h_high ); + cm.numLeafSurfaces = count; + + out = cm.leafsurfaces; + + for ( i=0 ; ifileofs); + if ( l->filelen % sizeof(*in) ) { + Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); + } + count = l->filelen / sizeof(*in); + + cm.brushsides = Hunk_Alloc( ( BOX_SIDES + count ) * sizeof( *cm.brushsides ), h_high ); + cm.numBrushSides = count; + + out = cm.brushsides; + + for ( i=0 ; iplaneNum ); + out->plane = &cm.planes[num]; + out->shaderNum = LittleLong( in->shaderNum ); + if ( out->shaderNum < 0 || out->shaderNum >= cm.numShaders ) { + Com_Error( ERR_DROP, "CMod_LoadBrushSides: bad shaderNum: %i", out->shaderNum ); + } + out->surfaceFlags = cm.shaders[out->shaderNum].surfaceFlags; + } +} + + +/* +================= +CMod_LoadEntityString +================= +*/ +void CMod_LoadEntityString( lump_t *l ) { + cm.entityString = Hunk_Alloc( l->filelen, h_high ); + cm.numEntityChars = l->filelen; + Com_Memcpy (cm.entityString, cmod_base + l->fileofs, l->filelen); +} + +/* +================= +CMod_LoadVisibility +================= +*/ +#define VIS_HEADER 8 +void CMod_LoadVisibility( lump_t *l ) { + int len; + byte *buf; + + len = l->filelen; + if ( !len ) { + cm.clusterBytes = ( cm.numClusters + 31 ) & ~31; + cm.visibility = Hunk_Alloc( cm.clusterBytes, h_high ); + Com_Memset( cm.visibility, 255, cm.clusterBytes ); + return; + } + buf = cmod_base + l->fileofs; + + cm.vised = qtrue; + cm.visibility = Hunk_Alloc( len, h_high ); + cm.numClusters = LittleLong( ((int *)buf)[0] ); + cm.clusterBytes = LittleLong( ((int *)buf)[1] ); + Com_Memcpy (cm.visibility, buf + VIS_HEADER, len - VIS_HEADER ); +} + +//================================================================== + + +/* +================= +CMod_LoadPatches +================= +*/ +#define MAX_PATCH_VERTS 1024 +void CMod_LoadPatches( lump_t *surfs, lump_t *verts ) { + drawVert_t *dv, *dv_p; + dsurface_t *in; + int count; + int i, j; + int c; + cPatch_t *patch; + vec3_t points[MAX_PATCH_VERTS]; + int width, height; + int shaderNum; + + in = (void *)(cmod_base + surfs->fileofs); + if (surfs->filelen % sizeof(*in)) + Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); + cm.numSurfaces = count = surfs->filelen / sizeof(*in); + cm.surfaces = Hunk_Alloc( cm.numSurfaces * sizeof( cm.surfaces[0] ), h_high ); + + dv = (void *)(cmod_base + verts->fileofs); + if (verts->filelen % sizeof(*dv)) + Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); + + // scan through all the surfaces, but only load patches, + // not planar faces + for ( i = 0 ; i < count ; i++, in++ ) { + if ( LittleLong( in->surfaceType ) != MST_PATCH ) { + continue; // ignore other surfaces + } + // FIXME: check for non-colliding patches + + cm.surfaces[ i ] = patch = Hunk_Alloc( sizeof( *patch ), h_high ); + + // load the full drawverts onto the stack + width = LittleLong( in->patchWidth ); + height = LittleLong( in->patchHeight ); + c = width * height; + if ( c > MAX_PATCH_VERTS ) { + Com_Error( ERR_DROP, "ParseMesh: MAX_PATCH_VERTS" ); + } + + dv_p = dv + LittleLong( in->firstVert ); + for ( j = 0 ; j < c ; j++, dv_p++ ) { + points[j][0] = LittleFloat( dv_p->xyz[0] ); + points[j][1] = LittleFloat( dv_p->xyz[1] ); + points[j][2] = LittleFloat( dv_p->xyz[2] ); + } + + shaderNum = LittleLong( in->shaderNum ); + patch->contents = cm.shaders[shaderNum].contentFlags; + patch->surfaceFlags = cm.shaders[shaderNum].surfaceFlags; + + // create the internal facet structure + patch->pc = CM_GeneratePatchCollide( width, height, points ); + } +} + +//================================================================== + +unsigned CM_LumpChecksum(lump_t *lump) { + return LittleLong (Com_BlockChecksum (cmod_base + lump->fileofs, lump->filelen)); +} + +unsigned CM_Checksum(dheader_t *header) { + unsigned checksums[16]; + checksums[0] = CM_LumpChecksum(&header->lumps[LUMP_SHADERS]); + checksums[1] = CM_LumpChecksum(&header->lumps[LUMP_LEAFS]); + checksums[2] = CM_LumpChecksum(&header->lumps[LUMP_LEAFBRUSHES]); + checksums[3] = CM_LumpChecksum(&header->lumps[LUMP_LEAFSURFACES]); + checksums[4] = CM_LumpChecksum(&header->lumps[LUMP_PLANES]); + checksums[5] = CM_LumpChecksum(&header->lumps[LUMP_BRUSHSIDES]); + checksums[6] = CM_LumpChecksum(&header->lumps[LUMP_BRUSHES]); + checksums[7] = CM_LumpChecksum(&header->lumps[LUMP_MODELS]); + checksums[8] = CM_LumpChecksum(&header->lumps[LUMP_NODES]); + checksums[9] = CM_LumpChecksum(&header->lumps[LUMP_SURFACES]); + checksums[10] = CM_LumpChecksum(&header->lumps[LUMP_DRAWVERTS]); + + return LittleLong(Com_BlockChecksum(checksums, 11 * 4)); +} + +/* +================== +CM_LoadMap + +Loads in the map and all submodels +================== +*/ +void CM_LoadMap( const char *name, qboolean clientload, int *checksum ) { + int *buf; + int i; + dheader_t header; + int length; + static unsigned last_checksum; + + if ( !name || !name[0] ) { + Com_Error( ERR_DROP, "CM_LoadMap: NULL name" ); + } + +#ifndef BSPC + cm_noAreas = Cvar_Get ("cm_noAreas", "0", CVAR_CHEAT); + cm_noCurves = Cvar_Get ("cm_noCurves", "0", CVAR_CHEAT); + cm_playerCurveClip = Cvar_Get ("cm_playerCurveClip", "1", CVAR_ARCHIVE|CVAR_CHEAT ); +#endif + Com_DPrintf( "CM_LoadMap( %s, %i )\n", name, clientload ); + + if ( !strcmp( cm.name, name ) && clientload ) { + *checksum = last_checksum; + return; + } + + // free old stuff + Com_Memset( &cm, 0, sizeof( cm ) ); + CM_ClearLevelPatches(); + + if ( !name[0] ) { + cm.numLeafs = 1; + cm.numClusters = 1; + cm.numAreas = 1; + cm.cmodels = Hunk_Alloc( sizeof( *cm.cmodels ), h_high ); + *checksum = 0; + return; + } + + // + // load the file + // +#ifndef BSPC + length = FS_ReadFile( name, (void **)&buf ); +#else + length = LoadQuakeFile((quakefile_t *) name, (void **)&buf); +#endif + + if ( !buf ) { + Com_Error (ERR_DROP, "Couldn't load %s", name); + } + + last_checksum = LittleLong (Com_BlockChecksum (buf, length)); + *checksum = last_checksum; + + header = *(dheader_t *)buf; + for (i=0 ; i= cm.numSubModels ) { + Com_Error (ERR_DROP, "CM_InlineModel: bad number"); + } + return index; +} + +int CM_NumClusters( void ) { + return cm.numClusters; +} + +int CM_NumInlineModels( void ) { + return cm.numSubModels; +} + +char *CM_EntityString( void ) { + return cm.entityString; +} + +int CM_LeafCluster( int leafnum ) { + if (leafnum < 0 || leafnum >= cm.numLeafs) { + Com_Error (ERR_DROP, "CM_LeafCluster: bad number"); + } + return cm.leafs[leafnum].cluster; +} + +int CM_LeafArea( int leafnum ) { + if ( leafnum < 0 || leafnum >= cm.numLeafs ) { + Com_Error (ERR_DROP, "CM_LeafArea: bad number"); + } + return cm.leafs[leafnum].area; +} + +//======================================================================= + + +/* +=================== +CM_InitBoxHull + +Set up the planes and nodes so that the six floats of a bounding box +can just be stored out and get a proper clipping hull structure. +=================== +*/ +void CM_InitBoxHull (void) +{ + int i; + int side; + cplane_t *p; + cbrushside_t *s; + + box_planes = &cm.planes[cm.numPlanes]; + + box_brush = &cm.brushes[cm.numBrushes]; + box_brush->numsides = 6; + box_brush->sides = cm.brushsides + cm.numBrushSides; + box_brush->contents = CONTENTS_BODY; + + box_model.leaf.numLeafBrushes = 1; +// box_model.leaf.firstLeafBrush = cm.numBrushes; + box_model.leaf.firstLeafBrush = cm.numLeafBrushes; + cm.leafbrushes[cm.numLeafBrushes] = cm.numBrushes; + + for (i=0 ; i<6 ; i++) + { + side = i&1; + + // brush sides + s = &cm.brushsides[cm.numBrushSides+i]; + s->plane = cm.planes + (cm.numPlanes+i*2+side); + s->surfaceFlags = 0; + + // planes + p = &box_planes[i*2]; + p->type = i>>1; + p->signbits = 0; + VectorClear (p->normal); + p->normal[i>>1] = 1; + + p = &box_planes[i*2+1]; + p->type = 3 + (i>>1); + p->signbits = 0; + VectorClear (p->normal); + p->normal[i>>1] = -1; + + SetPlaneSignbits( p ); + } +} + +/* +=================== +CM_TempBoxModel + +To keep everything totally uniform, bounding boxes are turned into small +BSP trees instead of being compared directly. +Capsules are handled differently though. +=================== +*/ +clipHandle_t CM_TempBoxModel( const vec3_t mins, const vec3_t maxs, int capsule ) { + + VectorCopy( mins, box_model.mins ); + VectorCopy( maxs, box_model.maxs ); + + if ( capsule ) { + return CAPSULE_MODEL_HANDLE; + } + + box_planes[0].dist = maxs[0]; + box_planes[1].dist = -maxs[0]; + box_planes[2].dist = mins[0]; + box_planes[3].dist = -mins[0]; + box_planes[4].dist = maxs[1]; + box_planes[5].dist = -maxs[1]; + box_planes[6].dist = mins[1]; + box_planes[7].dist = -mins[1]; + box_planes[8].dist = maxs[2]; + box_planes[9].dist = -maxs[2]; + box_planes[10].dist = mins[2]; + box_planes[11].dist = -mins[2]; + + VectorCopy( mins, box_brush->bounds[0] ); + VectorCopy( maxs, box_brush->bounds[1] ); + + return BOX_MODEL_HANDLE; +} + +/* +=================== +CM_ModelBounds +=================== +*/ +void CM_ModelBounds( clipHandle_t model, vec3_t mins, vec3_t maxs ) { + cmodel_t *cmod; + + cmod = CM_ClipHandleToModel( model ); + VectorCopy( cmod->mins, mins ); + VectorCopy( cmod->maxs, maxs ); +} + + -- cgit v1.2.3