Moved modified HL SDK to trunk

This commit is contained in:
Scott Ehlert
2006-08-27 02:22:59 +00:00
parent 28c4ea4fec
commit 30235e05e5
900 changed files with 344676 additions and 0 deletions

987
hlsdk/utils/qcsg/brush.c Normal file
View File

@ -0,0 +1,987 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// brush.c
#include "csg.h"
plane_t mapplanes[MAX_MAP_PLANES];
int nummapplanes;
/*
=============================================================================
PLANE FINDING
=============================================================================
*/
void FindGCD (int *v)
{
int i, j, smallest;
int rem[3];
int val[3];
for (i=0 ; i<3 ; i++)
val[i] = abs(v[i]);
while (1)
{
smallest = 1<<30;
for (i=0 ; i<3 ; i++)
{
j = abs(val[i]);
if (j && j<smallest)
smallest = j;
}
for (i=0 ; i<3 ; i++)
rem[i] = val[i]%smallest;
if (rem[0] + rem[1] + rem[2] == 0)
break; // smallest == gcd
for (i=0 ; i<3 ; i++)
if (!rem[i])
val[i] = smallest;
else
val[i] = rem[i];
}
for (i=0 ; i<3 ; i++)
v[i] /= smallest;
}
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;
}
/*
=============
FindIntPlane
Returns which plane number to use for a given integer defined plane.
=============
*/
int FindIntPlane (int *inormal, int *iorigin)
{
int i, j;
plane_t *p, temp;
int t;
vec3_t origin;
qboolean locked;
FindGCD (inormal);
p = mapplanes;
locked = false;
i = 0;
while (1)
{
if (i == nummapplanes)
{
if (!locked)
{
locked = true;
ThreadLock (); // make sure we don't race
}
if (i == nummapplanes)
break; // we didn't race
}
// see if origin is on plane
t = 0;
for (j=0 ; j<3 ; j++)
t += (iorigin[j] - p->iorigin[j]) * inormal[j];
if (!t)
{ // on plane
// see if the normal is forward, backwards, or off
for (j=0 ; j<3 ; j++)
if (inormal[j] != p->inormal[j])
break;
if (j == 3)
{
if (locked)
ThreadUnlock ();
return i;
}
}
i++;
p++;
}
if (!locked)
Error ("not locked");
// create a new plane
for (j=0 ; j<3 ; j++)
{
p->inormal[j] = inormal[j];
(p+1)->inormal[j] = -inormal[j];
p->iorigin[j] = iorigin[j];
(p+1)->iorigin[j] = iorigin[j];
p->normal[j] = inormal[j];
origin[j] = iorigin[j];
}
if (nummapplanes >= MAX_MAP_PLANES)
Error ("MAX_MAP_PLANES");
VectorNormalize (p->normal);
p->type = (p+1)->type = PlaneTypeForNormal (p->normal);
p->dist = DotProduct (origin, p->normal);
VectorSubtract (vec3_origin, p->normal, (p+1)->normal);
(p+1)->dist = -p->dist;
// allways put axial planes facing positive first
if (p->type < 3)
{
if (inormal[0] < 0 || inormal[1] < 0 || inormal[2] < 0)
{
// flip order
temp = *p;
*p = *(p+1);
*(p+1) = temp;
nummapplanes += 2;
ThreadUnlock ();
return i + 1;
}
}
nummapplanes += 2;
ThreadUnlock ();
return i;
}
int PlaneFromPoints (int *p0, int *p1, int *p2)
{
int j;
int t1[3], t2[3];
int normal[3];
// convert to a vector / dist plane
for (j=0 ; j<3 ; j++)
{
t1[j] = p0[j] - p1[j];
t2[j] = p2[j] - p1[j];
}
FindGCD (t1);
FindGCD (t2);
normal[0] = t1[1]*t2[2] - t1[2]*t2[1];
normal[1] = t1[2]*t2[0] - t1[0]*t2[2];
normal[2] = t1[0]*t2[1] - t1[1]*t2[0];
if (!normal[0] && !normal[1] && !normal[2])
return -1;
return FindIntPlane (normal, p0);
}
/*
=============================================================================
TURN BRUSHES INTO GROUPS OF FACES
=============================================================================
*/
void ScaleUpIVector (int *iv, int min)
{
int i;
int largest, scale;
largest = 0;
for (i=0 ; i<3 ; i++)
{
if (abs(iv[i]) > largest)
largest = abs(iv[i]);
}
scale = (min + largest - 1)/largest;
for (i=0 ; i<3 ; i++)
iv[i] *= scale;
}
/*
=================
BaseWindingForIPlane
=================
*/
winding_t *BaseWindingForIPlane (plane_t *p)
{
int i, x;
vec_t max, v;
winding_t *w;
int org[3], vup[3], vright[3];
VectorCopy (p->iorigin, org);
VectorCopy (vec3_origin, vup);
VectorCopy (vec3_origin, vright);
if (!p->inormal[1] && !p->inormal[2])
{
vup[2] = 8192;
vright[1] = 8192*p->normal[0];
}
else if (!p->inormal[0] && !p->inormal[2])
{
vup[2] = 8192;
vright[0] = -8192*p->normal[1];
}
else if (!p->inormal[0] && !p->inormal[1])
{
vup[1] = 8192;
vright[0] = 8192*p->normal[2];
}
else
{
vup[0] = -2*p->inormal[1]*p->inormal[2];
vup[1] = p->inormal[0]*p->inormal[2];
vup[2] = p->inormal[0]*p->inormal[1];
FindGCD (vup);
vright[0] = vup[1]*p->inormal[2] - vup[2]*p->inormal[1];
vright[1] = vup[2]*p->inormal[0] - vup[0]*p->inormal[2];
vright[2] = vup[0]*p->inormal[1] - vup[1]*p->inormal[0];
FindGCD (vright);
ScaleUpIVector (vup, 8192);
ScaleUpIVector (vright, 8192);
}
w = AllocWinding (4);
VectorSubtract (org, vright, w->p[0]);
VectorAdd (w->p[0], vup, w->p[0]);
VectorAdd (org, vright, w->p[1]);
VectorAdd (w->p[1], vup, w->p[1]);
VectorAdd (org, vright, w->p[2]);
VectorSubtract (w->p[2], vup, w->p[2]);
VectorSubtract (org, vright, w->p[3]);
VectorSubtract (w->p[3], vup, w->p[3]);
w->numpoints = 4;
return w;
}
/*
==============================================================================
BEVELED CLIPPING HULL GENERATION
This is done by brute force, and could easily get a lot faster if anyone cares.
==============================================================================
*/
#if 0
vec3_t hull_size[NUM_HULLS][2] = {
{ {0, 0, 0}, {0, 0, 0} },
{ {-16,-16,-32}, {16,16,24} },
{ {-32,-32,-64}, {32,32,24} }
};
#endif
#if 1
vec3_t hull_size[NUM_HULLS][2] = {
{ {0, 0, 0}, {0, 0, 0} },
{ {-16,-16,-36}, {16,16,36} },// 32x32x72
{ {-32,-32,-32}, {32,32,32} }, // 64x64x64
{ {-16,-16,-18}, {16,16,18} } // 32x32x36
};
#endif
#define MAX_HULL_POINTS 32
#define MAX_HULL_EDGES 64
typedef struct
{
brush_t *b;
int hullnum;
int num_hull_points;
vec3_t hull_points[MAX_HULL_POINTS];
vec3_t hull_corners[MAX_HULL_POINTS*8];
int num_hull_edges;
int hull_edges[MAX_HULL_EDGES][2];
} expand_t;
/*
=============
IPlaneEquiv
=============
*/
qboolean IPlaneEquiv (plane_t *p1, plane_t *p2)
{
int t;
int j;
// see if origin is on plane
t = 0;
for (j=0 ; j<3 ; j++)
t += (p2->iorigin[j] - p1->iorigin[j]) * p2->inormal[j];
if (t)
return false;
// see if the normal is forward, backwards, or off
for (j=0 ; j<3 ; j++)
if (p2->inormal[j] != p1->inormal[j])
break;
if (j == 3)
return true;
for (j=0 ; j<3 ; j++)
if (p2->inormal[j] != -p1->inormal[j])
break;
if (j == 3)
return true;
return false;
}
/*
============
AddBrushPlane
=============
*/
void AddBrushPlane (expand_t *ex, plane_t *plane)
{
int i;
plane_t *pl;
bface_t *f, *nf;
brushhull_t *h;
h = &ex->b->hulls[ex->hullnum];
// see if the plane has allready been added
for (f=h->faces ; f ; f=f->next)
{
pl = f->plane;
if (IPlaneEquiv (plane, pl))
return;
}
nf = malloc(sizeof(*nf));
memset (nf, 0, sizeof(*nf));
nf->planenum = FindIntPlane (plane->inormal, plane->iorigin);
nf->plane = &mapplanes[nf->planenum];
nf->next = h->faces;
nf->contents = CONTENTS_EMPTY;
h->faces = nf;
nf->texinfo = 0; // all clip hulls have same texture
}
/*
============
TestAddPlane
Adds the given plane to the brush description if all of the original brush
vertexes can be put on the front side
=============
*/
void TestAddPlane (expand_t *ex, plane_t *plane)
{
int i, j, c, t;
vec_t d;
vec_t *corner;
plane_t flip;
vec3_t inv;
int counts[3];
plane_t *pl;
bface_t *f, *nf;
brushhull_t *h;
// see if the plane has allready been added
h = &ex->b->hulls[ex->hullnum];
for (f=h->faces ; f ; f=f->next)
{
pl = f->plane;
if (IPlaneEquiv (plane, pl))
return;
}
// check all the corner points
counts[0] = counts[1] = counts[2] = 0;
c = ex->num_hull_points * 8;
corner = ex->hull_corners[0];
for (i=0 ; i<c ; i++, corner += 3)
{
t = 0;
for (j=0 ; j<3 ; j++)
t += (corner[j] - plane->iorigin[j]) * plane->inormal[j];
if (t < 0)
{
if (counts[0])
return;
counts[1]++;
}
else if (t > 0)
{
if (counts[1])
return;
counts[0]++;
}
else
counts[2]++;
}
// the plane is a seperator
if (counts[0])
{
VectorSubtract (vec3_origin, plane->inormal, flip.inormal);
VectorCopy (plane->iorigin, flip.iorigin);
plane = &flip;
}
nf = malloc(sizeof(*nf));
memset (nf, 0, sizeof(*nf));
nf->planenum = FindIntPlane (plane->inormal, plane->iorigin);
nf->plane = &mapplanes[nf->planenum];
nf->next = h->faces;
nf->contents = CONTENTS_EMPTY;
h->faces = nf;
nf->texinfo = 0; // all clip hulls have same texture
}
/*
============
AddHullPoint
Doesn't add if duplicated
=============
*/
int AddHullPoint (expand_t *ex, vec3_t p)
{
int i, j;
vec_t *c;
int x,y,z;
vec3_t r;
for (i=0 ; i<3 ; i++)
r[i] = floor (p[i]+0.5);
for (i=0 ; i<ex->num_hull_points ; i++)
{
for (j=0 ; j<3 ; j++)
if (r[j] != ex->hull_points[i][j])
break;
if (j == 3)
return i; // allready added
}
if (ex->num_hull_points == MAX_HULL_POINTS)
Error ("MAX_HULL_POINTS");
ex->num_hull_points++;
VectorCopy (r, ex->hull_points[ex->num_hull_points]);
c = ex->hull_corners[i*8];
for (x=0 ; x<2 ; x++)
for (y=0 ; y<2 ; y++)
for (z=0; z<2 ; z++)
{
c[0] = r[0] + hull_size[ex->hullnum][x][0];
c[1] = r[1] + hull_size[ex->hullnum][y][1];
c[2] = r[2] + hull_size[ex->hullnum][z][2];
c += 3;
}
return i;
}
/*
============
AddHullEdge
Creates all of the hull planes around the given edge, if not done allready
=============
*/
//#define ANGLEEPSILON 0.00001
#define ANGLEEPSILON ON_EPSILON
void AddHullEdge (expand_t *ex, vec3_t p1, vec3_t p2)
{
int pt1, pt2;
int i;
int a, b, c, d, e;
vec3_t edgevec, planeorg, planevec;
plane_t plane;
vec_t l;
pt1 = AddHullPoint (ex, p1);
pt2 = AddHullPoint (ex, p2);
// now use the rounded values
p1 = ex->hull_points[pt1];
p2 = ex->hull_points[pt2];
for (i=0 ; i<ex->num_hull_edges ; i++)
if ( (ex->hull_edges[i][0] == pt1 && ex->hull_edges[i][1] == pt2)
|| (ex->hull_edges[i][0] == pt2 && ex->hull_edges[i][1] == pt1) )
return; // allread added
if (ex->num_hull_edges == MAX_HULL_EDGES)
Error ("MAX_HULL_EDGES");
ex->hull_edges[i][0] = pt1;
ex->hull_edges[i][1] = pt2;
ex->num_hull_edges++;
VectorSubtract (p1, p2, edgevec);
VectorNormalize (edgevec);
for (a=0 ; a<3 ; a++)
{
b = (a+1)%3;
c = (a+2)%3;
for (d=0 ; d<=1 ; d++)
for (e=0 ; e<=1 ; e++)
{
VectorCopy (p1, plane.iorigin);
plane.iorigin[b] += hull_size[ex->hullnum][d][b];
plane.iorigin[c] += hull_size[ex->hullnum][e][c];
VectorCopy (vec3_origin, planevec);
planevec[a] = 1;
plane.inormal[0] = planevec[1]*edgevec[2] - planevec[2]*edgevec[1];
plane.inormal[1] = planevec[2]*edgevec[0] - planevec[0]*edgevec[2];
plane.inormal[2] = planevec[0]*edgevec[1] - planevec[1]*edgevec[0];
if (!plane.inormal[0] && !plane.inormal[1] && !plane.inormal[2])
continue; // degenerate
TestAddPlane (ex, &plane);
}
}
}
/*
============
ExpandBrush
=============
*/
void ExpandBrush (brush_t *b, int hullnum)
{
int i, x, s;
int corner;
bface_t *brush_faces, *f, *nf;
plane_t *p, plane;
int iorigin[3], inormal[3];
expand_t ex;
brushhull_t *h;
qboolean axial;
brush_faces = b->hulls[0].faces;
h = &b->hulls[hullnum];
ex.b = b;
ex.hullnum = hullnum;
ex.num_hull_points = 0;
ex.num_hull_edges = 0;
// expand all of the planes
axial = true;
for (f=brush_faces ; f ; f=f->next)
{
p = f->plane;
if (p->type > PLANE_Z)
axial = false; // not an xyz axial plane
VectorCopy (p->iorigin, iorigin);
VectorCopy (p->inormal, inormal);
for (x=0 ; x<3 ; x++)
{
if (p->normal[x] > 0)
corner = hull_size[hullnum][1][x];
else if (p->normal[x] < 0)
corner = - hull_size[hullnum][0][x];
else
corner = 0;
iorigin[x] += p->normal[x]*corner;
}
nf = malloc(sizeof(*nf));
memset (nf, 0, sizeof(*nf));
nf->planenum = FindIntPlane (inormal, iorigin);
nf->plane = &mapplanes[nf->planenum];
nf->next = h->faces;
nf->contents = CONTENTS_EMPTY;
h->faces = nf;
nf->texinfo = 0; // all clip hulls have same texture
}
// if this was an axial brush, we are done
if (axial)
return;
#if 1
// add any axis planes not contained in the brush to bevel off corners
for (x=0 ; x<3 ; x++)
for (s=-1 ; s<=1 ; s+=2)
{
// add the plane
VectorCopy (vec3_origin, plane.inormal);
plane.inormal[x] = s;
if (s == -1)
{
VectorAdd (b->hulls[0].mins, hull_size[hullnum][0], plane.iorigin);
}
else
{
VectorAdd (b->hulls[0].maxs, hull_size[hullnum][1], plane.iorigin);
}
AddBrushPlane (&ex, &plane);
}
#endif
#if 0
// create all the hull points
for (f=brush_faces ; f ; f=f->next)
for (i=0 ; i<f->w->numpoints ; i++)
AddHullPoint (&ex, f->w->p[i]);
// add all of the edge bevels
for (f=brush_faces ; f ; f=f->next)
for (i=0 ; i<f->w->numpoints ; i++)
AddHullEdge (&ex, f->w->p[i], f->w->p[(i+1)%f->w->numpoints]);
#endif
}
//============================================================================
/*
===========
MakeHullFaces
===========
*/
void MakeHullFaces (brush_t *b, brushhull_t *h)
{
bface_t *f, *f2;
winding_t *w;
plane_t *p;
int i, j;
vec_t v;
vec_t area;
restart:
h->mins[0] = h->mins[1] = h->mins[2] = 9999;
h->maxs[0] = h->maxs[1] = h->maxs[2] = -9999;
for (f = h->faces ; f ; f=f->next)
{
// w = BaseWindingForIPlane (f->plane);
w = BaseWindingForPlane (f->plane->normal, f->plane->dist);
for (f2 = h->faces ; f2 && w ; f2=f2->next)
{
if (f == f2)
continue;
p = &mapplanes[f2->planenum ^ 1];
w = ChopWinding (w, p->normal, p->dist);
}
area = w ? WindingArea(w) : 0;
if (area < 0.1)
{
qprintf ("Entity %i, Brush %i: plane with area %4.2f\n"
, b->entitynum, b->brushnum, area);
// remove the face and regenerate the hull
if (h->faces == f)
h->faces = f->next;
else
{
for (f2=h->faces ; f2->next != f ; f2=f2->next)
;
f2->next = f->next;
}
goto restart;
}
f->w = w;
f->contents = CONTENTS_EMPTY;
if (w)
{
for (i=0 ; i<w->numpoints ; i++)
{
for (j=0 ; j<3 ; j++)
{
v = w->p[i][j];
// w->p[i][j] = floor (v+0.5); // round to int
if (v<h->mins[j])
h->mins[j] = v;
if (v>h->maxs[j])
h->maxs[j] = v;
}
}
}
}
for (i=0 ; i<3 ; i++)
{
if (h->mins[i] < -BOGUS_RANGE/2
|| h->maxs[i] > BOGUS_RANGE/2)
{
vec3_t eorigin = { 0, 0, 0};
char *pszClass = "Unknown Class";
if ( b->entitynum )
{
entity_t *e = entities + b->entitynum;
pszClass = ValueForKey(e, "classname" );
GetVectorForKey( e, "origin", eorigin );
}
printf( "Entity %i, Brush %i: A '%s' @(%.0f,%.0f,%.0f)\n",
b->entitynum, b->brushnum, pszClass, eorigin[0], eorigin[1], eorigin[2] );
printf( "\toutside world(+/-%d): (%.0f, %.0f, %.0f)-(%.0f,%.0f,%.0f)\n",
BOGUS_RANGE/2, h->mins[0], h->mins[1], h->mins[2], h->maxs[0], h->maxs[1], h->maxs[2] );
break;
}
}
}
/*
===========
MakeBrushPlanes
===========
*/
qboolean MakeBrushPlanes (brush_t *b)
{
int i, j;
int planenum;
side_t *s;
int contents;
bface_t *f;
vec3_t origin;
//
// if the origin key is set (by an origin brush), offset all of the values
//
GetVectorForKey (&entities[b->entitynum], "origin", origin);
//
// convert to mapplanes
//
for (i=0 ; i<b->numsides ; i++)
{
s = &brushsides[b->firstside + i];
for (j=0 ; j<3 ; j++)
{
VectorSubtract (s->planepts[j], origin, s->planepts[j]);
}
planenum = PlaneFromPoints (s->planepts[0], s->planepts[1], s->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 (f=b->hulls[0].faces ; f ; f=f->next)
{
if (f->planenum == planenum || f->planenum == (planenum^1) )
{
char *pszClass = "Unknown Class";
if ( b->entitynum )
{
entity_t *e = entities + b->entitynum;
pszClass = ValueForKey(e, "classname" );
}
printf( "Entity %i, Brush %i: A '%s' @(%.0f,%.0f,%.0f) has a coplanar plane at (%.0f, %.0f, %.0f), texture %s\n",
b->entitynum, b->brushnum, pszClass, origin[0], origin[1], origin[2], s->planepts[0][0]+origin[0], s->planepts[0][1]+origin[1], s->planepts[0][2]+origin[2], s->td.name );
return false;
}
}
f = malloc(sizeof(*f));
memset (f, 0, sizeof(*f));
f->planenum = planenum;
f->plane = &mapplanes[planenum];
f->next = b->hulls[0].faces;
b->hulls[0].faces = f;
f->texinfo = onlyents ? 0 : TexinfoForBrushTexture (f->plane, &s->td, origin);
}
return true;
}
/*
===========
TextureContents
===========
*/
int TextureContents (char *name)
{
if (!Q_strncasecmp (name, "sky",3))
return CONTENTS_SKY;
if (!Q_strncasecmp(name+1,"!lava",5))
return CONTENTS_LAVA;
if (!Q_strncasecmp(name+1,"!slime",6))
return CONTENTS_SLIME;
if (!Q_strncasecmp (name, "!cur_90",7))
return CONTENTS_CURRENT_90;
if (!Q_strncasecmp (name, "!cur_0",6))
return CONTENTS_CURRENT_0;
if (!Q_strncasecmp (name, "!cur_270",8))
return CONTENTS_CURRENT_270;
if (!Q_strncasecmp (name, "!cur_180",8))
return CONTENTS_CURRENT_180;
if (!Q_strncasecmp (name, "!cur_up",7))
return CONTENTS_CURRENT_UP;
if (!Q_strncasecmp (name, "!cur_dwn",8))
return CONTENTS_CURRENT_DOWN;
if (name[0] == '!')
return CONTENTS_WATER;
if (!Q_strncasecmp (name, "origin",6))
return CONTENTS_ORIGIN;
if (!Q_strncasecmp (name, "clip",4))
return CONTENTS_CLIP;
if( !Q_strncasecmp( name, "translucent", 11 ) )
return CONTENTS_TRANSLUCENT;
if( name[0] == '@' )
return CONTENTS_TRANSLUCENT;
return CONTENTS_SOLID;
}
/*
===========
BrushContents
===========
*/
int BrushContents (brush_t *b)
{
char *name;
int contents;
bface_t *f;
side_t *s;
int i;
s = &brushsides[b->firstside];
contents = TextureContents (s->td.name);
for (i=1 ; i<b->numsides ; i++, s++)
{
if (TextureContents(s->td.name) != contents)
{
printf ("Entity %i, Brush %i: mixed face contents"
, b->entitynum, b->brushnum);
break;
}
}
return contents;
}
/*
===========
CreateBrush
===========
*/
void CreateBrush (int brushnum)
{
brush_t *b;
int contents;
int h;
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
b = &mapbrushes[brushnum];
contents = b->contents;
if (contents == CONTENTS_ORIGIN)
return;
//
// convert brush sides to planes
//
MakeBrushPlanes (b);
MakeHullFaces (b, &b->hulls[0]);
// water brushes are not solid, so are not represented in
// the clipping hull
if (contents == CONTENTS_LAVA
|| contents == CONTENTS_SLIME
|| contents == CONTENTS_WATER
|| contents == CONTENTS_TRANSLUCENT )
return;
if (!noclip)
{
for (h=1 ; h<NUM_HULLS ; h++)
{
ExpandBrush (b, h);
MakeHullFaces (b, &b->hulls[h]);
}
}
// clip brushes don't stay in the drawing hull
if (contents == CONTENTS_CLIP)
{
b->hulls[0].faces = NULL;
b->contents = CONTENTS_SOLID;
}
}

144
hlsdk/utils/qcsg/csg.h Normal file
View File

@ -0,0 +1,144 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "cmdlib.h"
#include "mathlib.h"
#include "scriplib.h"
#include "polylib.h"
#include "threads.h"
#include "bspfile.h"
#include <windows.h>
#ifndef DOUBLEVEC_T
#error you must add -dDOUBLEVEC_T to the project!
#endif
#define BOGUS_RANGE 8192
typedef struct
{
vec3_t normal;
vec_t dist;
int type;
int iorigin[3];
int inormal[3];
} plane_t;
extern plane_t mapplanes[MAX_MAP_PLANES];
extern int nummapplanes;
extern int g_nMapFileVersion; // map file version * 100 (ie 201), zero for pre-Worldcraft 2.0.1 maps
typedef struct
{
vec3_t UAxis;
vec3_t VAxis;
vec_t shift[2];
vec_t rotate;
vec_t scale[2];
char name[32];
} brush_texture_t;
typedef struct side_s
{
brush_texture_t td;
int planepts[3][3];
} side_t;
typedef struct bface_s
{
struct bface_s *next;
int planenum;
plane_t *plane;
winding_t *w;
int texinfo;
qboolean used; // just for face counting
int contents, backcontents;
vec3_t mins, maxs;
} bface_t;
#define NUM_HULLS 4 // no larger than MAX_MAP_HULLS
typedef struct
{
vec3_t mins, maxs;
bface_t *faces;
} brushhull_t;
typedef struct brush_s
{
int entitynum;
int brushnum;
int firstside;
int numsides;
int contents;
brushhull_t hulls[NUM_HULLS];
} brush_t;
extern int nummapbrushes;
extern brush_t mapbrushes[MAX_MAP_BRUSHES];
#define MAX_MAP_SIDES (MAX_MAP_BRUSHES*6)
extern int numbrushplanes;
extern plane_t planes[MAX_MAP_PLANES];
extern int numbrushsides;
extern side_t brushsides[MAX_MAP_SIDES];
extern qboolean noclip;
extern qboolean wadtextures;
int nWadInclude;
char *pszWadInclude[];
void LoadMapFile (char *filename);
//=============================================================================
// textures.c
extern int nummiptex;
void WriteMiptex (void);
int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, vec3_t origin);
//=============================================================================
// brush.c
void FindGCD (int *v);
brush_t *Brush_LoadEntity (entity_t *ent, int hullnum);
int PlaneTypeForNormal (vec3_t normal);
void CreateBrush (int brushnum);
//=============================================================================
// csg.c
bface_t *NewFaceFromFace (bface_t *in);
extern qboolean onlyents;
//=============================================================================
// draw.c
extern vec3_t draw_mins, draw_maxs;
extern qboolean drawflag;
void Draw_ClearWindow (void);
void DrawWinding (winding_t *w);

154
hlsdk/utils/qcsg/gldraw.c Normal file
View File

@ -0,0 +1,154 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include <windows.h>
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
#include "csg.h"
// can't use the glvertex3fv functions, because the vec3_t fields
// could be either floats or doubles, depending on DOUBLEVEC_T
qboolean drawflag;
vec3_t draw_mins, draw_maxs;
#define WIN_SIZE 512
void InitWindow (void)
{
auxInitDisplayMode (AUX_SINGLE | AUX_RGB);
auxInitPosition (0, 0, WIN_SIZE, WIN_SIZE);
auxInitWindow ("qcsg");
}
void Draw_ClearWindow (void)
{
static int init;
int w, h, g;
vec_t mx, my;
if (!drawflag)
return;
if (!init)
{
init = true;
InitWindow ();
}
glClearColor (1,0.8,0.8,0);
glClear (GL_COLOR_BUFFER_BIT);
w = (draw_maxs[0] - draw_mins[0]);
h = (draw_maxs[1] - draw_mins[1]);
mx = draw_mins[0] + w/2;
my = draw_mins[1] + h/2;
g = w > h ? w : h;
glLoadIdentity ();
gluPerspective (90, 1, 2, 16384);
gluLookAt (mx, my, draw_maxs[2] + g/2, mx , my, draw_maxs[2], 0, 1, 0);
glColor3f (0,0,0);
// glPolygonMode (GL_FRONT_AND_BACK, GL_LINE);
glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
glDisable (GL_DEPTH_TEST);
glEnable (GL_BLEND);
glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#if 0
glColor4f (1,0,0,0.5);
glBegin (GL_POLYGON);
glVertex3f (0, 500, 0);
glVertex3f (0, 900, 0);
glVertex3f (0, 900, 100);
glVertex3f (0, 500, 100);
glEnd ();
#endif
glFlush ();
}
void Draw_SetRed (void)
{
if (!drawflag)
return;
glColor3f (1,0,0);
}
void Draw_SetGrey (void)
{
if (!drawflag)
return;
glColor3f (0.5,0.5,0.5);
}
void Draw_SetBlack (void)
{
if (!drawflag)
return;
glColor3f (0,0,0);
}
void DrawWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (0,1,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}
void DrawAuxWinding (winding_t *w)
{
int i;
if (!drawflag)
return;
glColor4f (0,0,0,0.5);
glBegin (GL_LINE_LOOP);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glColor4f (1,0,0,0.3);
glBegin (GL_POLYGON);
for (i=0 ; i<w->numpoints ; i++)
glVertex3f (w->p[i][0],w->p[i][1],w->p[i][2] );
glEnd ();
glFlush ();
}

View File

@ -0,0 +1,87 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "csg.h"
extern vec3_t hull_size[NUM_HULLS][2];
/*
============
CheckHullFile
============
*/
void CheckHullFile( qboolean hullfile, char *filename )
{
FILE *f;
char scan[ 128 ];
vec3_t new_hulls[NUM_HULLS][2];
qboolean read_error = false;
int i;
if ( !hullfile )
return;
// Open up hull file
f = fopen (filename, "r");
if ( !f )
{
printf ("WARNING: Couldn't open hullfile %s, using default hulls", filename );
return;
}
else
{
printf("[Reading hulls from '%s']\n", filename);
}
for ( i = 0 ; i < NUM_HULLS; i++ )
{
float x1, y1, z1, x2, y2, z2;
vec3_t mins, maxs;
int argCnt;
if ( !fgets(scan, sizeof(scan), f ) )
{
printf ("WARNING: Error parsing %s, couln't read hull line %i, using default hulls", filename, i );
read_error = true;
break;
}
argCnt = sscanf (scan, "( %f %f %f ) ( %f %f %f ) ", &x1, &y1, &z1, &x2, &y2, &z2 );
if ( argCnt != 6 )
{
printf ("WARNING: Error parsing %s, expeciting '( x y z ) ( x y z )' using default hulls", filename );
read_error = true;
break;
}
else
{
mins[0] = x1;
mins[1] = y1;
mins[2] = z1;
maxs[0] = x2;
maxs[1] = y2;
maxs[2] = z2;
}
VectorCopy( mins, new_hulls[ i ][ 0 ] );
VectorCopy( maxs, new_hulls[ i ][ 1 ] );
}
if ( read_error )
{
printf ("WARNING: Error parsing %s, using default hulls", filename );
}
else
{
memcpy( hull_size, new_hulls, 2 * NUM_HULLS * sizeof( vec3_t ) );
}
fclose( f );
}

View File

@ -0,0 +1,4 @@
( 0 0 0 ) ( 0 0 0 )
( -16 -16 -24 ) ( 16 16 32 )
( -32 -32 -32 ) ( 32 32 32 )
( -16 -16 -24 ) ( 16 16 32 )

344
hlsdk/utils/qcsg/map.c Normal file
View File

@ -0,0 +1,344 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "csg.h"
int nummapbrushes;
brush_t mapbrushes[MAX_MAP_BRUSHES];
int numbrushsides;
side_t brushsides[MAX_MAP_SIDES];
int g_nMapFileVersion;
/*
==================
textureAxisFromPlane
==================
*/
vec3_t baseaxis[18] =
{
{0,0,1}, {1,0,0}, {0,-1,0}, // floor
{0,0,-1}, {1,0,0}, {0,-1,0}, // ceiling
{1,0,0}, {0,1,0}, {0,0,-1}, // west wall
{-1,0,0}, {0,1,0}, {0,0,-1}, // east wall
{0,1,0}, {1,0,0}, {0,0,-1}, // south wall
{0,-1,0}, {1,0,0}, {0,0,-1} // north wall
};
void TextureAxisFromPlane(plane_t *pln, vec3_t xv, vec3_t yv)
{
int bestaxis;
vec_t dot,best;
int i;
best = 0;
bestaxis = 0;
for (i=0 ; i<6 ; i++)
{
dot = DotProduct (pln->normal, baseaxis[i*3]);
if (dot > best)
{
best = dot;
bestaxis = i;
}
}
VectorCopy (baseaxis[bestaxis*3+1], xv);
VectorCopy (baseaxis[bestaxis*3+2], yv);
}
/*
=================
ParseBrush
=================
*/
void ParseBrush (entity_t *mapent)
{
brush_t *b;
bface_t *f, *f2;
int planepts[3][3];
vec3_t t1, t2, t3;
int i,j;
vec_t d;
int planenum;
side_t *side;
int contents;
if (nummapbrushes == MAX_MAP_BRUSHES)
Error ("nummapbrushes == MAX_MAP_BRUSHES");
b = &mapbrushes[nummapbrushes];
nummapbrushes++;
b->firstside = numbrushsides;
b->entitynum = num_entities-1;
b->brushnum = nummapbrushes - mapent->firstbrush - 1;
mapent->numbrushes++;
do
{
if (!GetToken (true))
break;
if (!strcmp (token, "}") )
break;
if (numbrushsides == MAX_MAP_SIDES)
Error ("numbrushsides == MAX_MAP_SIDES");
side = &brushsides[numbrushsides];
numbrushsides++;
b->numsides++;
// 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);
side->planepts[i][j] = atoi(token);
}
GetToken (false);
if (strcmp (token, ")") )
Error ("parsing brush");
}
// read the texturedef
GetToken (false);
strcpy (side->td.name, token);
if (g_nMapFileVersion < 220)
{
GetToken (false);
side->td.shift[0] = atof(token);
GetToken (false);
side->td.shift[1] = atof(token);
GetToken (false);
side->td.rotate = atof(token);
}
else
{
// texture U axis
GetToken (false);
if (strcmp (token, "["))
{
Error("missing '[ in texturedef");
}
GetToken (false);
side->td.UAxis[0] = atof(token);
GetToken (false);
side->td.UAxis[1] = atof(token);
GetToken (false);
side->td.UAxis[2] = atof(token);
GetToken (false);
side->td.shift[0] = atof(token);
GetToken (false);
if (strcmp (token, "]"))
{
Error("missing ']' in texturedef");
}
// texture V axis
GetToken (false);
if (strcmp (token, "["))
{
Error("missing '[ in texturedef");
}
GetToken (false);
side->td.VAxis[0] = atof(token);
GetToken (false);
side->td.VAxis[1] = atof(token);
GetToken (false);
side->td.VAxis[2] = atof(token);
GetToken (false);
side->td.shift[1] = atof(token);
GetToken (false);
if (strcmp (token, "]"))
{
Error("missing ']' in texturedef");
}
// Texture rotation is implicit in U/V axes.
GetToken(false);
side->td.rotate = 0;
}
// texure scale
GetToken (false);
side->td.scale[0] = atof(token);
GetToken (false);
side->td.scale[1] = atof(token);
} while (1);
b->contents = contents = BrushContents (b);
//
// origin brushes are removed, but they set
// the rotation origin for the rest of the brushes
// in the entity
//
if (contents == CONTENTS_ORIGIN)
{
char string[32];
vec3_t origin;
b->contents = CONTENTS_SOLID;
CreateBrush (mapent->firstbrush + b->brushnum); // to get sizes
b->contents = contents;
for (i = 0; i < NUM_HULLS; i++) {
b->hulls[i].faces = NULL;
}
if (b->entitynum == 0)
{
printf ("Entity %i, Brush %i: origin brushes not allowed in world"
, b->entitynum, b->brushnum);
return;
}
VectorAdd (b->hulls[0].mins, b->hulls[0].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);
}
}
/*
================
ParseMapEntity
================
*/
qboolean ParseMapEntity (void)
{
entity_t *mapent;
epair_t *e;
if (!GetToken (true))
return false;
if (strcmp (token, "{") )
Error ("ParseEntity: { not found");
if (num_entities == MAX_MAP_ENTITIES)
Error ("num_entities == MAX_MAP_ENTITIES");
mapent = &entities[num_entities];
num_entities++;
mapent->firstbrush = nummapbrushes;
mapent->numbrushes = 0;
do
{
if (!GetToken (true))
Error ("ParseEntity: EOF without closing brace");
if (!strcmp (token, "}") )
break;
if (!strcmp (token, "{") )
ParseBrush (mapent);
else
{
e = ParseEpair ();
if (!strcmp(e->key, "mapversion"))
{
g_nMapFileVersion = atoi(e->value);
}
e->next = mapent->epairs;
mapent->epairs = e;
}
} while (1);
if ( mapent->numbrushes == 1 && mapbrushes[mapent->firstbrush].contents == CONTENTS_ORIGIN )
{
brushhull_t *hull = mapbrushes[mapent->firstbrush].hulls;
Error("Found an entity with ONLY an origin brush near(%.0f,%.0f,%.0f)!\n",
hull->mins[0], hull->mins[1], hull->mins[2] );
}
GetVectorForKey (mapent, "origin", mapent->origin);
// group entities are just for editor convenience
// toss all brushes into the world entity
if ( !onlyents && !strcmp ("func_group", ValueForKey (mapent, "classname")))
{
// this is pretty gross, because the brushes are expected to be
// in linear order for each entity
brush_t *temp;
int newbrushes;
int worldbrushes;
int i;
newbrushes = mapent->numbrushes;
worldbrushes = entities[0].numbrushes;
temp = malloc(newbrushes*sizeof(brush_t));
memcpy (temp, mapbrushes + mapent->firstbrush, newbrushes*sizeof(brush_t));
for (i=0 ; i<newbrushes ; i++)
temp[i].entitynum = 0;
// make space to move the brushes (overlapped copy)
memmove (mapbrushes + worldbrushes + newbrushes,
mapbrushes + worldbrushes,
sizeof(brush_t) * (nummapbrushes - worldbrushes - newbrushes) );
// copy the new brushes down
memcpy (mapbrushes + worldbrushes, temp, sizeof(brush_t) * newbrushes);
// fix up indexes
num_entities--;
entities[0].numbrushes += newbrushes;
for (i=1 ; i<num_entities ; i++)
entities[i].firstbrush += newbrushes;
memset (mapent,0, sizeof(*mapent));
free (temp);
}
return true;
}
/*
================
LoadMapFile
================
*/
void LoadMapFile (char *filename)
{
LoadScriptFile (filename);
num_entities = 0;
while (ParseMapEntity ())
{
}
qprintf ("Load map:%s\n", filename);
qprintf ("%5i brushes\n", nummapbrushes);
qprintf ("%5i entities\n", num_entities);
}

View File

@ -0,0 +1,172 @@
# Microsoft Developer Studio Project File - Name="qcsg" - Package Owner=<4>
# Microsoft Developer Studio Generated Build File, Format Version 6.00
# ** DO NOT EDIT **
# TARGTYPE "Win32 (x86) Console Application" 0x0103
CFG=qcsg - Win32 Release
!MESSAGE This is not a valid makefile. To build this project using NMAKE,
!MESSAGE use the Export Makefile command and run
!MESSAGE
!MESSAGE NMAKE /f "qcsg.mak".
!MESSAGE
!MESSAGE You can specify a configuration when running NMAKE
!MESSAGE by defining the macro CFG on the command line. For example:
!MESSAGE
!MESSAGE NMAKE /f "qcsg.mak" CFG="qcsg - Win32 Release"
!MESSAGE
!MESSAGE Possible choices for configuration are:
!MESSAGE
!MESSAGE "qcsg - Win32 Release" (based on "Win32 (x86) Console Application")
!MESSAGE "qcsg - Win32 Debug" (based on "Win32 (x86) Console Application")
!MESSAGE
# Begin Project
# PROP AllowPerConfigDependencies 0
# PROP Scc_ProjName ""$/SDKSrc/Tools/utils/qcsg", XUGBAAAA"
# PROP Scc_LocalPath "."
CPP=cl.exe
RSC=rc.exe
!IF "$(CFG)" == "qcsg - Win32 Release"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 0
# PROP BASE Output_Dir ".\Release"
# PROP BASE Intermediate_Dir ".\Release"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 0
# PROP Output_Dir ".\Release"
# PROP Intermediate_Dir ".\Release"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MT /GX /O2 /I "..\..\common" /D "NDEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DOUBLEVEC_T" /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /subsystem:console /machine:I386
!ELSEIF "$(CFG)" == "qcsg - Win32 Debug"
# PROP BASE Use_MFC 0
# PROP BASE Use_Debug_Libraries 1
# PROP BASE Output_Dir ".\Debug"
# PROP BASE Intermediate_Dir ".\Debug"
# PROP BASE Target_Dir ""
# PROP Use_MFC 0
# PROP Use_Debug_Libraries 1
# PROP Output_Dir ".\Debug"
# PROP Intermediate_Dir ".\Debug"
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /YX /c
# ADD CPP /nologo /MTd /Gm /GX /ZI /Od /I "..\..\common" /D "_DEBUG" /D "WIN32" /D "_CONSOLE" /D "_MBCS" /D "DOUBLEVEC_T" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe
# ADD BASE BSC32 /nologo
# ADD BSC32 /nologo
LINK32=link.exe
# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386
# ADD LINK32 opengl32.lib glu32.lib glaux.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib uuid.lib /nologo /subsystem:console /debug /machine:I386
!ENDIF
# Begin Target
# Name "qcsg - Win32 Release"
# Name "qcsg - Win32 Debug"
# Begin Group "Source Files"
# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
# Begin Source File
SOURCE=..\brush.c
# End Source File
# Begin Source File
SOURCE=..\..\common\bspfile.c
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.c
# End Source File
# Begin Source File
SOURCE=..\gldraw.c
# End Source File
# Begin Source File
SOURCE=..\hullfile.c
# End Source File
# Begin Source File
SOURCE=..\map.c
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.c
# End Source File
# Begin Source File
SOURCE=..\..\common\polylib.c
# End Source File
# Begin Source File
SOURCE=..\qcsg.c
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.c
# End Source File
# Begin Source File
SOURCE=..\textures.c
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.c
# End Source File
# End Group
# Begin Group "Header Files"
# PROP Default_Filter "h;hpp;hxx;hm;inl;fi;fd"
# Begin Source File
SOURCE=..\..\common\bspfile.h
# End Source File
# Begin Source File
SOURCE=..\..\common\cmdlib.h
# End Source File
# Begin Source File
SOURCE=..\csg.h
# End Source File
# Begin Source File
SOURCE=..\..\common\mathlib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\polylib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\scriplib.h
# End Source File
# Begin Source File
SOURCE=..\..\common\threads.h
# End Source File
# End Group
# Begin Group "Resource Files"
# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
# End Group
# End Target
# End Project

View File

@ -0,0 +1,37 @@
Microsoft Developer Studio Workspace File, Format Version 6.00
# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
###############################################################################
Project: "qcsg"=.\qcsg.dsp - Package Owner=<4>
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/qcsg", XUGBAAAA
.
end source code control
}}}
Package=<4>
{{{
}}}
###############################################################################
Global:
Package=<5>
{{{
begin source code control
"$/SDKSrc/Tools/utils/qcsg", XUGBAAAA
.
end source code control
}}}
Package=<3>
{{{
}}}
###############################################################################

View File

@ -0,0 +1,414 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="7.10"
Name="qcsg"
ProjectGUID="{73F7C531-9735-478E-8AC2-911C11201614}"
SccProjectName="&quot;$/SDKSrc/Tools/utils/qcsg&quot;, XUGBAAAA"
SccLocalPath=".">
<Platforms>
<Platform
Name="Win32"/>
</Platforms>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
RuntimeLibrary="1"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Debug/qcsg.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
SuppressStartupBanner="TRUE"
DebugInformationFormat="3"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib"
OutputFile=".\Debug/qcsg.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
GenerateDebugInformation="TRUE"
ProgramDatabaseFile=".\Debug/qcsg.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/qcsg.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="FALSE"
CharacterSet="2">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
StringPooling="TRUE"
RuntimeLibrary="0"
EnableFunctionLevelLinking="TRUE"
UsePrecompiledHeader="2"
PrecompiledHeaderFile=".\Release/qcsg.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="TRUE"
CompileAs="0"/>
<Tool
Name="VCCustomBuildTool"/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib"
OutputFile=".\Release/qcsg.exe"
LinkIncremental="1"
SuppressStartupBanner="TRUE"
ProgramDatabaseFile=".\Release/qcsg.pdb"
SubSystem="1"
TargetMachine="1"/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/qcsg.tlb"
HeaderFileName=""/>
<Tool
Name="VCPostBuildEventTool"/>
<Tool
Name="VCPreBuildEventTool"/>
<Tool
Name="VCPreLinkEventTool"/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"/>
<Tool
Name="VCWebServiceProxyGeneratorTool"/>
<Tool
Name="VCXMLDataGeneratorTool"/>
<Tool
Name="VCWebDeploymentTool"/>
<Tool
Name="VCManagedWrapperGeneratorTool"/>
<Tool
Name="VCAuxiliaryManagedWrapperGeneratorTool"/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90">
<File
RelativePath="..\brush.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\bspfile.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\gldraw.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\hullfile.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\map.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\polylib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\qcsg.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\textures.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c">
<FileConfiguration
Name="Debug|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32">
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd">
<File
RelativePath="..\..\common\bspfile.h">
</File>
<File
RelativePath="..\..\common\cmdlib.h">
</File>
<File
RelativePath="..\csg.h">
</File>
<File
RelativePath="..\..\common\mathlib.h">
</File>
<File
RelativePath="..\..\common\polylib.h">
</File>
<File
RelativePath="..\..\common\scriplib.h">
</File>
<File
RelativePath="..\..\common\threads.h">
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe">
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

View File

@ -0,0 +1,546 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8.00"
Name="qcsg"
ProjectGUID="{73F7C531-9735-478E-8AC2-911C11201614}"
>
<Platforms>
<Platform
Name="Win32"
/>
</Platforms>
<ToolFiles>
</ToolFiles>
<Configurations>
<Configuration
Name="Debug|Win32"
OutputDirectory=".\Debug"
IntermediateDirectory=".\Debug"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Debug/qcsg.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="_DEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
RuntimeLibrary="1"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Debug/qcsg.pch"
AssemblerListingLocation=".\Debug/"
ObjectFile=".\Debug/"
ProgramDataBaseFileName=".\Debug/"
BrowseInformation="1"
SuppressStartupBanner="true"
DebugInformationFormat="3"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="_DEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib"
OutputFile=".\Debug/qcsg.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
GenerateDebugInformation="true"
ProgramDatabaseFile=".\Debug/qcsg.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
<Configuration
Name="Release|Win32"
OutputDirectory=".\Release"
IntermediateDirectory=".\Release"
ConfigurationType="1"
InheritedPropertySheets="$(VCInstallDir)VCProjectDefaults\UpgradeFromVC71.vsprops"
UseOfMFC="0"
ATLMinimizesCRunTimeLibraryUsage="false"
CharacterSet="2"
>
<Tool
Name="VCPreBuildEventTool"
/>
<Tool
Name="VCCustomBuildTool"
/>
<Tool
Name="VCXMLDataGeneratorTool"
/>
<Tool
Name="VCWebServiceProxyGeneratorTool"
/>
<Tool
Name="VCMIDLTool"
TypeLibraryName=".\Release/qcsg.tlb"
HeaderFileName=""
/>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
InlineFunctionExpansion="1"
AdditionalIncludeDirectories="..\..\common"
PreprocessorDefinitions="NDEBUG;WIN32;_CONSOLE;DOUBLEVEC_T"
StringPooling="true"
RuntimeLibrary="0"
EnableFunctionLevelLinking="true"
UsePrecompiledHeader="0"
PrecompiledHeaderFile=".\Release/qcsg.pch"
AssemblerListingLocation=".\Release/"
ObjectFile=".\Release/"
ProgramDataBaseFileName=".\Release/"
SuppressStartupBanner="true"
CompileAs="0"
/>
<Tool
Name="VCManagedResourceCompilerTool"
/>
<Tool
Name="VCResourceCompilerTool"
PreprocessorDefinitions="NDEBUG"
Culture="1033"
/>
<Tool
Name="VCPreLinkEventTool"
/>
<Tool
Name="VCLinkerTool"
AdditionalDependencies="opengl32.lib glu32.lib glaux.lib"
OutputFile=".\Release/qcsg.exe"
LinkIncremental="1"
SuppressStartupBanner="true"
ProgramDatabaseFile=".\Release/qcsg.pdb"
SubSystem="1"
TargetMachine="1"
/>
<Tool
Name="VCALinkTool"
/>
<Tool
Name="VCManifestTool"
/>
<Tool
Name="VCXDCMakeTool"
/>
<Tool
Name="VCBscMakeTool"
/>
<Tool
Name="VCFxCopTool"
/>
<Tool
Name="VCAppVerifierTool"
/>
<Tool
Name="VCWebDeploymentTool"
/>
<Tool
Name="VCPostBuildEventTool"
/>
</Configuration>
</Configurations>
<References>
</References>
<Files>
<Filter
Name="Source Files"
Filter="cpp;c;cxx;rc;def;r;odl;idl;hpj;bat;for;f90"
>
<File
RelativePath="..\brush.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\bspfile.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\cmdlib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gldraw.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\hullfile.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\map.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\mathlib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\polylib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\qcsg.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\scriplib.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\textures.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\..\common\threads.c"
>
<FileConfiguration
Name="Debug|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
BrowseInformation="1"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
>
<Tool
Name="VCCLCompilerTool"
Optimization="2"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
</Filter>
<Filter
Name="Header Files"
Filter="h;hpp;hxx;hm;inl;fi;fd"
>
<File
RelativePath="..\..\common\bspfile.h"
>
</File>
<File
RelativePath="..\..\common\cmdlib.h"
>
</File>
<File
RelativePath="..\csg.h"
>
</File>
<File
RelativePath="..\..\common\mathlib.h"
>
</File>
<File
RelativePath="..\..\common\polylib.h"
>
</File>
<File
RelativePath="..\..\common\scriplib.h"
>
</File>
<File
RelativePath="..\..\common\threads.h"
>
</File>
</Filter>
<Filter
Name="Resource Files"
Filter="ico;cur;bmp;dlg;rc2;rct;bin;cnt;rtf;gif;jpg;jpeg;jpe"
>
</Filter>
</Files>
<Globals>
</Globals>
</VisualStudioProject>

879
hlsdk/utils/qcsg/qcsg.c Normal file
View File

@ -0,0 +1,879 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
// csg4.c
#include "csg.h"
/*
NOTES
-----
check map size for +/- 4k limit at load time
*/
int brushfaces;
int c_csgfaces;
FILE *out[NUM_HULLS];
int c_tiny, c_tiny_clip;
int c_outfaces;
qboolean hullfile = false;
static char qhullfile[ 256 ];
qboolean glview;
qboolean noclip;
qboolean onlyents;
qboolean wadtextures = true;
vec3_t world_mins, world_maxs;
/*
==================
NewFaceFromFace
Duplicates the non point information of a face, used by SplitFace
==================
*/
bface_t *NewFaceFromFace (bface_t *in)
{
bface_t *newf;
newf = malloc (sizeof(bface_t));
memset (newf, 0, sizeof(newf));
newf->contents = in->contents;
newf->texinfo = in->texinfo;
newf->planenum = in->planenum;
newf->plane = in->plane;
return newf;
}
void FreeFace (bface_t *f)
{
free (f->w);
free (f);
}
/*
=================
ClipFace
Clips a faces by a plane, returning the fragment on the backside
and adding any fragment to the outside.
Faces exactly on the plane will stay inside unless overdrawn by later brush
frontside is the side of the plane that holds the outside list
Precedence is necesary to handle overlapping coplanar faces.
=================
*/
#define SPLIT_EPSILON 0.3
bface_t *ClipFace (brush_t *b, bface_t *f, bface_t **outside,
int splitplane, qboolean precedence)
{
bface_t *front;
winding_t *fw, *bw;
vec_t d;
plane_t *split;
int i, count[3];
// handle exact plane matches special
if (f->planenum == (splitplane^1) )
{ // opposite side, so put on inside list
return f;
}
if ( f->planenum == splitplane )
{
// coplanar
if (precedence)
{ // this fragment will go to the inside, because
// the earlier one was clipped to the outside
return f;
}
f->next = *outside;
*outside = f;
return NULL;
}
split = &mapplanes[splitplane];
#if 0
count[0] = count[1] = count[2] = 0;
for (i=0 ; i<f->w->numpoints ; i++)
{
d = DotProduct (f->w->p[i], split->normal) - split->dist;
if (d < -SPLIT_EPSILON)
count[1]++;
else if (d > SPLIT_EPSILON)
count[0]++;
else
count[2]++;
}
if (!count[0])
{
fw = NULL;
bw = f->w;
}
else if (!count[1])
{
fw = f->w;
bw = NULL;
}
else
#endif
ClipWindingNoCopy (f->w, split->normal, split->dist, &fw, &bw);
if (!fw)
return f;
if (!bw)
{
f->next = *outside;
*outside = f;
return NULL;
}
FreeWinding (f->w);
front = NewFaceFromFace (f);
front->w = fw;
WindingBounds (fw, front->mins, front->maxs);
front->next = *outside;
*outside = front;
f->w = bw;
WindingBounds (bw, f->mins, f->maxs);
return f;
}
/*
===========
WriteFace
===========
*/
void WriteFace (int hull, bface_t *f)
{
int i, j;
winding_t *w;
static int level = 128;
vec_t light;
ThreadLock ();
if (!hull)
c_csgfaces++;
if (glview)
{
// .gl format
w = f->w;
fprintf (out[hull], "%i\n", w->numpoints);
level+=28;
light = (level&255)/255.0;
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (out[hull], "%5.2f %5.2f %5.2f %5.3f %5.3f %5.3f\n",
w->p[i][0],
w->p[i][1],
w->p[i][2],
light,
light,
light);
}
fprintf (out[hull], "\n");
}
else
{
// .p0 format
w = f->w;
fprintf (out[hull], "%i %i %i %i\n", f->planenum, f->texinfo, f->contents, w->numpoints);
for (i=0 ; i<w->numpoints ; i++)
{
fprintf (out[hull], "%5.2f %5.2f %5.2f\n",
w->p[i][0],
w->p[i][1],
w->p[i][2]);
}
fprintf (out[hull], "\n");
}
ThreadUnlock ();
}
/*
==================
SaveOutside
The faces remaining on the outside list are final
polygons. Write them to the output file.
Passable contents (water, lava, etc) will generate
a mirrored copy of the face to be seen from the inside.
==================
*/
void SaveOutside (brush_t *b, int hull, bface_t *outside, int mirrorcontents)
{
bface_t *f , *next, *f2;
int i;
int planenum;
vec3_t temp;
for (f=outside ; f ; f=next)
{
next = f->next;
if (WindingArea (f->w) < 1.0)
{
c_tiny++;
qprintf ("Entity %i, Brush %i: tiny fragment\n"
, b->entitynum, b->brushnum);
continue;
}
// count unique faces
if (!hull)
{
for (f2=b->hulls[hull].faces ; f2 ; f2=f2->next)
{
if (f2->planenum == f->planenum)
{
if (!f2->used)
{
f2->used = true;
c_outfaces++;
}
break;
}
}
}
WriteFace (hull, f);
// if (mirrorcontents != CONTENTS_SOLID)
{
f->planenum ^= 1;
f->plane = &mapplanes[f->planenum];
f->contents = mirrorcontents;
// swap point orders
for (i=0 ; i<f->w->numpoints/2 ; i++) // add points backwards
{
VectorCopy (f->w->p[i], temp);
VectorCopy (f->w->p[f->w->numpoints-1-i]
, f->w->p[i]);
VectorCopy (temp, f->w->p[f->w->numpoints-1-i]);
}
WriteFace (hull, f);
}
FreeFace (f);
}
}
/*
==================
EncloseInside
Changes the contents on all faces that got clipped out
and moves them back to the outside list
==================
*/
void EncloseInside (bface_t *inside, bface_t **outside
, int contents)
{
bface_t *f, *next;
for (f=inside ; f ; f=next)
{
next = f->next;
f->contents = contents;
f->next = *outside;
*outside = f;
}
}
//==========================================================================
bface_t *CopyFace (bface_t *f)
{
bface_t *n;
n = NewFaceFromFace (f);
n->w = CopyWinding (f->w);
VectorCopy (f->mins, n->mins);
VectorCopy (f->maxs, n->maxs);
return n;
}
/*
==================
CopyFacesToOutside
Make a copy of all the faces of the brush, so they
can be chewed up by other brushes.
All of the faces start on the outside list.
As other brushes take bites out of the faces, the
fragments are moved to the inside list, so they
can be freed when they are determined to be
completely enclosed in solid.
==================
*/
bface_t *CopyFacesToOutside (brushhull_t *bh)
{
bface_t *f, *newf;
bface_t *outside;
outside = NULL;
for (f=bh->faces ; f ; f=f->next)
{
brushfaces++;
newf = CopyFace (f);
WindingBounds (newf->w, newf->mins, newf->maxs);
newf->next = outside;
outside = newf;
}
return outside;
}
//============================================================
/*
===========
CSGBrush
===========
*/
void CSGBrush (int brushnum)
{
int hull;
brush_t *b1, *b2;
brushhull_t *bh1, *bh2;
int bn;
qboolean overwrite;
int i;
bface_t *f, *f2, *next, *fcopy;
bface_t *outside, *oldoutside;
entity_t *e;
vec_t area;
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
b1 = &mapbrushes[brushnum];
e = &entities[b1->entitynum];
for (hull = 0 ; hull<NUM_HULLS ; hull++)
{
bh1 = &b1->hulls[hull];
// set outside to a copy of the brush's faces
outside = CopyFacesToOutside (bh1);
overwrite = false;
for (bn=0 ; bn<e->numbrushes ; bn++)
{
// see if b2 needs to clip a chunk out of b1
if (bn==brushnum)
{
overwrite = true; // later brushes now overwrite
continue;
}
b2 = &mapbrushes[e->firstbrush + bn];
bh2 = &b2->hulls[hull];
if (!bh2->faces)
continue; // brush isn't in this hull
// check brush bounding box first
for (i=0 ; i<3 ; i++)
if (bh1->mins[i] > bh2->maxs[i]
|| bh1->maxs[i] < bh2->mins[i])
break;
if (i<3)
continue;
// divide faces by the planes of the b2 to find which
// fragments are inside
f = outside;
outside = NULL;
for ( ; f ; f=next)
{
next = f->next;
// check face bounding box first
for (i=0 ; i<3 ; i++)
if (bh2->mins[i] > f->maxs[i]
|| bh2->maxs[i] < f->mins[i])
break;
if (i<3)
{ // this face doesn't intersect brush2's bbox
f->next = outside;
outside = f;
continue;
}
oldoutside = outside;
fcopy = CopyFace (f); // save to avoid fake splits
// throw pieces on the front sides of the planes
// into the outside list, return the remains on the inside
for (f2=bh2->faces ; f2 && f ; f2=f2->next)
f = ClipFace (b1, f, &outside, f2->planenum, overwrite);
area = f ? WindingArea (f->w) : 0;
if (f && area < 1.0)
{
qprintf ("Entity %i, Brush %i: tiny penetration\n"
, b1->entitynum, b1->brushnum);
c_tiny_clip++;
FreeFace (f);
f = NULL;
}
if (f)
{
// there is one convex fragment of the original
// face left inside brush2
FreeFace (fcopy);
if (b1->contents > b2->contents)
{ // inside a water brush
f->contents = b2->contents;
f->next = outside;
outside = f;
}
else // inside a solid brush
FreeFace (f); // throw it away
}
else
{ // the entire thing was on the outside, even
// though the bounding boxes intersected,
// which will never happen with axial planes
// free the fragments chopped to the outside
while (outside != oldoutside)
{
f2 = outside->next;
FreeFace (outside);
outside = f2;
}
// revert to the original face to avoid
// unneeded false cuts
fcopy->next = outside;
outside = fcopy;
}
}
}
// all of the faces left in outside are real surface faces
SaveOutside (b1, hull, outside, b1->contents);
}
}
//======================================================================
/*
============
EmitPlanes
============
*/
void EmitPlanes (void)
{
int i;
dplane_t *dp;
plane_t *mp;
numplanes = nummapplanes;
mp = mapplanes;
dp = dplanes;
for (i=0 ; i<nummapplanes ; i++, mp++, dp++)
{
VectorCopy ( mp->normal, dp->normal);
dp->dist = mp->dist;
dp->type = mp->type;
}
}
/*
============
SetModelNumbers
============
*/
void SetModelNumbers (void)
{
int i;
int models;
char value[10];
models = 1;
for (i=1 ; i<num_entities ; i++)
{
if (entities[i].numbrushes)
{
sprintf (value, "*%i", models);
models++;
SetKeyValue (&entities[i], "model", value);
}
}
}
/*
============
SetLightStyles
============
*/
#define MAX_SWITCHED_LIGHTS 32
void SetLightStyles (void)
{
int stylenum;
char *t;
entity_t *e;
int i, j;
char value[10];
char lighttargets[MAX_SWITCHED_LIGHTS][64];
// any light that is controlled (has a targetname)
// must have a unique style number generated for it
stylenum = 0;
for (i=1 ; i<num_entities ; i++)
{
e = &entities[i];
t = ValueForKey (e, "classname");
if (Q_strncasecmp (t, "light", 5))
continue;
t = ValueForKey (e, "targetname");
if (!t[0])
continue;
// find this targetname
for (j=0 ; j<stylenum ; j++)
if (!strcmp (lighttargets[j], t))
break;
if (j == stylenum)
{
if (stylenum == MAX_SWITCHED_LIGHTS)
Error ("stylenum == MAX_SWITCHED_LIGHTS");
strcpy (lighttargets[j], t);
stylenum++;
}
sprintf (value, "%i", 32 + j);
SetKeyValue (e, "style", value);
}
}
/*
============
WriteBSP
============
*/
void WriteBSP (char *name)
{
char path[1024];
strcpy (path, name);
DefaultExtension (path, ".bsp");
SetModelNumbers ();
SetLightStyles ();
UnparseEntities ();
if ( !onlyents )
WriteMiptex ();
WriteBSPFile (path);
}
//======================================================================
/*
============
ProcessModels
============
*/
int typecontents[4] = {CONTENTS_WATER, CONTENTS_SLIME, CONTENTS_LAVA
, CONTENTS_SKY};
void ProcessModels (void)
{
int i, j, type;
int placed;
int first, contents;
brush_t temp;
vec3_t origin;
for (i=0 ; i<num_entities ; i++)
{
if (!entities[i].numbrushes)
continue;
//
// sort the contents down so stone bites water, etc
//
first = entities[i].firstbrush;
placed = 0;
for (type=0 ; type<4 ; type++)
{
contents = typecontents[type];
for (j=placed+1 ; j< entities[i].numbrushes ; j++)
{
if (mapbrushes[first+j].contents == contents)
{
temp = mapbrushes[first+placed];
mapbrushes[first+placed] = mapbrushes[j];
mapbrushes[j] = temp;
placed++;
}
}
}
//
// csg them in order
//
if (i == 0)
{
RunThreadsOnIndividual (entities[i].numbrushes, 1 , CSGBrush);
}
else
{
for (j=0 ; j<entities[i].numbrushes ; j++)
CSGBrush (first + j);
}
// write end of model marker
if (!glview)
{
for (j=0 ; j<NUM_HULLS ; j++)
fprintf (out[j], "-1 -1 -1 -1\n");
}
}
}
//=========================================
/*
============
BoundWorld
============
*/
void BoundWorld (void)
{
int i;
brushhull_t *h;
ClearBounds (world_mins, world_maxs);
for (i=0 ; i<nummapbrushes ; i++)
{
h = &mapbrushes[i].hulls[0];
if (!h->faces)
continue;
AddPointToBounds (h->mins, world_mins, world_maxs);
AddPointToBounds (h->maxs, world_mins, world_maxs);
}
qprintf ("World bounds: (%i %i %i) to (%i %i %i)\n",
(int)world_mins[0],(int)world_mins[1],(int)world_mins[2],
(int)world_maxs[0],(int)world_maxs[1],(int)world_maxs[2]);
VectorCopy (world_mins, draw_mins);
VectorCopy (world_maxs, draw_maxs);
Draw_ClearWindow ();
}
/*
============
main
============
*/
extern char qproject[];
int main (int argc, char **argv)
{
int i, j;
int hull;
entity_t *ent;
char source[1024];
char name[1024];
double start, end;
printf( "qcsg.exe v2.8 (%s)\n", __DATE__ );
printf ("---- qcsg ----\n" );
for (i=1 ; i<argc ; i++)
{
if (!strcmp(argv[i],"-threads"))
{
numthreads = atoi (argv[i+1]);
i++;
}
else if (!strcmp(argv[i],"-glview"))
{
glview = true;
}
else if (!strcmp(argv[i], "-v"))
{
printf ("verbose = true\n");
verbose = true;
}
else if (!strcmp(argv[i], "-draw"))
{
printf ("drawflag = true\n");
drawflag = true;
}
else if (!strcmp(argv[i], "-noclip"))
{
printf ("noclip = true\n");
noclip = true;
}
else if (!strcmp(argv[i], "-onlyents"))
{
printf ("onlyents = true\n");
onlyents = true;
}
else if (!strcmp(argv[i], "-nowadtextures"))
{
printf ("wadtextures = false\n");
wadtextures = false;
}
else if (!strcmp(argv[i], "-wadinclude"))
{
pszWadInclude[nWadInclude++] = strdup( argv[i + 1] );
i++;
}
else if( !strcmp( argv[ i ], "-proj" ) )
{
strcpy( qproject, argv[ i + 1 ] );
i++;
}
else if (!strcmp(argv[i], "-hullfile"))
{
hullfile = true;
strcpy( qhullfile, argv[i + 1] );
i++;
}
else if (argv[i][0] == '-')
Error ("Unknown option \"%s\"", argv[i]);
else
break;
}
if (i != argc - 1)
Error ("usage: qcsg [-nowadtextures] [-wadinclude <name>] [-draw] [-glview] [-noclip] [-onlyents] [-proj <name>] [-threads #] [-v] [-hullfile <name>] mapfile");
SetThreadPriority(GetCurrentThread(),THREAD_PRIORITY_ABOVE_NORMAL);
start = I_FloatTime ();
CheckHullFile( hullfile, qhullfile );
ThreadSetDefault ();
SetQdirFromPath (argv[i]);
strcpy (source, ExpandArg (argv[i]));
COM_FixSlashes(source);
StripExtension (source);
strcpy (name, ExpandArg (argv[i]));
DefaultExtension (name, ".map"); // might be .reg
//
// if onlyents, just grab the entites and resave
//
if (onlyents && !glview)
{
char out[1024];
int old_entities;
sprintf (out, "%s.bsp", source);
LoadBSPFile (out);
// Get the new entity data from the map file
LoadMapFile (name);
// Write it all back out again.
WriteBSP (source);
end = I_FloatTime ();
printf ("%5.0f seconds elapsed\n", end-start);
return 0;
}
//
// start from scratch
//
LoadMapFile (name);
RunThreadsOnIndividual (nummapbrushes, true, CreateBrush);
BoundWorld ();
qprintf ("%5i map planes\n", nummapplanes);
for (i=0 ; i<NUM_HULLS ; i++)
{
char name[1024];
if (glview)
sprintf (name, "%s.gl%i",source, i);
else
sprintf (name, "%s.p%i",source, i);
out[i] = fopen (name, "w");
if (!out[i])
Error ("Couldn't open %s",name);
}
ProcessModels ();
qprintf ("%5i csg faces\n", c_csgfaces);
qprintf ("%5i used faces\n", c_outfaces);
qprintf ("%5i tiny faces\n", c_tiny);
qprintf ("%5i tiny clips\n", c_tiny_clip);
for (i=0 ; i<NUM_HULLS ; i++)
fclose (out[i]);
if (!glview)
{
EmitPlanes ();
WriteBSP (source);
}
end = I_FloatTime ();
printf ("%5.0f seconds elapsed\n", end-start);
return 0;
}

520
hlsdk/utils/qcsg/textures.c Normal file
View File

@ -0,0 +1,520 @@
/***
*
* Copyright (c) 1996-2002, Valve LLC. All rights reserved.
*
* This product contains software technology licensed from Id
* Software, Inc. ("Id Technology"). Id Technology (c) 1996 Id Software, Inc.
* All Rights Reserved.
*
****/
#include "csg.h"
typedef struct
{
char identification[4]; // should be WAD2/WAD3
int numlumps;
int infotableofs;
} wadinfo_t;
typedef struct
{
int filepos;
int disksize;
int size; // uncompressed
char type;
char compression;
char pad1, pad2;
char name[16]; // must be null terminated
int iTexFile; // index of the wad this texture is located in
} lumpinfo_t;
int nummiptex;
lumpinfo_t miptex[MAX_MAP_TEXTURES];
int nTexLumps = 0;
lumpinfo_t *lumpinfo = NULL;
int nTexFiles = 0;
FILE *texfiles[128];
int nWadInclude;
char *pszWadInclude[128];
qboolean wadInclude[128]; // include the textures from this WAD in the BSP
void CleanupName (char *in, char *out)
{
int i;
for (i=0 ; i< 16 ; i++ )
{
if (!in[i])
break;
out[i] = toupper(in[i]);
}
for ( ; i< 16 ; i++ )
out[i] = 0;
}
/*
=================
lump_sorters
=================
*/
int
lump_sorter_by_wad_and_name( const void *lump1, const void *lump2 )
{
lumpinfo_t *plump1 = (lumpinfo_t *)lump1;
lumpinfo_t *plump2 = (lumpinfo_t *)lump2;
if ( plump1->iTexFile == plump2->iTexFile )
return strcmp( plump1->name, plump2->name );
else
return plump1->iTexFile - plump2->iTexFile;
}
int
lump_sorter_by_name( const void *lump1, const void *lump2 )
{
lumpinfo_t *plump1 = (lumpinfo_t *)lump1;
lumpinfo_t *plump2 = (lumpinfo_t *)lump2;
return strcmp( plump1->name, plump2->name );
}
/*
=================
TEX_InitFromWad
=================
*/
qboolean TEX_InitFromWad (char *path)
{
int i;
wadinfo_t wadinfo;
char szTmpPath[512];
char *pszWadFile;
strcpy(szTmpPath, path);
// temporary kludge so we don't have to deal with no occurances of a semicolon
// in the path name ..
if(strchr(szTmpPath, ';') == NULL)
strcat(szTmpPath, ";");
pszWadFile = strtok(szTmpPath, ";");
while(pszWadFile)
{
FILE *texfile; // temporary used in this loop
texfiles[nTexFiles] = fopen(pszWadFile, "rb");
if (!texfiles[nTexFiles])
{
// maybe this wad file has a hard code drive
if (pszWadFile[1] == ':')
{
pszWadFile += 2; // skip past the file
texfiles[nTexFiles] = fopen (pszWadFile, "rb");
}
}
if (!texfiles[nTexFiles])
{
printf ("WARNING: couldn't open %s\n", pszWadFile);
return false;
}
++nTexFiles;
// look and see if we're supposed to include the textures from this WAD in the bsp.
for (i = 0; i < nWadInclude; i++)
{
if (stricmp( pszWadInclude[i], pszWadFile ) == 0)
{
wadInclude[nTexFiles-1] = true;
}
}
// temp assignment to make things cleaner:
texfile = texfiles[nTexFiles-1];
printf ("Using WAD File: %s\n", pszWadFile);
SafeRead(texfile, &wadinfo, sizeof(wadinfo));
if (strncmp (wadinfo.identification, "WAD2", 4) &&
strncmp (wadinfo.identification, "WAD3", 4))
Error ("TEX_InitFromWad: %s isn't a wadfile",pszWadFile);
wadinfo.numlumps = LittleLong(wadinfo.numlumps);
wadinfo.infotableofs = LittleLong(wadinfo.infotableofs);
fseek (texfile, wadinfo.infotableofs, SEEK_SET);
lumpinfo = realloc(lumpinfo, (nTexLumps + wadinfo.numlumps)
* sizeof(lumpinfo_t));
for(i = 0; i < wadinfo.numlumps; i++)
{
SafeRead(texfile, &lumpinfo[nTexLumps], sizeof(lumpinfo_t) -
sizeof(int)); // iTexFile is NOT read from file
CleanupName (lumpinfo[nTexLumps].name, lumpinfo[nTexLumps].name);
lumpinfo[nTexLumps].filepos = LittleLong(lumpinfo[nTexLumps].filepos);
lumpinfo[nTexLumps].disksize = LittleLong(lumpinfo[nTexLumps].disksize);
lumpinfo[nTexLumps].iTexFile = nTexFiles-1;
++nTexLumps;
}
// next wad file
pszWadFile = strtok(NULL, ";");
}
qsort( (void *)lumpinfo, (size_t)nTexLumps, sizeof(lumpinfo[0]), lump_sorter_by_name );
return true;
}
/*
==================
FindTexture
==================
*/
lumpinfo_t *
FindTexture (lumpinfo_t *source )
{
lumpinfo_t *found = NULL;
if ( !( found = bsearch( source, (void *)lumpinfo, (size_t)nTexLumps, sizeof(lumpinfo[0]), lump_sorter_by_name ) ) )
printf ("WARNING: texture %s not found in BSP's wad file list!\n", source->name);
return found;
}
/*
==================
LoadLump
==================
*/
int LoadLump (lumpinfo_t *source, byte *dest, int *texsize)
{
*texsize = 0;
if ( source->filepos )
{
fseek (texfiles[source->iTexFile], source->filepos, SEEK_SET);
*texsize = source->disksize;
// Should we just load the texture header w/o the palette & bitmap?
if ( wadtextures && !wadInclude[source->iTexFile] )
{
// Just read the miptex header and zero out the data offsets.
// We will load the entire texture from the WAD at engine runtime
int i;
miptex_t *miptex = (miptex_t *)dest;
SafeRead (texfiles[source->iTexFile], dest, sizeof(miptex_t) );
for( i=0; i<MIPLEVELS; i++ )
miptex->offsets[i] = 0;
return sizeof(miptex_t);
}
else
{
// Load the entire texture here so the BSP contains the texture
SafeRead (texfiles[source->iTexFile], dest, source->disksize );
return source->disksize;
}
}
printf ("WARNING: texture %s not found in BSP's wad file list!\n", source->name);
return 0;
}
/*
==================
AddAnimatingTextures
==================
*/
void AddAnimatingTextures (void)
{
int base;
int i, j, k;
char name[32];
base = nummiptex;
for (i=0 ; i<base ; i++)
{
if (miptex[i].name[0] != '+' && miptex[i].name[0] != '-')
continue;
strcpy (name, miptex[i].name);
for (j=0 ; j<20 ; j++)
{
if (j < 10)
name[1] = '0'+j;
else
name[1] = 'A'+j-10; // alternate animation
// see if this name exists in the wadfile
for (k=0 ; k < nTexLumps; k++)
if (!strcmp(name, lumpinfo[k].name))
{
FindMiptex (name); // add to the miptex list
break;
}
}
}
if ( nummiptex - base )
printf ("added %i additional animating textures.\n", nummiptex - base);
}
/*
==================
WriteMiptex
==================
*/
void WriteMiptex(void)
{
int i, len, texsize, totaltexsize = 0;
byte *data;
dmiptexlump_t *l;
char *path;
char fullpath[1024];
int start;
texdatasize = 0;
path = ValueForKey (&entities[0], "_wad");
if (!path || !path[0])
{
path = ValueForKey (&entities[0], "wad");
if (!path || !path[0])
{
printf ("WARNING: no wadfile specified\n");
return;
}
}
strcpy(fullpath, path);
start = GetTickCount();
{
if (!TEX_InitFromWad (fullpath))
return;
AddAnimatingTextures ();
}
qprintf( "TEX_InitFromWad & AddAnimatingTextures elapsed time = %ldms\n", GetTickCount()-start );
start = GetTickCount();
{
for (i=0; i<nummiptex; i++ )
{
lumpinfo_t *found;
if ( found = FindTexture( miptex + i ) )
miptex[i] = *found;
else
{
miptex[i].iTexFile = miptex[i].filepos = miptex[i].disksize = 0;
}
}
}
qprintf( "FindTextures elapsed time = %ldms\n", GetTickCount()-start );
start = GetTickCount();
{
int final_miptex, i;
texinfo_t *tx = texinfo;
// Sort them FIRST by wadfile and THEN by name for most efficient loading in the engine.
qsort( (void *)miptex, (size_t)nummiptex, sizeof(miptex[0]), lump_sorter_by_wad_and_name );
// Sleazy Hack 104 Pt 2 - After sorting the miptex array, reset the texinfos to point to the right miptexs
for(i=0; i<numtexinfo; i++, tx++)
{
char *miptex_name = (char *)tx->miptex;
tx->miptex = FindMiptex( miptex_name );
// Free up the originally strdup()'ed miptex_name
free( miptex_name );
}
}
qprintf( "qsort(miptex) elapsed time = %ldms\n", GetTickCount()-start );
start = GetTickCount();
{
// Now setup to get the miptex data (or just the headers if using -wadtextures) from the wadfile
l = (dmiptexlump_t *)dtexdata;
data = (byte *)&l->dataofs[nummiptex];
l->nummiptex = nummiptex;
for (i=0 ; i<nummiptex ; i++)
{
l->dataofs[i] = data - (byte *)l;
len = LoadLump (miptex+i, data, &texsize);
if (data + len - dtexdata >= MAX_MAP_MIPTEX)
Error ("Textures exceeded MAX_MAP_MIPTEX");
if (!len)
l->dataofs[i] = -1; // didn't find the texture
else
{
totaltexsize += texsize;
if ( totaltexsize > MAX_MAP_MIPTEX )
Error("Textures exceeded MAX_MAP_MIPTEX" );
}
data += len;
}
texdatasize = data - dtexdata;
}
qprintf( "LoadLump() elapsed time = %ldms\n", GetTickCount()-start );
}
//==========================================================================
int FindMiptex (char *name)
{
int i;
ThreadLock ();
for (i=0 ; i<nummiptex ; i++)
if (!Q_strcasecmp (name, miptex[i].name))
{
ThreadUnlock ();
return i;
}
if (nummiptex == MAX_MAP_TEXTURES)
Error ("Exceeded MAX_MAP_TEXTURES");
strcpy (miptex[i].name, name);
nummiptex++;
ThreadUnlock ();
return i;
}
int TexinfoForBrushTexture (plane_t *plane, brush_texture_t *bt, vec3_t origin)
{
vec3_t vecs[2];
int sv, tv;
vec_t ang, sinv, cosv;
vec_t ns, nt;
texinfo_t tx, *tc;
int i, j, k;
memset (&tx, 0, sizeof(tx));
tx.miptex = FindMiptex (bt->name);
// Note: FindMiptex() still needs to be called here to add it to the global miptex array
// Very Sleazy Hack 104 - since the tx.miptex index will be bogus after we sort the miptex array later
// Put the string name of the miptex in this "index" until after we are done sorting it in WriteMiptex().
tx.miptex = (int)strdup(bt->name);
// set the special flag
if (bt->name[0] == '*'
|| !Q_strncasecmp (bt->name, "sky",3)
|| !Q_strncasecmp (bt->name, "clip",4)
|| !Q_strncasecmp (bt->name, "origin",6)
|| !Q_strncasecmp (bt->name, "aaatrigger",10))
tx.flags |= TEX_SPECIAL;
if (g_nMapFileVersion < 220)
{
TextureAxisFromPlane(plane, vecs[0], vecs[1]);
}
if (!bt->scale[0])
bt->scale[0] = 1;
if (!bt->scale[1])
bt->scale[1] = 1;
if (g_nMapFileVersion < 220)
{
// rotate axis
if (bt->rotate == 0)
{ sinv = 0 ; cosv = 1; }
else if (bt->rotate == 90)
{ sinv = 1 ; cosv = 0; }
else if (bt->rotate == 180)
{ sinv = 0 ; cosv = -1; }
else if (bt->rotate == 270)
{ sinv = -1 ; cosv = 0; }
else
{
ang = bt->rotate / 180 * Q_PI;
sinv = sin(ang);
cosv = cos(ang);
}
if (vecs[0][0])
sv = 0;
else if (vecs[0][1])
sv = 1;
else
sv = 2;
if (vecs[1][0])
tv = 0;
else if (vecs[1][1])
tv = 1;
else
tv = 2;
for (i=0 ; i<2 ; i++)
{
ns = cosv * vecs[i][sv] - sinv * vecs[i][tv];
nt = sinv * vecs[i][sv] + cosv * vecs[i][tv];
vecs[i][sv] = ns;
vecs[i][tv] = nt;
}
for (i=0 ; i<2 ; i++)
for (j=0 ; j<3 ; j++)
tx.vecs[i][j] = vecs[i][j] / bt->scale[i];
}
else
{
tx.vecs[0][0] = bt->UAxis[0] / bt->scale[0];
tx.vecs[0][1] = bt->UAxis[1] / bt->scale[0];
tx.vecs[0][2] = bt->UAxis[2] / bt->scale[0];
tx.vecs[1][0] = bt->VAxis[0] / bt->scale[1];
tx.vecs[1][1] = bt->VAxis[1] / bt->scale[1];
tx.vecs[1][2] = bt->VAxis[2] / bt->scale[1];
}
tx.vecs[0][3] = bt->shift[0] + DotProduct( origin, tx.vecs[0] );
tx.vecs[1][3] = bt->shift[1] + DotProduct( origin, tx.vecs[1] );
//
// find the texinfo
//
ThreadLock ();
tc = texinfo;
for (i=0 ; i<numtexinfo ; i++, tc++)
{
// Sleazy hack 104, Pt 3 - Use strcmp on names to avoid dups
if ( strcmp( (char *)(tc->miptex), (char *)(tx.miptex)) != 0 )
continue;
if (tc->flags != tx.flags)
continue;
for (j=0 ; j<2 ; j++)
{
for (k=0 ; k<4 ; k++)
{
if (tc->vecs[j][k] != tx.vecs[j][k])
goto skip;
}
}
ThreadUnlock ();
return i;
skip:;
}
if (numtexinfo == MAX_MAP_TEXINFO)
Error ("Exceeded MAX_MAP_TEXINFO");
*tc = tx;
numtexinfo++;
ThreadUnlock ();
return i;
}