aboutsummaryrefslogtreecommitdiffstats
path: root/code/bspc/map.c
diff options
context:
space:
mode:
authortma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-10-29 23:13:09 +0000
committertma <tma@edf5b092-35ff-0310-97b2-ce42778d08ea>2005-10-29 23:13:09 +0000
commitce25a7def5dc658d78c06016494b90972f1cf973 (patch)
treeba01dacc114803beafb50a02ce7b01d13302e7ad /code/bspc/map.c
parentcb1d870b05814322bc2ebd26a111eb792e186f33 (diff)
downloadioquake3-aero-ce25a7def5dc658d78c06016494b90972f1cf973.tar.gz
ioquake3-aero-ce25a7def5dc658d78c06016494b90972f1cf973.zip
* General decrufting:
* Removed Q3_STATIC and associated defines * Removed MAC_STATIC * Replaced __LCC__ with Q3_VM * Removed bspc and splines directories git-svn-id: svn://svn.icculus.org/quake3/trunk@201 edf5b092-35ff-0310-97b2-ce42778d08ea
Diffstat (limited to 'code/bspc/map.c')
-rw-r--r--code/bspc/map.c1267
1 files changed, 0 insertions, 1267 deletions
diff --git a/code/bspc/map.c b/code/bspc/map.c
deleted file mode 100644
index c3c5104..0000000
--- a/code/bspc/map.c
+++ /dev/null
@@ -1,1267 +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
-===========================================================================
-*/
-
-#include "qbsp.h"
-#include "l_bsp_hl.h"
-#include "l_bsp_q1.h"
-#include "l_bsp_q2.h"
-#include "l_bsp_q3.h"
-#include "l_bsp_sin.h"
-#include "l_mem.h"
-#include "../botlib/aasfile.h" //aas_bbox_t
-#include "aas_store.h" //AAS_MAX_BBOXES
-#include "aas_cfg.h"
-
-#define Sign(x) (x < 0 ? 1 : 0)
-
-int nummapbrushes;
-mapbrush_t mapbrushes[MAX_MAPFILE_BRUSHES];
-
-int nummapbrushsides;
-side_t brushsides[MAX_MAPFILE_BRUSHSIDES];
-brush_texture_t side_brushtextures[MAX_MAPFILE_BRUSHSIDES];
-
-int nummapplanes;
-plane_t mapplanes[MAX_MAPFILE_PLANES];
-int mapplaneusers[MAX_MAPFILE_PLANES];
-
-#define PLANE_HASHES 1024
-plane_t *planehash[PLANE_HASHES];
-vec3_t map_mins, map_maxs;
-
-#ifdef SIN
-textureref_t side_newrefs[MAX_MAPFILE_BRUSHSIDES];
-#endif
-
-map_texinfo_t map_texinfo[MAX_MAPFILE_TEXINFO];
-int map_numtexinfo;
-int loadedmaptype; //loaded map type
-
-// undefine to make plane finding use linear sort
-#define USE_HASHING
-
-int c_boxbevels;
-int c_edgebevels;
-int c_areaportals;
-int c_clipbrushes;
-int c_squattbrushes;
-int c_writtenbrushes;
-
-/*
-=============================================================================
-
-PLANE FINDING
-
-=============================================================================
-*/
-
-
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int PlaneSignBits(vec3_t normal)
-{
- int i, signbits;
-
- signbits = 0;
- for (i = 2; i >= 0; i--)
- {
- signbits = (signbits << 1) + Sign(normal[i]);
- } //end for
- return signbits;
-} //end of the function PlaneSignBits
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int PlaneTypeForNormal(vec3_t normal)
-{
- vec_t ax, ay, az;
-
-// NOTE: should these have an epsilon around 1.0?
- if (normal[0] == 1.0 || normal[0] == -1.0)
- return PLANE_X;
- if (normal[1] == 1.0 || normal[1] == -1.0)
- return PLANE_Y;
- if (normal[2] == 1.0 || normal[2] == -1.0)
- return PLANE_Z;
-
- ax = fabs(normal[0]);
- ay = fabs(normal[1]);
- az = fabs(normal[2]);
-
- if (ax >= ay && ax >= az)
- return PLANE_ANYX;
- if (ay >= ax && ay >= az)
- return PLANE_ANYY;
- return PLANE_ANYZ;
-} //end of the function PlaneTypeForNormal
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-//ME NOTE: changed from 0.00001
-#define NORMAL_EPSILON 0.0001
-//ME NOTE: changed from 0.01
-#define DIST_EPSILON 0.02
-qboolean PlaneEqual(plane_t *p, vec3_t normal, vec_t dist)
-{
-#if 1
- if (
- fabs(p->normal[0] - normal[0]) < NORMAL_EPSILON
- && fabs(p->normal[1] - normal[1]) < NORMAL_EPSILON
- && fabs(p->normal[2] - normal[2]) < NORMAL_EPSILON
- && fabs(p->dist - dist) < DIST_EPSILON )
- return true;
-#else
- if (p->normal[0] == normal[0]
- && p->normal[1] == normal[1]
- && p->normal[2] == normal[2]
- && p->dist == dist)
- return true;
-#endif
- return false;
-} //end of the function PlaneEqual
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddPlaneToHash(plane_t *p)
-{
- int hash;
-
- hash = (int)fabs(p->dist) / 8;
- hash &= (PLANE_HASHES-1);
-
- p->hash_chain = planehash[hash];
- planehash[hash] = p;
-} //end of the function AddPlaneToHash
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int CreateNewFloatPlane (vec3_t normal, vec_t dist)
-{
- plane_t *p, temp;
-
- if (VectorLength(normal) < 0.5)
- Error ("FloatPlane: bad normal");
- // create a new plane
- if (nummapplanes+2 > MAX_MAPFILE_PLANES)
- Error ("MAX_MAPFILE_PLANES");
-
- p = &mapplanes[nummapplanes];
- VectorCopy (normal, p->normal);
- p->dist = dist;
- p->type = (p+1)->type = PlaneTypeForNormal (p->normal);
- p->signbits = PlaneSignBits(p->normal);
-
- VectorSubtract (vec3_origin, normal, (p+1)->normal);
- (p+1)->dist = -dist;
- (p+1)->signbits = PlaneSignBits((p+1)->normal);
-
- nummapplanes += 2;
-
- // allways put axial planes facing positive first
- if (p->type < 3)
- {
- if (p->normal[0] < 0 || p->normal[1] < 0 || p->normal[2] < 0)
- {
- // flip order
- temp = *p;
- *p = *(p+1);
- *(p+1) = temp;
-
- AddPlaneToHash (p);
- AddPlaneToHash (p+1);
- return nummapplanes - 1;
- }
- }
-
- AddPlaneToHash (p);
- AddPlaneToHash (p+1);
- return nummapplanes - 2;
-} //end of the function CreateNewFloatPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SnapVector(vec3_t normal)
-{
- int i;
-
- for (i=0 ; i<3 ; i++)
- {
- if ( fabs(normal[i] - 1) < NORMAL_EPSILON )
- {
- VectorClear (normal);
- normal[i] = 1;
- break;
- }
- if ( fabs(normal[i] - -1) < NORMAL_EPSILON )
- {
- VectorClear (normal);
- normal[i] = -1;
- break;
- }
- }
-} //end of the function SnapVector
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void SnapPlane(vec3_t normal, vec_t *dist)
-{
- SnapVector(normal);
-
- if (fabs(*dist-Q_rint(*dist)) < DIST_EPSILON)
- *dist = Q_rint(*dist);
-} //end of the function SnapPlane
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#ifndef USE_HASHING
-int FindFloatPlane(vec3_t normal, vec_t dist)
-{
- int i;
- plane_t *p;
-
- SnapPlane(normal, &dist);
- for (i = 0, p = mapplanes; i < nummapplanes; i++, p++)
- {
- if (PlaneEqual (p, normal, dist))
- {
- mapplaneusers[i]++;
- return i;
- } //end if
- } //end for
- i = CreateNewFloatPlane (normal, dist);
- mapplaneusers[i]++;
- return i;
-} //end of the function FindFloatPlane
-#else
-int FindFloatPlane (vec3_t normal, vec_t dist)
-{
- int i;
- plane_t *p;
- int hash, h;
-
- SnapPlane (normal, &dist);
- hash = (int)fabs(dist) / 8;
- hash &= (PLANE_HASHES-1);
-
- // search the border bins as well
- for (i = -1; i <= 1; i++)
- {
- h = (hash+i)&(PLANE_HASHES-1);
- for (p = planehash[h]; p; p = p->hash_chain)
- {
- if (PlaneEqual(p, normal, dist))
- {
- mapplaneusers[p-mapplanes]++;
- return p - mapplanes;
- } //end if
- } //end for
- } //end for
- i = CreateNewFloatPlane (normal, dist);
- mapplaneusers[i]++;
- return i;
-} //end of the function FindFloatPlane
-#endif
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int PlaneFromPoints (int *p0, int *p1, int *p2)
-{
- vec3_t t1, t2, normal;
- vec_t dist;
-
- VectorSubtract (p0, p1, t1);
- VectorSubtract (p2, p1, t2);
- CrossProduct (t1, t2, normal);
- VectorNormalize (normal);
-
- dist = DotProduct (p0, normal);
-
- return FindFloatPlane (normal, dist);
-} //end of the function PlaneFromPoints
-//===========================================================================
-// Adds any additional planes necessary to allow the brush to be expanded
-// against axial bounding boxes
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void AddBrushBevels (mapbrush_t *b)
-{
- int axis, dir;
- int i, j, k, l, order;
- side_t sidetemp;
- brush_texture_t tdtemp;
-#ifdef SIN
- textureref_t trtemp;
-#endif
- side_t *s, *s2;
- vec3_t normal;
- float dist;
- winding_t *w, *w2;
- vec3_t vec, vec2;
- float d;
-
- //
- // add the axial planes
- //
- order = 0;
- for (axis=0 ; axis <3 ; axis++)
- {
- for (dir=-1 ; dir <= 1 ; dir+=2, order++)
- {
- // see if the plane is allready present
- for (i=0, s=b->original_sides ; i<b->numsides ; i++,s++)
- {
- if (mapplanes[s->planenum].normal[axis] == dir)
- break;
- }
-
- if (i == b->numsides)
- { // add a new side
- if (nummapbrushsides == MAX_MAP_BRUSHSIDES)
- Error ("MAX_MAP_BRUSHSIDES");
- nummapbrushsides++;
- b->numsides++;
- VectorClear (normal);
- normal[axis] = dir;
- if (dir == 1)
- dist = b->maxs[axis];
- else
- dist = -b->mins[axis];
- s->planenum = FindFloatPlane (normal, dist);
- s->texinfo = b->original_sides[0].texinfo;
-#ifdef SIN
- s->lightinfo = b->original_sides[0].lightinfo;
-#endif
- s->contents = b->original_sides[0].contents;
- s->flags |= SFL_BEVEL;
- c_boxbevels++;
- }
-
- // if the plane is not in it canonical order, swap it
- if (i != order)
- {
- sidetemp = b->original_sides[order];
- b->original_sides[order] = b->original_sides[i];
- b->original_sides[i] = sidetemp;
-
- j = b->original_sides - brushsides;
- tdtemp = side_brushtextures[j+order];
- side_brushtextures[j+order] = side_brushtextures[j+i];
- side_brushtextures[j+i] = tdtemp;
-
-#ifdef SIN
- trtemp = side_newrefs[j+order];
- side_newrefs[j+order] = side_newrefs[j+i];
- side_newrefs[j+i] = trtemp;
-#endif
- }
- }
- }
-
- //
- // add the edge bevels
- //
- if (b->numsides == 6)
- return; // pure axial
-
- // test the non-axial plane edges
- for (i=6 ; i<b->numsides ; i++)
- {
- s = b->original_sides + i;
- w = s->winding;
- if (!w)
- continue;
- for (j=0 ; j<w->numpoints ; j++)
- {
- k = (j+1)%w->numpoints;
- VectorSubtract (w->p[j], w->p[k], vec);
- if (VectorNormalize (vec) < 0.5)
- continue;
- SnapVector (vec);
- for (k=0 ; k<3 ; k++)
- if ( vec[k] == -1 || vec[k] == 1)
- break; // axial
- if (k != 3)
- continue; // only test non-axial edges
-
- // try the six possible slanted axials from this edge
- for (axis=0 ; axis <3 ; axis++)
- {
- for (dir=-1 ; dir <= 1 ; dir+=2)
- {
- // construct a plane
- VectorClear (vec2);
- vec2[axis] = dir;
- CrossProduct (vec, vec2, normal);
- if (VectorNormalize (normal) < 0.5)
- continue;
- dist = DotProduct (w->p[j], normal);
-
- // if all the points on all the sides are
- // behind this plane, it is a proper edge bevel
- for (k=0 ; k<b->numsides ; k++)
- {
- // if this plane has allready been used, skip it
- if (PlaneEqual (&mapplanes[b->original_sides[k].planenum]
- , normal, dist) )
- break;
-
- w2 = b->original_sides[k].winding;
- if (!w2)
- continue;
- for (l=0 ; l<w2->numpoints ; l++)
- {
- d = DotProduct (w2->p[l], normal) - dist;
- if (d > 0.1)
- break; // point in front
- }
- if (l != w2->numpoints)
- break;
- }
-
- if (k != b->numsides)
- continue; // wasn't part of the outer hull
- // add this plane
- if (nummapbrushsides == MAX_MAP_BRUSHSIDES)
- Error ("MAX_MAP_BRUSHSIDES");
- nummapbrushsides++;
- s2 = &b->original_sides[b->numsides];
- s2->planenum = FindFloatPlane (normal, dist);
- s2->texinfo = b->original_sides[0].texinfo;
-#ifdef SIN
- s2->lightinfo = b->original_sides[0].lightinfo;
-#endif
- s2->contents = b->original_sides[0].contents;
- s2->flags |= SFL_BEVEL;
- c_edgebevels++;
- b->numsides++;
- }
- }
- }
- }
-} //end of the function AddBrushBevels
-//===========================================================================
-// creates windigs for sides and mins / maxs for the brush
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean MakeBrushWindings(mapbrush_t *ob)
-{
- int i, j;
- winding_t *w;
- side_t *side;
- plane_t *plane;
-
- ClearBounds (ob->mins, ob->maxs);
-
- for (i = 0; i < ob->numsides; i++)
- {
- plane = &mapplanes[ob->original_sides[i].planenum];
- w = BaseWindingForPlane(plane->normal, plane->dist);
- for (j = 0; j <ob->numsides && w; j++)
- {
- if (i == j) continue;
- if (ob->original_sides[j].flags & SFL_BEVEL) continue;
- plane = &mapplanes[ob->original_sides[j].planenum^1];
- ChopWindingInPlace(&w, plane->normal, plane->dist, 0); //CLIP_EPSILON);
- }
-
- side = &ob->original_sides[i];
- side->winding = w;
- if (w)
- {
- side->flags |= SFL_VISIBLE;
- for (j = 0; j < w->numpoints; j++)
- AddPointToBounds (w->p[j], ob->mins, ob->maxs);
- }
- }
-
- for (i = 0; i < 3; i++)
- {
- //IDBUG: all the indexes into the mins and maxs were zero (not using i)
- if (ob->mins[i] < -MAX_MAP_BOUNDS || ob->maxs[i] > MAX_MAP_BOUNDS)
- {
- Log_Print("entity %i, brush %i: bounds out of range\n", ob->entitynum, ob->brushnum);
- ob->numsides = 0; //remove the brush
- break;
- } //end if
- if (ob->mins[i] > MAX_MAP_BOUNDS || ob->maxs[i] < -MAX_MAP_BOUNDS)
- {
- Log_Print("entity %i, brush %i: no visible sides on brush\n", ob->entitynum, ob->brushnum);
- ob->numsides = 0; //remove the brush
- break;
- } //end if
- } //end for
- return true;
-} //end of the function MakeBrushWindings
-//===========================================================================
-// FIXME: currently doesn't mark all bevels
-// NOTE: when one brush bevel is found the remaining sides of the brush
-// are bevels as well (when the brush isn't expanded for AAS :))
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void MarkBrushBevels(mapbrush_t *brush)
-{
- int i;
- int we;
- side_t *s;
-
- //check all the sides of the brush
- for (i = 0; i < brush->numsides; i++)
- {
- s = brush->original_sides + i;
- //if the side has no winding
- if (!s->winding)
- {
- Log_Write("MarkBrushBevels: brush %d no winding", brush->brushnum);
- s->flags |= SFL_BEVEL;
- } //end if
- //if the winding is tiny
- else if (WindingIsTiny(s->winding))
- {
- s->flags |= SFL_BEVEL;
- Log_Write("MarkBrushBevels: brush %d tiny winding", brush->brushnum);
- } //end else if
- //if the winding has errors
- else
- {
- we = WindingError(s->winding);
- if (we == WE_NOTENOUGHPOINTS
- || we == WE_SMALLAREA
- || we == WE_POINTBOGUSRANGE
-// || we == WE_NONCONVEX
- )
- {
- Log_Write("MarkBrushBevels: brush %d %s", brush->brushnum, WindingErrorString());
- s->flags |= SFL_BEVEL;
- } //end else if
- } //end else
- if (s->flags & SFL_BEVEL)
- {
- s->flags &= ~SFL_VISIBLE;
- //if the side has a valid plane
- if (s->planenum > 0 && s->planenum < nummapplanes)
- {
- //if it is an axial plane
- if (mapplanes[s->planenum].type < 3) c_boxbevels++;
- else c_edgebevels++;
- } //end if
- } //end if
- } //end for
-} //end of the function MarkBrushBevels
-//===========================================================================
-// returns true if the map brush already exists
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-int BrushExists(mapbrush_t *brush)
-{
- int i, s1, s2;
- side_t *side1, *side2;
- mapbrush_t *brush1, *brush2;
-
- for (i = 0; i < nummapbrushes; i++)
- {
- brush1 = brush;
- brush2 = &mapbrushes[i];
- //compare the brushes
- if (brush1->entitynum != brush2->entitynum) continue;
- //if (brush1->contents != brush2->contents) continue;
- if (brush1->numsides != brush2->numsides) continue;
- for (s1 = 0; s1 < brush1->numsides; s1++)
- {
- side1 = brush1->original_sides + s1;
- //
- for (s2 = 0; s2 < brush2->numsides; s2++)
- {
- side2 = brush2->original_sides + s2;
- //
- if ((side1->planenum & ~1) == (side2->planenum & ~1)
-// && side1->texinfo == side2->texinfo
-// && side1->contents == side2->contents
-// && side1->surf == side2->surf
- ) break;
- } //end if
- if (s2 >= brush2->numsides) break;
- } //end for
- if (s1 >= brush1->numsides) return true;
- } //end for
- return false;
-} //end of the function BrushExists
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WriteMapBrush(FILE *fp, mapbrush_t *brush, vec3_t origin)
-{
- int sn, rotate, shift[2], sv, tv, planenum, p1, i, j;
- float scale[2], originshift[2], ang1, ang2, newdist;
- vec3_t vecs[2], axis[2];
- map_texinfo_t *ti;
- winding_t *w;
- side_t *s;
- plane_t *plane;
-
- if (noliquids)
- {
- if (brush->contents & (CONTENTS_WATER|CONTENTS_SLIME|CONTENTS_LAVA))
- {
- return true;
- } //end if
- } //end if
- //if the brush has no contents
- if (!brush->contents) return true;
- //print the leading {
- if (fprintf(fp, " { //brush %d\n", brush->brushnum) < 0) return false;
- //write brush sides
- for (sn = 0; sn < brush->numsides; sn++)
- {
- s = brush->original_sides + sn;
- //don't write out bevels
- if (!(s->flags & SFL_BEVEL))
- {
- //if the entity has an origin set
- if (origin[0] || origin[1] || origin[2])
- {
- newdist = mapplanes[s->planenum].dist +
- DotProduct(mapplanes[s->planenum].normal, origin);
- planenum = FindFloatPlane(mapplanes[s->planenum].normal, newdist);
- } //end if
- else
- {
- planenum = s->planenum;
- } //end else
- //always take the first plane, then flip the points if necesary
- plane = &mapplanes[planenum & ~1];
- w = BaseWindingForPlane(plane->normal, plane->dist);
- //
- for (i = 0; i < 3; i++)
- {
- for (j = 0; j < 3; j++)
- {
- if (fabs(w->p[i][j]) < 0.2) w->p[i][j] = 0;
- else if (fabs((int)w->p[i][j] - w->p[i][j]) < 0.3) w->p[i][j] = (int) w->p[i][j];
- //w->p[i][j] = (int) (w->p[i][j] + 0.2);
- } //end for
- } //end for
- //three non-colinear points to define the plane
- if (planenum & 1) p1 = 1;
- else p1 = 0;
- if (fprintf(fp," ( %5i %5i %5i ) ", (int)w->p[p1][0], (int)w->p[p1][1], (int)w->p[p1][2]) < 0) return false;
- if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[!p1][0], (int)w->p[!p1][1], (int)w->p[!p1][2]) < 0) return false;
- if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]) < 0) return false;
- //free the winding
- FreeWinding(w);
- //
- if (s->texinfo == TEXINFO_NODE)
- {
- if (brush->contents & CONTENTS_PLAYERCLIP)
- {
- //player clip
- if (loadedmaptype == MAPTYPE_SIN)
- {
- if (fprintf(fp, "generic/misc/clip 0 0 0 1 1") < 0) return false;
- } //end if
- else if (loadedmaptype == MAPTYPE_QUAKE2)
- { //FIXME: don't always use e1u1
- if (fprintf(fp, "e1u1/clip 0 0 0 1 1") < 0) return false;
- } //end else
- else if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- if (fprintf(fp, "e1u1/clip 0 0 0 1 1") < 0) return false;
- } //end else if
- else
- {
- if (fprintf(fp, "clip 0 0 0 1 1") < 0) return false;
- } //end else
- } //end if
- else if (brush->contents == CONTENTS_MONSTERCLIP)
- {
- //monster clip
- if (loadedmaptype == MAPTYPE_SIN)
- {
- if (fprintf(fp, "generic/misc/monster 0 0 0 1 1") < 0) return false;
- } //end if
- else if (loadedmaptype == MAPTYPE_QUAKE2)
- {
- if (fprintf(fp, "e1u1/clip_mon 0 0 0 1 1") < 0) return false;
- } //end else
- else
- {
- if (fprintf(fp, "clip 0 0 0 1 1") < 0) return false;
- } //end else
- } //end else
- else
- {
- if (fprintf(fp, "clip 0 0 0 1 1") < 0) return false;
- Log_Write("brush->contents = %d\n", brush->contents);
- } //end else
- } //end if
- else if (loadedmaptype == MAPTYPE_SIN && s->texinfo == 0)
- {
- if (brush->contents & CONTENTS_DUMMYFENCE)
- {
- if (fprintf(fp, "generic/misc/fence 0 0 0 1 1") < 0) return false;
- } //end if
- else if (brush->contents & CONTENTS_MIST)
- {
- if (fprintf(fp, "generic/misc/volumetric_base 0 0 0 1 1") < 0) return false;
- } //end if
- else //unknown so far
- {
- if (fprintf(fp, "generic/misc/red 0 0 0 1 1") < 0) return false;
- } //end else
- } //end if
- else if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- //always use the same texture
- if (fprintf(fp, "e2u3/floor1_2 0 0 0 1 1 1 0 0") < 0) return false;
- } //end else if
- else
- {
- //*
- ti = &map_texinfo[s->texinfo];
- //the scaling of the texture
- scale[0] = 1 / VectorNormalize2(ti->vecs[0], vecs[0]);
- scale[1] = 1 / VectorNormalize2(ti->vecs[1], vecs[1]);
- //
- TextureAxisFromPlane(plane, axis[0], axis[1]);
- //calculate texture shift done by entity origin
- originshift[0] = DotProduct(origin, axis[0]);
- originshift[1] = DotProduct(origin, axis[1]);
- //the texture shift without origin shift
- shift[0] = ti->vecs[0][3] - originshift[0];
- shift[1] = ti->vecs[1][3] - originshift[1];
- //
- if (axis[0][0]) sv = 0;
- else if (axis[0][1]) sv = 1;
- else sv = 2;
- if (axis[1][0]) tv = 0;
- else if (axis[1][1]) tv = 1;
- else tv = 2;
- //calculate rotation of texture
- if (vecs[0][tv] == 0) ang1 = vecs[0][sv] > 0 ? 90.0 : -90.0;
- else ang1 = atan2(vecs[0][sv], vecs[0][tv]) * 180 / Q_PI;
- if (ang1 < 0) ang1 += 360;
- if (ang1 >= 360) ang1 -= 360;
- if (axis[0][tv] == 0) ang2 = axis[0][sv] > 0 ? 90.0 : -90.0;
- else ang2 = atan2(axis[0][sv], axis[0][tv]) * 180 / Q_PI;
- if (ang2 < 0) ang2 += 360;
- if (ang2 >= 360) ang2 -= 360;
- rotate = ang2 - ang1;
- if (rotate < 0) rotate += 360;
- if (rotate >= 360) rotate -= 360;
- //write the texture info
- if (fprintf(fp, "%s %d %d %d", ti->texture, shift[0], shift[1], rotate) < 0) return false;
- if (fabs(scale[0] - ((int) scale[0])) < 0.001)
- {
- if (fprintf(fp, " %d", (int) scale[0]) < 0) return false;
- } //end if
- else
- {
- if (fprintf(fp, " %4f", scale[0]) < 0) return false;
- } //end if
- if (fabs(scale[1] - ((int) scale[1])) < 0.001)
- {
- if (fprintf(fp, " %d", (int) scale[1]) < 0) return false;
- } //end if
- else
- {
- if (fprintf(fp, " %4f", scale[1]) < 0) return false;
- } //end else
- //write the extra brush side info
- if (loadedmaptype == MAPTYPE_QUAKE2)
- {
- if (fprintf(fp, " %ld %ld %ld", s->contents, ti->flags, ti->value) < 0) return false;
- } //end if
- //*/
- } //end else
- if (fprintf(fp, "\n") < 0) return false;
- } //end if
- } //end if
- if (fprintf(fp, " }\n") < 0) return false;
- c_writtenbrushes++;
- return true;
-} //end of the function WriteMapBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WriteOriginBrush(FILE *fp, vec3_t origin)
-{
- vec3_t normal;
- float dist;
- int i, s;
- winding_t *w;
-
- if (fprintf(fp, " {\n") < 0) return false;
- //
- for (i = 0; i < 3; i++)
- {
- for (s = -1; s <= 1; s += 2)
- {
- //
- VectorClear(normal);
- normal[i] = s;
- dist = origin[i] * s + 16;
- //
- w = BaseWindingForPlane(normal, dist);
- //three non-colinear points to define the plane
- if (fprintf(fp," ( %5i %5i %5i ) ", (int)w->p[0][0], (int)w->p[0][1], (int)w->p[0][2]) < 0) return false;
- if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[1][0], (int)w->p[1][1], (int)w->p[1][2]) < 0) return false;
- if (fprintf(fp,"( %5i %5i %5i ) ", (int)w->p[2][0], (int)w->p[2][1], (int)w->p[2][2]) < 0) return false;
- //free the winding
- FreeWinding(w);
- //write origin texture:
- // CONTENTS_ORIGIN = 16777216
- // SURF_NODRAW = 128
- if (loadedmaptype == MAPTYPE_SIN)
- {
- if (fprintf(fp, "generic/misc/origin 0 0 0 1 1") < 0) return false;
- } //end if
- else if (loadedmaptype == MAPTYPE_HALFLIFE)
- {
- if (fprintf(fp, "origin 0 0 0 1 1") < 0) return false;
- } //end if
- else
- {
- if (fprintf(fp, "e1u1/origin 0 0 0 1 1") < 0) return false;
- } //end else
- //Quake2 extra brush side info
- if (loadedmaptype == MAPTYPE_QUAKE2)
- {
- //if (fprintf(fp, " 16777216 128 0") < 0) return false;
- } //end if
- if (fprintf(fp, "\n") < 0) return false;
- } //end for
- } //end for
- if (fprintf(fp, " }\n") < 0) return false;
- c_writtenbrushes++;
- return true;
-} //end of the function WriteOriginBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-mapbrush_t *GetAreaPortalBrush(entity_t *mapent)
-{
- int portalnum, bn;
- mapbrush_t *brush;
-
- //the area portal number
- portalnum = mapent->areaportalnum;
- //find the area portal brush in the world brushes
- for (bn = 0; bn < nummapbrushes && portalnum; bn++)
- {
- brush = &mapbrushes[bn];
- //must be in world entity
- if (brush->entitynum == 0)
- {
- if (brush->contents & CONTENTS_AREAPORTAL)
- {
- portalnum--;
- } //end if
- } //end if
- } //end for
- if (bn < nummapbrushes)
- {
- return brush;
- } //end if
- else
- {
- Log_Print("area portal %d brush not found\n", mapent->areaportalnum);
- return NULL;
- } //end else
-} //end of the function GetAreaPortalBrush
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-qboolean WriteMapFileSafe(FILE *fp)
-{
- char key[1024], value[1024];
- int i, bn, entitybrushes;
- epair_t *ep;
- mapbrush_t *brush;
- entity_t *mapent;
- //vec3_t vec_origin = {0, 0, 0};
-
- //
- if (fprintf(fp,"//=====================================================\n"
- "//\n"
- "// map file created with BSPC "BSPC_VERSION"\n"
- "//\n"
- "// BSPC is designed to decompile material in which you own the copyright\n"
- "// or have obtained permission to decompile from the copyright owner. Unless\n"
- "// you own the copyright or have permission to decompile from the copyright\n"
- "// owner, you may be violating copyright law and be subject to payment of\n"
- "// damages and other remedies. If you are uncertain about your rights, contact\n"
- "// your legal advisor.\n"
- "//\n") < 0) return false;
- if (loadedmaptype == MAPTYPE_SIN)
- {
- if (fprintf(fp,
- "// generic/misc/red is used for unknown textures\n") < 0) return false;
- } //end if
- if (fprintf(fp,"//\n"
- "//=====================================================\n") < 0) return false;
- //write out all the entities
- for (i = 0; i < num_entities; i++)
- {
- mapent = &entities[i];
- if (!mapent->epairs)
- {
- continue;
- } //end if
- if (fprintf(fp, "{\n") < 0) return false;
- //
- if (loadedmaptype == MAPTYPE_QUAKE3)
- {
- if (!stricmp(ValueForKey(mapent, "classname"), "light"))
- {
- SetKeyValue(mapent, "light", "10000");
- } //end if
- } //end if
- //write epairs
- for (ep = mapent->epairs; ep; ep = ep->next)
- {
- strcpy(key, ep->key);
- StripTrailing (key);
- strcpy(value, ep->value);
- StripTrailing(value);
- //
- if (loadedmaptype == MAPTYPE_QUAKE2 ||
- loadedmaptype == MAPTYPE_SIN)
- {
- //don't write an origin for BSP models
- if (mapent->modelnum >= 0 && !strcmp(key, "origin")) continue;
- } //end if
- //don't write BSP model numbers
- if (mapent->modelnum >= 0 && !strcmp(key, "model") && value[0] == '*') continue;
- //
- if (fprintf(fp, " \"%s\" \"%s\"\n", key, value) < 0) return false;
- } //end for
- //
- if (ValueForKey(mapent, "origin")) GetVectorForKey(mapent, "origin", mapent->origin);
- else mapent->origin[0] = mapent->origin[1] = mapent->origin[2] = 0;
- //if this is an area portal entity
- if (!strcmp("func_areaportal", ValueForKey(mapent, "classname")))
- {
- brush = GetAreaPortalBrush(mapent);
- if (!brush) return false;
- if (!WriteMapBrush(fp, brush, mapent->origin)) return false;
- } //end if
- else
- {
- entitybrushes = false;
- //write brushes
- for (bn = 0; bn < nummapbrushes; bn++)
- {
- brush = &mapbrushes[bn];
- //if the brush is part of this entity
- if (brush->entitynum == i)
- {
- //don't write out area portal brushes in the world
- if (!((brush->contents & CONTENTS_AREAPORTAL) && brush->entitynum == 0))
- {
- /*
- if (!strcmp("func_door_rotating", ValueForKey(mapent, "classname")))
- {
- AAS_PositionFuncRotatingBrush(mapent, brush);
- if (!WriteMapBrush(fp, brush, vec_origin)) return false;
- } //end if
- else //*/
- {
- if (!WriteMapBrush(fp, brush, mapent->origin)) return false;
- } //end else
- entitybrushes = true;
- } //end if
- } //end if
- } //end for
- //if the entity had brushes
- if (entitybrushes)
- {
- //if the entity has an origin set
- if (mapent->origin[0] || mapent->origin[1] || mapent->origin[2])
- {
- if (!WriteOriginBrush(fp, mapent->origin)) return false;
- } //end if
- } //end if
- } //end else
- if (fprintf(fp, "}\n") < 0) return false;
- } //end for
- if (fprintf(fp, "//total of %d brushes\n", c_writtenbrushes) < 0) return false;
- return true;
-} //end of the function WriteMapFileSafe
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void WriteMapFile(char *filename)
-{
- FILE *fp;
- double start_time;
-
- c_writtenbrushes = 0;
- //the time started
- start_time = I_FloatTime();
- //
- Log_Print("writing %s\n", filename);
- fp = fopen(filename, "wb");
- if (!fp)
- {
- Log_Print("can't open %s\n", filename);
- return;
- } //end if
- if (!WriteMapFileSafe(fp))
- {
- fclose(fp);
- Log_Print("error writing map file %s\n", filename);
- return;
- } //end if
- fclose(fp);
- //display creation time
- Log_Print("written %d brushes\n", c_writtenbrushes);
- Log_Print("map file written in %5.0f seconds\n", I_FloatTime() - start_time);
-} //end of the function WriteMapFile
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void PrintMapInfo(void)
-{
- Log_Print("\n");
- Log_Print("%6i brushes\n", nummapbrushes);
- Log_Print("%6i brush sides\n", nummapbrushsides);
-// Log_Print("%6i clipbrushes\n", c_clipbrushes);
-// Log_Print("%6i total sides\n", nummapbrushsides);
-// Log_Print("%6i boxbevels\n", c_boxbevels);
-// Log_Print("%6i edgebevels\n", c_edgebevels);
-// Log_Print("%6i entities\n", num_entities);
-// Log_Print("%6i planes\n", nummapplanes);
-// Log_Print("%6i areaportals\n", c_areaportals);
-// Log_Print("%6i squatt brushes\n", c_squattbrushes);
-// Log_Print("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]);
-} //end of the function PrintMapInfo
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-void ResetMapLoading(void)
-{
- int i;
- epair_t *ep, *nextep;
-
- Q2_ResetMapLoading();
- Sin_ResetMapLoading();
-
- //free all map brush side windings
- for (i = 0; i < nummapbrushsides; i++)
- {
- if (brushsides[i].winding)
- {
- FreeWinding(brushsides[i].winding);
- } //end for
- } //end for
-
- //reset regular stuff
- nummapbrushes = 0;
- memset(mapbrushes, 0, MAX_MAPFILE_BRUSHES * sizeof(mapbrush_t));
- //
- nummapbrushsides = 0;
- memset(brushsides, 0, MAX_MAPFILE_BRUSHSIDES * sizeof(side_t));
- memset(side_brushtextures, 0, MAX_MAPFILE_BRUSHSIDES * sizeof(brush_texture_t));
- //
- nummapplanes = 0;
- memset(mapplanes, 0, MAX_MAPFILE_PLANES * sizeof(plane_t));
- //
- memset(planehash, 0, PLANE_HASHES * sizeof(plane_t *));
- //
- memset(map_texinfo, 0, MAX_MAPFILE_TEXINFO * sizeof(map_texinfo_t));
- map_numtexinfo = 0;
- //
- VectorClear(map_mins);
- VectorClear(map_maxs);
- //
- c_boxbevels = 0;
- c_edgebevels = 0;
- c_areaportals = 0;
- c_clipbrushes = 0;
- c_writtenbrushes = 0;
- //clear the entities
- for (i = 0; i < num_entities; i++)
- {
- for (ep = entities[i].epairs; ep; ep = nextep)
- {
- nextep = ep->next;
- FreeMemory(ep->key);
- FreeMemory(ep->value);
- FreeMemory(ep);
- } //end for
- } //end for
- num_entities = 0;
- memset(entities, 0, MAX_MAP_ENTITIES * sizeof(entity_t));
-} //end of the function ResetMapLoading
-//===========================================================================
-//
-// Parameter: -
-// Returns: -
-// Changes Globals: -
-//===========================================================================
-#ifndef Q1_BSPVERSION
-#define Q1_BSPVERSION 29
-#endif
-#ifndef HL_BSPVERSION
-#define HL_BSPVERSION 30
-#endif
-
-#define Q2_BSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') //IBSP
-#define Q2_BSPVERSION 38
-
-#define SINGAME_BSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'R') //RBSP
-#define SINGAME_BSPVERSION 1
-
-#define SIN_BSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') //IBSP
-#define SIN_BSPVERSION 41
-
-typedef struct
-{
- int ident;
- int version;
-} idheader_t;
-
-int LoadMapFromBSP(struct quakefile_s *qf)
-{
- idheader_t idheader;
-
- if (ReadQuakeFile(qf, &idheader, 0, sizeof(idheader_t)) != sizeof(idheader_t))
- {
- return false;
- } //end if
-
- idheader.ident = LittleLong(idheader.ident);
- idheader.version = LittleLong(idheader.version);
- //Quake3 BSP file
- if (idheader.ident == Q3_BSP_IDENT && idheader.version == Q3_BSP_VERSION)
- {
- ResetMapLoading();
- Q3_LoadMapFromBSP(qf);
- Q3_FreeMaxBSP();
- } //end if
- //Quake2 BSP file
- else if (idheader.ident == Q2_BSPHEADER && idheader.version == Q2_BSPVERSION)
- {
- ResetMapLoading();
- Q2_AllocMaxBSP();
- Q2_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
- Q2_FreeMaxBSP();
- } //endif
- //Sin BSP file
- else if ((idheader.ident == SIN_BSPHEADER && idheader.version == SIN_BSPVERSION) ||
- //the dorks gave the same format another ident and verions
- (idheader.ident == SINGAME_BSPHEADER && idheader.version == SINGAME_BSPVERSION))
- {
- ResetMapLoading();
- Sin_AllocMaxBSP();
- Sin_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
- Sin_FreeMaxBSP();
- } //end if
- //the Quake1 bsp files don't have a ident only a version
- else if (idheader.ident == Q1_BSPVERSION)
- {
- ResetMapLoading();
- Q1_AllocMaxBSP();
- Q1_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
- Q1_FreeMaxBSP();
- } //end if
- //Half-Life also only uses a version number
- else if (idheader.ident == HL_BSPVERSION)
- {
- ResetMapLoading();
- HL_AllocMaxBSP();
- HL_LoadMapFromBSP(qf->filename, qf->offset, qf->length);
- HL_FreeMaxBSP();
- } //end if
- else
- {
- Error("unknown BSP format %c%c%c%c, version %d\n",
- (idheader.ident & 0xFF),
- ((idheader.ident >> 8) & 0xFF),
- ((idheader.ident >> 16) & 0xFF),
- ((idheader.ident >> 24) & 0xFF), idheader.version);
- return false;
- } //end if
- //
- return true;
-} //end of the function LoadMapFromBSP