diff options
Diffstat (limited to 'code/bspc/map_sin.c')
-rw-r--r-- | code/bspc/map_sin.c | 1211 |
1 files changed, 0 insertions, 1211 deletions
diff --git a/code/bspc/map_sin.c b/code/bspc/map_sin.c deleted file mode 100644 index 278c887..0000000 --- a/code/bspc/map_sin.c +++ /dev/null @@ -1,1211 +0,0 @@ -/* -=========================================================================== -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 Quake III Arena source code; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -=========================================================================== -*/ -//----------------------------------------------------------------------------- -// -// $Logfile:: /MissionPack/code/bspc/map_sin.c $ - -#include "qbsp.h" -#include "l_bsp_sin.h" -#include "aas_map.h" //AAS_CreateMapBrushes - - -//==================================================================== - - -/* -=========== -Sin_BrushContents -=========== -*/ - -int Sin_BrushContents(mapbrush_t *b) -{ - int contents; - side_t *s; - int i; -#ifdef SIN - float trans = 0; -#else - int trans; -#endif - - s = &b->original_sides[0]; - contents = s->contents; - -#ifdef SIN - trans = sin_texinfo[s->texinfo].translucence; -#else - trans = texinfo[s->texinfo].flags; -#endif - for (i=1 ; i<b->numsides ; i++, s++) - { - s = &b->original_sides[i]; -#ifdef SIN - trans += sin_texinfo[s->texinfo].translucence; -#else - trans |= texinfo[s->texinfo].flags; -#endif - if (s->contents != contents) - { -#ifdef SIN - if ( - ( s->contents & CONTENTS_DETAIL && !(contents & CONTENTS_DETAIL) ) || - ( !(s->contents & CONTENTS_DETAIL) && contents & CONTENTS_DETAIL ) - ) - { - s->contents |= CONTENTS_DETAIL; - contents |= CONTENTS_DETAIL; - continue; - } -#endif - printf ("Entity %i, Brush %i: mixed face contents\n" - , b->entitynum, b->brushnum); - break; - } - } - - -#ifdef SIN - if (contents & CONTENTS_FENCE) - { -// contents |= CONTENTS_TRANSLUCENT; - contents |= CONTENTS_DETAIL; - contents |= CONTENTS_DUMMYFENCE; - contents &= ~CONTENTS_SOLID; - contents &= ~CONTENTS_FENCE; - contents |= CONTENTS_WINDOW; - } -#endif - - // if any side is translucent, mark the contents - // and change solid to window -#ifdef SIN - if ( trans > 0 ) -#else - if ( trans & (SURF_TRANS33|SURF_TRANS66) ) -#endif - { - contents |= CONTENTS_Q2TRANSLUCENT; - if (contents & CONTENTS_SOLID) - { - contents &= ~CONTENTS_SOLID; - contents |= CONTENTS_WINDOW; - } - } - - return contents; -} //*/ - - -//============================================================================ - - - -/* -================= -ParseBrush -================= -* / -void ParseBrush (entity_t *mapent) -{ - mapbrush_t *b; - int i,j, k; - int mt; - side_t *side, *s2; - int planenum; - brush_texture_t td; -#ifdef SIN - textureref_t newref; -#endif - int planepts[3][3]; - - if (nummapbrushes == MAX_MAP_BRUSHES) - Error ("nummapbrushes == MAX_MAP_BRUSHES"); - - b = &mapbrushes[nummapbrushes]; - b->original_sides = &brushsides[nummapbrushsides]; - b->entitynum = num_entities-1; - b->brushnum = nummapbrushes - mapent->firstbrush; - - do - { - if (!GetToken (true)) - break; - if (!strcmp (token, "}") ) - break; - - if (nummapbrushsides == MAX_MAP_BRUSHSIDES) - Error ("MAX_MAP_BRUSHSIDES"); - side = &brushsides[nummapbrushsides]; - - // read the three point plane definition - for (i=0 ; i<3 ; i++) - { - if (i != 0) - GetToken (true); - if (strcmp (token, "(") ) - Error ("parsing brush"); - - for (j=0 ; j<3 ; j++) - { - GetToken (false); - planepts[i][j] = atoi(token); - } - - GetToken (false); - if (strcmp (token, ")") ) - Error ("parsing brush"); - - } - - - // - // read the texturedef - // - GetToken (false); - strcpy (td.name, token); - - GetToken (false); - td.shift[0] = atoi(token); - GetToken (false); - td.shift[1] = atoi(token); - GetToken (false); -#ifdef SIN - td.rotate = atof(token); -#else - td.rotate = atoi(token); -#endif - GetToken (false); - td.scale[0] = atof(token); - GetToken (false); - td.scale[1] = atof(token); - - // find default flags and values - mt = FindMiptex (td.name); -#ifdef SIN - // clear out the masks on newref - memset(&newref,0,sizeof(newref)); - // copy over the name - strcpy( newref.name, td.name ); - - ParseSurfaceInfo( &newref ); - MergeRefs( &bsp_textureref[mt], &newref, &td.tref ); - side->contents = td.tref.contents; - side->surf = td.tref.flags; -#else - td.flags = textureref[mt].flags; - td.value = textureref[mt].value; - side->contents = textureref[mt].contents; - side->surf = td.flags = textureref[mt].flags; - - if (TokenAvailable()) - { - GetToken (false); - side->contents = atoi(token); - GetToken (false); - side->surf = td.flags = atoi(token); - GetToken (false); - td.value = atoi(token); - } -#endif - - // translucent objects are automatically classified as detail -#ifdef SIN - if ( td.tref.translucence > 0 ) -#else - if (side->surf & (SURF_TRANS33|SURF_TRANS66) ) -#endif - side->contents |= CONTENTS_DETAIL; - if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) ) - side->contents |= CONTENTS_DETAIL; - if (fulldetail) - side->contents &= ~CONTENTS_DETAIL; - if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1) - | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) ) - side->contents |= CONTENTS_SOLID; - - // hints and skips are never detail, and have no content - if (side->surf & (SURF_HINT|SURF_SKIP) ) - { - side->contents = 0; -#ifndef SIN // I think this is a bug of some kind - side->surf &= ~CONTENTS_DETAIL; -#endif - } - - // - // find the plane number - // - planenum = PlaneFromPoints (planepts[0], planepts[1], planepts[2]); - if (planenum == -1) - { - printf ("Entity %i, Brush %i: plane with no normal\n" - , b->entitynum, b->brushnum); - continue; - } - - // - // see if the plane has been used already - // - for (k=0 ; k<b->numsides ; k++) - { - s2 = b->original_sides + k; - if (s2->planenum == planenum) - { - printf ("Entity %i, Brush %i: duplicate plane\n" - , b->entitynum, b->brushnum); - break; - } - if ( s2->planenum == (planenum^1) ) - { - printf ("Entity %i, Brush %i: mirrored plane\n" - , b->entitynum, b->brushnum); - break; - } - } - if (k != b->numsides) - continue; // duplicated - - // - // keep this side - // - - side = b->original_sides + b->numsides; - side->planenum = planenum; -#ifdef SIN - side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum], - &td, vec3_origin, &newref); - // - // save off lightinfo - // - side->lightinfo = LightinfoForBrushTexture ( &td ); -#else - side->texinfo = TexinfoForBrushTexture (&mapplanes[planenum], - &td, vec3_origin); - -#endif - - // save the td off in case there is an origin brush and we - // have to recalculate the texinfo - side_brushtextures[nummapbrushsides] = td; -#ifdef SIN - // save off the merged tref for animating textures - side_newrefs[nummapbrushsides] = newref; -#endif - - nummapbrushsides++; - b->numsides++; - } while (1); - - // get the content for the entire brush - b->contents = Sin_BrushContents (b); - - // allow detail brushes to be removed - if (nodetail && (b->contents & CONTENTS_DETAIL) ) - { - b->numsides = 0; - return; - } - - // allow water brushes to be removed - if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) ) - { - b->numsides = 0; - return; - } - - // create windings for sides and bounds for brush - MakeBrushWindings (b); - - // brushes that will not be visible at all will never be - // used as bsp splitters - if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) ) - { - c_clipbrushes++; - for (i=0 ; i<b->numsides ; i++) - b->original_sides[i].texinfo = TEXINFO_NODE; - } - - // - // origin brushes are removed, but they set - // the rotation origin for the rest of the brushes - // in the entity. After the entire entity is parsed, - // the planenums and texinfos will be adjusted for - // the origin brush - // - if (b->contents & CONTENTS_ORIGIN) - { - char string[32]; - vec3_t origin; - - if (num_entities == 1) - { - Error ("Entity %i, Brush %i: origin brushes not allowed in world" - , b->entitynum, b->brushnum); - return; - } - - VectorAdd (b->mins, b->maxs, origin); - VectorScale (origin, 0.5, origin); - - sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); - SetKeyValue (&entities[b->entitynum], "origin", string); - - VectorCopy (origin, entities[b->entitynum].origin); - - // don't keep this brush - b->numsides = 0; - - return; - } - - AddBrushBevels (b); - - nummapbrushes++; - mapent->numbrushes++; -} //*/ - -/* -================ -MoveBrushesToWorld - -Takes all of the brushes from the current entity and -adds them to the world's brush list. - -Used by func_group and func_areaportal -================ -* / -void MoveBrushesToWorld (entity_t *mapent) -{ - int newbrushes; - int worldbrushes; - mapbrush_t *temp; - int i; - - // this is pretty gross, because the brushes are expected to be - // in linear order for each entity - - newbrushes = mapent->numbrushes; - worldbrushes = entities[0].numbrushes; - - temp = malloc(newbrushes*sizeof(mapbrush_t)); - memcpy (temp, mapbrushes + mapent->firstbrush, newbrushes*sizeof(mapbrush_t)); - -#if 0 // let them keep their original brush numbers - for (i=0 ; i<newbrushes ; i++) - temp[i].entitynum = 0; -#endif - - // make space to move the brushes (overlapped copy) - memmove (mapbrushes + worldbrushes + newbrushes, - mapbrushes + worldbrushes, - sizeof(mapbrush_t) * (nummapbrushes - worldbrushes - newbrushes) ); - - // copy the new brushes down - memcpy (mapbrushes + worldbrushes, temp, sizeof(mapbrush_t) * newbrushes); - - // fix up indexes - entities[0].numbrushes += newbrushes; - for (i=1 ; i<num_entities ; i++) - entities[i].firstbrush += newbrushes; - free (temp); - - mapent->numbrushes = 0; -} //*/ - -/* -================ -ParseMapEntity -================ -* / -qboolean Sin_ParseMapEntity (void) -{ - entity_t *mapent; - epair_t *e; - side_t *s; - int i, j; - int startbrush, startsides; - vec_t newdist; - mapbrush_t *b; - - if (!GetToken (true)) - return false; - - if (strcmp (token, "{") ) - Error ("ParseEntity: { not found"); - - if (num_entities == MAX_MAP_ENTITIES) - Error ("num_entities == MAX_MAP_ENTITIES"); - - startbrush = nummapbrushes; - startsides = nummapbrushsides; - - mapent = &entities[num_entities]; - num_entities++; - memset (mapent, 0, sizeof(*mapent)); - mapent->firstbrush = nummapbrushes; - mapent->numbrushes = 0; -// mapent->portalareas[0] = -1; -// mapent->portalareas[1] = -1; - - do - { - if (!GetToken (true)) - Error ("ParseEntity: EOF without closing brace"); - if (!strcmp (token, "}") ) - break; - if (!strcmp (token, "{") ) - ParseBrush (mapent); - else - { - e = ParseEpair (); -#ifdef SIN - //HACK HACK HACK - // MED Gotta do this here - if ( !stricmp(e->key, "surfacefile") ) - { - if (!surfacefile[0]) - { - strcpy( surfacefile, e->value ); - } - printf ("--- ParseSurfaceFile ---\n"); - printf ("Surface script: %s\n", surfacefile); - if (!ParseSurfaceFile(surfacefile)) - { - Error ("Script file not found: %s\n", surfacefile); - } - } -#endif - e->next = mapent->epairs; - mapent->epairs = e; - } - } while (1); - -#ifdef SIN - if (!(strlen(ValueForKey(mapent, "origin"))) && ((num_entities-1) != 0)) - { - mapbrush_t *brush; - vec3_t origin; - char string[32]; - vec3_t mins, maxs; - int start, end; - // Calculate bounds - - start = mapent->firstbrush; - end = start + mapent->numbrushes; - ClearBounds (mins, maxs); - - for (j=start ; j<end ; j++) - { - brush = &mapbrushes[j]; - if (!brush->numsides) - continue; // not a real brush (origin brush) - shouldn't happen - AddPointToBounds (brush->mins, mins, maxs); - AddPointToBounds (brush->maxs, mins, maxs); - } - - // Set the origin to be the centroid of the entity. - VectorAdd ( mins, maxs, origin); - VectorScale( origin, 0.5f, origin ); - - sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); - SetKeyValue ( mapent, "origin", string); -// qprintf("Setting origin to %s\n",string); - } -#endif - - GetVectorForKey (mapent, "origin", mapent->origin); - -#ifdef SIN - if ( - (!strcmp ("func_areaportal", ValueForKey (mapent, "classname"))) || - (!strcmp ("func_group", ValueForKey (mapent, "classname"))) || - (!strcmp ("detail", ValueForKey (mapent, "classname")) && !entitydetails) - ) - { - VectorClear( mapent->origin ); - } -#endif - - // - // if there was an origin brush, offset all of the planes and texinfo - // - if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2]) - { - for (i=0 ; i<mapent->numbrushes ; i++) - { - b = &mapbrushes[mapent->firstbrush + i]; - for (j=0 ; j<b->numsides ; j++) - { - s = &b->original_sides[j]; - newdist = mapplanes[s->planenum].dist - - DotProduct (mapplanes[s->planenum].normal, mapent->origin); - s->planenum = FindFloatPlane (mapplanes[s->planenum].normal, newdist); -#ifdef SIN - s->texinfo = TexinfoForBrushTexture (&mapplanes[s->planenum], - &side_brushtextures[s-brushsides], mapent->origin, &side_newrefs[s-brushsides]); - // - // save off lightinfo - // - s->lightinfo = LightinfoForBrushTexture ( &side_brushtextures[s-brushsides] ); -#else - s->texinfo = TexinfoForBrushTexture (&mapplanes[s->planenum], - &side_brushtextures[s-brushsides], mapent->origin); -#endif - } - MakeBrushWindings (b); - } - } - - // group entities are just for editor convenience - // toss all brushes into the world entity - if (!strcmp ("func_group", ValueForKey (mapent, "classname"))) - { - MoveBrushesToWorld (mapent); - mapent->numbrushes = 0; - mapent->wasdetail = true; - FreeValueKeys( mapent ); - return true; - } -#ifdef SIN - // detail entities are just for editor convenience - // toss all brushes into the world entity as detail brushes - if (!strcmp ("detail", ValueForKey (mapent, "classname")) && !entitydetails) - { - for (i=0 ; i<mapent->numbrushes ; i++) - { - int j; - side_t * s; - b = &mapbrushes[mapent->firstbrush + i]; - if (nodetail) - { - b->numsides = 0; - continue; - } - if (!fulldetail) - { - // set the contents for the entire brush - b->contents |= CONTENTS_DETAIL; - // set the contents in the sides as well - for (j=0, s=b->original_sides ; j<b->numsides ; j++,s++) - { - s->contents |= CONTENTS_DETAIL; - } - } - else - { - // set the contents for the entire brush - b->contents |= CONTENTS_SOLID; - // set the contents in the sides as well - for (j=0, s=b->original_sides ; j<b->numsides ; j++,s++) - { - s->contents |= CONTENTS_SOLID; - } - } - } - MoveBrushesToWorld (mapent); - mapent->wasdetail = true; - FreeValueKeys( mapent ); - // kill off the entity - // num_entities--; - return true; - } -#endif - - // areaportal entities move their brushes, but don't eliminate - // the entity - if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname"))) - { - char str[128]; - - if (mapent->numbrushes != 1) - Error ("Entity %i: func_areaportal can only be a single brush", num_entities-1); - - b = &mapbrushes[nummapbrushes-1]; - b->contents = CONTENTS_AREAPORTAL; - c_areaportals++; - mapent->areaportalnum = c_areaportals; - // set the portal number as "style" - sprintf (str, "%i", c_areaportals); - SetKeyValue (mapent, "style", str); - MoveBrushesToWorld (mapent); - return true; - } - - return true; -} //end of the function Sin_ParseMapEntity */ - -//=================================================================== - -/* -================ -LoadMapFile -================ -* / -void Sin_LoadMapFile (char *filename) -{ - int i; -#ifdef SIN - int num_detailsides=0; - int num_detailbrushes=0; - int num_worldsides=0; - int num_worldbrushes=0; - int j,k; -#endif - - qprintf ("--- LoadMapFile ---\n"); - - LoadScriptFile (filename); - - nummapbrushsides = 0; - num_entities = 0; - - while (ParseMapEntity ()) - { - } - - ClearBounds (map_mins, map_maxs); - for (i=0 ; i<entities[0].numbrushes ; i++) - { - if (mapbrushes[i].mins[0] > 4096) - continue; // no valid points - AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs); - AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs); - } -#ifdef SIN - for (j=0; j<num_entities; j++) - { - for (i=0 ; i<entities[j].numbrushes ; i++) - { - side_t * s; - mapbrush_t *b; - b = &mapbrushes[entities[j].firstbrush + i]; - if (b->numsides && b->contents & CONTENTS_DETAIL) - num_detailbrushes++; - else if (b->numsides) - num_worldbrushes++; - for (k=0, s=b->original_sides ; k<b->numsides ; k++,s++) - { - if (s->contents & CONTENTS_DETAIL) - num_detailsides++; - else - num_worldsides++; - } - } - } -#endif - - qprintf ("%5i brushes\n", nummapbrushes); - qprintf ("%5i clipbrushes\n", c_clipbrushes); - qprintf ("%5i total sides\n", nummapbrushsides); - qprintf ("%5i boxbevels\n", c_boxbevels); - qprintf ("%5i edgebevels\n", c_edgebevels); - qprintf ("%5i entities\n", num_entities); - qprintf ("%5i planes\n", nummapplanes); - qprintf ("%5i areaportals\n", c_areaportals); - qprintf ("size: %5.0f,%5.0f,%5.0f to %5.0f,%5.0f,%5.0f\n", map_mins[0],map_mins[1],map_mins[2], - map_maxs[0],map_maxs[1],map_maxs[2]); -#ifdef SIN - qprintf ("%5i detailbrushes\n", num_detailbrushes); - qprintf ("%5i worldbrushes\n", num_worldbrushes); - qprintf ("%5i detailsides\n", num_detailsides); - qprintf ("%5i worldsides\n", num_worldsides); -#endif - -} //end of the function Sin_LoadMap */ - - -#ifdef ME //Begin MAP loading from BSP file -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void Sin_CreateMapTexinfo(void) -{ - int i; - vec_t defaultvec[4] = {1, 0, 0, 0}; - - memcpy(map_texinfo[0].vecs[0], defaultvec, sizeof(defaultvec)); - memcpy(map_texinfo[0].vecs[1], defaultvec, sizeof(defaultvec)); - map_texinfo[0].flags = 0; - map_texinfo[0].value = 0; - strcpy(map_texinfo[0].texture, "generic/misc/red"); //no texture - map_texinfo[0].nexttexinfo = -1; - for (i = 1; i < sin_numtexinfo; i++) - { - memcpy(map_texinfo[i].vecs, sin_texinfo[i].vecs, sizeof(float) * 2 * 4); - map_texinfo[i].flags = sin_texinfo[i].flags; - map_texinfo[i].value = 0; - strcpy(map_texinfo[i].texture, sin_texinfo[i].texture); - map_texinfo[i].nexttexinfo = -1; - } //end for -} //end of the function Sin_CreateMapTexinfo -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void Sin_SetLeafBrushesModelNumbers(int leafnum, int modelnum) -{ - int i, brushnum; - sin_dleaf_t *leaf; - - leaf = &sin_dleafs[leafnum]; - for (i = 0; i < leaf->numleafbrushes; i++) - { - brushnum = sin_dleafbrushes[leaf->firstleafbrush + i]; - brushmodelnumbers[brushnum] = modelnum; - dbrushleafnums[brushnum] = leafnum; - } //end for -} //end of the function Sin_SetLeafBrushesModelNumbers -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void Sin_InitNodeStack(void) -{ - nodestackptr = nodestack; - nodestacksize = 0; -} //end of the function Sin_InitNodeStack -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void Sin_PushNodeStack(int num) -{ - *nodestackptr = num; - nodestackptr++; - nodestacksize++; - // - if (nodestackptr >= &nodestack[NODESTACKSIZE]) - { - Error("Sin_PushNodeStack: stack overflow\n"); - } //end if -} //end of the function Sin_PushNodeStack -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -int Sin_PopNodeStack(void) -{ - //if the stack is empty - if (nodestackptr <= nodestack) return -1; - //decrease stack pointer - nodestackptr--; - nodestacksize--; - //return the top value from the stack - return *nodestackptr; -} //end of the function Sin_PopNodeStack -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void Sin_SetBrushModelNumbers(entity_t *mapent) -{ - int n, pn; - int leafnum; - - // - Sin_InitNodeStack(); - //head node (root) of the bsp tree - n = sin_dmodels[mapent->modelnum].headnode; - pn = 0; - - do - { - //if we are in a leaf (negative node number) - if (n < 0) - { - //number of the leaf - leafnum = (-n) - 1; - //set the brush numbers - Sin_SetLeafBrushesModelNumbers(leafnum, mapent->modelnum); - //walk back into the tree to find a second child to continue with - for (pn = Sin_PopNodeStack(); pn >= 0; n = pn, pn = Sin_PopNodeStack()) - { - //if we took the first child at the parent node - if (sin_dnodes[pn].children[0] == n) break; - } //end for - //if the stack wasn't empty (if not processed whole tree) - if (pn >= 0) - { - //push the parent node again - Sin_PushNodeStack(pn); - //we proceed with the second child of the parent node - n = sin_dnodes[pn].children[1]; - } //end if - } //end if - else - { - //push the current node onto the stack - Sin_PushNodeStack(n); - //walk forward into the tree to the first child - n = sin_dnodes[n].children[0]; - } //end else - } while(pn >= 0); -} //end of the function Sin_SetBrushModelNumbers -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void Sin_BSPBrushToMapBrush(sin_dbrush_t *bspbrush, entity_t *mapent) -{ - mapbrush_t *b; - int i, k, n; - side_t *side, *s2; - int planenum; - sin_dbrushside_t *bspbrushside; - sin_dplane_t *bspplane; - - if (nummapbrushes >= MAX_MAPFILE_BRUSHES) - Error ("nummapbrushes >= MAX_MAPFILE_BRUSHES"); - - b = &mapbrushes[nummapbrushes]; - b->original_sides = &brushsides[nummapbrushsides]; - b->entitynum = mapent-entities; - b->brushnum = nummapbrushes - mapent->firstbrush; - b->leafnum = dbrushleafnums[bspbrush - sin_dbrushes]; - - for (n = 0; n < bspbrush->numsides; n++) - { - //pointer to the bsp brush side - bspbrushside = &sin_dbrushsides[bspbrush->firstside + n]; - - if (nummapbrushsides >= MAX_MAPFILE_BRUSHSIDES) - { - Error ("MAX_MAPFILE_BRUSHSIDES"); - } //end if - //pointer to the map brush side - side = &brushsides[nummapbrushsides]; - //if the BSP brush side is textured - if (sin_dbrushsidetextured[bspbrush->firstside + n]) side->flags |= SFL_TEXTURED; - else side->flags &= ~SFL_TEXTURED; - //ME: can get side contents and surf directly from BSP file - side->contents = bspbrush->contents; - //if the texinfo is TEXINFO_NODE - if (bspbrushside->texinfo < 0) side->surf = 0; - else side->surf = sin_texinfo[bspbrushside->texinfo].flags; - - // translucent objects are automatically classified as detail - if (side->surf & (SURF_TRANS33|SURF_TRANS66) ) - side->contents |= CONTENTS_DETAIL; - if (side->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) ) - side->contents |= CONTENTS_DETAIL; - if (fulldetail) - side->contents &= ~CONTENTS_DETAIL; - if (!(side->contents & ((LAST_VISIBLE_CONTENTS-1) - | CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP|CONTENTS_MIST) ) ) - side->contents |= CONTENTS_SOLID; - - // hints and skips are never detail, and have no content - if (side->surf & (SURF_HINT|SURF_SKIP) ) - { - side->contents = 0; - side->surf &= ~CONTENTS_DETAIL; - } - - //ME: get a plane for this side - bspplane = &sin_dplanes[bspbrushside->planenum]; - planenum = FindFloatPlane(bspplane->normal, bspplane->dist); - // - // see if the plane has been used already - // - //ME: this really shouldn't happen!!! - //ME: otherwise the bsp file is corrupted?? - //ME: still it seems to happen, maybe Johny Boy's - //ME: brush bevel adding is crappy ? - for (k = 0; k < b->numsides; k++) - { - s2 = b->original_sides + k; - if (s2->planenum == planenum) - { - Log_Print("Entity %i, Brush %i: duplicate plane\n" - , b->entitynum, b->brushnum); - break; - } - if ( s2->planenum == (planenum^1) ) - { - Log_Print("Entity %i, Brush %i: mirrored plane\n" - , b->entitynum, b->brushnum); - break; - } - } - if (k != b->numsides) - continue; // duplicated - - // - // keep this side - // - //ME: reset pointer to side, why? hell I dunno (pointer is set above already) - side = b->original_sides + b->numsides; - //ME: store the plane number - side->planenum = planenum; - //ME: texinfo is already stored when bsp is loaded - //NOTE: check for TEXINFO_NODE, otherwise crash in Sin_BrushContents - if (bspbrushside->texinfo < 0) side->texinfo = 0; - else side->texinfo = bspbrushside->texinfo; - - // save the td off in case there is an origin brush and we - // have to recalculate the texinfo - // ME: don't need to recalculate because it's already done - // (for non-world entities) in the BSP file -// side_brushtextures[nummapbrushsides] = td; - - nummapbrushsides++; - b->numsides++; - } //end for - - // get the content for the entire brush - b->contents = bspbrush->contents; - Sin_BrushContents(b); - - if (BrushExists(b)) - { - c_squattbrushes++; - b->numsides = 0; - return; - } //end if - - //if we're creating AAS - if (create_aas) - { - //create the AAS brushes from this brush, don't add brush bevels - AAS_CreateMapBrushes(b, mapent, false); - return; - } //end if - - // allow detail brushes to be removed - if (nodetail && (b->contents & CONTENTS_DETAIL) ) - { - b->numsides = 0; - return; - } //end if - - // allow water brushes to be removed - if (nowater && (b->contents & (CONTENTS_LAVA | CONTENTS_SLIME | CONTENTS_WATER)) ) - { - b->numsides = 0; - return; - } //end if - - // create windings for sides and bounds for brush - MakeBrushWindings(b); - - //mark brushes without winding or with a tiny window as bevels - MarkBrushBevels(b); - - // brushes that will not be visible at all will never be - // used as bsp splitters - if (b->contents & (CONTENTS_PLAYERCLIP|CONTENTS_MONSTERCLIP) ) - { - c_clipbrushes++; - for (i = 0; i < b->numsides; i++) - b->original_sides[i].texinfo = TEXINFO_NODE; - } //end for - - // - // origin brushes are removed, but they set - // the rotation origin for the rest of the brushes - // in the entity. After the entire entity is parsed, - // the planenums and texinfos will be adjusted for - // the origin brush - // - //ME: not needed because the entities in the BSP file already - // have an origin set -// if (b->contents & CONTENTS_ORIGIN) -// { -// char string[32]; -// vec3_t origin; -// -// if (num_entities == 1) -// { -// Error ("Entity %i, Brush %i: origin brushes not allowed in world" -// , b->entitynum, b->brushnum); -// return; -// } -// -// VectorAdd (b->mins, b->maxs, origin); -// VectorScale (origin, 0.5, origin); -// -// sprintf (string, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); -// SetKeyValue (&entities[b->entitynum], "origin", string); -// -// VectorCopy (origin, entities[b->entitynum].origin); -// -// // don't keep this brush -// b->numsides = 0; -// -// return; -// } - - //ME: the bsp brushes already have bevels, so we won't try to - // add them again (especially since Johny Boy's bevel adding might - // be crappy) -// AddBrushBevels(b); - - nummapbrushes++; - mapent->numbrushes++; -} //end of the function Sin_BSPBrushToMapBrush -//=========================================================================== -//=========================================================================== -void Sin_ParseBSPBrushes(entity_t *mapent) -{ - int i, testnum = 0; - - //give all the brushes that belong to this entity the number of the - //BSP model used by this entity - Sin_SetBrushModelNumbers(mapent); - //now parse all the brushes with the correct mapent->modelnum - for (i = 0; i < sin_numbrushes; i++) - { - if (brushmodelnumbers[i] == mapent->modelnum) - { - testnum++; - Sin_BSPBrushToMapBrush(&sin_dbrushes[i], mapent); - } //end if - } //end for -} //end of the function Sin_ParseBSPBrushes -//=========================================================================== -//=========================================================================== -qboolean Sin_ParseBSPEntity(int entnum) -{ - entity_t *mapent; - char *model; - int startbrush, startsides; - - startbrush = nummapbrushes; - startsides = nummapbrushsides; - - mapent = &entities[entnum];//num_entities]; - mapent->firstbrush = nummapbrushes; - mapent->numbrushes = 0; - mapent->modelnum = -1; //-1 = no model - - model = ValueForKey(mapent, "model"); - if (model && *model == '*') - { - mapent->modelnum = atoi(&model[1]); - //Log_Print("model = %s\n", model); - //Log_Print("mapent->modelnum = %d\n", mapent->modelnum); - } //end if - - GetVectorForKey(mapent, "origin", mapent->origin); - - //if this is the world entity it has model number zero - //the world entity has no model key - if (!strcmp("worldspawn", ValueForKey(mapent, "classname"))) - { - mapent->modelnum = 0; - } //end if - //if the map entity has a BSP model (a modelnum of -1 is used for - //entities that aren't using a BSP model) - if (mapent->modelnum >= 0) - { - //parse the bsp brushes - Sin_ParseBSPBrushes(mapent); - } //end if - // - //the origin of the entity is already taken into account - // - //func_group entities can't be in the bsp file - // - //check out the func_areaportal entities - if (!strcmp ("func_areaportal", ValueForKey (mapent, "classname"))) - { - c_areaportals++; - mapent->areaportalnum = c_areaportals; - return true; - } //end if - return true; -} //end of the function Sin_ParseBSPEntity -//=========================================================================== -// -// Parameter: - -// Returns: - -// Changes Globals: - -//=========================================================================== -void Sin_LoadMapFromBSP(char *filename, int offset, int length) -{ - int i; - - Log_Print("-- Sin_LoadMapFromBSP --\n"); - //loaded map type - loadedmaptype = MAPTYPE_SIN; - - Log_Print("Loading map from %s...\n", filename); - //load the bsp file - Sin_LoadBSPFile(filename, offset, length); - - //create an index from bsp planes to map planes - //DPlanes2MapPlanes(); - //clear brush model numbers - for (i = 0; i < MAX_MAPFILE_BRUSHES; i++) - brushmodelnumbers[i] = -1; - - nummapbrushsides = 0; - num_entities = 0; - - Sin_ParseEntities(); - // - for (i = 0; i < num_entities; i++) - { - Sin_ParseBSPEntity(i); - } //end for - - //get the map mins and maxs from the world model - ClearBounds(map_mins, map_maxs); - for (i = 0; i < entities[0].numbrushes; i++) - { - if (mapbrushes[i].mins[0] > 4096) - continue; //no valid points - AddPointToBounds (mapbrushes[i].mins, map_mins, map_maxs); - AddPointToBounds (mapbrushes[i].maxs, map_mins, map_maxs); - } //end for - // - Sin_CreateMapTexinfo(); -} //end of the function Sin_LoadMapFromBSP - -void Sin_ResetMapLoading(void) -{ - //reset for map loading from bsp - memset(nodestack, 0, NODESTACKSIZE * sizeof(int)); - nodestackptr = NULL; - nodestacksize = 0; - memset(brushmodelnumbers, 0, MAX_MAPFILE_BRUSHES * sizeof(int)); -} //end of the function Sin_ResetMapLoading - -//End MAP loading from BSP file - -#endif //ME |