mirror of
https://github.com/id-Software/GtkRadiant.git
synced 2026-03-20 08:59:32 +01:00
The GtkRadiant sources as originally released under the GPL license.
This commit is contained in:
793
tools/quake2/qdata_heretic2/common/bspfile.c
Normal file
793
tools/quake2/qdata_heretic2/common/bspfile.c
Normal file
@@ -0,0 +1,793 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "inout.h"
|
||||
#include "mathlib.h"
|
||||
#include "bspfile.h"
|
||||
#include "scriplib.h"
|
||||
|
||||
void GetLeafNums (void);
|
||||
|
||||
//=============================================================================
|
||||
|
||||
int nummodels;
|
||||
dmodel_t dmodels[MAX_MAP_MODELS];
|
||||
|
||||
int visdatasize;
|
||||
byte dvisdata[MAX_MAP_VISIBILITY];
|
||||
dvis_t *dvis = (dvis_t *)dvisdata;
|
||||
|
||||
int lightdatasize;
|
||||
byte dlightdata[MAX_MAP_LIGHTING];
|
||||
|
||||
int entdatasize;
|
||||
char dentdata[MAX_MAP_ENTSTRING];
|
||||
|
||||
int numleafs;
|
||||
dleaf_t dleafs[MAX_MAP_LEAFS];
|
||||
|
||||
int numplanes;
|
||||
dplane_t dplanes[MAX_MAP_PLANES];
|
||||
|
||||
int numvertexes;
|
||||
dvertex_t dvertexes[MAX_MAP_VERTS];
|
||||
|
||||
int numnodes;
|
||||
dnode_t dnodes[MAX_MAP_NODES];
|
||||
|
||||
int numtexinfo;
|
||||
texinfo_t texinfo[MAX_MAP_TEXINFO];
|
||||
|
||||
int numfaces;
|
||||
dface_t dfaces[MAX_MAP_FACES];
|
||||
|
||||
int numedges;
|
||||
dedge_t dedges[MAX_MAP_EDGES];
|
||||
|
||||
int numleaffaces;
|
||||
unsigned short dleaffaces[MAX_MAP_LEAFFACES];
|
||||
|
||||
int numleafbrushes;
|
||||
unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
|
||||
int numsurfedges;
|
||||
int dsurfedges[MAX_MAP_SURFEDGES];
|
||||
|
||||
int numbrushes;
|
||||
dbrush_t dbrushes[MAX_MAP_BRUSHES];
|
||||
|
||||
int numbrushsides;
|
||||
dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES];
|
||||
|
||||
int numareas;
|
||||
darea_t dareas[MAX_MAP_AREAS];
|
||||
|
||||
int numareaportals;
|
||||
dareaportal_t dareaportals[MAX_MAP_AREAPORTALS];
|
||||
|
||||
byte dpop[256];
|
||||
|
||||
/*
|
||||
===============
|
||||
CompressVis
|
||||
|
||||
===============
|
||||
*/
|
||||
int CompressVis (byte *vis, byte *dest)
|
||||
{
|
||||
int j;
|
||||
int rep;
|
||||
int visrow;
|
||||
byte *dest_p;
|
||||
|
||||
dest_p = dest;
|
||||
// visrow = (r_numvisleafs + 7)>>3;
|
||||
visrow = (dvis->numclusters + 7)>>3;
|
||||
|
||||
for (j=0 ; j<visrow ; j++)
|
||||
{
|
||||
*dest_p++ = vis[j];
|
||||
if (vis[j])
|
||||
continue;
|
||||
|
||||
rep = 1;
|
||||
for ( j++; j<visrow ; j++)
|
||||
if (vis[j] || rep == 255)
|
||||
break;
|
||||
else
|
||||
rep++;
|
||||
*dest_p++ = rep;
|
||||
j--;
|
||||
}
|
||||
|
||||
return dest_p - dest;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================
|
||||
DecompressVis
|
||||
===================
|
||||
*/
|
||||
void DecompressVis (byte *in, byte *decompressed)
|
||||
{
|
||||
int c;
|
||||
byte *out;
|
||||
int row;
|
||||
|
||||
// row = (r_numvisleafs+7)>>3;
|
||||
row = (dvis->numclusters+7)>>3;
|
||||
out = decompressed;
|
||||
|
||||
do
|
||||
{
|
||||
if (*in)
|
||||
{
|
||||
*out++ = *in++;
|
||||
continue;
|
||||
}
|
||||
|
||||
c = in[1];
|
||||
if (!c)
|
||||
Error ("DecompressVis: 0 repeat");
|
||||
in += 2;
|
||||
while (c)
|
||||
{
|
||||
*out++ = 0;
|
||||
c--;
|
||||
}
|
||||
} while (out - decompressed < row);
|
||||
}
|
||||
|
||||
//=============================================================================
|
||||
|
||||
/*
|
||||
=============
|
||||
SwapBSPFile
|
||||
|
||||
Byte swaps all data in a bsp file.
|
||||
=============
|
||||
*/
|
||||
void SwapBSPFile (qboolean todisk)
|
||||
{
|
||||
int i, j;
|
||||
dmodel_t *d;
|
||||
|
||||
|
||||
// models
|
||||
for (i=0 ; i<nummodels ; i++)
|
||||
{
|
||||
d = &dmodels[i];
|
||||
|
||||
d->firstface = LittleLong (d->firstface);
|
||||
d->numfaces = LittleLong (d->numfaces);
|
||||
d->headnode = LittleLong (d->headnode);
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
d->mins[j] = LittleFloat(d->mins[j]);
|
||||
d->maxs[j] = LittleFloat(d->maxs[j]);
|
||||
d->origin[j] = LittleFloat(d->origin[j]);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// vertexes
|
||||
//
|
||||
for (i=0 ; i<numvertexes ; i++)
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
dvertexes[i].point[j] = LittleFloat (dvertexes[i].point[j]);
|
||||
}
|
||||
|
||||
//
|
||||
// planes
|
||||
//
|
||||
for (i=0 ; i<numplanes ; i++)
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
dplanes[i].normal[j] = LittleFloat (dplanes[i].normal[j]);
|
||||
dplanes[i].dist = LittleFloat (dplanes[i].dist);
|
||||
dplanes[i].type = LittleLong (dplanes[i].type);
|
||||
}
|
||||
|
||||
//
|
||||
// texinfos
|
||||
//
|
||||
for (i=0 ; i<numtexinfo ; i++)
|
||||
{
|
||||
for (j=0 ; j<8 ; j++)
|
||||
texinfo[i].vecs[0][j] = LittleFloat (texinfo[i].vecs[0][j]);
|
||||
texinfo[i].flags = LittleLong (texinfo[i].flags);
|
||||
texinfo[i].value = LittleLong (texinfo[i].value);
|
||||
texinfo[i].nexttexinfo = LittleLong (texinfo[i].nexttexinfo);
|
||||
}
|
||||
|
||||
//
|
||||
// faces
|
||||
//
|
||||
for (i=0 ; i<numfaces ; i++)
|
||||
{
|
||||
dfaces[i].texinfo = LittleShort (dfaces[i].texinfo);
|
||||
dfaces[i].planenum = LittleShort (dfaces[i].planenum);
|
||||
dfaces[i].side = LittleShort (dfaces[i].side);
|
||||
dfaces[i].lighting.c = LittleLong (dfaces[i].lighting.c);
|
||||
dfaces[i].lightofs = LittleLong (dfaces[i].lightofs);
|
||||
dfaces[i].firstedge = LittleLong (dfaces[i].firstedge);
|
||||
dfaces[i].numedges = LittleShort (dfaces[i].numedges);
|
||||
}
|
||||
|
||||
//
|
||||
// nodes
|
||||
//
|
||||
for (i=0 ; i<numnodes ; i++)
|
||||
{
|
||||
dnodes[i].planenum = LittleLong (dnodes[i].planenum);
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
dnodes[i].mins[j] = LittleShort (dnodes[i].mins[j]);
|
||||
dnodes[i].maxs[j] = LittleShort (dnodes[i].maxs[j]);
|
||||
}
|
||||
dnodes[i].children[0] = LittleLong (dnodes[i].children[0]);
|
||||
dnodes[i].children[1] = LittleLong (dnodes[i].children[1]);
|
||||
dnodes[i].firstface = LittleShort (dnodes[i].firstface);
|
||||
dnodes[i].numfaces = LittleShort (dnodes[i].numfaces);
|
||||
}
|
||||
|
||||
//
|
||||
// leafs
|
||||
//
|
||||
for (i=0 ; i<numleafs ; i++)
|
||||
{
|
||||
dleafs[i].contents = LittleLong (dleafs[i].contents);
|
||||
dleafs[i].cluster = LittleShort (dleafs[i].cluster);
|
||||
dleafs[i].area = LittleShort (dleafs[i].area);
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
dleafs[i].mins[j] = LittleShort (dleafs[i].mins[j]);
|
||||
dleafs[i].maxs[j] = LittleShort (dleafs[i].maxs[j]);
|
||||
}
|
||||
|
||||
dleafs[i].firstleafface = LittleShort (dleafs[i].firstleafface);
|
||||
dleafs[i].numleaffaces = LittleShort (dleafs[i].numleaffaces);
|
||||
dleafs[i].firstleafbrush = LittleShort (dleafs[i].firstleafbrush);
|
||||
dleafs[i].numleafbrushes = LittleShort (dleafs[i].numleafbrushes);
|
||||
}
|
||||
|
||||
//
|
||||
// leaffaces
|
||||
//
|
||||
for (i=0 ; i<numleaffaces ; i++)
|
||||
dleaffaces[i] = LittleShort (dleaffaces[i]);
|
||||
|
||||
//
|
||||
// leafbrushes
|
||||
//
|
||||
for (i=0 ; i<numleafbrushes ; i++)
|
||||
dleafbrushes[i] = LittleShort (dleafbrushes[i]);
|
||||
|
||||
//
|
||||
// surfedges
|
||||
//
|
||||
for (i=0 ; i<numsurfedges ; i++)
|
||||
dsurfedges[i] = LittleLong (dsurfedges[i]);
|
||||
|
||||
//
|
||||
// edges
|
||||
//
|
||||
for (i=0 ; i<numedges ; i++)
|
||||
{
|
||||
dedges[i].v[0] = LittleShort (dedges[i].v[0]);
|
||||
dedges[i].v[1] = LittleShort (dedges[i].v[1]);
|
||||
}
|
||||
|
||||
//
|
||||
// brushes
|
||||
//
|
||||
for (i=0 ; i<numbrushes ; i++)
|
||||
{
|
||||
dbrushes[i].firstside = LittleLong (dbrushes[i].firstside);
|
||||
dbrushes[i].numsides = LittleLong (dbrushes[i].numsides);
|
||||
dbrushes[i].contents = LittleLong (dbrushes[i].contents);
|
||||
}
|
||||
|
||||
//
|
||||
// areas
|
||||
//
|
||||
for (i=0 ; i<numareas ; i++)
|
||||
{
|
||||
dareas[i].numareaportals = LittleLong (dareas[i].numareaportals);
|
||||
dareas[i].firstareaportal = LittleLong (dareas[i].firstareaportal);
|
||||
}
|
||||
|
||||
//
|
||||
// areasportals
|
||||
//
|
||||
for (i=0 ; i<numareaportals ; i++)
|
||||
{
|
||||
dareaportals[i].portalnum = LittleLong (dareaportals[i].portalnum);
|
||||
dareaportals[i].otherarea = LittleLong (dareaportals[i].otherarea);
|
||||
}
|
||||
|
||||
//
|
||||
// brushsides
|
||||
//
|
||||
for (i=0 ; i<numbrushsides ; i++)
|
||||
{
|
||||
dbrushsides[i].planenum = LittleShort (dbrushsides[i].planenum);
|
||||
dbrushsides[i].texinfo = LittleShort (dbrushsides[i].texinfo);
|
||||
}
|
||||
|
||||
//
|
||||
// visibility
|
||||
//
|
||||
if (todisk)
|
||||
j = dvis->numclusters;
|
||||
else
|
||||
j = LittleLong(dvis->numclusters);
|
||||
dvis->numclusters = LittleLong (dvis->numclusters);
|
||||
for (i=0 ; i<j ; i++)
|
||||
{
|
||||
dvis->bitofs[i][0] = LittleLong (dvis->bitofs[i][0]);
|
||||
dvis->bitofs[i][1] = LittleLong (dvis->bitofs[i][1]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dheader_t *header;
|
||||
|
||||
int CopyLump (int lump, void *dest, int size)
|
||||
{
|
||||
int length, ofs;
|
||||
|
||||
length = header->lumps[lump].filelen;
|
||||
ofs = header->lumps[lump].fileofs;
|
||||
|
||||
if (length % size)
|
||||
Error ("LoadBSPFile: odd lump size");
|
||||
|
||||
memcpy (dest, (byte *)header + ofs, length);
|
||||
|
||||
return length / size;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
LoadBSPFile
|
||||
=============
|
||||
*/
|
||||
void LoadBSPFile (char *filename)
|
||||
{
|
||||
int i;
|
||||
|
||||
//
|
||||
// load the file header
|
||||
//
|
||||
LoadFile (filename, (void **)&header);
|
||||
|
||||
// swap the header
|
||||
for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
|
||||
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
|
||||
|
||||
if (header->ident != IDBSPHEADER)
|
||||
Error ("%s is not a IBSP file", filename);
|
||||
if (header->version != BSPVERSION)
|
||||
Error ("%s is version %i, not %i", filename, header->version, BSPVERSION);
|
||||
|
||||
nummodels = CopyLump (LUMP_MODELS, dmodels, sizeof(dmodel_t));
|
||||
numvertexes = CopyLump (LUMP_VERTEXES, dvertexes, sizeof(dvertex_t));
|
||||
numplanes = CopyLump (LUMP_PLANES, dplanes, sizeof(dplane_t));
|
||||
numleafs = CopyLump (LUMP_LEAFS, dleafs, sizeof(dleaf_t));
|
||||
numnodes = CopyLump (LUMP_NODES, dnodes, sizeof(dnode_t));
|
||||
numtexinfo = CopyLump (LUMP_TEXINFO, texinfo, sizeof(texinfo_t));
|
||||
numfaces = CopyLump (LUMP_FACES, dfaces, sizeof(dface_t));
|
||||
numleaffaces = CopyLump (LUMP_LEAFFACES, dleaffaces, sizeof(dleaffaces[0]));
|
||||
numleafbrushes = CopyLump (LUMP_LEAFBRUSHES, dleafbrushes, sizeof(dleafbrushes[0]));
|
||||
numsurfedges = CopyLump (LUMP_SURFEDGES, dsurfedges, sizeof(dsurfedges[0]));
|
||||
numedges = CopyLump (LUMP_EDGES, dedges, sizeof(dedge_t));
|
||||
numbrushes = CopyLump (LUMP_BRUSHES, dbrushes, sizeof(dbrush_t));
|
||||
numbrushsides = CopyLump (LUMP_BRUSHSIDES, dbrushsides, sizeof(dbrushside_t));
|
||||
numareas = CopyLump (LUMP_AREAS, dareas, sizeof(darea_t));
|
||||
numareaportals = CopyLump (LUMP_AREAPORTALS, dareaportals, sizeof(dareaportal_t));
|
||||
|
||||
visdatasize = CopyLump (LUMP_VISIBILITY, dvisdata, 1);
|
||||
lightdatasize = CopyLump (LUMP_LIGHTING, dlightdata, 1);
|
||||
entdatasize = CopyLump (LUMP_ENTITIES, dentdata, 1);
|
||||
|
||||
CopyLump (LUMP_POP, dpop, 1);
|
||||
|
||||
free (header); // everything has been copied out
|
||||
|
||||
//
|
||||
// swap everything
|
||||
//
|
||||
SwapBSPFile (false);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
LoadBSPFileTexinfo
|
||||
|
||||
Only loads the texinfo lump, so qdata can scan for textures
|
||||
=============
|
||||
*/
|
||||
void LoadBSPFileTexinfo (char *filename)
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
int length, ofs;
|
||||
|
||||
header = malloc(sizeof(dheader_t));
|
||||
|
||||
f = fopen (filename, "rb");
|
||||
fread (header, sizeof(dheader_t), 1, f);
|
||||
|
||||
// swap the header
|
||||
for (i=0 ; i< sizeof(dheader_t)/4 ; i++)
|
||||
((int *)header)[i] = LittleLong ( ((int *)header)[i]);
|
||||
|
||||
if (header->ident != IDBSPHEADER)
|
||||
Error ("%s is not a IBSP file", filename);
|
||||
if (header->version != BSPVERSION)
|
||||
Error ("%s is version %i, not %i", filename, header->version, BSPVERSION);
|
||||
|
||||
|
||||
length = header->lumps[LUMP_TEXINFO].filelen;
|
||||
ofs = header->lumps[LUMP_TEXINFO].fileofs;
|
||||
|
||||
fseek (f, ofs, SEEK_SET);
|
||||
fread (texinfo, length, 1, f);
|
||||
fclose (f);
|
||||
|
||||
numtexinfo = length / sizeof(texinfo_t);
|
||||
|
||||
free (header); // everything has been copied out
|
||||
|
||||
SwapBSPFile (false);
|
||||
}
|
||||
|
||||
|
||||
//============================================================================
|
||||
|
||||
FILE *wadfile;
|
||||
dheader_t outheader;
|
||||
|
||||
void AddLump (int lumpnum, void *data, int len)
|
||||
{
|
||||
lump_t *lump;
|
||||
|
||||
lump = &header->lumps[lumpnum];
|
||||
|
||||
lump->fileofs = LittleLong( ftell(wadfile) );
|
||||
lump->filelen = LittleLong(len);
|
||||
SafeWrite (wadfile, data, (len+3)&~3);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
WriteBSPFile
|
||||
|
||||
Swaps the bsp file in place, so it should not be referenced again
|
||||
=============
|
||||
*/
|
||||
void WriteBSPFile (char *filename)
|
||||
{
|
||||
header = &outheader;
|
||||
memset (header, 0, sizeof(dheader_t));
|
||||
|
||||
SwapBSPFile (true);
|
||||
|
||||
header->ident = LittleLong (IDBSPHEADER);
|
||||
header->version = LittleLong (BSPVERSION);
|
||||
|
||||
wadfile = SafeOpenWrite (filename);
|
||||
SafeWrite (wadfile, header, sizeof(dheader_t)); // overwritten later
|
||||
|
||||
AddLump (LUMP_PLANES, dplanes, numplanes*sizeof(dplane_t));
|
||||
AddLump (LUMP_LEAFS, dleafs, numleafs*sizeof(dleaf_t));
|
||||
AddLump (LUMP_VERTEXES, dvertexes, numvertexes*sizeof(dvertex_t));
|
||||
AddLump (LUMP_NODES, dnodes, numnodes*sizeof(dnode_t));
|
||||
AddLump (LUMP_TEXINFO, texinfo, numtexinfo*sizeof(texinfo_t));
|
||||
AddLump (LUMP_FACES, dfaces, numfaces*sizeof(dface_t));
|
||||
AddLump (LUMP_BRUSHES, dbrushes, numbrushes*sizeof(dbrush_t));
|
||||
AddLump (LUMP_BRUSHSIDES, dbrushsides, numbrushsides*sizeof(dbrushside_t));
|
||||
AddLump (LUMP_LEAFFACES, dleaffaces, numleaffaces*sizeof(dleaffaces[0]));
|
||||
AddLump (LUMP_LEAFBRUSHES, dleafbrushes, numleafbrushes*sizeof(dleafbrushes[0]));
|
||||
AddLump (LUMP_SURFEDGES, dsurfedges, numsurfedges*sizeof(dsurfedges[0]));
|
||||
AddLump (LUMP_EDGES, dedges, numedges*sizeof(dedge_t));
|
||||
AddLump (LUMP_MODELS, dmodels, nummodels*sizeof(dmodel_t));
|
||||
AddLump (LUMP_AREAS, dareas, numareas*sizeof(darea_t));
|
||||
AddLump (LUMP_AREAPORTALS, dareaportals, numareaportals*sizeof(dareaportal_t));
|
||||
|
||||
AddLump (LUMP_LIGHTING, dlightdata, lightdatasize);
|
||||
AddLump (LUMP_VISIBILITY, dvisdata, visdatasize);
|
||||
AddLump (LUMP_ENTITIES, dentdata, entdatasize);
|
||||
AddLump (LUMP_POP, dpop, sizeof(dpop));
|
||||
|
||||
fseek (wadfile, 0, SEEK_SET);
|
||||
SafeWrite (wadfile, header, sizeof(dheader_t));
|
||||
fclose (wadfile);
|
||||
}
|
||||
|
||||
//============================================================================
|
||||
|
||||
/*
|
||||
=============
|
||||
PrintBSPFileSizes
|
||||
|
||||
Dumps info about current file
|
||||
=============
|
||||
*/
|
||||
void PrintBSPFileSizes (void)
|
||||
{
|
||||
if (!num_entities)
|
||||
ParseEntities ();
|
||||
|
||||
printf ("%5i models %7i\n"
|
||||
,nummodels, (int)(nummodels*sizeof(dmodel_t)));
|
||||
printf ("%5i brushes %7i\n"
|
||||
,numbrushes, (int)(numbrushes*sizeof(dbrush_t)));
|
||||
printf ("%5i brushsides %7i\n"
|
||||
,numbrushsides, (int)(numbrushsides*sizeof(dbrushside_t)));
|
||||
printf ("%5i planes %7i\n"
|
||||
,numplanes, (int)(numplanes*sizeof(dplane_t)));
|
||||
printf ("%5i texinfo %7i\n"
|
||||
,numtexinfo, (int)(numtexinfo*sizeof(texinfo_t)));
|
||||
printf ("%5i entdata %7i\n", num_entities, entdatasize);
|
||||
|
||||
printf ("\n");
|
||||
|
||||
printf ("%5i vertexes %7i\n"
|
||||
,numvertexes, (int)(numvertexes*sizeof(dvertex_t)));
|
||||
printf ("%5i nodes %7i\n"
|
||||
,numnodes, (int)(numnodes*sizeof(dnode_t)));
|
||||
printf ("%5i faces %7i\n"
|
||||
,numfaces, (int)(numfaces*sizeof(dface_t)));
|
||||
printf ("%5i leafs %7i\n"
|
||||
,numleafs, (int)(numleafs*sizeof(dleaf_t)));
|
||||
printf ("%5i leaffaces %7i\n"
|
||||
,numleaffaces, (int)(numleaffaces*sizeof(dleaffaces[0])));
|
||||
printf ("%5i leafbrushes %7i\n"
|
||||
,numleafbrushes, (int)(numleafbrushes*sizeof(dleafbrushes[0])));
|
||||
printf ("%5i surfedges %7i\n"
|
||||
,numsurfedges, (int)(numsurfedges*sizeof(dsurfedges[0])));
|
||||
printf ("%5i edges %7i\n"
|
||||
,numedges, (int)(numedges*sizeof(dedge_t)));
|
||||
printf (" lightdata %7i\n", lightdatasize);
|
||||
printf (" visdata %7i\n", visdatasize);
|
||||
}
|
||||
|
||||
|
||||
//============================================
|
||||
|
||||
int num_entities;
|
||||
entity_t entities[MAX_MAP_ENTITIES];
|
||||
|
||||
void StripTrailing (char *e)
|
||||
{
|
||||
char *s;
|
||||
|
||||
s = e + strlen(e)-1;
|
||||
while (s >= e && *s <= 32)
|
||||
{
|
||||
*s = 0;
|
||||
s--;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
ParseEpair
|
||||
=================
|
||||
*/
|
||||
epair_t *ParseEpair (void)
|
||||
{
|
||||
epair_t *e;
|
||||
|
||||
e = malloc (sizeof(epair_t));
|
||||
memset (e, 0, sizeof(epair_t));
|
||||
|
||||
if (strlen(token) >= MAX_KEY-1)
|
||||
Error ("ParseEpar: token too long");
|
||||
e->key = copystring(token);
|
||||
GetScriptToken (false);
|
||||
if (strlen(token) >= MAX_VALUE-1)
|
||||
Error ("ParseEpar: token too long");
|
||||
e->value = copystring(token);
|
||||
|
||||
// strip trailing spaces
|
||||
StripTrailing (e->key);
|
||||
StripTrailing (e->value);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
ParseEntity
|
||||
================
|
||||
*/
|
||||
qboolean ParseEntity (void)
|
||||
{
|
||||
epair_t *e;
|
||||
entity_t *mapent;
|
||||
|
||||
if (!GetScriptToken (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++;
|
||||
|
||||
do
|
||||
{
|
||||
if (!GetScriptToken (true))
|
||||
Error ("ParseEntity: EOF without closing brace");
|
||||
if (!strcmp (token, "}") )
|
||||
break;
|
||||
e = ParseEpair ();
|
||||
e->next = mapent->epairs;
|
||||
mapent->epairs = e;
|
||||
} while (1);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
================
|
||||
ParseEntities
|
||||
|
||||
Parses the dentdata string into entities
|
||||
================
|
||||
*/
|
||||
void ParseEntities (void)
|
||||
{
|
||||
num_entities = 0;
|
||||
ParseFromMemory (dentdata, entdatasize);
|
||||
|
||||
while (ParseEntity ())
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
================
|
||||
UnparseEntities
|
||||
|
||||
Generates the dentdata string from all the entities
|
||||
================
|
||||
*/
|
||||
void UnparseEntities (void)
|
||||
{
|
||||
char *buf, *end;
|
||||
epair_t *ep;
|
||||
char line[2048];
|
||||
int i;
|
||||
char key[1024], value[1024];
|
||||
|
||||
buf = dentdata;
|
||||
end = buf;
|
||||
*end = 0;
|
||||
|
||||
for (i=0 ; i<num_entities ; i++)
|
||||
{
|
||||
ep = entities[i].epairs;
|
||||
if (!ep)
|
||||
continue; // ent got removed
|
||||
|
||||
strcat (end,"{\n");
|
||||
end += 2;
|
||||
|
||||
for (ep = entities[i].epairs ; ep ; ep=ep->next)
|
||||
{
|
||||
strcpy (key, ep->key);
|
||||
StripTrailing (key);
|
||||
strcpy (value, ep->value);
|
||||
StripTrailing (value);
|
||||
|
||||
sprintf (line, "\"%s\" \"%s\"\n", key, value);
|
||||
strcat (end, line);
|
||||
end += strlen(line);
|
||||
}
|
||||
strcat (end,"}\n");
|
||||
end += 2;
|
||||
|
||||
if (end > buf + MAX_MAP_ENTSTRING)
|
||||
Error ("Entity text too long");
|
||||
}
|
||||
entdatasize = end - buf + 1;
|
||||
}
|
||||
|
||||
void PrintEntity (entity_t *ent)
|
||||
{
|
||||
epair_t *ep;
|
||||
|
||||
printf ("------- entity %p -------\n", ent);
|
||||
for (ep=ent->epairs ; ep ; ep=ep->next)
|
||||
{
|
||||
printf ("%s = %s\n", ep->key, ep->value);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void SetKeyValue (entity_t *ent, char *key, char *value)
|
||||
{
|
||||
epair_t *ep;
|
||||
|
||||
for (ep=ent->epairs ; ep ; ep=ep->next)
|
||||
if (!strcmp (ep->key, key) )
|
||||
{
|
||||
free (ep->value);
|
||||
ep->value = copystring(value);
|
||||
return;
|
||||
}
|
||||
ep = malloc (sizeof(*ep));
|
||||
if (!ep)
|
||||
Error("SetKeyValue MALLOC failed! Could not allocate %s bytes.", sizeof(*ep));
|
||||
ep->next = ent->epairs;
|
||||
ent->epairs = ep;
|
||||
ep->key = copystring(key);
|
||||
ep->value = copystring(value);
|
||||
}
|
||||
|
||||
char *ValueForKey (entity_t *ent, char *key)
|
||||
{
|
||||
epair_t *ep;
|
||||
|
||||
for (ep=ent->epairs ; ep ; ep=ep->next)
|
||||
if (!strcmp (ep->key, key) )
|
||||
return ep->value;
|
||||
return "";
|
||||
}
|
||||
|
||||
vec_t FloatForKey (entity_t *ent, char *key)
|
||||
{
|
||||
char *k;
|
||||
|
||||
k = ValueForKey (ent, key);
|
||||
return atof(k);
|
||||
}
|
||||
|
||||
void GetVectorForKey (entity_t *ent, char *key, vec3_t vec)
|
||||
{
|
||||
char *k;
|
||||
double v1, v2, v3;
|
||||
|
||||
k = ValueForKey (ent, key);
|
||||
// scanf into doubles, then assign, so it is vec_t size independent
|
||||
v1 = v2 = v3 = 0;
|
||||
sscanf (k, "%lf %lf %lf", &v1, &v2, &v3);
|
||||
vec[0] = v1;
|
||||
vec[1] = v2;
|
||||
vec[2] = v3;
|
||||
}
|
||||
|
||||
|
||||
133
tools/quake2/qdata_heretic2/common/bspfile.h
Normal file
133
tools/quake2/qdata_heretic2/common/bspfile.h
Normal file
@@ -0,0 +1,133 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _QBSP3_H
|
||||
#define _QBSP3_H
|
||||
|
||||
|
||||
#include "qfiles.h"
|
||||
|
||||
|
||||
extern int nummodels;
|
||||
extern dmodel_t dmodels[MAX_MAP_MODELS];
|
||||
|
||||
extern int visdatasize;
|
||||
extern byte dvisdata[MAX_MAP_VISIBILITY];
|
||||
extern dvis_t *dvis;
|
||||
|
||||
extern int lightdatasize;
|
||||
extern byte dlightdata[MAX_MAP_LIGHTING];
|
||||
|
||||
extern int entdatasize;
|
||||
extern char dentdata[MAX_MAP_ENTSTRING];
|
||||
|
||||
extern int numleafs;
|
||||
extern dleaf_t dleafs[MAX_MAP_LEAFS];
|
||||
|
||||
extern int numplanes;
|
||||
extern dplane_t dplanes[MAX_MAP_PLANES];
|
||||
|
||||
extern int numvertexes;
|
||||
extern dvertex_t dvertexes[MAX_MAP_VERTS];
|
||||
|
||||
extern int numnodes;
|
||||
extern dnode_t dnodes[MAX_MAP_NODES];
|
||||
|
||||
extern int numtexinfo;
|
||||
extern texinfo_t texinfo[MAX_MAP_TEXINFO];
|
||||
|
||||
extern int numfaces;
|
||||
extern dface_t dfaces[MAX_MAP_FACES];
|
||||
|
||||
extern int numedges;
|
||||
extern dedge_t dedges[MAX_MAP_EDGES];
|
||||
|
||||
extern int numleaffaces;
|
||||
extern unsigned short dleaffaces[MAX_MAP_LEAFFACES];
|
||||
|
||||
extern int numleafbrushes;
|
||||
extern unsigned short dleafbrushes[MAX_MAP_LEAFBRUSHES];
|
||||
|
||||
extern int numsurfedges;
|
||||
extern int dsurfedges[MAX_MAP_SURFEDGES];
|
||||
|
||||
extern int numareas;
|
||||
extern darea_t dareas[MAX_MAP_AREAS];
|
||||
|
||||
extern int numareaportals;
|
||||
extern dareaportal_t dareaportals[MAX_MAP_AREAPORTALS];
|
||||
|
||||
extern int numbrushes;
|
||||
extern dbrush_t dbrushes[MAX_MAP_BRUSHES];
|
||||
|
||||
extern int numbrushsides;
|
||||
extern dbrushside_t dbrushsides[MAX_MAP_BRUSHSIDES];
|
||||
|
||||
extern byte dpop[256];
|
||||
|
||||
void DecompressVis (byte *in, byte *decompressed);
|
||||
int CompressVis (byte *vis, byte *dest);
|
||||
|
||||
void LoadBSPFile (char *filename);
|
||||
void LoadBSPFileTexinfo (char *filename); // just for qdata
|
||||
void WriteBSPFile (char *filename);
|
||||
void PrintBSPFileSizes (void);
|
||||
|
||||
//===============
|
||||
|
||||
|
||||
typedef struct epair_s
|
||||
{
|
||||
struct epair_s *next;
|
||||
char *key;
|
||||
char *value;
|
||||
} epair_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t origin;
|
||||
int firstbrush;
|
||||
int numbrushes;
|
||||
epair_t *epairs;
|
||||
|
||||
// only valid for func_areaportals
|
||||
int areaportalnum;
|
||||
int portalareas[2];
|
||||
} entity_t;
|
||||
|
||||
extern int num_entities;
|
||||
extern entity_t entities[MAX_MAP_ENTITIES];
|
||||
|
||||
void ParseEntities (void);
|
||||
void UnparseEntities (void);
|
||||
|
||||
void SetKeyValue (entity_t *ent, char *key, char *value);
|
||||
char *ValueForKey (entity_t *ent, char *key);
|
||||
// will return "" if not present
|
||||
|
||||
vec_t FloatForKey (entity_t *ent, char *key);
|
||||
void GetVectorForKey (entity_t *ent, char *key, vec3_t vec);
|
||||
|
||||
epair_t *ParseEpair (void);
|
||||
|
||||
void PrintEntity (entity_t *ent);
|
||||
|
||||
#endif //_QBSP3_H
|
||||
1238
tools/quake2/qdata_heretic2/common/cmdlib.c
Normal file
1238
tools/quake2/qdata_heretic2/common/cmdlib.c
Normal file
File diff suppressed because it is too large
Load Diff
177
tools/quake2/qdata_heretic2/common/cmdlib.h
Normal file
177
tools/quake2/qdata_heretic2/common/cmdlib.h
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// cmdlib.h
|
||||
|
||||
#ifndef __CMDLIB__
|
||||
#define __CMDLIB__
|
||||
|
||||
#ifdef _WIN32
|
||||
#pragma warning(disable : 4244) // MIPS
|
||||
#pragma warning(disable : 4136) // X86
|
||||
#pragma warning(disable : 4051) // ALPHA
|
||||
|
||||
#pragma warning(disable : 4018) // signed/unsigned mismatch
|
||||
#pragma warning(disable : 4305) // truncate from double to float
|
||||
|
||||
#pragma check_stack(off)
|
||||
|
||||
#endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#pragma intrinsic( memset, memcpy )
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef __BYTEBOOL__
|
||||
#define __BYTEBOOL__
|
||||
//typedef enum {false, true} qboolean;
|
||||
//typedef unsigned char byte;
|
||||
#include "q_typedef.h"
|
||||
#endif
|
||||
|
||||
#define MAX_OS_PATH 1024
|
||||
#define MEM_BLOCKSIZE 4096
|
||||
/*
|
||||
extern qboolean verbose;
|
||||
#define SYS_VRB 0 // verbose support (on/off)
|
||||
#define SYS_STD 1 // standard print level
|
||||
#define SYS_WRN 2 // warnings
|
||||
#define SYS_ERR 3 // error
|
||||
*/
|
||||
// the dec offsetof macro doesnt work very well...
|
||||
#define myoffsetof(type,identifier) ((size_t)&((type *)0)->identifier)
|
||||
|
||||
#define SAFE_MALLOC
|
||||
#ifdef SAFE_MALLOC
|
||||
void *safe_malloc( size_t size );
|
||||
void *safe_malloc_info( size_t size, char* info );
|
||||
#else
|
||||
#define safe_malloc(a) malloc(a)
|
||||
#endif /* SAFE_MALLOC */
|
||||
|
||||
// set these before calling CheckParm
|
||||
extern int myargc;
|
||||
extern char **myargv;
|
||||
|
||||
char *strlower (char *in);
|
||||
int Q_strncasecmp( const char *s1, const char *s2, int n );
|
||||
int Q_stricmp( const char *s1, const char *s2 );
|
||||
int Q_strcasecmp( const char *s1, const char *s2 );
|
||||
void Q_getwd( char *out );
|
||||
|
||||
int Q_filelength (FILE *f);
|
||||
int FileTime( const char *path );
|
||||
|
||||
void Q_mkdir( const char *path );
|
||||
|
||||
extern char qdir[1024];
|
||||
extern char gamedir[1024];
|
||||
extern char writedir[1024];
|
||||
extern char *moddirparam;
|
||||
void SetQdirFromPath( const char *path);
|
||||
char *ExpandArg( const char *path ); // from cmd line
|
||||
char *ExpandPath( const char *path ); // from scripts
|
||||
char *ExpandGamePath (const char *path);
|
||||
char *ExpandPathAndArchive( const char *path );
|
||||
void ExpandWildcards( int *argc, char ***argv );
|
||||
|
||||
|
||||
double I_FloatTime( void );
|
||||
|
||||
int CheckParm( const char *check );
|
||||
|
||||
void *SafeMalloc(size_t n, char *desc);
|
||||
FILE *SafeOpenWrite( const char *filename );
|
||||
FILE *SafeOpenRead( const char *filename );
|
||||
void SafeRead (FILE *f, void *buffer, int count);
|
||||
void SafeWrite (FILE *f, const void *buffer, int count);
|
||||
|
||||
int LoadFile( const char *filename, void **bufferptr );
|
||||
int LoadFileBlock( const char *filename, void **bufferptr );
|
||||
int TryLoadFile( const char *filename, void **bufferptr );
|
||||
void SaveFile( const char *filename, const void *buffer, int count );
|
||||
qboolean FileExists( const char *filename );
|
||||
|
||||
void DefaultExtension( char *path, const char *extension );
|
||||
void DefaultPath( char *path, const char *basepath );
|
||||
void StripFilename( char *path );
|
||||
void StripExtension( char *path );
|
||||
|
||||
void ExtractFilePath( const char *path, char *dest );
|
||||
void ExtractFileBase( const char *path, char *dest );
|
||||
void ExtractFileExtension( const char *path, char *dest );
|
||||
|
||||
int ParseNum (const char *str);
|
||||
/*
|
||||
void Sys_Printf (const char *text, ...);
|
||||
void Sys_FPrintf (int flag, const char *text, ...);
|
||||
void Error( const char *error, ... );
|
||||
*/
|
||||
short BigShort (short l);
|
||||
short LittleShort (short l);
|
||||
int BigLong (int l);
|
||||
int LittleLong (int l);
|
||||
float BigFloat (float l);
|
||||
float LittleFloat (float l);
|
||||
|
||||
|
||||
char *COM_Parse (char *data);
|
||||
|
||||
extern char com_token[1024];
|
||||
extern qboolean com_eof;
|
||||
|
||||
char *copystring(const char *s);
|
||||
|
||||
|
||||
void CRC_Init(unsigned short *crcvalue);
|
||||
void CRC_ProcessByte(unsigned short *crcvalue, byte data);
|
||||
unsigned short CRC_Value(unsigned short crcvalue);
|
||||
|
||||
void CreatePath( const char *path );
|
||||
void QCopyFile( const char *from, const char *to );
|
||||
|
||||
extern qboolean archive;
|
||||
extern char archivedir[1024];
|
||||
|
||||
extern qboolean g_dokeypress;
|
||||
|
||||
// sleep for the given amount of milliseconds
|
||||
void Sys_Sleep(int n);
|
||||
|
||||
// for compression routines
|
||||
typedef struct
|
||||
{
|
||||
byte *data;
|
||||
int count;
|
||||
} cblock_t;
|
||||
|
||||
|
||||
#endif
|
||||
35
tools/quake2/qdata_heretic2/common/her2_threads.h
Normal file
35
tools/quake2/qdata_heretic2/common/her2_threads.h
Normal file
@@ -0,0 +1,35 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
#ifndef _THREADS_H
|
||||
|
||||
#define _THREADS_H
|
||||
|
||||
|
||||
extern int numthreads;
|
||||
|
||||
void ThreadSetDefault (void);
|
||||
int GetThreadWork (void);
|
||||
void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int));
|
||||
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int));
|
||||
void ThreadLock (void);
|
||||
void ThreadUnlock (void);
|
||||
|
||||
#endif //_THREADS_H
|
||||
367
tools/quake2/qdata_heretic2/common/inout.c
Normal file
367
tools/quake2/qdata_heretic2/common/inout.c
Normal file
@@ -0,0 +1,367 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//
|
||||
//
|
||||
// DESCRIPTION:
|
||||
// deal with in/out tasks, for either stdin/stdout or network/XML stream
|
||||
//
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "mathlib.h"
|
||||
#include "polylib.h"
|
||||
#include "inout.h"
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#ifdef WIN32
|
||||
#include <direct.h>
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
// network broadcasting
|
||||
#include "l_net/l_net.h"
|
||||
#include "libxml/tree.h"
|
||||
|
||||
#ifdef WIN32
|
||||
HWND hwndOut = NULL;
|
||||
qboolean lookedForServer = false;
|
||||
UINT wm_BroadcastCommand = -1;
|
||||
#endif
|
||||
|
||||
socket_t *brdcst_socket;
|
||||
netmessage_t msg;
|
||||
|
||||
qboolean verbose = false;
|
||||
|
||||
// our main document
|
||||
// is streamed through the network to Radiant
|
||||
// possibly written to disk at the end of the run
|
||||
//++timo FIXME: need to be global, required when creating nodes?
|
||||
xmlDocPtr doc;
|
||||
xmlNodePtr tree;
|
||||
|
||||
// some useful stuff
|
||||
xmlNodePtr xml_NodeForVec( vec3_t v )
|
||||
{
|
||||
xmlNodePtr ret;
|
||||
char buf[1024];
|
||||
|
||||
sprintf (buf, "%f %f %f", v[0], v[1], v[2]);
|
||||
ret = xmlNewNode (NULL, "point");
|
||||
xmlNodeSetContent (ret, buf);
|
||||
return ret;
|
||||
}
|
||||
|
||||
// send a node down the stream, add it to the document
|
||||
void xml_SendNode (xmlNodePtr node)
|
||||
{
|
||||
xmlBufferPtr xml_buf;
|
||||
char xmlbuf[MAX_NETMESSAGE]; // we have to copy content from the xmlBufferPtr into an aux buffer .. that sucks ..
|
||||
// this index loops through the node buffer
|
||||
int pos = 0;
|
||||
int size;
|
||||
|
||||
xmlAddChild( doc->children, node );
|
||||
|
||||
if (brdcst_socket)
|
||||
{
|
||||
xml_buf = xmlBufferCreate();
|
||||
xmlNodeDump( xml_buf, doc, node, 0, 0 );
|
||||
|
||||
// the XML node might be too big to fit in a single network message
|
||||
// l_net library defines an upper limit of MAX_NETMESSAGE
|
||||
// there are some size check errors, so we use MAX_NETMESSAGE-10 to be safe
|
||||
// if the size of the buffer exceeds MAX_NETMESSAGE-10 we'll send in several network messages
|
||||
while (pos < xml_buf->use)
|
||||
{
|
||||
// what size are we gonna send now?
|
||||
(xml_buf->use - pos < MAX_NETMESSAGE - 10) ? (size = xml_buf->use - pos) : (size = MAX_NETMESSAGE - 10);
|
||||
//++timo just a debug thing
|
||||
if (size == MAX_NETMESSAGE - 10)
|
||||
Sys_FPrintf (SYS_NOXML, "Got to split the buffer\n");
|
||||
memcpy( xmlbuf, xml_buf->content+pos, size);
|
||||
xmlbuf[size] = '\0';
|
||||
NMSG_Clear( &msg );
|
||||
NMSG_WriteString (&msg, xmlbuf );
|
||||
Net_Send(brdcst_socket, &msg );
|
||||
// now that the thing is sent prepare to loop again
|
||||
pos += size;
|
||||
}
|
||||
|
||||
#if 0
|
||||
// NOTE: the NMSG_WriteString is limited to MAX_NETMESSAGE
|
||||
// we will need to split into chunks
|
||||
// (we could also go lower level, in the end it's using send and receiv which are not size limited)
|
||||
//++timo FIXME: MAX_NETMESSAGE is not exactly the max size we can stick in the message
|
||||
// there's some tweaking to do in l_net for that .. so let's give us a margin for now
|
||||
|
||||
//++timo we need to handle the case of a buffer too big to fit in a single message
|
||||
// try without checks for now
|
||||
if (xml_buf->use > MAX_NETMESSAGE-10 )
|
||||
{
|
||||
// if we send that we are probably gonna break the stream at the other end..
|
||||
// and Error will call right there
|
||||
//Error( "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use);
|
||||
Sys_FPrintf (SYS_NOXML, "MAX_NETMESSAGE exceeded for XML feedback stream in FPrintf (%d)\n", xml_buf->use);
|
||||
xml_buf->content[xml_buf->use]='\0'; //++timo this corrupts the buffer but we don't care it's for printing
|
||||
Sys_FPrintf (SYS_NOXML, xml_buf->content);
|
||||
|
||||
}
|
||||
|
||||
size = xml_buf->use;
|
||||
memcpy( xmlbuf, xml_buf->content, size );
|
||||
xmlbuf[size] = '\0';
|
||||
NMSG_Clear( &msg );
|
||||
NMSG_WriteString (&msg, xmlbuf );
|
||||
Net_Send(brdcst_socket, &msg );
|
||||
#endif
|
||||
|
||||
xmlBufferFree( xml_buf );
|
||||
}
|
||||
}
|
||||
|
||||
void xml_Select (char *msg, int entitynum, int brushnum, qboolean bError)
|
||||
{
|
||||
xmlNodePtr node, select;
|
||||
char buf[1024];
|
||||
char level[2];
|
||||
|
||||
// now build a proper "select" XML node
|
||||
sprintf (buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg);
|
||||
node = xmlNewNode (NULL, "select");
|
||||
xmlNodeSetContent (node, buf);
|
||||
level[0] = (int)'0' + (bError ? SYS_ERR : SYS_WRN) ;
|
||||
level[1] = 0;
|
||||
xmlSetProp (node, "level", (char *)&level);
|
||||
// a 'select' information
|
||||
sprintf (buf, "%i %i", entitynum, brushnum);
|
||||
select = xmlNewNode (NULL, "brush");
|
||||
xmlNodeSetContent (select, buf);
|
||||
xmlAddChild (node, select);
|
||||
xml_SendNode (node);
|
||||
|
||||
sprintf (buf, "Entity %i, Brush %i: %s", entitynum, brushnum, msg);
|
||||
if (bError)
|
||||
Error(buf);
|
||||
else
|
||||
Sys_FPrintf (SYS_NOXML, "%s\n", buf);
|
||||
|
||||
}
|
||||
|
||||
void xml_Point (char *msg, vec3_t pt)
|
||||
{
|
||||
xmlNodePtr node, point;
|
||||
char buf[1024];
|
||||
char level[2];
|
||||
|
||||
node = xmlNewNode (NULL, "pointmsg");
|
||||
xmlNodeSetContent (node, msg);
|
||||
level[0] = (int)'0' + SYS_ERR;
|
||||
level[1] = 0;
|
||||
xmlSetProp (node, "level", (char *)&level);
|
||||
// a 'point' node
|
||||
sprintf (buf, "%g %g %g", pt[0], pt[1], pt[2]);
|
||||
point = xmlNewNode (NULL, "point");
|
||||
xmlNodeSetContent (point, buf);
|
||||
xmlAddChild (node, point);
|
||||
xml_SendNode (node);
|
||||
|
||||
sprintf (buf, "%s (%g %g %g)", msg, pt[0], pt[1], pt[2]);
|
||||
Error (buf);
|
||||
}
|
||||
|
||||
#define WINDING_BUFSIZE 2048
|
||||
void xml_Winding (char *msg, vec3_t p[], int numpoints, qboolean die)
|
||||
{
|
||||
xmlNodePtr node, winding;
|
||||
char buf[WINDING_BUFSIZE];
|
||||
char smlbuf[128];
|
||||
char level[2];
|
||||
int i;
|
||||
|
||||
node = xmlNewNode (NULL, "windingmsg");
|
||||
xmlNodeSetContent (node, msg);
|
||||
level[0] = (int)'0' + SYS_ERR;
|
||||
level[1] = 0;
|
||||
xmlSetProp (node, "level", (char *)&level);
|
||||
// a 'winding' node
|
||||
sprintf( buf, "%i ", numpoints);
|
||||
for(i = 0; i < numpoints; i++)
|
||||
{
|
||||
sprintf (smlbuf, "(%g %g %g)", p[i][0], p[i][1], p[i][2]);
|
||||
// don't overflow
|
||||
if (strlen(buf)+strlen(smlbuf)>WINDING_BUFSIZE)
|
||||
break;
|
||||
strcat( buf, smlbuf);
|
||||
}
|
||||
|
||||
winding = xmlNewNode (NULL, "winding");
|
||||
xmlNodeSetContent (winding, buf);
|
||||
xmlAddChild (node, winding);
|
||||
xml_SendNode (node);
|
||||
|
||||
if(die)
|
||||
Error (msg);
|
||||
else
|
||||
{
|
||||
Sys_Printf(msg);
|
||||
Sys_Printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
// in include
|
||||
#include "stream_version.h"
|
||||
|
||||
void Broadcast_Setup( const char *dest )
|
||||
{
|
||||
address_t address;
|
||||
char sMsg[1024];
|
||||
|
||||
Net_Setup();
|
||||
Net_StringToAddress((char *)dest, &address);
|
||||
brdcst_socket = Net_Connect(&address, 0);
|
||||
if (brdcst_socket)
|
||||
{
|
||||
// send in a header
|
||||
sprintf (sMsg, "<?xml version=\"1.0\"?><q3map_feedback version=\"" Q3MAP_STREAM_VERSION "\">");
|
||||
NMSG_Clear( &msg );
|
||||
NMSG_WriteString(&msg, sMsg );
|
||||
Net_Send(brdcst_socket, &msg );
|
||||
}
|
||||
}
|
||||
|
||||
void Broadcast_Shutdown()
|
||||
{
|
||||
if (brdcst_socket)
|
||||
{
|
||||
Sys_Printf("Disconnecting\n");
|
||||
Net_Disconnect(brdcst_socket);
|
||||
brdcst_socket = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
// all output ends up through here
|
||||
void FPrintf (int flag, char *buf)
|
||||
{
|
||||
xmlNodePtr node;
|
||||
static qboolean bGotXML = false;
|
||||
char level[2];
|
||||
|
||||
printf(buf);
|
||||
|
||||
// the following part is XML stuff only.. but maybe we don't want that message to go down the XML pipe?
|
||||
if (flag == SYS_NOXML)
|
||||
return;
|
||||
|
||||
// ouput an XML file of the run
|
||||
// use the DOM interface to build a tree
|
||||
/*
|
||||
<message level='flag'>
|
||||
message string
|
||||
.. various nodes to describe corresponding geometry ..
|
||||
</message>
|
||||
*/
|
||||
if (!bGotXML)
|
||||
{
|
||||
// initialize
|
||||
doc = xmlNewDoc("1.0");
|
||||
doc->children = xmlNewDocRawNode(doc, NULL, "q3map_feedback", NULL);
|
||||
bGotXML = true;
|
||||
}
|
||||
node = xmlNewNode (NULL, "message");
|
||||
xmlNodeSetContent (node, buf);
|
||||
level[0] = (int)'0' + flag;
|
||||
level[1] = 0;
|
||||
xmlSetProp (node, "level", (char *)&level );
|
||||
|
||||
xml_SendNode (node);
|
||||
}
|
||||
|
||||
#ifdef DBG_XML
|
||||
void DumpXML()
|
||||
{
|
||||
xmlSaveFile( "XMLDump.xml", doc );
|
||||
}
|
||||
#endif
|
||||
|
||||
void Sys_FPrintf (int flag, const char *format, ...)
|
||||
{
|
||||
char out_buffer[4096];
|
||||
va_list argptr;
|
||||
|
||||
if ((flag == SYS_VRB) && (verbose == false))
|
||||
return;
|
||||
|
||||
va_start (argptr, format);
|
||||
vsprintf (out_buffer, format, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
FPrintf (flag, out_buffer);
|
||||
}
|
||||
|
||||
void Sys_Printf (const char *format, ...)
|
||||
{
|
||||
char out_buffer[4096];
|
||||
va_list argptr;
|
||||
|
||||
va_start (argptr, format);
|
||||
vsprintf (out_buffer, format, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
FPrintf (SYS_STD, out_buffer);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
Error
|
||||
|
||||
For abnormal program terminations
|
||||
=================
|
||||
*/
|
||||
void Error( const char *error, ...)
|
||||
{
|
||||
char out_buffer[4096];
|
||||
char tmp[4096];
|
||||
va_list argptr;
|
||||
|
||||
va_start (argptr,error);
|
||||
vsprintf (tmp, error, argptr);
|
||||
va_end (argptr);
|
||||
|
||||
sprintf( out_buffer, "************ ERROR ************\n%s\n", tmp );
|
||||
|
||||
FPrintf( SYS_ERR, out_buffer );
|
||||
|
||||
#ifdef DBG_XML
|
||||
DumpXML();
|
||||
#endif
|
||||
|
||||
//++timo HACK ALERT .. if we shut down too fast the xml stream won't reach the listener.
|
||||
// a clean solution is to send a sync request node in the stream and wait for an answer before exiting
|
||||
Sys_Sleep( 1000 );
|
||||
|
||||
Broadcast_Shutdown();
|
||||
|
||||
exit (1);
|
||||
}
|
||||
|
||||
63
tools/quake2/qdata_heretic2/common/inout.h
Normal file
63
tools/quake2/qdata_heretic2/common/inout.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __INOUT__
|
||||
#define __INOUT__
|
||||
|
||||
// inout is the only stuff relying on xml, include the headers there
|
||||
#include "libxml/tree.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
// some useful xml routines
|
||||
xmlNodePtr xml_NodeForVec( vec3_t v );
|
||||
void xml_SendNode (xmlNodePtr node);
|
||||
// print a message in q3map output and send the corresponding select information down the xml stream
|
||||
// bError: do we end with an error on this one or do we go ahead?
|
||||
void xml_Select (char *msg, int entitynum, int brushnum, qboolean bError);
|
||||
// end q3map with an error message and send a point information in the xml stream
|
||||
// note: we might want to add a boolean to use this as a warning or an error thing..
|
||||
void xml_Winding (char *msg, vec3_t p[], int numpoints, qboolean die);
|
||||
void xml_Point (char *msg, vec3_t pt);
|
||||
|
||||
extern qboolean bNetworkBroadcast;
|
||||
void Broadcast_Setup( const char *dest );
|
||||
void Broadcast_Shutdown();
|
||||
|
||||
#define SYS_VRB 0 // verbose support (on/off)
|
||||
#define SYS_STD 1 // standard print level
|
||||
#define SYS_WRN 2 // warnings
|
||||
#define SYS_ERR 3 // error
|
||||
#define SYS_NOXML 4 // don't send that down the XML stream
|
||||
|
||||
extern qboolean verbose;
|
||||
void Sys_Printf (const char *text, ...);
|
||||
void Sys_FPrintf (int flag, const char *text, ...);
|
||||
void Error( const char *error, ...);
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define DBG_XML 1
|
||||
#endif
|
||||
|
||||
#ifdef DBG_XML
|
||||
void DumpXML();
|
||||
#endif
|
||||
|
||||
#endif
|
||||
476
tools/quake2/qdata_heretic2/common/l3dslib.c
Normal file
476
tools/quake2/qdata_heretic2/common/l3dslib.c
Normal file
@@ -0,0 +1,476 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
//
|
||||
// l3dslib.c: library for loading triangles from an Alias triangle file
|
||||
//
|
||||
|
||||
#include <stdio.h>
|
||||
#include "cmdlib.h"
|
||||
#include "inout.h"
|
||||
#include "mathlib.h"
|
||||
#include "trilib.h"
|
||||
#include "l3dslib.h"
|
||||
#include "token.h"
|
||||
#include "fmodel.h"
|
||||
#include "bspfile.h"
|
||||
|
||||
#define MAIN3DS 0x4D4D
|
||||
#define EDIT3DS 0x3D3D // this is the start of the editor config
|
||||
#define EDIT_OBJECT 0x4000
|
||||
#define OBJ_TRIMESH 0x4100
|
||||
#define TRI_VERTEXL 0x4110
|
||||
#define TRI_FACEL1 0x4120
|
||||
|
||||
#define MAXVERTS 2000
|
||||
|
||||
typedef struct {
|
||||
int v[4];
|
||||
} tri;
|
||||
|
||||
float fverts[MAXVERTS][3];
|
||||
tri tris[MAXTRIANGLES];
|
||||
|
||||
int bytesread, level, numtris, totaltris;
|
||||
int vertsfound, trisfound;
|
||||
|
||||
triangle_t *ptri;
|
||||
|
||||
|
||||
|
||||
void DefaultNodesList(mesh_node_t **nodesList, int *num_mesh_nodes, int *numtriangles)
|
||||
{
|
||||
int pos, bit, i;
|
||||
|
||||
if (nodesList)
|
||||
{
|
||||
*num_mesh_nodes = 1;
|
||||
memset(&(*nodesList)[0], 0, sizeof(mesh_node_t));
|
||||
strcpy((*nodesList)[0].name, "default");
|
||||
|
||||
// set all of the tris to be used for the top node
|
||||
for(i = 0; i < (*numtriangles); i++)
|
||||
{
|
||||
pos = (i) >> 3;
|
||||
bit = 1 << ((i) & 7 );
|
||||
|
||||
(*nodesList)[0].tris[pos] |= bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Alias stores triangles as 3 explicit vertices in .tri files, so even though we
|
||||
// start out with a vertex pool and vertex indices for triangles, we have to convert
|
||||
// to raw, explicit triangles
|
||||
void StoreAliasTriangles (void)
|
||||
{
|
||||
int i, j, k;
|
||||
|
||||
if ((totaltris + numtris) > MAXTRIANGLES)
|
||||
Error ("Error: Too many triangles");
|
||||
|
||||
for (i=0; i<numtris ; i++)
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
for (k=0 ; k<3 ; k++)
|
||||
{
|
||||
ptri[i+totaltris].verts[j][k] = fverts[tris[i].v[j]][k];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
totaltris += numtris;
|
||||
numtris = 0;
|
||||
vertsfound = 0;
|
||||
trisfound = 0;
|
||||
}
|
||||
|
||||
|
||||
int ParseVertexL (FILE *input)
|
||||
{
|
||||
int i, j, startbytesread, numverts;
|
||||
unsigned short tshort;
|
||||
|
||||
if (vertsfound)
|
||||
Error ("Error: Multiple vertex chunks");
|
||||
|
||||
vertsfound = 1;
|
||||
startbytesread = bytesread;
|
||||
|
||||
if (feof(input))
|
||||
Error ("Error: unexpected end of file");
|
||||
|
||||
fread(&tshort, sizeof(tshort), 1, input);
|
||||
bytesread += sizeof(tshort);
|
||||
numverts = (int)tshort;
|
||||
|
||||
if (numverts > MAXVERTS)
|
||||
Error ("Error: Too many vertices");
|
||||
|
||||
for (i=0 ; i<numverts ; i++)
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
if (feof(input))
|
||||
Error ("Error: unexpected end of file");
|
||||
|
||||
fread(&fverts[i][j], sizeof(float), 1, input);
|
||||
bytesread += sizeof(float);
|
||||
}
|
||||
}
|
||||
|
||||
if (vertsfound && trisfound)
|
||||
StoreAliasTriangles ();
|
||||
|
||||
return bytesread - startbytesread;
|
||||
}
|
||||
|
||||
|
||||
int ParseFaceL1 (FILE *input)
|
||||
{
|
||||
|
||||
int i, j, startbytesread;
|
||||
unsigned short tshort;
|
||||
|
||||
if (trisfound)
|
||||
Error ("Error: Multiple face chunks");
|
||||
|
||||
trisfound = 1;
|
||||
startbytesread = bytesread;
|
||||
|
||||
if (feof(input))
|
||||
Error ("Error: unexpected end of file");
|
||||
|
||||
fread(&tshort, sizeof(tshort), 1, input);
|
||||
bytesread += sizeof(tshort);
|
||||
numtris = (int)tshort;
|
||||
|
||||
if (numtris > MAXTRIANGLES)
|
||||
Error ("Error: Too many triangles");
|
||||
|
||||
for (i=0 ; i<numtris ; i++)
|
||||
{
|
||||
for (j=0 ; j<4 ; j++)
|
||||
{
|
||||
if (feof(input))
|
||||
Error ("Error: unexpected end of file");
|
||||
|
||||
fread(&tshort, sizeof(tshort), 1, input);
|
||||
bytesread += sizeof(tshort);
|
||||
tris[i].v[j] = (int)tshort;
|
||||
}
|
||||
}
|
||||
|
||||
if (vertsfound && trisfound)
|
||||
StoreAliasTriangles ();
|
||||
|
||||
return bytesread - startbytesread;
|
||||
}
|
||||
|
||||
|
||||
int ParseChunk (FILE *input)
|
||||
{
|
||||
#define BLOCK_SIZE 4096
|
||||
char temp[BLOCK_SIZE];
|
||||
unsigned short type;
|
||||
int i, length, w, t, retval;
|
||||
|
||||
level++;
|
||||
retval = 0;
|
||||
|
||||
// chunk type
|
||||
if (feof(input))
|
||||
Error ("Error: unexpected end of file");
|
||||
|
||||
fread(&type, sizeof(type), 1, input);
|
||||
bytesread += sizeof(type);
|
||||
|
||||
// chunk length
|
||||
if (feof(input))
|
||||
Error ("Error: unexpected end of file");
|
||||
|
||||
fread (&length, sizeof(length), 1, input);
|
||||
bytesread += sizeof(length);
|
||||
w = length - 6;
|
||||
|
||||
// process chunk if we care about it, otherwise skip it
|
||||
switch (type)
|
||||
{
|
||||
case TRI_VERTEXL:
|
||||
w -= ParseVertexL (input);
|
||||
goto ParseSubchunk;
|
||||
|
||||
case TRI_FACEL1:
|
||||
w -= ParseFaceL1 (input);
|
||||
goto ParseSubchunk;
|
||||
|
||||
case EDIT_OBJECT:
|
||||
// read the name
|
||||
i = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if (feof(input))
|
||||
Error ("Error: unexpected end of file");
|
||||
|
||||
fread (&temp[i], 1, 1, input);
|
||||
i++;
|
||||
w--;
|
||||
bytesread++;
|
||||
} while (temp[i-1]);
|
||||
|
||||
case MAIN3DS:
|
||||
case OBJ_TRIMESH:
|
||||
case EDIT3DS:
|
||||
// parse through subchunks
|
||||
ParseSubchunk:
|
||||
while (w > 0)
|
||||
{
|
||||
w -= ParseChunk (input);
|
||||
}
|
||||
|
||||
retval = length;
|
||||
goto Done;
|
||||
|
||||
default:
|
||||
// skip other chunks
|
||||
while (w > 0)
|
||||
{
|
||||
t = w;
|
||||
|
||||
if (t > BLOCK_SIZE)
|
||||
t = BLOCK_SIZE;
|
||||
|
||||
if (feof(input))
|
||||
Error ("Error: unexpected end of file");
|
||||
|
||||
fread (&temp, t, 1, input);
|
||||
bytesread += t;
|
||||
|
||||
w -= t;
|
||||
}
|
||||
|
||||
retval = length;
|
||||
goto Done;
|
||||
}
|
||||
|
||||
Done:
|
||||
level--;
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
void Load3DSTriangleList (char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **nodesList, int *num_mesh_nodes)
|
||||
{
|
||||
FILE *input;
|
||||
short int tshort;
|
||||
|
||||
if (nodesList)
|
||||
{
|
||||
*num_mesh_nodes = 0;
|
||||
*nodesList = (mesh_node_t *) SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");
|
||||
}
|
||||
|
||||
bytesread = 0;
|
||||
level = 0;
|
||||
numtris = 0;
|
||||
totaltris = 0;
|
||||
vertsfound = 0;
|
||||
trisfound = 0;
|
||||
|
||||
if ((input = fopen(filename, "rb")) == 0) {
|
||||
fprintf(stderr,"reader: could not open file '%s'\n", filename);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
fread(&tshort, sizeof(tshort), 1, input);
|
||||
|
||||
// should only be MAIN3DS, but some files seem to start with EDIT3DS, with
|
||||
// no MAIN3DS
|
||||
if ((tshort != MAIN3DS) && (tshort != EDIT3DS)) {
|
||||
fprintf(stderr,"File is not a 3DS file.\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
// back to top of file so we can parse the first chunk descriptor
|
||||
fseek(input, 0, SEEK_SET);
|
||||
|
||||
ptri = malloc (MAXTRIANGLES * sizeof(triangle_t));
|
||||
|
||||
*pptri = ptri;
|
||||
|
||||
// parse through looking for the relevant chunk tree (MAIN3DS | EDIT3DS | EDIT_OBJECT |
|
||||
// OBJ_TRIMESH | {TRI_VERTEXL, TRI_FACEL1}) and skipping other chunks
|
||||
ParseChunk (input);
|
||||
|
||||
if (vertsfound || trisfound)
|
||||
Error ("Incomplete triangle set");
|
||||
|
||||
*numtriangles = totaltris;
|
||||
|
||||
fclose (input);
|
||||
|
||||
DefaultNodesList(nodesList,num_mesh_nodes,numtriangles);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// LoadASC
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void LoadASC(char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **nodesList, int *num_mesh_nodes)
|
||||
{
|
||||
int i, j;
|
||||
int vertexCount;
|
||||
struct
|
||||
{
|
||||
float v[3];
|
||||
} *vList;
|
||||
int triCount;
|
||||
triangle_t *tList;
|
||||
float x, y, z;
|
||||
// float x2, y2, z2;
|
||||
// float rx, ry, rz;
|
||||
qboolean goodObject;
|
||||
|
||||
if (nodesList)
|
||||
{
|
||||
*num_mesh_nodes = 0;
|
||||
*nodesList = (mesh_node_t *) SafeMalloc(MAX_FM_MESH_NODES * sizeof(mesh_node_t), "Mesh Node List");
|
||||
}
|
||||
|
||||
TK_OpenSource(fileName);
|
||||
|
||||
goodObject = false;
|
||||
while(goodObject == false)
|
||||
{
|
||||
TK_Beyond(TK_C_NAMED);
|
||||
TK_Beyond(TK_OBJECT);
|
||||
TK_Beyond(TK_C_TRI);
|
||||
TK_Beyond(TK_MESH);
|
||||
TK_BeyondRequire(TK_C_VERTICES, TK_COLON);
|
||||
TK_FetchRequire(TK_INTNUMBER);
|
||||
vertexCount = tk_IntNumber;
|
||||
if(vertexCount > 0)
|
||||
{
|
||||
goodObject = true;
|
||||
}
|
||||
}
|
||||
TK_BeyondRequire(TK_C_FACES, TK_COLON);
|
||||
TK_FetchRequire(TK_INTNUMBER);
|
||||
triCount = tk_IntNumber;
|
||||
if(triCount >= MAXTRIANGLES)
|
||||
{
|
||||
Error("Too many triangles in file %s\n", fileName);
|
||||
}
|
||||
*triangleCount = triCount;
|
||||
tList = (triangle_t *) SafeMalloc(MAXTRIANGLES*sizeof(triangle_t), "Triangle list");
|
||||
*triList = tList;
|
||||
|
||||
memset(*triList,0,MAXTRIANGLES*sizeof(triangle_t));
|
||||
TK_BeyondRequire(TK_C_VERTEX, TK_LIST);
|
||||
|
||||
/* rx = ((rotation[0]+90.0)/360.0)*2.0*M_PI;
|
||||
//rx = (rotation[0]/360.0)*2.0*M_PI;
|
||||
ry = (rotation[1]/360.0)*2.0*M_PI;
|
||||
rz = (rotation[2]/360.0)*2.0*M_PI;
|
||||
*/
|
||||
vList = (void *) SafeMalloc(vertexCount*sizeof vList[0], "Vertex list");
|
||||
for(i = 0; i < vertexCount; i++)
|
||||
{
|
||||
TK_BeyondRequire(TK_C_VERTEX, TK_INTNUMBER);
|
||||
if(tk_IntNumber != i)
|
||||
{
|
||||
Error("File '%s', line %d:\nVertex index mismatch.\n",
|
||||
tk_SourceName, tk_Line);
|
||||
}
|
||||
TK_FetchRequireFetch(TK_COLON);
|
||||
|
||||
TK_BeyondRequire(TK_COLON, TK_FLOATNUMBER);
|
||||
x = tk_FloatNumber;
|
||||
TK_BeyondRequire(TK_COLON, TK_FLOATNUMBER);
|
||||
y = tk_FloatNumber;
|
||||
TK_BeyondRequire(TK_COLON, TK_FLOATNUMBER);
|
||||
z = tk_FloatNumber;
|
||||
|
||||
/* x2 = x*cos(rz)+y*sin(rz);
|
||||
y2 = -x*sin(rz)+y*cos(rz);
|
||||
x = x2;
|
||||
y = y2;
|
||||
y2 = y*cos(rx)+z*sin(rx);
|
||||
z2 = -y*sin(rx)+z*cos(rx);
|
||||
y = y2;
|
||||
z = z2;
|
||||
x2 = x*cos(ry)-z*sin(ry);
|
||||
z2 = x*sin(ry)+z*cos(ry);
|
||||
x = x2;
|
||||
z = z2;
|
||||
*/
|
||||
vList[i].v[0] = x;
|
||||
vList[i].v[1] = y;
|
||||
vList[i].v[2] = z;
|
||||
}
|
||||
TK_BeyondRequire(TK_C_FACE, TK_LIST);
|
||||
for(i = 0; i < triCount; i++)
|
||||
{
|
||||
TK_BeyondRequire(TK_C_FACE, TK_INTNUMBER);
|
||||
if(tk_IntNumber != i)
|
||||
{
|
||||
Error("File '%s', line %d:\nTriangle index mismatch.\n",
|
||||
tk_SourceName, tk_Line);
|
||||
}
|
||||
for(j = 0; j < 3; j++)
|
||||
{
|
||||
TK_BeyondRequire(TK_IDENTIFIER, TK_COLON);
|
||||
TK_FetchRequire(TK_INTNUMBER);
|
||||
if(tk_IntNumber >= vertexCount)
|
||||
{
|
||||
Error("File '%s', line %d:\nVertex number"
|
||||
" > vertexCount: %d\n", tk_SourceName, tk_Line,
|
||||
tk_IntNumber);
|
||||
}
|
||||
tList[i].verts[2-j][0] = vList[tk_IntNumber].v[0];
|
||||
tList[i].verts[2-j][1] = vList[tk_IntNumber].v[1];
|
||||
tList[i].verts[2-j][2] = vList[tk_IntNumber].v[2];
|
||||
#ifdef _QDATA
|
||||
tList[i].indicies[2-j] = tk_IntNumber;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* printf("Face %i:\n v0: %f, %f, %f\n v1: %f, %f, %f\n"
|
||||
" v2: %f, %f, %f\n", i,
|
||||
tList[i].verts[0][0],
|
||||
tList[i].verts[0][1],
|
||||
tList[i].verts[0][2],
|
||||
tList[i].verts[1][0],
|
||||
tList[i].verts[1][1],
|
||||
tList[i].verts[1][2],
|
||||
tList[i].verts[2][0],
|
||||
tList[i].verts[2][1],
|
||||
tList[i].verts[2][2]);
|
||||
*/
|
||||
}
|
||||
|
||||
DefaultNodesList(nodesList,num_mesh_nodes,triangleCount);
|
||||
}
|
||||
28
tools/quake2/qdata_heretic2/common/l3dslib.h
Normal file
28
tools/quake2/qdata_heretic2/common/l3dslib.h
Normal file
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
//
|
||||
// l3dslib.h: header file for loading triangles from a 3DS triangle file
|
||||
//
|
||||
void DefaultNodesList(mesh_node_t **nodesList, int *num_mesh_nodes, int *numtriangles);
|
||||
|
||||
void Load3DSTriangleList (char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **ppmnodes, int *num_mesh_nodes);
|
||||
void LoadASC(char *fileName, triangle_t **triList, int *triangleCount, mesh_node_t **ppmnodes, int *num_mesh_nodes);
|
||||
1052
tools/quake2/qdata_heretic2/common/lbmlib.c
Normal file
1052
tools/quake2/qdata_heretic2/common/lbmlib.c
Normal file
File diff suppressed because it is too large
Load Diff
41
tools/quake2/qdata_heretic2/common/lbmlib.h
Normal file
41
tools/quake2/qdata_heretic2/common/lbmlib.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// piclib.h
|
||||
|
||||
|
||||
void LoadLBM (char *filename, byte **picture, byte **palette);
|
||||
void WriteLBMfile (char *filename, byte *data, int width, int height
|
||||
, byte *palette);
|
||||
void LoadPCX (char *filename, byte **picture, byte **palette, int *width, int *height);
|
||||
void WritePCXfile (char *filename, byte *data, int width, int height
|
||||
, byte *palette);
|
||||
|
||||
// loads / saves either lbm or pcx, depending on extension
|
||||
void Load256Image (char *name, byte **pixels, byte **palette,
|
||||
int *width, int *height);
|
||||
void Save256Image (char *name, byte *pixels, byte *palette,
|
||||
int width, int height);
|
||||
|
||||
|
||||
void LoadTGA (char *filename, byte **pixels, int *width, int *height);
|
||||
|
||||
qboolean LoadAnyImage (char *name, byte **pixels, byte **palette, int *width, int *height);
|
||||
176
tools/quake2/qdata_heretic2/common/mathlib.c
Normal file
176
tools/quake2/qdata_heretic2/common/mathlib.c
Normal file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// mathlib.c -- math primitives
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "mathlib.h"
|
||||
|
||||
vec3_t vec3_origin = {0,0,0};
|
||||
|
||||
|
||||
double VectorLength(vec3_t v)
|
||||
{
|
||||
int i;
|
||||
double length;
|
||||
|
||||
length = 0;
|
||||
for (i=0 ; i< 3 ; i++)
|
||||
length += v[i]*v[i];
|
||||
length = sqrt (length); // FIXME
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
qboolean VectorCompare (vec3_t v1, vec3_t v2)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
if (fabs(v1[i]-v2[i]) > EQUAL_EPSILON)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
vec_t Q_rint (vec_t in)
|
||||
{
|
||||
return floor (in + 0.5);
|
||||
}
|
||||
|
||||
void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc)
|
||||
{
|
||||
vc[0] = va[0] + scale*vb[0];
|
||||
vc[1] = va[1] + scale*vb[1];
|
||||
vc[2] = va[2] + scale*vb[2];
|
||||
}
|
||||
|
||||
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross)
|
||||
{
|
||||
cross[0] = v1[1]*v2[2] - v1[2]*v2[1];
|
||||
cross[1] = v1[2]*v2[0] - v1[0]*v2[2];
|
||||
cross[2] = v1[0]*v2[1] - v1[1]*v2[0];
|
||||
}
|
||||
|
||||
vec_t _DotProduct (vec3_t v1, vec3_t v2)
|
||||
{
|
||||
return v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2];
|
||||
}
|
||||
|
||||
void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out)
|
||||
{
|
||||
out[0] = va[0]-vb[0];
|
||||
out[1] = va[1]-vb[1];
|
||||
out[2] = va[2]-vb[2];
|
||||
}
|
||||
|
||||
void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out)
|
||||
{
|
||||
out[0] = va[0]+vb[0];
|
||||
out[1] = va[1]+vb[1];
|
||||
out[2] = va[2]+vb[2];
|
||||
}
|
||||
|
||||
void _VectorCopy (vec3_t in, vec3_t out)
|
||||
{
|
||||
out[0] = in[0];
|
||||
out[1] = in[1];
|
||||
out[2] = in[2];
|
||||
}
|
||||
|
||||
void _VectorScale (vec3_t v, vec_t scale, vec3_t out)
|
||||
{
|
||||
out[0] = v[0] * scale;
|
||||
out[1] = v[1] * scale;
|
||||
out[2] = v[2] * scale;
|
||||
}
|
||||
|
||||
#pragma optimize("g", off) // went back to turning optimization off,
|
||||
// the bug_fix thing stopped working
|
||||
|
||||
vec_t VectorNormalize (vec3_t in, vec3_t out)
|
||||
{
|
||||
vec_t length, ilength;
|
||||
|
||||
length = sqrt (in[0]*in[0] + in[1]*in[1] + in[2]*in[2]);
|
||||
if (length == 0)
|
||||
{
|
||||
VectorClear (out);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ilength = 1.0/length;
|
||||
out[0] = in[0]*ilength;
|
||||
out[1] = in[1]*ilength;
|
||||
out[2] = in[2]*ilength;
|
||||
|
||||
return length;
|
||||
}
|
||||
|
||||
vec_t ColorNormalize (vec3_t in, vec3_t out)
|
||||
{
|
||||
float max, scale;
|
||||
|
||||
max = in[0];
|
||||
if (in[1] > max)
|
||||
max = in[1];
|
||||
if (in[2] > max)
|
||||
max = in[2];
|
||||
|
||||
if (max == 0)
|
||||
return 0;
|
||||
|
||||
scale = 1.0 / max;
|
||||
|
||||
VectorScale (in, scale, out);
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
#pragma optimize("", on)
|
||||
|
||||
void VectorInverse (vec3_t v)
|
||||
{
|
||||
v[0] = -v[0];
|
||||
v[1] = -v[1];
|
||||
v[2] = -v[2];
|
||||
}
|
||||
|
||||
void ClearBounds (vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
mins[0] = mins[1] = mins[2] = 99999;
|
||||
maxs[0] = maxs[1] = maxs[2] = -99999;
|
||||
}
|
||||
|
||||
void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
int i;
|
||||
vec_t val;
|
||||
|
||||
for (i=0 ; i<3 ; i++)
|
||||
{
|
||||
val = v[i];
|
||||
if (val < mins[i])
|
||||
mins[i] = val;
|
||||
if (val > maxs[i])
|
||||
maxs[i] = val;
|
||||
}
|
||||
}
|
||||
76
tools/quake2/qdata_heretic2/common/mathlib.h
Normal file
76
tools/quake2/qdata_heretic2/common/mathlib.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef __MATHLIB__
|
||||
#define __MATHLIB__
|
||||
|
||||
// mathlib.h
|
||||
|
||||
#include <math.h>
|
||||
/*
|
||||
#ifdef DOUBLEVEC_T
|
||||
typedef double vec_t;
|
||||
#else
|
||||
typedef float vec_t;
|
||||
#endif
|
||||
typedef vec_t vec3_t[3];
|
||||
*/
|
||||
#define SIDE_FRONT 0
|
||||
#define SIDE_ON 2
|
||||
#define SIDE_BACK 1
|
||||
#define SIDE_CROSS -2
|
||||
|
||||
#define Q_PI 3.14159265358979323846
|
||||
|
||||
extern vec3_t vec3_origin;
|
||||
|
||||
#define EQUAL_EPSILON 0.001
|
||||
|
||||
qboolean VectorCompare (vec3_t v1, vec3_t v2);
|
||||
|
||||
#define DotProduct(x,y) (x[0]*y[0]+x[1]*y[1]+x[2]*y[2])
|
||||
#define VectorSubtract(a,b,c) {c[0]=a[0]-b[0];c[1]=a[1]-b[1];c[2]=a[2]-b[2];}
|
||||
#define VectorAdd(a,b,c) {c[0]=a[0]+b[0];c[1]=a[1]+b[1];c[2]=a[2]+b[2];}
|
||||
#define VectorCopy(a,b) {b[0]=a[0];b[1]=a[1];b[2]=a[2];}
|
||||
#define VectorScale(a,b,c) {c[0]=b*a[0];c[1]=b*a[1];c[2]=b*a[2];}
|
||||
#define VectorClear(x) {x[0] = x[1] = x[2] = 0;}
|
||||
#define VectorNegate(x) {x[0]=-x[0];x[1]=-x[1];x[2]=-x[2];}
|
||||
|
||||
vec_t Q_rint (vec_t in);
|
||||
vec_t _DotProduct (vec3_t v1, vec3_t v2);
|
||||
void _VectorSubtract (vec3_t va, vec3_t vb, vec3_t out);
|
||||
void _VectorAdd (vec3_t va, vec3_t vb, vec3_t out);
|
||||
void _VectorCopy (vec3_t in, vec3_t out);
|
||||
void _VectorScale (vec3_t v, vec_t scale, vec3_t out);
|
||||
|
||||
double VectorLength(vec3_t v);
|
||||
|
||||
void VectorMA (vec3_t va, double scale, vec3_t vb, vec3_t vc);
|
||||
|
||||
void CrossProduct (vec3_t v1, vec3_t v2, vec3_t cross);
|
||||
vec_t VectorNormalize (vec3_t in, vec3_t out);
|
||||
vec_t ColorNormalize (vec3_t in, vec3_t out);
|
||||
void VectorInverse (vec3_t v);
|
||||
|
||||
void ClearBounds (vec3_t mins, vec3_t maxs);
|
||||
void AddPointToBounds (vec3_t v, vec3_t mins, vec3_t maxs);
|
||||
|
||||
#endif
|
||||
298
tools/quake2/qdata_heretic2/common/md4.c
Normal file
298
tools/quake2/qdata_heretic2/common/md4.c
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/* GLOBAL.H - RSAREF types and constants */
|
||||
|
||||
#include <string.h>
|
||||
|
||||
/* POINTER defines a generic pointer type */
|
||||
typedef unsigned char *POINTER;
|
||||
|
||||
/* UINT2 defines a two byte word */
|
||||
typedef unsigned short int UINT2;
|
||||
|
||||
/* UINT4 defines a four byte word */
|
||||
typedef unsigned long int UINT4;
|
||||
|
||||
|
||||
/* MD4.H - header file for MD4C.C */
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991.
|
||||
|
||||
All rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it is identified as the “RSA Data Security, Inc. MD4 Message-Digest Algorithm” in all material mentioning or referencing this software or this function.
|
||||
License is also granted to make and use derivative works provided that such works are identified as “derived from the RSA Data Security, Inc. MD4 Message-Digest Algorithm” in all material mentioning or referencing the derived work.
|
||||
RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided “as is” without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this documentation and/or software. */
|
||||
|
||||
/* MD4 context. */
|
||||
typedef struct {
|
||||
UINT4 state[4]; /* state (ABCD) */
|
||||
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
unsigned char buffer[64]; /* input buffer */
|
||||
} MD4_CTX;
|
||||
|
||||
void MD4Init (MD4_CTX *);
|
||||
void MD4Update (MD4_CTX *, unsigned char *, unsigned int);
|
||||
void MD4Final (unsigned char [16], MD4_CTX *);
|
||||
|
||||
|
||||
|
||||
/* MD4C.C - RSA Data Security, Inc., MD4 message-digest algorithm */
|
||||
/* Copyright (C) 1990-2, RSA Data Security, Inc. All rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it is identified as the
|
||||
RSA Data Security, Inc. MD4 Message-Digest Algorithm
|
||||
in all material mentioning or referencing this software or this function.
|
||||
License is also granted to make and use derivative works provided that such works are identified as
|
||||
derived from the RSA Data Security, Inc. MD4 Message-Digest Algorithm
|
||||
in all material mentioning or referencing the derived work.
|
||||
RSA Data Security, Inc. makes no representations concerning either the merchantability of this software or the suitability of this software for any particular purpose. It is provided
|
||||
as is without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this documentation and/or software. */
|
||||
|
||||
/* Constants for MD4Transform routine. */
|
||||
#define S11 3
|
||||
#define S12 7
|
||||
#define S13 11
|
||||
#define S14 19
|
||||
#define S21 3
|
||||
#define S22 5
|
||||
#define S23 9
|
||||
#define S24 13
|
||||
#define S31 3
|
||||
#define S32 9
|
||||
#define S33 11
|
||||
#define S34 15
|
||||
|
||||
static void MD4Transform (UINT4 [4], unsigned char [64]);
|
||||
static void Encode (unsigned char *, UINT4 *, unsigned int);
|
||||
static void Decode (UINT4 *, unsigned char *, unsigned int);
|
||||
static void MD4_memcpy (POINTER, POINTER, unsigned int);
|
||||
static void MD4_memset (POINTER, int, unsigned int);
|
||||
|
||||
static unsigned char PADDING[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* F, G and H are basic MD4 functions. */
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits. */
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG and HH are transformations for rounds 1, 2 and 3 */
|
||||
/* Rotation is separate from addition to prevent recomputation */
|
||||
#define FF(a, b, c, d, x, s) {(a) += F ((b), (c), (d)) + (x); (a) = ROTATE_LEFT ((a), (s));}
|
||||
|
||||
#define GG(a, b, c, d, x, s) {(a) += G ((b), (c), (d)) + (x) + (UINT4)0x5a827999; (a) = ROTATE_LEFT ((a), (s));}
|
||||
|
||||
#define HH(a, b, c, d, x, s) {(a) += H ((b), (c), (d)) + (x) + (UINT4)0x6ed9eba1; (a) = \
|
||||
ROTATE_LEFT ((a), (s)); }
|
||||
|
||||
|
||||
/* MD4 initialization. Begins an MD4 operation, writing a new context. */
|
||||
void MD4Init (MD4_CTX *context)
|
||||
{
|
||||
context->count[0] = context->count[1] = 0;
|
||||
|
||||
/* Load magic initialization constants.*/
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xefcdab89;
|
||||
context->state[2] = 0x98badcfe;
|
||||
context->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
/* MD4 block update operation. Continues an MD4 message-digest operation, processing another message block, and updating the context. */
|
||||
void MD4Update (MD4_CTX *context, unsigned char *input, unsigned int inputLen)
|
||||
{
|
||||
unsigned int i, index, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (unsigned int)((context->count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((context->count[0] += ((UINT4)inputLen << 3))< ((UINT4)inputLen << 3))
|
||||
context->count[1]++;
|
||||
|
||||
context->count[1] += ((UINT4)inputLen >> 29);
|
||||
|
||||
partLen = 64 - index;
|
||||
|
||||
/* Transform as many times as possible.*/
|
||||
if (inputLen >= partLen)
|
||||
{
|
||||
memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
|
||||
MD4Transform (context->state, context->buffer);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
MD4Transform (context->state, &input[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
memcpy ((POINTER)&context->buffer[index], (POINTER)&input[i], inputLen-i);
|
||||
}
|
||||
|
||||
|
||||
/* MD4 finalization. Ends an MD4 message-digest operation, writing the the message digest and zeroizing the context. */
|
||||
void MD4Final (unsigned char digest[16], MD4_CTX *context)
|
||||
{
|
||||
unsigned char bits[8];
|
||||
unsigned int index, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
Encode (bits, context->count, 8);
|
||||
|
||||
/* Pad out to 56 mod 64.*/
|
||||
index = (unsigned int)((context->count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
MD4Update (context, PADDING, padLen);
|
||||
|
||||
/* Append length (before padding) */
|
||||
MD4Update (context, bits, 8);
|
||||
|
||||
/* Store state in digest */
|
||||
Encode (digest, context->state, 16);
|
||||
|
||||
/* Zeroize sensitive information.*/
|
||||
memset ((POINTER)context, 0, sizeof (*context));
|
||||
}
|
||||
|
||||
|
||||
/* MD4 basic transformation. Transforms state based on block. */
|
||||
static void MD4Transform (UINT4 state[4], unsigned char block[64])
|
||||
{
|
||||
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
Decode (x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 0], S21); /* 17 */
|
||||
GG (d, a, b, c, x[ 4], S22); /* 18 */
|
||||
GG (c, d, a, b, x[ 8], S23); /* 19 */
|
||||
GG (b, c, d, a, x[12], S24); /* 20 */
|
||||
GG (a, b, c, d, x[ 1], S21); /* 21 */
|
||||
GG (d, a, b, c, x[ 5], S22); /* 22 */
|
||||
GG (c, d, a, b, x[ 9], S23); /* 23 */
|
||||
GG (b, c, d, a, x[13], S24); /* 24 */
|
||||
GG (a, b, c, d, x[ 2], S21); /* 25 */
|
||||
GG (d, a, b, c, x[ 6], S22); /* 26 */
|
||||
GG (c, d, a, b, x[10], S23); /* 27 */
|
||||
GG (b, c, d, a, x[14], S24); /* 28 */
|
||||
GG (a, b, c, d, x[ 3], S21); /* 29 */
|
||||
GG (d, a, b, c, x[ 7], S22); /* 30 */
|
||||
GG (c, d, a, b, x[11], S23); /* 31 */
|
||||
GG (b, c, d, a, x[15], S24); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 0], S31); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32); /* 34 */
|
||||
HH (c, d, a, b, x[ 4], S33); /* 35 */
|
||||
HH (b, c, d, a, x[12], S34); /* 36 */
|
||||
HH (a, b, c, d, x[ 2], S31); /* 37 */
|
||||
HH (d, a, b, c, x[10], S32); /* 38 */
|
||||
HH (c, d, a, b, x[ 6], S33); /* 39 */
|
||||
HH (b, c, d, a, x[14], S34); /* 40 */
|
||||
HH (a, b, c, d, x[ 1], S31); /* 41 */
|
||||
HH (d, a, b, c, x[ 9], S32); /* 42 */
|
||||
HH (c, d, a, b, x[ 5], S33); /* 43 */
|
||||
HH (b, c, d, a, x[13], S34); /* 44 */
|
||||
HH (a, b, c, d, x[ 3], S31); /* 45 */
|
||||
HH (d, a, b, c, x[11], S32); /* 46 */
|
||||
HH (c, d, a, b, x[ 7], S33); /* 47 */
|
||||
HH (b, c, d, a, x[15], S34); /* 48 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information.*/
|
||||
memset ((POINTER)x, 0, sizeof (x));
|
||||
}
|
||||
|
||||
|
||||
/* Encodes input (UINT4) into output (unsigned char). Assumes len is a multiple of 4. */
|
||||
static void Encode (unsigned char *output, UINT4 *input, unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (unsigned char)(input[i] & 0xff);
|
||||
output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Decodes input (unsigned char) into output (UINT4). Assumes len is a multiple of 4. */
|
||||
static void Decode (UINT4 *output, unsigned char *input, unsigned int len)
|
||||
{
|
||||
unsigned int i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
//===================================================================
|
||||
|
||||
unsigned Com_BlockChecksum (void *buffer, int length)
|
||||
{
|
||||
int digest[4];
|
||||
unsigned val;
|
||||
MD4_CTX ctx;
|
||||
|
||||
MD4Init (&ctx);
|
||||
MD4Update (&ctx, (unsigned char *)buffer, length);
|
||||
MD4Final ( (unsigned char *)digest, &ctx);
|
||||
|
||||
val = digest[0] ^ digest[1] ^ digest[2] ^ digest[3];
|
||||
|
||||
return val;
|
||||
}
|
||||
405
tools/quake2/qdata_heretic2/common/path_init.c
Normal file
405
tools/quake2/qdata_heretic2/common/path_init.c
Normal file
@@ -0,0 +1,405 @@
|
||||
/* -------------------------------------------------------------------------------
|
||||
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
/*
|
||||
Nurail: Swiped from Q3Map2
|
||||
*/
|
||||
|
||||
|
||||
|
||||
/* marker */
|
||||
#define PATH_INIT_C
|
||||
|
||||
#if defined( __linux__ ) || defined( __APPLE__ )
|
||||
#define Q_UNIX
|
||||
#endif
|
||||
|
||||
#ifdef Q_UNIX
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
|
||||
/* dependencies */
|
||||
#include "cmdlib.h"
|
||||
#include "inout.h"
|
||||
|
||||
|
||||
|
||||
/* path support */
|
||||
#define MAX_BASE_PATHS 10
|
||||
#define MAX_GAME_PATHS 10
|
||||
|
||||
char *homePath;
|
||||
char installPath[ MAX_OS_PATH ];
|
||||
|
||||
int numBasePaths;
|
||||
char *basePaths[ MAX_BASE_PATHS ];
|
||||
int numGamePaths;
|
||||
char *gamePaths[ MAX_GAME_PATHS ];
|
||||
|
||||
/*
|
||||
some of this code is based off the original q3map port from loki
|
||||
and finds various paths. moved here from bsp.c for clarity.
|
||||
*/
|
||||
|
||||
/*
|
||||
PathLokiGetHomeDir()
|
||||
gets the user's home dir (for ~/.q3a)
|
||||
*/
|
||||
|
||||
char *LokiGetHomeDir( void )
|
||||
{
|
||||
#ifndef Q_UNIX
|
||||
return NULL;
|
||||
#else
|
||||
char *home;
|
||||
uid_t id;
|
||||
struct passwd *pwd;
|
||||
|
||||
|
||||
/* get the home environment variable */
|
||||
home = getenv( "HOME" );
|
||||
if( home == NULL )
|
||||
{
|
||||
/* do some more digging */
|
||||
id = getuid();
|
||||
setpwent();
|
||||
while( (pwd = getpwent()) != NULL )
|
||||
{
|
||||
if( pwd->pw_uid == id )
|
||||
{
|
||||
home = pwd->pw_dir;
|
||||
break;
|
||||
}
|
||||
}
|
||||
endpwent();
|
||||
}
|
||||
|
||||
/* return it */
|
||||
return home;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
PathLokiInitPaths()
|
||||
initializes some paths on linux/os x
|
||||
*/
|
||||
|
||||
void LokiInitPaths( char *argv0 )
|
||||
{
|
||||
#ifndef Q_UNIX
|
||||
/* this is kinda crap, but hey */
|
||||
strcpy( installPath, "../" );
|
||||
#else
|
||||
char temp[ MAX_OS_PATH ];
|
||||
char *home;
|
||||
char *path;
|
||||
char *last;
|
||||
qboolean found;
|
||||
|
||||
|
||||
/* get home dir */
|
||||
home = LokiGetHomeDir();
|
||||
if( home == NULL )
|
||||
home = ".";
|
||||
|
||||
/* do some path divining */
|
||||
strcpy( temp, argv0 );
|
||||
if( strrchr( temp, '/' ) )
|
||||
argv0 = strrchr( argv0, '/' ) + 1;
|
||||
else
|
||||
{
|
||||
/* get path environment variable */
|
||||
path = getenv( "PATH" );
|
||||
|
||||
/* minor setup */
|
||||
last[ 0 ] = path[ 0 ];
|
||||
last[ 1 ] = '\0';
|
||||
found = false;
|
||||
|
||||
/* go through each : segment of path */
|
||||
while( last[ 0 ] != '\0' && found == false )
|
||||
{
|
||||
/* null out temp */
|
||||
temp[ 0 ] = '\0';
|
||||
|
||||
/* find next chunk */
|
||||
last = strchr( path, ':' );
|
||||
if( last == NULL )
|
||||
last = path + strlen( path );
|
||||
|
||||
/* found home dir candidate */
|
||||
if( *path == '~' )
|
||||
{
|
||||
strcpy( temp, home );
|
||||
path++;
|
||||
}
|
||||
|
||||
/* concatenate */
|
||||
if( last > (path + 1) )
|
||||
{
|
||||
strncat( temp, path, (last - path) );
|
||||
strcat( temp, "/" );
|
||||
}
|
||||
strcat( temp, "./" );
|
||||
strcat( temp, argv0 );
|
||||
|
||||
/* verify the path */
|
||||
if( access( temp, X_OK ) == 0 )
|
||||
found++;
|
||||
path = last + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* flake */
|
||||
if( realpath( temp, installPath ) )
|
||||
{
|
||||
/* q3map is in "tools/" */
|
||||
*(strrchr( installPath, '/' )) = '\0';
|
||||
*(strrchr( installPath, '/' ) + 1) = '\0';
|
||||
}
|
||||
|
||||
/* set home path */
|
||||
homePath = home;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
CleanPath() - ydnar
|
||||
cleans a dos path \ -> /
|
||||
*/
|
||||
|
||||
void CleanPath( char *path )
|
||||
{
|
||||
while( *path )
|
||||
{
|
||||
if( *path == '\\' )
|
||||
*path = '/';
|
||||
path++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
AddBasePath() - ydnar
|
||||
adds a base path to the list
|
||||
*/
|
||||
|
||||
void AddBasePath( char *path )
|
||||
{
|
||||
/* dummy check */
|
||||
if( path == NULL || path[ 0 ] == '\0' || numBasePaths >= MAX_BASE_PATHS )
|
||||
return;
|
||||
|
||||
/* add it to the list */
|
||||
basePaths[ numBasePaths ] = safe_malloc( strlen( path ) + 1 );
|
||||
strcpy( basePaths[ numBasePaths ], path );
|
||||
CleanPath( basePaths[ numBasePaths ] );
|
||||
numBasePaths++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
AddHomeBasePath() - ydnar
|
||||
adds a base path to the beginning of the list, prefixed by ~/
|
||||
*/
|
||||
|
||||
void AddHomeBasePath( char *path )
|
||||
{
|
||||
#ifdef Q_UNIX
|
||||
int i;
|
||||
char temp[ MAX_OS_PATH ];
|
||||
|
||||
|
||||
/* dummy check */
|
||||
if( path == NULL || path[ 0 ] == '\0' )
|
||||
return;
|
||||
|
||||
/* make a hole */
|
||||
for( i = 0; i < (MAX_BASE_PATHS - 1); i++ )
|
||||
basePaths[ i + 1 ] = basePaths[ i ];
|
||||
|
||||
/* concatenate home dir and path */
|
||||
sprintf( temp, "%s/%s", homePath, path );
|
||||
|
||||
/* add it to the list */
|
||||
basePaths[ 0 ] = safe_malloc( strlen( temp ) + 1 );
|
||||
strcpy( basePaths[ 0 ], temp );
|
||||
CleanPath( basePaths[ 0 ] );
|
||||
numBasePaths++;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*
|
||||
AddGamePath() - ydnar
|
||||
adds a game path to the list
|
||||
*/
|
||||
|
||||
void AddGamePath( char *path )
|
||||
{
|
||||
/* dummy check */
|
||||
if( path == NULL || path[ 0 ] == '\0' || numGamePaths >= MAX_GAME_PATHS )
|
||||
return;
|
||||
|
||||
/* add it to the list */
|
||||
gamePaths[ numGamePaths ] = safe_malloc( strlen( path ) + 1 );
|
||||
strcpy( gamePaths[ numGamePaths ], path );
|
||||
CleanPath( gamePaths[ numGamePaths ] );
|
||||
numGamePaths++;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
InitPaths() - ydnar
|
||||
cleaned up some of the path initialization code from bsp.c
|
||||
will remove any arguments it uses
|
||||
*/
|
||||
|
||||
void InitPaths( int *argc, char **argv )
|
||||
{
|
||||
int i, j, k, len, len2;
|
||||
char temp[ MAX_OS_PATH ];
|
||||
char gamePath[MAX_OS_PATH], homeBasePath[MAX_OS_PATH], game_magic[10];
|
||||
|
||||
strcpy(gamePath, "base");
|
||||
strcpy(game_magic, "h");
|
||||
strcpy(homeBasePath, ".heretic2");
|
||||
|
||||
/* note it */
|
||||
Sys_FPrintf( SYS_VRB, "--- InitPaths ---\n" );
|
||||
|
||||
/* get the install path for backup */
|
||||
LokiInitPaths( argv[ 0 ] );
|
||||
|
||||
/* set game to default (q3a) */
|
||||
numBasePaths = 0;
|
||||
numGamePaths = 0;
|
||||
|
||||
/* parse through the arguments and extract those relevant to paths */
|
||||
for( i = 0; i < *argc; i++ )
|
||||
{
|
||||
/* check for null */
|
||||
if( argv[ i ] == NULL )
|
||||
continue;
|
||||
|
||||
/* -fs_basepath */
|
||||
if( strcmp( argv[ i ], "-fs_basepath" ) == 0 )
|
||||
{
|
||||
if( ++i >= *argc )
|
||||
Error( "Out of arguments: No path specified after %s.", argv[ i - 1 ] );
|
||||
argv[ i - 1 ] = NULL;
|
||||
AddBasePath( argv[ i ] );
|
||||
argv[ i ] = NULL;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* remove processed arguments */
|
||||
for( i = 0, j = 0, k = 0; i < *argc && j < *argc; i++, j++ )
|
||||
{
|
||||
for( j; j < *argc && argv[ j ] == NULL; j++ );
|
||||
argv[ i ] = argv[ j ];
|
||||
if( argv[ i ] != NULL )
|
||||
k++;
|
||||
}
|
||||
*argc = k;
|
||||
|
||||
/* add standard game path */
|
||||
AddGamePath( gamePath );
|
||||
|
||||
/* if there is no base path set, figure it out */
|
||||
if( numBasePaths == 0 )
|
||||
{
|
||||
/* this is another crappy replacement for SetQdirFromPath() */
|
||||
len2 = strlen( game_magic );
|
||||
for( i = 0; i < *argc && numBasePaths == 0; i++ )
|
||||
{
|
||||
/* extract the arg */
|
||||
strcpy( temp, argv[ i ] );
|
||||
CleanPath( temp );
|
||||
len = strlen( temp );
|
||||
Sys_FPrintf( SYS_VRB, "Searching for \"%s\" in \"%s\" (%d)...\n", game_magic, temp, i );
|
||||
|
||||
/* this is slow, but only done once */
|
||||
for( j = 0; j < (len - len2); j++ )
|
||||
{
|
||||
/* check for the game's magic word */
|
||||
if( Q_strncasecmp( &temp[ j ], game_magic, len2 ) == 0 )
|
||||
{
|
||||
/* now find the next slash and nuke everything after it */
|
||||
while( temp[ ++j ] != '/' && temp[ j ] != '\0' );
|
||||
temp[ j ] = '\0';
|
||||
|
||||
/* add this as a base path */
|
||||
AddBasePath( temp );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* add install path */
|
||||
if( numBasePaths == 0 )
|
||||
AddBasePath( installPath );
|
||||
|
||||
/* check again */
|
||||
if( numBasePaths == 0 )
|
||||
Error( "Failed to find a valid base path." );
|
||||
}
|
||||
|
||||
/* this only affects unix */
|
||||
AddHomeBasePath( homeBasePath );
|
||||
|
||||
/* initialize vfs paths */
|
||||
if( numBasePaths > MAX_BASE_PATHS )
|
||||
numBasePaths = MAX_BASE_PATHS;
|
||||
if( numGamePaths > MAX_GAME_PATHS )
|
||||
numGamePaths = MAX_GAME_PATHS;
|
||||
|
||||
/* walk the list of game paths */
|
||||
//for( j = 0; j < numGamePaths; j++ )
|
||||
//{
|
||||
/* walk the list of base paths */
|
||||
// for( i = 0; i < numBasePaths; i++ )
|
||||
// {
|
||||
/* create a full path and initialize it */
|
||||
// sprintf( temp, "%s/%s/", basePaths[ i ], gamePaths[ j ] );
|
||||
// vfsInitDirectory( temp );
|
||||
// }
|
||||
//}
|
||||
|
||||
/* done */
|
||||
Sys_Printf( "\n" );
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
656
tools/quake2/qdata_heretic2/common/polylib.c
Normal file
656
tools/quake2/qdata_heretic2/common/polylib.c
Normal file
@@ -0,0 +1,656 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "inout.h"
|
||||
#include "mathlib.h"
|
||||
#include "polylib.h"
|
||||
|
||||
|
||||
extern int numthreads;
|
||||
|
||||
// counters are only bumped when running single threaded,
|
||||
// because they are an awefull coherence problem
|
||||
int c_active_windings;
|
||||
int c_peak_windings;
|
||||
int c_winding_allocs;
|
||||
int c_winding_points;
|
||||
|
||||
#define BOGUS_RANGE 8192
|
||||
|
||||
void pw(winding_t *w)
|
||||
{
|
||||
int i;
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
printf ("(%5.1f, %5.1f, %5.1f)\n",w->p[i][0], w->p[i][1],w->p[i][2]);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
AllocWinding
|
||||
=============
|
||||
*/
|
||||
winding_t *AllocWinding (int points)
|
||||
{
|
||||
winding_t *w;
|
||||
int s;
|
||||
|
||||
if (numthreads == 1)
|
||||
{
|
||||
c_winding_allocs++;
|
||||
c_winding_points += points;
|
||||
c_active_windings++;
|
||||
if (c_active_windings > c_peak_windings)
|
||||
c_peak_windings = c_active_windings;
|
||||
}
|
||||
s = sizeof(vec_t)*3*points + sizeof(int);
|
||||
w = malloc (s);
|
||||
if (!w)
|
||||
Error("AllocWinding MALLOC failed! Could not allocate %s bytes.", s);
|
||||
memset (w, 0, s);
|
||||
return w;
|
||||
}
|
||||
|
||||
void FreeWinding (winding_t *w)
|
||||
{
|
||||
if (*(unsigned *)w == 0xdeaddead)
|
||||
Error ("FreeWinding: freed a freed winding");
|
||||
*(unsigned *)w = 0xdeaddead;
|
||||
|
||||
if (numthreads == 1)
|
||||
c_active_windings--;
|
||||
free (w);
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
RemoveColinearPoints
|
||||
============
|
||||
*/
|
||||
int c_removed;
|
||||
|
||||
void RemoveColinearPoints (winding_t *w)
|
||||
{
|
||||
int i, j, k;
|
||||
vec3_t v1, v2;
|
||||
int nump;
|
||||
vec3_t p[MAX_POINTS_ON_WINDING];
|
||||
|
||||
nump = 0;
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
j = (i+1)%w->numpoints;
|
||||
k = (i+w->numpoints-1)%w->numpoints;
|
||||
VectorSubtract (w->p[j], w->p[i], v1);
|
||||
VectorSubtract (w->p[i], w->p[k], v2);
|
||||
VectorNormalize(v1,v1);
|
||||
VectorNormalize(v2,v2);
|
||||
if (DotProduct(v1, v2) < 0.999)
|
||||
{
|
||||
VectorCopy (w->p[i], p[nump]);
|
||||
nump++;
|
||||
}
|
||||
}
|
||||
|
||||
if (nump == w->numpoints)
|
||||
return;
|
||||
|
||||
if (numthreads == 1)
|
||||
c_removed += w->numpoints - nump;
|
||||
w->numpoints = nump;
|
||||
memcpy (w->p, p, nump*sizeof(p[0]));
|
||||
}
|
||||
|
||||
/*
|
||||
============
|
||||
WindingPlane
|
||||
============
|
||||
*/
|
||||
void WindingPlane (winding_t *w, vec3_t normal, vec_t *dist)
|
||||
{
|
||||
vec3_t v1, v2;
|
||||
|
||||
VectorSubtract (w->p[1], w->p[0], v1);
|
||||
VectorSubtract (w->p[2], w->p[0], v2);
|
||||
CrossProduct (v2, v1, normal);
|
||||
VectorNormalize (normal, normal);
|
||||
*dist = DotProduct (w->p[0], normal);
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
WindingArea
|
||||
=============
|
||||
*/
|
||||
vec_t WindingArea (winding_t *w)
|
||||
{
|
||||
int i;
|
||||
vec3_t d1, d2, cross;
|
||||
vec_t total;
|
||||
|
||||
total = 0;
|
||||
for (i=2 ; i<w->numpoints ; i++)
|
||||
{
|
||||
VectorSubtract (w->p[i-1], w->p[0], d1);
|
||||
VectorSubtract (w->p[i], w->p[0], d2);
|
||||
CrossProduct (d1, d2, cross);
|
||||
total += 0.5 * VectorLength ( cross );
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs)
|
||||
{
|
||||
vec_t v;
|
||||
int i,j;
|
||||
|
||||
mins[0] = mins[1] = mins[2] = 99999;
|
||||
maxs[0] = maxs[1] = maxs[2] = -99999;
|
||||
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{
|
||||
v = w->p[i][j];
|
||||
if (v < mins[j])
|
||||
mins[j] = v;
|
||||
if (v > maxs[j])
|
||||
maxs[j] = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
WindingCenter
|
||||
=============
|
||||
*/
|
||||
void WindingCenter (winding_t *w, vec3_t center)
|
||||
{
|
||||
int i;
|
||||
float scale;
|
||||
|
||||
VectorCopy (vec3_origin, center);
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
VectorAdd (w->p[i], center, center);
|
||||
|
||||
scale = 1.0/w->numpoints;
|
||||
VectorScale (center, scale, center);
|
||||
}
|
||||
|
||||
/*
|
||||
=================
|
||||
BaseWindingForPlane
|
||||
=================
|
||||
*/
|
||||
winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist)
|
||||
{
|
||||
int i, x;
|
||||
vec_t max, v;
|
||||
vec3_t org, vright, vup;
|
||||
winding_t *w;
|
||||
|
||||
// find the major axis
|
||||
|
||||
max = -BOGUS_RANGE;
|
||||
x = -1;
|
||||
for (i=0 ; i<3; i++)
|
||||
{
|
||||
v = fabs(normal[i]);
|
||||
if (v > max)
|
||||
{
|
||||
x = i;
|
||||
max = v;
|
||||
}
|
||||
}
|
||||
if (x==-1)
|
||||
Error ("BaseWindingForPlane: no axis found");
|
||||
|
||||
VectorCopy (vec3_origin, vup);
|
||||
switch (x)
|
||||
{
|
||||
case 0:
|
||||
case 1:
|
||||
vup[2] = 1;
|
||||
break;
|
||||
case 2:
|
||||
vup[0] = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
v = DotProduct (vup, normal);
|
||||
VectorMA (vup, -v, normal, vup);
|
||||
VectorNormalize (vup, vup);
|
||||
|
||||
VectorScale (normal, dist, org);
|
||||
|
||||
CrossProduct (vup, normal, vright);
|
||||
|
||||
VectorScale (vup, 8192, vup);
|
||||
VectorScale (vright, 8192, vright);
|
||||
|
||||
// project a really big axis aligned box onto the plane
|
||||
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;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CopyWinding
|
||||
==================
|
||||
*/
|
||||
winding_t *CopyWinding (winding_t *w)
|
||||
{
|
||||
int size;
|
||||
winding_t *c;
|
||||
|
||||
c = AllocWinding (w->numpoints);
|
||||
size = (int)((winding_t *)0)->p[w->numpoints];
|
||||
memcpy (c, w, size);
|
||||
return c;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
ReverseWinding
|
||||
==================
|
||||
*/
|
||||
winding_t *ReverseWinding (winding_t *w)
|
||||
{
|
||||
int i;
|
||||
winding_t *c;
|
||||
|
||||
c = AllocWinding (w->numpoints);
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
VectorCopy (w->p[w->numpoints-1-i], c->p[i]);
|
||||
}
|
||||
c->numpoints = w->numpoints;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
ClipWindingEpsilon
|
||||
=============
|
||||
*/
|
||||
void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back)
|
||||
{
|
||||
vec_t dists[MAX_POINTS_ON_WINDING+4];
|
||||
int sides[MAX_POINTS_ON_WINDING+4];
|
||||
int counts[3];
|
||||
vec_t dot; // VC 4.2 optimizer bug if not static
|
||||
int i, j;
|
||||
vec_t *p1, *p2;
|
||||
vec3_t mid;
|
||||
winding_t *f, *b;
|
||||
int maxpts;
|
||||
|
||||
if (in->numpoints >= MAX_POINTS_ON_WINDING-4)
|
||||
Error ("ClipWinding: MAX_POINTS_ON_WINDING");
|
||||
|
||||
counts[0] = counts[1] = counts[2] = 0;
|
||||
|
||||
// determine sides for each point
|
||||
for (i=0 ; i<in->numpoints ; i++)
|
||||
{
|
||||
dot = DotProduct (in->p[i], normal);
|
||||
dot -= dist;
|
||||
dists[i] = dot;
|
||||
if (dot > epsilon)
|
||||
sides[i] = SIDE_FRONT;
|
||||
else if (dot < -epsilon)
|
||||
sides[i] = SIDE_BACK;
|
||||
else
|
||||
{
|
||||
sides[i] = SIDE_ON;
|
||||
}
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
sides[i] = sides[0];
|
||||
dists[i] = dists[0];
|
||||
|
||||
*front = *back = NULL;
|
||||
|
||||
if (!counts[0])
|
||||
{
|
||||
*back = CopyWinding (in);
|
||||
return;
|
||||
}
|
||||
if (!counts[1])
|
||||
{
|
||||
*front = CopyWinding (in);
|
||||
return;
|
||||
}
|
||||
|
||||
maxpts = in->numpoints+4; // cant use counts[0]+2 because
|
||||
// of fp grouping errors
|
||||
|
||||
*front = f = AllocWinding (maxpts);
|
||||
*back = b = AllocWinding (maxpts);
|
||||
|
||||
for (i=0 ; i<in->numpoints ; i++)
|
||||
{
|
||||
p1 = in->p[i];
|
||||
|
||||
if (sides[i] == SIDE_ON)
|
||||
{
|
||||
VectorCopy (p1, f->p[f->numpoints]);
|
||||
f->numpoints++;
|
||||
VectorCopy (p1, b->p[b->numpoints]);
|
||||
b->numpoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sides[i] == SIDE_FRONT)
|
||||
{
|
||||
VectorCopy (p1, f->p[f->numpoints]);
|
||||
f->numpoints++;
|
||||
}
|
||||
if (sides[i] == SIDE_BACK)
|
||||
{
|
||||
VectorCopy (p1, b->p[b->numpoints]);
|
||||
b->numpoints++;
|
||||
}
|
||||
|
||||
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
|
||||
continue;
|
||||
|
||||
// generate a split point
|
||||
p2 = in->p[(i+1)%in->numpoints];
|
||||
|
||||
dot = dists[i] / (dists[i]-dists[i+1]);
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{ // avoid round off error when possible
|
||||
if (normal[j] == 1)
|
||||
mid[j] = dist;
|
||||
else if (normal[j] == -1)
|
||||
mid[j] = -dist;
|
||||
else
|
||||
mid[j] = p1[j] + dot*(p2[j]-p1[j]);
|
||||
}
|
||||
|
||||
VectorCopy (mid, f->p[f->numpoints]);
|
||||
f->numpoints++;
|
||||
VectorCopy (mid, b->p[b->numpoints]);
|
||||
b->numpoints++;
|
||||
}
|
||||
|
||||
if (f->numpoints > maxpts || b->numpoints > maxpts)
|
||||
Error ("ClipWinding: points exceeded estimate");
|
||||
if (f->numpoints > MAX_POINTS_ON_WINDING || b->numpoints > MAX_POINTS_ON_WINDING)
|
||||
Error ("ClipWinding: MAX_POINTS_ON_WINDING");
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
ChopWindingInPlace
|
||||
=============
|
||||
*/
|
||||
void ChopWindingInPlace (winding_t **inout, vec3_t normal, vec_t dist, vec_t epsilon)
|
||||
{
|
||||
winding_t *in;
|
||||
vec_t dists[MAX_POINTS_ON_WINDING+4];
|
||||
int sides[MAX_POINTS_ON_WINDING+4];
|
||||
int counts[3];
|
||||
vec_t dot; // VC 4.2 optimizer bug if not static
|
||||
int i, j;
|
||||
vec_t *p1, *p2;
|
||||
vec3_t mid;
|
||||
winding_t *f;
|
||||
int maxpts;
|
||||
|
||||
in = *inout;
|
||||
counts[0] = counts[1] = counts[2] = 0;
|
||||
|
||||
if (!in)
|
||||
{
|
||||
printf ("Warning: NULL passed to ChopWindingInPlace\n");
|
||||
return;
|
||||
}
|
||||
if (in->numpoints >= MAX_POINTS_ON_WINDING-4)
|
||||
Error ("ChopWinding: MAX_POINTS_ON_WINDING");
|
||||
|
||||
// determine sides for each point
|
||||
for (i=0 ; i<in->numpoints ; i++)
|
||||
{
|
||||
dot = DotProduct (in->p[i], normal);
|
||||
dot -= dist;
|
||||
dists[i] = dot;
|
||||
if (dot > epsilon)
|
||||
sides[i] = SIDE_FRONT;
|
||||
else if (dot < -epsilon)
|
||||
sides[i] = SIDE_BACK;
|
||||
else
|
||||
{
|
||||
sides[i] = SIDE_ON;
|
||||
}
|
||||
counts[sides[i]]++;
|
||||
}
|
||||
sides[i] = sides[0];
|
||||
dists[i] = dists[0];
|
||||
|
||||
if (!counts[0])
|
||||
{
|
||||
FreeWinding (in);
|
||||
*inout = NULL;
|
||||
return;
|
||||
}
|
||||
if (!counts[1])
|
||||
return; // inout stays the same
|
||||
|
||||
maxpts = in->numpoints+4; // cant use counts[0]+2 because
|
||||
// of fp grouping errors
|
||||
|
||||
f = AllocWinding (maxpts);
|
||||
|
||||
for (i=0 ; i<in->numpoints ; i++)
|
||||
{
|
||||
p1 = in->p[i];
|
||||
|
||||
if (sides[i] == SIDE_ON)
|
||||
{
|
||||
VectorCopy (p1, f->p[f->numpoints]);
|
||||
f->numpoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (sides[i] == SIDE_FRONT)
|
||||
{
|
||||
VectorCopy (p1, f->p[f->numpoints]);
|
||||
f->numpoints++;
|
||||
}
|
||||
|
||||
if (sides[i+1] == SIDE_ON || sides[i+1] == sides[i])
|
||||
continue;
|
||||
|
||||
// generate a split point
|
||||
p2 = in->p[(i+1)%in->numpoints];
|
||||
|
||||
dot = dists[i] / (dists[i]-dists[i+1]);
|
||||
for (j=0 ; j<3 ; j++)
|
||||
{ // avoid round off error when possible
|
||||
if (normal[j] == 1)
|
||||
mid[j] = dist;
|
||||
else if (normal[j] == -1)
|
||||
mid[j] = -dist;
|
||||
else
|
||||
mid[j] = p1[j] + dot*(p2[j]-p1[j]);
|
||||
}
|
||||
|
||||
VectorCopy (mid, f->p[f->numpoints]);
|
||||
f->numpoints++;
|
||||
}
|
||||
|
||||
if (f->numpoints > maxpts)
|
||||
Error ("ClipWinding: points exceeded estimate");
|
||||
if (f->numpoints > MAX_POINTS_ON_WINDING)
|
||||
Error ("ClipWinding: MAX_POINTS_ON_WINDING");
|
||||
|
||||
FreeWinding (in);
|
||||
*inout = f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
ChopWinding
|
||||
|
||||
Returns the fragment of in that is on the front side
|
||||
of the cliping plane. The original is freed.
|
||||
=================
|
||||
*/
|
||||
winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist)
|
||||
{
|
||||
winding_t *f, *b;
|
||||
|
||||
ClipWindingEpsilon (in, normal, dist, ON_EPSILON, &f, &b);
|
||||
FreeWinding (in);
|
||||
if (b)
|
||||
FreeWinding (b);
|
||||
return f;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
CheckWinding
|
||||
|
||||
=================
|
||||
*/
|
||||
void CheckWinding (winding_t *w)
|
||||
{
|
||||
int i, j;
|
||||
vec_t *p1, *p2;
|
||||
vec_t d, edgedist;
|
||||
vec3_t dir, edgenormal, facenormal;
|
||||
vec_t area;
|
||||
vec_t facedist;
|
||||
|
||||
if (w->numpoints < 3)
|
||||
Error ("CheckWinding: %i points",w->numpoints);
|
||||
|
||||
area = WindingArea(w);
|
||||
if (area < 1)
|
||||
Error ("CheckWinding: %f area", area);
|
||||
|
||||
WindingPlane (w, facenormal, &facedist);
|
||||
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
p1 = w->p[i];
|
||||
|
||||
for (j=0 ; j<3 ; j++)
|
||||
if (p1[j] > BOGUS_RANGE || p1[j] < -BOGUS_RANGE)
|
||||
Error ("CheckFace: BUGUS_RANGE: %f",p1[j]);
|
||||
|
||||
j = i+1 == w->numpoints ? 0 : i+1;
|
||||
|
||||
// check the point is on the face plane
|
||||
d = DotProduct (p1, facenormal) - facedist;
|
||||
if (d < -ON_EPSILON || d > ON_EPSILON)
|
||||
Error ("CheckWinding: point off plane");
|
||||
|
||||
// check the edge isnt degenerate
|
||||
p2 = w->p[j];
|
||||
VectorSubtract (p2, p1, dir);
|
||||
|
||||
if (VectorLength (dir) < ON_EPSILON)
|
||||
Error ("CheckWinding: degenerate edge");
|
||||
|
||||
CrossProduct (facenormal, dir, edgenormal);
|
||||
VectorNormalize (edgenormal, edgenormal);
|
||||
edgedist = DotProduct (p1, edgenormal);
|
||||
edgedist += ON_EPSILON;
|
||||
|
||||
// all other points must be on front side
|
||||
for (j=0 ; j<w->numpoints ; j++)
|
||||
{
|
||||
if (j == i)
|
||||
continue;
|
||||
d = DotProduct (w->p[j], edgenormal);
|
||||
if (d > edgedist)
|
||||
Error ("CheckWinding: non-convex");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
============
|
||||
WindingOnPlaneSide
|
||||
============
|
||||
*/
|
||||
int WindingOnPlaneSide (winding_t *w, vec3_t normal, vec_t dist)
|
||||
{
|
||||
qboolean front, back;
|
||||
int i;
|
||||
vec_t d;
|
||||
|
||||
front = false;
|
||||
back = false;
|
||||
for (i=0 ; i<w->numpoints ; i++)
|
||||
{
|
||||
d = DotProduct (w->p[i], normal) - dist;
|
||||
if (d < -ON_EPSILON)
|
||||
{
|
||||
if (front)
|
||||
return SIDE_CROSS;
|
||||
back = true;
|
||||
continue;
|
||||
}
|
||||
if (d > ON_EPSILON)
|
||||
{
|
||||
if (back)
|
||||
return SIDE_CROSS;
|
||||
front = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (back)
|
||||
return SIDE_BACK;
|
||||
if (front)
|
||||
return SIDE_FRONT;
|
||||
return SIDE_ON;
|
||||
}
|
||||
|
||||
55
tools/quake2/qdata_heretic2/common/polylib.h
Normal file
55
tools/quake2/qdata_heretic2/common/polylib.h
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int numpoints;
|
||||
vec3_t p[4]; // variable sized
|
||||
} winding_t;
|
||||
|
||||
#define MAX_POINTS_ON_WINDING 64
|
||||
|
||||
// you can define on_epsilon in the makefile as tighter
|
||||
#ifndef ON_EPSILON
|
||||
#define ON_EPSILON 0.1
|
||||
#endif
|
||||
|
||||
winding_t *AllocWinding (int points);
|
||||
vec_t WindingArea (winding_t *w);
|
||||
void WindingCenter (winding_t *w, vec3_t center);
|
||||
void ClipWindingEpsilon (winding_t *in, vec3_t normal, vec_t dist,
|
||||
vec_t epsilon, winding_t **front, winding_t **back);
|
||||
winding_t *ChopWinding (winding_t *in, vec3_t normal, vec_t dist);
|
||||
winding_t *CopyWinding (winding_t *w);
|
||||
winding_t *ReverseWinding (winding_t *w);
|
||||
winding_t *BaseWindingForPlane (vec3_t normal, vec_t dist);
|
||||
void CheckWinding (winding_t *w);
|
||||
void WindingPlane (winding_t *w, vec3_t normal, vec_t *dist);
|
||||
void RemoveColinearPoints (winding_t *w);
|
||||
int WindingOnPlaneSide (winding_t *w, vec3_t normal, vec_t dist);
|
||||
void FreeWinding (winding_t *w);
|
||||
void WindingBounds (winding_t *w, vec3_t mins, vec3_t maxs);
|
||||
|
||||
void ChopWindingInPlace (winding_t **w, vec3_t normal, vec_t dist, vec_t epsilon);
|
||||
// frees the original if clipped
|
||||
|
||||
void pw(winding_t *w);
|
||||
82
tools/quake2/qdata_heretic2/common/qfiles.c
Normal file
82
tools/quake2/qdata_heretic2/common/qfiles.c
Normal file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "qfiles.h"
|
||||
#include "scriplib.h"
|
||||
//#include <windows.h>
|
||||
|
||||
materialtype_t defaultmaterialtypes[] =
|
||||
{
|
||||
{"gravel", MATERIAL_GRAVEL},
|
||||
{"metal", MATERIAL_METAL},
|
||||
{"stone", MATERIAL_STONE},
|
||||
{"wood", MATERIAL_WOOD},
|
||||
{NULL, 0}
|
||||
};
|
||||
|
||||
materialtype_t *materialtypes;
|
||||
|
||||
void QFile_ReadMaterialTypes(char* filename)
|
||||
{
|
||||
int i;
|
||||
FILE *f;
|
||||
|
||||
f = fopen (filename, "rb");
|
||||
if (!f)
|
||||
{
|
||||
materialtypes = defaultmaterialtypes;
|
||||
return;
|
||||
}
|
||||
fclose (f);
|
||||
|
||||
free(materialtypes);
|
||||
materialtypes = (materialtype_t*)malloc(256 * sizeof(materialtype_t));
|
||||
|
||||
LoadScriptFile(filename);
|
||||
i = 0;
|
||||
|
||||
while (i < 255)
|
||||
{
|
||||
GetScriptToken (true);
|
||||
if (endofscript)
|
||||
{
|
||||
break;
|
||||
}
|
||||
if (strcmp(token, "material") != 0)
|
||||
{
|
||||
while (ScriptTokenAvailable())
|
||||
{
|
||||
GetScriptToken(false);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GetScriptToken(false);
|
||||
materialtypes[i].name = (char*)malloc(strlen(token) + 1);
|
||||
strcpy(materialtypes[i].name, token);
|
||||
GetScriptToken (false);
|
||||
materialtypes[i].value = atoi(token);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
materialtypes[i].name = NULL;
|
||||
materialtypes[i].value = 0;
|
||||
}
|
||||
619
tools/quake2/qdata_heretic2/common/qfiles.h
Normal file
619
tools/quake2/qdata_heretic2/common/qfiles.h
Normal file
@@ -0,0 +1,619 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef _QFILES_H
|
||||
#define _QFILES_H
|
||||
|
||||
#include "q_typedef.h"
|
||||
|
||||
//
|
||||
// qfiles.h: quake file formats
|
||||
// This file must be identical in the quake and utils directories
|
||||
//
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
The .pak files are just a linear collapse of a directory tree
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
#define IDPAKHEADER (('K'<<24)+('C'<<16)+('A'<<8)+'P')
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[56];
|
||||
int filepos, filelen;
|
||||
} dpackfile_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident; // == IDPAKHEADER
|
||||
int dirofs;
|
||||
int dirlen;
|
||||
} dpackheader_t;
|
||||
|
||||
#define MAX_FILES_IN_PACK 4096
|
||||
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
PCX files are used for as many images as possible
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char manufacturer;
|
||||
char version;
|
||||
char encoding;
|
||||
char bits_per_pixel;
|
||||
unsigned short xmin,ymin,xmax,ymax;
|
||||
unsigned short hres,vres;
|
||||
unsigned char palette[48];
|
||||
char reserved;
|
||||
char color_planes;
|
||||
unsigned short bytes_per_line;
|
||||
unsigned short palette_type;
|
||||
char filler[58];
|
||||
unsigned char data; // unbounded
|
||||
} pcx_t;
|
||||
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.MD2 compressed triangle model file format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
#define IDJOINTEDALIASHEADER (('2'<<24)+('J'<<16)+('D'<<8)+'I')
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.MD2 triangle model file format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
#define IDALIASHEADER (('2'<<24)+('P'<<16)+('D'<<8)+'I')
|
||||
#define ALIAS_VERSION 8
|
||||
|
||||
#define MAX_TRIANGLES 2048
|
||||
#define MAX_VERTS 2048
|
||||
#define MAX_FRAMES 512
|
||||
#define MAX_MD2SKINS 64
|
||||
#define MAX_SKINNAME 64
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short s;
|
||||
short t;
|
||||
} dstvert_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
short index_xyz[3];
|
||||
short index_st[3];
|
||||
} dtriangle_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
byte v[3]; // scaled byte to fit in frame mins/maxs
|
||||
byte lightnormalindex;
|
||||
} dtrivertx_t;
|
||||
|
||||
#define DTRIVERTX_V0 0
|
||||
#define DTRIVERTX_V1 1
|
||||
#define DTRIVERTX_V2 2
|
||||
#define DTRIVERTX_LNI 3
|
||||
#define DTRIVERTX_SIZE 4
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float scale[3]; // multiply byte verts by this
|
||||
float translate[3]; // then add this
|
||||
char name[16]; // frame name from grabbing
|
||||
dtrivertx_t verts[1]; // variable sized
|
||||
} daliasframe_t;
|
||||
|
||||
|
||||
// the glcmd format:
|
||||
// a positive integer starts a tristrip command, followed by that many
|
||||
// vertex structures.
|
||||
// a negative integer starts a trifan command, followed by -x vertexes
|
||||
// a zero indicates the end of the command list.
|
||||
// a vertex consists of a floating point s, a floating point t,
|
||||
// and an integer vertex index.
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
|
||||
int skinwidth;
|
||||
int skinheight;
|
||||
int framesize; // byte size of each frame
|
||||
|
||||
int num_skins;
|
||||
int num_xyz;
|
||||
int num_st; // greater than num_xyz for seams
|
||||
int num_tris;
|
||||
int num_glcmds; // dwords in strip/fan command list
|
||||
int num_frames;
|
||||
|
||||
int ofs_skins; // each skin is a MAX_SKINNAME string
|
||||
int ofs_st; // byte offset from start for stverts
|
||||
int ofs_tris; // offset for dtriangles
|
||||
int ofs_frames; // offset for first frame
|
||||
int ofs_glcmds;
|
||||
int ofs_end; // end of file
|
||||
|
||||
} dmdl_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.BK file format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
#define IDBOOKHEADER (('K'<<24)+('O'<<16)+('O'<<8)+'B')
|
||||
#define BOOK_VERSION 2
|
||||
|
||||
typedef struct bookframe_s
|
||||
{
|
||||
int x;
|
||||
int y;
|
||||
int w;
|
||||
int h;
|
||||
char name[MAX_SKINNAME]; // name of gfx file
|
||||
} bookframe_t;
|
||||
|
||||
typedef struct bookheader_s
|
||||
{
|
||||
unsigned int ident;
|
||||
unsigned int version;
|
||||
int num_segments;
|
||||
int total_w;
|
||||
int total_h;
|
||||
} bookheader_t;
|
||||
|
||||
typedef struct book_s
|
||||
{
|
||||
bookheader_t bheader;
|
||||
bookframe_t bframes[MAX_MD2SKINS];
|
||||
} book_t;
|
||||
|
||||
/*
|
||||
========================================================================
|
||||
|
||||
.SP2 sprite file format
|
||||
|
||||
========================================================================
|
||||
*/
|
||||
|
||||
#define IDSPRITEHEADER (('2'<<24)+('S'<<16)+('D'<<8)+'I')
|
||||
// little-endian "IDS2"
|
||||
#define SPRITE_VERSION 2
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int width, height;
|
||||
int origin_x, origin_y; // raster coordinates inside pic
|
||||
char name[MAX_SKINNAME]; // name of pcx file
|
||||
} dsprframe_t;
|
||||
|
||||
typedef struct {
|
||||
int ident;
|
||||
int version;
|
||||
int numframes;
|
||||
dsprframe_t frames[1]; // variable sized
|
||||
} dsprite_t;
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
.M8 texture file format
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
typedef struct palette_s
|
||||
{
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
byte r,g,b;
|
||||
};
|
||||
};
|
||||
} palette_t;
|
||||
|
||||
#define MIP_VERSION 2
|
||||
#define PAL_SIZE 256
|
||||
#define MIPLEVELS 16
|
||||
|
||||
typedef struct miptex_s
|
||||
{
|
||||
int version;
|
||||
char name[32];
|
||||
unsigned width[MIPLEVELS], height[MIPLEVELS];
|
||||
unsigned offsets[MIPLEVELS]; // four mip maps stored
|
||||
char animname[32]; // next frame in animation chain
|
||||
palette_t palette[PAL_SIZE];
|
||||
int flags;
|
||||
int contents;
|
||||
int value;
|
||||
} miptex_t;
|
||||
|
||||
|
||||
#define MIP32_VERSION 4
|
||||
|
||||
#define MIP32_NOMIP_FLAG2 0x00000001
|
||||
#define MIP32_DETAILER_FLAG2 0x00000002
|
||||
|
||||
typedef struct miptex32_s
|
||||
{
|
||||
int version;
|
||||
char name[128];
|
||||
char altname[128]; // texture substitution
|
||||
char animname[128]; // next frame in animation chain
|
||||
char damagename[128]; // image that should be shown when damaged
|
||||
unsigned width[MIPLEVELS], height[MIPLEVELS];
|
||||
unsigned offsets[MIPLEVELS];
|
||||
int flags;
|
||||
int contents;
|
||||
int value;
|
||||
float scale_x, scale_y;
|
||||
int mip_scale;
|
||||
|
||||
// detail texturing info
|
||||
char dt_name[128]; // detailed texture name
|
||||
float dt_scale_x, dt_scale_y;
|
||||
float dt_u, dt_v;
|
||||
float dt_alpha;
|
||||
int dt_src_blend_mode, dt_dst_blend_mode;
|
||||
|
||||
int flags2;
|
||||
int unused[19]; // future expansion to maintain compatibility with h2
|
||||
} miptex32_t;
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================
|
||||
|
||||
.BSP file format
|
||||
|
||||
==============================================================================
|
||||
*/
|
||||
|
||||
#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I')
|
||||
// little-endian "IBSP"
|
||||
|
||||
#define BSPVERSION 38
|
||||
|
||||
|
||||
// upper design bounds
|
||||
// leaffaces, leafbrushes, planes, and verts are still bounded by
|
||||
// 16 bit short limits
|
||||
#define MAX_MAP_MODELS 1024
|
||||
#define MAX_MAP_BRUSHES 8192
|
||||
#define MAX_MAP_ENTITIES 2048
|
||||
#define MAX_MAP_ENTSTRING 0x40000
|
||||
#define MAX_MAP_TEXINFO 8192
|
||||
|
||||
#define MAX_MAP_AREAS 256
|
||||
#define MAX_MAP_AREAPORTALS 1024
|
||||
#define MAX_MAP_PLANES 65536
|
||||
#define MAX_MAP_NODES 65536
|
||||
#define MAX_MAP_BRUSHSIDES 65536
|
||||
#define MAX_MAP_LEAFS 65536
|
||||
#define MAX_MAP_VERTS 65536
|
||||
#define MAX_MAP_FACES 65536
|
||||
#define MAX_MAP_LEAFFACES 65536
|
||||
#define MAX_MAP_LEAFBRUSHES 65536
|
||||
#define MAX_MAP_PORTALS 65536
|
||||
#define MAX_MAP_EDGES 128000
|
||||
#define MAX_MAP_SURFEDGES 256000
|
||||
#define MAX_MAP_LIGHTING 0x200000
|
||||
#define MAX_MAP_VISIBILITY 0x180000
|
||||
|
||||
// key / value pair sizes
|
||||
|
||||
#define MAX_KEY 32
|
||||
#define MAX_VALUE 1024
|
||||
|
||||
//=============================================================================
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int fileofs, filelen;
|
||||
} lump_t;
|
||||
|
||||
#define LUMP_ENTITIES 0
|
||||
#define LUMP_PLANES 1
|
||||
#define LUMP_VERTEXES 2
|
||||
#define LUMP_VISIBILITY 3
|
||||
#define LUMP_NODES 4
|
||||
#define LUMP_TEXINFO 5
|
||||
#define LUMP_FACES 6
|
||||
#define LUMP_LIGHTING 7
|
||||
#define LUMP_LEAFS 8
|
||||
#define LUMP_LEAFFACES 9
|
||||
#define LUMP_LEAFBRUSHES 10
|
||||
#define LUMP_EDGES 11
|
||||
#define LUMP_SURFEDGES 12
|
||||
#define LUMP_MODELS 13
|
||||
#define LUMP_BRUSHES 14
|
||||
#define LUMP_BRUSHSIDES 15
|
||||
#define LUMP_POP 16
|
||||
#define LUMP_AREAS 17
|
||||
#define LUMP_AREAPORTALS 18
|
||||
#define HEADER_LUMPS 19
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int ident;
|
||||
int version;
|
||||
lump_t lumps[HEADER_LUMPS];
|
||||
} dheader_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float mins[3], maxs[3];
|
||||
float origin[3]; // for sounds or lights
|
||||
int headnode;
|
||||
int firstface, numfaces; // submodels just draw faces
|
||||
// without walking the bsp tree
|
||||
} dmodel_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float point[3];
|
||||
} dvertex_t;
|
||||
|
||||
|
||||
// 0-2 are axial planes
|
||||
#define PLANE_X 0
|
||||
#define PLANE_Y 1
|
||||
#define PLANE_Z 2
|
||||
|
||||
// 3-5 are non-axial planes snapped to the nearest
|
||||
#define PLANE_ANYX 3
|
||||
#define PLANE_ANYY 4
|
||||
#define PLANE_ANYZ 5
|
||||
|
||||
// planes (x&~1) and (x&~1)+1 are allways opposites
|
||||
|
||||
typedef struct
|
||||
{
|
||||
float normal[3];
|
||||
float dist;
|
||||
int type; // PLANE_X - PLANE_ANYZ ?remove? trivial to regenerate
|
||||
} dplane_t;
|
||||
|
||||
|
||||
// contents flags are seperate bits
|
||||
// a given brush can contribute multiple content bits
|
||||
// multiple brushes can be in a single leaf
|
||||
|
||||
// these definitions also need to be in q_shared.h!
|
||||
|
||||
// lower bits are stronger, and will eat weaker brushes completely
|
||||
#define CONTENTS_SOLID 0x00000001 // an eye is never valid in a solid
|
||||
#define CONTENTS_WINDOW 0x00000002 // translucent, but not watery
|
||||
#define CONTENTS_PUSHPULL 0x00000004
|
||||
#define CONTENTS_LAVA 0x00000008
|
||||
#define CONTENTS_SLIME 0x00000010
|
||||
#define CONTENTS_WATER 0x00000020
|
||||
#define CONTENTS_MIST 0x00000040 // 64
|
||||
#define LAST_VISIBLE_CONTENTS 64 // this one worries me a bit JKH
|
||||
|
||||
// remaining contents are non-visible, and don't eat brushes
|
||||
|
||||
#define CONTENTS_AREAPORTAL 0x00008000
|
||||
|
||||
#define CONTENTS_PLAYERCLIP 0x00010000
|
||||
#define CONTENTS_MONSTERCLIP 0x00020000
|
||||
|
||||
// currents can be added to any other contents, and may be mixed
|
||||
#define CONTENTS_CURRENT_0 0x00040000
|
||||
#define CONTENTS_CURRENT_90 0x00080000
|
||||
#define CONTENTS_CURRENT_180 0x00100000
|
||||
#define CONTENTS_CURRENT_270 0x00200000
|
||||
#define CONTENTS_CURRENT_UP 0x00400000
|
||||
#define CONTENTS_CURRENT_DOWN 0x00800000
|
||||
|
||||
#define CONTENTS_ORIGIN 0x01000000 // removed before bsping an entity
|
||||
|
||||
#define CONTENTS_MONSTER 0x02000000 // should never be on a brush, only in game
|
||||
#define CONTENTS_DEADMONSTER 0x04000000
|
||||
#define CONTENTS_DETAIL 0x08000000 // brushes to be added after vis leafs
|
||||
#define CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans
|
||||
#define CONTENTS_LADDER 0x20000000
|
||||
|
||||
|
||||
|
||||
#define SURF_LIGHT 0x00000001 // value will hold the light strength
|
||||
|
||||
#define SURF_SLICK 0x00000002 // effects game physics
|
||||
|
||||
#define SURF_SKY 0x00000004 // don't draw, but add to skybox
|
||||
#define SURF_WARP 0x00000008 // turbulent water warp
|
||||
#define SURF_TRANS33 0x00000010
|
||||
#define SURF_TRANS66 0x00000020
|
||||
#define SURF_FLOWING 0x00000040 // scroll towards angle
|
||||
#define SURF_NODRAW 0x00000080 // don't bother referencing the texture
|
||||
|
||||
#define SURF_HINT 0x00000100 // make a primary bsp splitter
|
||||
#define SURF_SKIP 0x00000200 // completely ignore, allowing non-closed brushes
|
||||
#define SURF_TALL_WALL 0x00000400 // face doesn't get broken up as normal
|
||||
|
||||
#define SURF_ALPHA_TEXTURE 0x00000800 // texture has alpha in it, and should show through in bsp process
|
||||
#define SURF_ANIMSPEED 0x00001000 // value will hold the anim speed in fps
|
||||
|
||||
#define SURF_UNDULATE 0x00002000 // rock surface up and down...
|
||||
#define SURF_SKYREFLECT 0x00004000 // liquid will somewhat reflect the sky - not quite finished....
|
||||
|
||||
#define SURF_TYPE_GRAVEL 0x00000000
|
||||
#define SURF_TYPE_METAL 0x01000000
|
||||
#define SURF_TYPE_STONE 0x02000000
|
||||
#define SURF_TYPE_WOOD 0x03000000
|
||||
#define SURF_MATERIAL 0xFF000000
|
||||
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int planenum;
|
||||
int children[2]; // negative numbers are -(leafs+1), not nodes
|
||||
short mins[3]; // for frustom culling
|
||||
short maxs[3];
|
||||
unsigned short firstface;
|
||||
unsigned short numfaces; // counting both sides
|
||||
} dnode_t;
|
||||
|
||||
|
||||
typedef struct texinfo_s
|
||||
{
|
||||
float vecs[2][4]; // [s/t][xyz offset]
|
||||
int flags; // miptex flags + overrides
|
||||
int value; // light emission, etc
|
||||
char texture[32]; // texture name (textures/*.wal)
|
||||
int nexttexinfo; // for animations, -1 = end of chain
|
||||
} texinfo_t;
|
||||
|
||||
|
||||
// note that edge 0 is never used, because negative edge nums are used for
|
||||
// counterclockwise use of the edge in a face
|
||||
typedef struct
|
||||
{
|
||||
unsigned short v[2]; // vertex numbers
|
||||
} dedge_t;
|
||||
|
||||
#define MAXLIGHTMAPS 4
|
||||
typedef struct
|
||||
{
|
||||
unsigned short planenum;
|
||||
short side;
|
||||
|
||||
int firstedge; // we must support > 64k edges
|
||||
short numedges;
|
||||
short texinfo;
|
||||
|
||||
// lighting info
|
||||
union {
|
||||
byte styles[MAXLIGHTMAPS];
|
||||
paletteRGBA_t lighting;
|
||||
};
|
||||
int lightofs; // start of [numstyles*surfsize] samples
|
||||
} dface_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int contents; // OR of all brushes (not needed?)
|
||||
|
||||
short cluster;
|
||||
short area;
|
||||
|
||||
short mins[3]; // for frustum culling
|
||||
short maxs[3];
|
||||
|
||||
unsigned short firstleafface;
|
||||
unsigned short numleaffaces;
|
||||
|
||||
unsigned short firstleafbrush;
|
||||
unsigned short numleafbrushes;
|
||||
} dleaf_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned short planenum; // facing out of the leaf
|
||||
short texinfo;
|
||||
} dbrushside_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int firstside;
|
||||
int numsides;
|
||||
int contents;
|
||||
} dbrush_t;
|
||||
|
||||
#define ANGLE_UP -1
|
||||
#define ANGLE_DOWN -2
|
||||
|
||||
|
||||
// the visibility lump consists of a header with a count, then
|
||||
// byte offsets for the PVS and PHS of each cluster, then the raw
|
||||
// compressed bit vectors
|
||||
#define DVIS_PVS 0
|
||||
#define DVIS_PHS 1
|
||||
typedef struct
|
||||
{
|
||||
int numclusters;
|
||||
int bitofs[8][2]; // bitofs[numclusters][2]
|
||||
} dvis_t;
|
||||
|
||||
// each area has a list of portals that lead into other areas
|
||||
// when portals are closed, other areas may not be visible or
|
||||
// hearable even if the vis info says that it should be
|
||||
typedef struct
|
||||
{
|
||||
int portalnum;
|
||||
int otherarea;
|
||||
} dareaportal_t;
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int numareaportals;
|
||||
int firstareaportal;
|
||||
} darea_t;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char *name;
|
||||
int value;
|
||||
} materialtype_t;
|
||||
|
||||
enum
|
||||
{
|
||||
MATERIAL_GRAVEL,
|
||||
MATERIAL_METAL,
|
||||
MATERIAL_STONE,
|
||||
MATERIAL_WOOD,
|
||||
};
|
||||
|
||||
materialtype_t *materialtypes;
|
||||
|
||||
void QFile_ReadMaterialTypes(char* filename);
|
||||
|
||||
|
||||
#endif //_QFILES_H
|
||||
297
tools/quake2/qdata_heretic2/common/scriplib.c
Normal file
297
tools/quake2/qdata_heretic2/common/scriplib.c
Normal file
@@ -0,0 +1,297 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// scriplib.c
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "inout.h"
|
||||
#include "scriplib.h"
|
||||
|
||||
/*
|
||||
=============================================================================
|
||||
|
||||
PARSING STUFF
|
||||
|
||||
=============================================================================
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char filename[1024];
|
||||
char *buffer,*script_p,*end_p;
|
||||
int line;
|
||||
} script_t;
|
||||
|
||||
#define MAX_INCLUDES 8
|
||||
script_t scriptstack[MAX_INCLUDES];
|
||||
script_t *script;
|
||||
int scriptline;
|
||||
|
||||
char token[MAXTOKEN];
|
||||
qboolean endofscript;
|
||||
qboolean tokenready; // only true if UnGetScriptToken was just called
|
||||
|
||||
/*
|
||||
==============
|
||||
AddScriptToStack
|
||||
==============
|
||||
*/
|
||||
void AddScriptToStack (char *filename)
|
||||
{
|
||||
int size;
|
||||
|
||||
script++;
|
||||
if (script == &scriptstack[MAX_INCLUDES])
|
||||
Error ("script file exceeded MAX_INCLUDES");
|
||||
strcpy (script->filename, ExpandPath (filename) );
|
||||
|
||||
size = LoadFile (script->filename, (void **)&script->buffer);
|
||||
|
||||
printf ("entering %s\n", script->filename);
|
||||
|
||||
script->line = 1;
|
||||
|
||||
script->script_p = script->buffer;
|
||||
script->end_p = script->buffer + size;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
LoadScriptFile
|
||||
==============
|
||||
*/
|
||||
void LoadScriptFile (char *filename)
|
||||
{
|
||||
script = scriptstack;
|
||||
AddScriptToStack (filename);
|
||||
|
||||
endofscript = false;
|
||||
tokenready = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
ParseFromMemory
|
||||
==============
|
||||
*/
|
||||
void ParseFromMemory (char *buffer, int size)
|
||||
{
|
||||
script = scriptstack;
|
||||
script++;
|
||||
if (script == &scriptstack[MAX_INCLUDES])
|
||||
Error ("script file exceeded MAX_INCLUDES");
|
||||
strcpy (script->filename, "memory buffer" );
|
||||
|
||||
script->buffer = buffer;
|
||||
script->line = 1;
|
||||
script->script_p = script->buffer;
|
||||
script->end_p = script->buffer + size;
|
||||
|
||||
endofscript = false;
|
||||
tokenready = false;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
UnGetScriptToken
|
||||
|
||||
Signals that the current token was not used, and should be reported
|
||||
for the next GetScriptToken. Note that
|
||||
|
||||
GetScriptToken (true);
|
||||
UnGetScriptToken ();
|
||||
GetScriptToken (false);
|
||||
|
||||
could cross a line boundary.
|
||||
==============
|
||||
*/
|
||||
void UnGetScriptToken (void)
|
||||
{
|
||||
tokenready = true;
|
||||
}
|
||||
|
||||
|
||||
qboolean EndOfScript (qboolean crossline)
|
||||
{
|
||||
if (!crossline)
|
||||
Error ("Line %i is incomplete\n",scriptline);
|
||||
|
||||
if (!strcmp (script->filename, "memory buffer"))
|
||||
{
|
||||
endofscript = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
free (script->buffer);
|
||||
if (script == scriptstack+1)
|
||||
{
|
||||
endofscript = true;
|
||||
return false;
|
||||
}
|
||||
script--;
|
||||
scriptline = script->line;
|
||||
printf ("returning to %s\n", script->filename);
|
||||
return GetScriptToken (crossline);
|
||||
}
|
||||
|
||||
/*
|
||||
==============
|
||||
GetScriptToken
|
||||
==============
|
||||
*/
|
||||
qboolean GetScriptToken (qboolean crossline)
|
||||
{
|
||||
char *token_p;
|
||||
|
||||
if (tokenready) // is a token allready waiting?
|
||||
{
|
||||
tokenready = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
if (script->script_p >= script->end_p)
|
||||
return EndOfScript (crossline);
|
||||
|
||||
//
|
||||
// skip space
|
||||
//
|
||||
skipspace:
|
||||
while (*script->script_p <= 32)
|
||||
{
|
||||
if (script->script_p >= script->end_p)
|
||||
return EndOfScript (crossline);
|
||||
if (*script->script_p++ == '\n')
|
||||
{
|
||||
if (!crossline)
|
||||
Error ("Line %i is incomplete\n",scriptline);
|
||||
scriptline = script->line++;
|
||||
}
|
||||
}
|
||||
|
||||
if (script->script_p >= script->end_p)
|
||||
return EndOfScript (crossline);
|
||||
|
||||
// ; # // comments
|
||||
if (*script->script_p == ';' || *script->script_p == '#'
|
||||
|| ( script->script_p[0] == '/' && script->script_p[1] == '/') )
|
||||
{
|
||||
if (!crossline)
|
||||
Error ("Line %i is incomplete\n",scriptline);
|
||||
while (*script->script_p++ != '\n')
|
||||
if (script->script_p >= script->end_p)
|
||||
return EndOfScript (crossline);
|
||||
goto skipspace;
|
||||
}
|
||||
|
||||
// /* */ comments
|
||||
if (script->script_p[0] == '/' && script->script_p[1] == '*')
|
||||
{
|
||||
if (!crossline)
|
||||
Error ("Line %i is incomplete\n",scriptline);
|
||||
script->script_p+=2;
|
||||
while (script->script_p[0] != '*' && script->script_p[1] != '/')
|
||||
{
|
||||
script->script_p++;
|
||||
if (script->script_p >= script->end_p)
|
||||
return EndOfScript (crossline);
|
||||
}
|
||||
script->script_p += 2;
|
||||
goto skipspace;
|
||||
}
|
||||
|
||||
//
|
||||
// copy token
|
||||
//
|
||||
token_p = token;
|
||||
|
||||
if (*script->script_p == '"')
|
||||
{
|
||||
// quoted token
|
||||
script->script_p++;
|
||||
while (*script->script_p != '"')
|
||||
{
|
||||
*token_p++ = *script->script_p++;
|
||||
if (script->script_p == script->end_p)
|
||||
break;
|
||||
if (token_p == &token[MAXTOKEN])
|
||||
Error ("Token too large on line %i\n",scriptline);
|
||||
}
|
||||
script->script_p++;
|
||||
}
|
||||
else // regular token
|
||||
while ( *script->script_p > 32 && *script->script_p != ';')
|
||||
{
|
||||
*token_p++ = *script->script_p++;
|
||||
if (script->script_p == script->end_p)
|
||||
break;
|
||||
if (token_p == &token[MAXTOKEN])
|
||||
Error ("Token too large on line %i\n",scriptline);
|
||||
}
|
||||
|
||||
*token_p = 0;
|
||||
|
||||
if (!strcmp (token, "$include"))
|
||||
{
|
||||
GetScriptToken (false);
|
||||
AddScriptToStack (token);
|
||||
return GetScriptToken (crossline);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
==============
|
||||
ScriptTokenAvailable
|
||||
|
||||
Returns true if there is another token on the line
|
||||
==============
|
||||
*/
|
||||
qboolean ScriptTokenAvailable (void)
|
||||
{
|
||||
char *search_p;
|
||||
|
||||
search_p = script->script_p;
|
||||
|
||||
if (search_p >= script->end_p)
|
||||
return false;
|
||||
|
||||
while ( *search_p <= 32)
|
||||
{
|
||||
if (*search_p == '\n')
|
||||
return false;
|
||||
search_p++;
|
||||
if (search_p == script->end_p)
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
if (*search_p == ';')
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
44
tools/quake2/qdata_heretic2/common/scriplib.h
Normal file
44
tools/quake2/qdata_heretic2/common/scriplib.h
Normal file
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
// scriplib.h
|
||||
|
||||
#ifndef __CMDLIB__
|
||||
#include "cmdlib.h"
|
||||
#endif
|
||||
|
||||
#define MAXTOKEN 1024
|
||||
|
||||
extern char token[MAXTOKEN];
|
||||
extern char *scriptbuffer,*script_p,*scriptend_p;
|
||||
extern int grabbed;
|
||||
extern int scriptline;
|
||||
extern qboolean endofscript;
|
||||
|
||||
|
||||
void LoadScriptFile (char *filename);
|
||||
void ParseFromMemory (char *buffer, int size);
|
||||
|
||||
qboolean GetScriptToken (qboolean crossline);
|
||||
void UnGetScriptToken (void);
|
||||
qboolean ScriptTokenAvailable (void);
|
||||
|
||||
|
||||
620
tools/quake2/qdata_heretic2/common/threads.c
Normal file
620
tools/quake2/qdata_heretic2/common/threads.c
Normal file
@@ -0,0 +1,620 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#ifndef WIN32
|
||||
// The below define is necessary to use
|
||||
// pthreads extensions like pthread_mutexattr_settype
|
||||
#define _GNU_SOURCE
|
||||
#include <pthread.h>
|
||||
#endif
|
||||
|
||||
#include "cmdlib.h"
|
||||
#include "mathlib.h"
|
||||
#include "inout.h"
|
||||
#include "her2_threads.h"
|
||||
|
||||
#define MAX_THREADS 64
|
||||
|
||||
int dispatch;
|
||||
int workcount;
|
||||
int oldf;
|
||||
qboolean pacifier;
|
||||
|
||||
qboolean threaded;
|
||||
|
||||
/*
|
||||
=============
|
||||
GetThreadWork
|
||||
|
||||
=============
|
||||
*/
|
||||
int GetThreadWork (void)
|
||||
{
|
||||
int r;
|
||||
int f;
|
||||
|
||||
ThreadLock ();
|
||||
|
||||
if (dispatch == workcount)
|
||||
{
|
||||
ThreadUnlock ();
|
||||
return -1;
|
||||
}
|
||||
|
||||
f = 10*dispatch / workcount;
|
||||
if (f != oldf)
|
||||
{
|
||||
oldf = f;
|
||||
if (pacifier)
|
||||
{
|
||||
Sys_Printf ("%i...", f);
|
||||
fflush( stdout ); /* ydnar */
|
||||
}
|
||||
}
|
||||
|
||||
r = dispatch;
|
||||
dispatch++;
|
||||
ThreadUnlock ();
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
void (*workfunction) (int);
|
||||
|
||||
void ThreadWorkerFunction (int threadnum)
|
||||
{
|
||||
int work;
|
||||
|
||||
while (1)
|
||||
{
|
||||
work = GetThreadWork ();
|
||||
if (work == -1)
|
||||
break;
|
||||
//Sys_Printf ("thread %i, work %i\n", threadnum, work);
|
||||
workfunction(work);
|
||||
}
|
||||
}
|
||||
|
||||
void RunThreadsOnIndividual (int workcnt, qboolean showpacifier, void(*func)(int))
|
||||
{
|
||||
if (numthreads == -1)
|
||||
ThreadSetDefault ();
|
||||
workfunction = func;
|
||||
RunThreadsOn (workcnt, showpacifier, ThreadWorkerFunction);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
===================================================================
|
||||
|
||||
WIN32
|
||||
|
||||
===================================================================
|
||||
*/
|
||||
#ifdef WIN32
|
||||
|
||||
#define USED
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
int numthreads = -1;
|
||||
CRITICAL_SECTION crit;
|
||||
static int enter;
|
||||
|
||||
void ThreadSetDefault (void)
|
||||
{
|
||||
SYSTEM_INFO info;
|
||||
|
||||
if (numthreads == -1) // not set manually
|
||||
{
|
||||
GetSystemInfo (&info);
|
||||
numthreads = info.dwNumberOfProcessors;
|
||||
if (numthreads < 1 || numthreads > 32)
|
||||
numthreads = 1;
|
||||
}
|
||||
|
||||
Sys_Printf ("%i threads\n", numthreads);
|
||||
}
|
||||
|
||||
|
||||
void ThreadLock (void)
|
||||
{
|
||||
if (!threaded)
|
||||
return;
|
||||
EnterCriticalSection (&crit);
|
||||
if (enter)
|
||||
Error ("Recursive ThreadLock\n");
|
||||
enter = 1;
|
||||
}
|
||||
|
||||
void ThreadUnlock (void)
|
||||
{
|
||||
if (!threaded)
|
||||
return;
|
||||
if (!enter)
|
||||
Error ("ThreadUnlock without lock\n");
|
||||
enter = 0;
|
||||
LeaveCriticalSection (&crit);
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RunThreadsOn
|
||||
=============
|
||||
*/
|
||||
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
|
||||
{
|
||||
int threadid[MAX_THREADS];
|
||||
HANDLE threadhandle[MAX_THREADS];
|
||||
int i;
|
||||
int start, end;
|
||||
|
||||
start = I_FloatTime ();
|
||||
dispatch = 0;
|
||||
workcount = workcnt;
|
||||
oldf = -1;
|
||||
pacifier = showpacifier;
|
||||
threaded = true;
|
||||
|
||||
//
|
||||
// run threads in parallel
|
||||
//
|
||||
InitializeCriticalSection (&crit);
|
||||
|
||||
if (numthreads == 1)
|
||||
{ // use same thread
|
||||
func (0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0 ; i<numthreads ; i++)
|
||||
{
|
||||
threadhandle[i] = CreateThread(
|
||||
NULL, // LPSECURITY_ATTRIBUTES lpsa,
|
||||
//0, // DWORD cbStack,
|
||||
|
||||
/* ydnar: cranking stack size to eliminate radiosity crash with 1MB stack on win32 */
|
||||
(4096 * 1024),
|
||||
|
||||
(LPTHREAD_START_ROUTINE)func, // LPTHREAD_START_ROUTINE lpStartAddr,
|
||||
(LPVOID)i, // LPVOID lpvThreadParm,
|
||||
0, // DWORD fdwCreate,
|
||||
&threadid[i]);
|
||||
}
|
||||
|
||||
for (i=0 ; i<numthreads ; i++)
|
||||
WaitForSingleObject (threadhandle[i], INFINITE);
|
||||
}
|
||||
DeleteCriticalSection (&crit);
|
||||
|
||||
threaded = false;
|
||||
end = I_FloatTime ();
|
||||
if (pacifier)
|
||||
Sys_Printf (" (%i)\n", end-start);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
===================================================================
|
||||
|
||||
OSF1
|
||||
|
||||
===================================================================
|
||||
*/
|
||||
|
||||
#ifdef __osf__
|
||||
#define USED
|
||||
|
||||
int numthreads = 4;
|
||||
|
||||
void ThreadSetDefault (void)
|
||||
{
|
||||
if (numthreads == -1) // not set manually
|
||||
{
|
||||
numthreads = 4;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
pthread_mutex_t *my_mutex;
|
||||
|
||||
void ThreadLock (void)
|
||||
{
|
||||
if (my_mutex)
|
||||
pthread_mutex_lock (my_mutex);
|
||||
}
|
||||
|
||||
void ThreadUnlock (void)
|
||||
{
|
||||
if (my_mutex)
|
||||
pthread_mutex_unlock (my_mutex);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RunThreadsOn
|
||||
=============
|
||||
*/
|
||||
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
|
||||
{
|
||||
int i;
|
||||
pthread_t work_threads[MAX_THREADS];
|
||||
pthread_addr_t status;
|
||||
pthread_attr_t attrib;
|
||||
pthread_mutexattr_t mattrib;
|
||||
int start, end;
|
||||
|
||||
start = I_FloatTime ();
|
||||
dispatch = 0;
|
||||
workcount = workcnt;
|
||||
oldf = -1;
|
||||
pacifier = showpacifier;
|
||||
threaded = true;
|
||||
|
||||
if (pacifier)
|
||||
setbuf (stdout, NULL);
|
||||
|
||||
if (!my_mutex)
|
||||
{
|
||||
my_mutex = safe_malloc (sizeof(*my_mutex));
|
||||
if (pthread_mutexattr_create (&mattrib) == -1)
|
||||
Error ("pthread_mutex_attr_create failed");
|
||||
if (pthread_mutexattr_setkind_np (&mattrib, MUTEX_FAST_NP) == -1)
|
||||
Error ("pthread_mutexattr_setkind_np failed");
|
||||
if (pthread_mutex_init (my_mutex, mattrib) == -1)
|
||||
Error ("pthread_mutex_init failed");
|
||||
}
|
||||
|
||||
if (pthread_attr_create (&attrib) == -1)
|
||||
Error ("pthread_attr_create failed");
|
||||
if (pthread_attr_setstacksize (&attrib, 0x100000) == -1)
|
||||
Error ("pthread_attr_setstacksize failed");
|
||||
|
||||
for (i=0 ; i<numthreads ; i++)
|
||||
{
|
||||
if (pthread_create(&work_threads[i], attrib
|
||||
, (pthread_startroutine_t)func, (pthread_addr_t)i) == -1)
|
||||
Error ("pthread_create failed");
|
||||
}
|
||||
|
||||
for (i=0 ; i<numthreads ; i++)
|
||||
{
|
||||
if (pthread_join (work_threads[i], &status) == -1)
|
||||
Error ("pthread_join failed");
|
||||
}
|
||||
|
||||
threaded = false;
|
||||
|
||||
end = I_FloatTime ();
|
||||
if (pacifier)
|
||||
Sys_Printf (" (%i)\n", end-start);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
===================================================================
|
||||
|
||||
IRIX
|
||||
|
||||
===================================================================
|
||||
*/
|
||||
|
||||
#ifdef _MIPS_ISA
|
||||
#define USED
|
||||
|
||||
#include <task.h>
|
||||
#include <abi_mutex.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/prctl.h>
|
||||
|
||||
|
||||
int numthreads = -1;
|
||||
abilock_t lck;
|
||||
|
||||
void ThreadSetDefault (void)
|
||||
{
|
||||
if (numthreads == -1)
|
||||
numthreads = prctl(PR_MAXPPROCS);
|
||||
Sys_Printf ("%i threads\n", numthreads);
|
||||
usconfig (CONF_INITUSERS, numthreads);
|
||||
}
|
||||
|
||||
|
||||
void ThreadLock (void)
|
||||
{
|
||||
spin_lock (&lck);
|
||||
}
|
||||
|
||||
void ThreadUnlock (void)
|
||||
{
|
||||
release_lock (&lck);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=============
|
||||
RunThreadsOn
|
||||
=============
|
||||
*/
|
||||
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
|
||||
{
|
||||
int i;
|
||||
int pid[MAX_THREADS];
|
||||
int start, end;
|
||||
|
||||
start = I_FloatTime ();
|
||||
dispatch = 0;
|
||||
workcount = workcnt;
|
||||
oldf = -1;
|
||||
pacifier = showpacifier;
|
||||
threaded = true;
|
||||
|
||||
if (pacifier)
|
||||
setbuf (stdout, NULL);
|
||||
|
||||
init_lock (&lck);
|
||||
|
||||
for (i=0 ; i<numthreads-1 ; i++)
|
||||
{
|
||||
pid[i] = sprocsp ( (void (*)(void *, size_t))func, PR_SALL, (void *)i
|
||||
, NULL, 0x200000); // 2 meg stacks
|
||||
if (pid[i] == -1)
|
||||
{
|
||||
perror ("sproc");
|
||||
Error ("sproc failed");
|
||||
}
|
||||
}
|
||||
|
||||
func(i);
|
||||
|
||||
for (i=0 ; i<numthreads-1 ; i++)
|
||||
wait (NULL);
|
||||
|
||||
threaded = false;
|
||||
|
||||
end = I_FloatTime ();
|
||||
if (pacifier)
|
||||
Sys_Printf (" (%i)\n", end-start);
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
||||
Linux pthreads
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
|
||||
#ifdef __linux__
|
||||
#define USED
|
||||
|
||||
int numthreads = 4;
|
||||
|
||||
void ThreadSetDefault (void)
|
||||
{
|
||||
if (numthreads == -1) // not set manually
|
||||
{
|
||||
/* default to one thread, only multi-thread when specifically told to */
|
||||
numthreads = 1;
|
||||
}
|
||||
if(numthreads > 1)
|
||||
Sys_Printf("threads: %d\n", numthreads);
|
||||
}
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
typedef struct pt_mutex_s
|
||||
{
|
||||
pthread_t *owner;
|
||||
pthread_mutex_t a_mutex;
|
||||
pthread_cond_t cond;
|
||||
unsigned int lock;
|
||||
} pt_mutex_t;
|
||||
|
||||
pt_mutex_t global_lock;
|
||||
|
||||
void ThreadLock(void)
|
||||
{
|
||||
pt_mutex_t *pt_mutex = &global_lock;
|
||||
|
||||
if(!threaded)
|
||||
return;
|
||||
|
||||
pthread_mutex_lock(&pt_mutex->a_mutex);
|
||||
if(pthread_equal(pthread_self(), (pthread_t)&pt_mutex->owner))
|
||||
pt_mutex->lock++;
|
||||
else
|
||||
{
|
||||
if((!pt_mutex->owner) && (pt_mutex->lock == 0))
|
||||
{
|
||||
pt_mutex->owner = (pthread_t *)pthread_self();
|
||||
pt_mutex->lock = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
while(1)
|
||||
{
|
||||
pthread_cond_wait(&pt_mutex->cond, &pt_mutex->a_mutex);
|
||||
if((!pt_mutex->owner) && (pt_mutex->lock == 0))
|
||||
{
|
||||
pt_mutex->owner = (pthread_t *)pthread_self();
|
||||
pt_mutex->lock = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pthread_mutex_unlock(&pt_mutex->a_mutex);
|
||||
}
|
||||
|
||||
void ThreadUnlock(void)
|
||||
{
|
||||
pt_mutex_t *pt_mutex = &global_lock;
|
||||
|
||||
if(!threaded)
|
||||
return;
|
||||
|
||||
pthread_mutex_lock(&pt_mutex->a_mutex);
|
||||
pt_mutex->lock--;
|
||||
|
||||
if(pt_mutex->lock == 0)
|
||||
{
|
||||
pt_mutex->owner = NULL;
|
||||
pthread_cond_signal(&pt_mutex->cond);
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&pt_mutex->a_mutex);
|
||||
}
|
||||
|
||||
void recursive_mutex_init(pthread_mutexattr_t attribs)
|
||||
{
|
||||
pt_mutex_t *pt_mutex = &global_lock;
|
||||
|
||||
pt_mutex->owner = NULL;
|
||||
if(pthread_mutex_init(&pt_mutex->a_mutex, &attribs) != 0)
|
||||
Error("pthread_mutex_init failed\n");
|
||||
if(pthread_cond_init(&pt_mutex->cond, NULL) != 0)
|
||||
Error("pthread_cond_init failed\n");
|
||||
|
||||
pt_mutex->lock = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RunThreadsOn
|
||||
=============
|
||||
*/
|
||||
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
|
||||
{
|
||||
pthread_mutexattr_t mattrib;
|
||||
pthread_t work_threads[MAX_THREADS];
|
||||
|
||||
int start, end;
|
||||
int i=0, status=0;
|
||||
|
||||
start = I_FloatTime ();
|
||||
pacifier = showpacifier;
|
||||
|
||||
dispatch = 0;
|
||||
oldf = -1;
|
||||
workcount = workcnt;
|
||||
|
||||
if(numthreads == 1)
|
||||
func(0);
|
||||
else
|
||||
{
|
||||
threaded = true;
|
||||
|
||||
if(pacifier)
|
||||
setbuf(stdout, NULL);
|
||||
|
||||
if(pthread_mutexattr_init(&mattrib) != 0)
|
||||
Error("pthread_mutexattr_init failed");
|
||||
#if __GLIBC_MINOR__ == 1
|
||||
if (pthread_mutexattr_settype(&mattrib, PTHREAD_MUTEX_FAST_NP) != 0)
|
||||
#else
|
||||
if (pthread_mutexattr_settype(&mattrib, PTHREAD_MUTEX_ADAPTIVE_NP) != 0)
|
||||
#endif
|
||||
Error ("pthread_mutexattr_settype failed");
|
||||
recursive_mutex_init(mattrib);
|
||||
|
||||
for (i=0 ; i<numthreads ; i++)
|
||||
{
|
||||
/* Default pthread attributes: joinable & non-realtime scheduling */
|
||||
if(pthread_create(&work_threads[i], NULL, (void*)func, (void*)i) != 0)
|
||||
Error("pthread_create failed");
|
||||
}
|
||||
for (i=0 ; i<numthreads ; i++)
|
||||
{
|
||||
if(pthread_join(work_threads[i], (void **)&status) != 0)
|
||||
Error("pthread_join failed");
|
||||
}
|
||||
pthread_mutexattr_destroy(&mattrib);
|
||||
threaded = false;
|
||||
}
|
||||
|
||||
end = I_FloatTime ();
|
||||
if (pacifier)
|
||||
Sys_Printf (" (%i)\n", end-start);
|
||||
}
|
||||
#endif // ifdef __linux__
|
||||
|
||||
|
||||
/*
|
||||
=======================================================================
|
||||
|
||||
SINGLE THREAD
|
||||
|
||||
=======================================================================
|
||||
*/
|
||||
|
||||
#ifndef USED
|
||||
|
||||
int numthreads = 1;
|
||||
|
||||
void ThreadSetDefault (void)
|
||||
{
|
||||
numthreads = 1;
|
||||
}
|
||||
|
||||
void ThreadLock (void)
|
||||
{
|
||||
}
|
||||
|
||||
void ThreadUnlock (void)
|
||||
{
|
||||
}
|
||||
|
||||
/*
|
||||
=============
|
||||
RunThreadsOn
|
||||
=============
|
||||
*/
|
||||
void RunThreadsOn (int workcnt, qboolean showpacifier, void(*func)(int))
|
||||
{
|
||||
int i;
|
||||
int start, end;
|
||||
|
||||
dispatch = 0;
|
||||
workcount = workcnt;
|
||||
oldf = -1;
|
||||
pacifier = showpacifier;
|
||||
start = I_FloatTime ();
|
||||
func(0);
|
||||
|
||||
end = I_FloatTime ();
|
||||
if (pacifier)
|
||||
Sys_Printf (" (%i)\n", end-start);
|
||||
}
|
||||
|
||||
#endif
|
||||
550
tools/quake2/qdata_heretic2/common/token.c
Normal file
550
tools/quake2/qdata_heretic2/common/token.c
Normal file
@@ -0,0 +1,550 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** token.c
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
// HEADER FILES ------------------------------------------------------------
|
||||
|
||||
#include "token.h"
|
||||
#include "inout.h"
|
||||
|
||||
// MACROS ------------------------------------------------------------------
|
||||
|
||||
// TYPES -------------------------------------------------------------------
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CHR_EOF,
|
||||
CHR_LETTER,
|
||||
CHR_NUMBER,
|
||||
CHR_QUOTE,
|
||||
CHR_SPECIAL
|
||||
} chr_t;
|
||||
|
||||
// EXTERNAL FUNCTION PROTOTYPES --------------------------------------------
|
||||
|
||||
// PUBLIC FUNCTION PROTOTYPES ----------------------------------------------
|
||||
|
||||
// PRIVATE FUNCTION PROTOTYPES ---------------------------------------------
|
||||
|
||||
static void ProcessLetterToken(void);
|
||||
static void ProcessNumberToken(void);
|
||||
static void ProcessQuoteToken(void);
|
||||
static void ProcessSpecialToken(void);
|
||||
static qboolean CheckForKeyword(void);
|
||||
static void NextChr(void);
|
||||
|
||||
// EXTERNAL DATA DECLARATIONS ----------------------------------------------
|
||||
|
||||
// PUBLIC DATA DEFINITIONS -------------------------------------------------
|
||||
|
||||
tokenType_t tk_Token;
|
||||
int tk_Line;
|
||||
int tk_IntNumber;
|
||||
float tk_FloatNumber;
|
||||
char *tk_String;
|
||||
char tk_SourceName[MAX_FILE_NAME_LENGTH];
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
static char Chr;
|
||||
static char *FileStart;
|
||||
static char *FilePtr;
|
||||
static char *FileEnd;
|
||||
static qboolean SourceOpen;
|
||||
static char ASCIIToChrCode[256];
|
||||
static char TokenStringBuffer[MAX_QUOTED_LENGTH];
|
||||
static qboolean IncLineNumber;
|
||||
static char TempBuffer[2048];
|
||||
|
||||
static struct
|
||||
{
|
||||
char *name;
|
||||
tokenType_t token;
|
||||
} Keywords[] =
|
||||
{
|
||||
"model", TK_MODEL,
|
||||
"mesh", TK_MESH,
|
||||
"vertices", TK_VERTICES,
|
||||
"edges", TK_EDGES,
|
||||
"position", TK_POSITION,
|
||||
"polygons", TK_POLYGONS,
|
||||
"nodes", TK_NODES,
|
||||
"rotation", TK_ROTATION,
|
||||
"scaling", TK_SCALING,
|
||||
"translation", TK_TRANSLATION,
|
||||
"vertex", TK_VERTEX,
|
||||
"HRCH", TK_HRCH,
|
||||
"Softimage", TK_SOFTIMAGE,
|
||||
"material", TK_MATERIAL,
|
||||
"spline", TK_SPLINE,
|
||||
|
||||
"Named", TK_C_NAMED,
|
||||
"object", TK_OBJECT,
|
||||
"Tri", TK_C_TRI,
|
||||
"Vertices", TK_C_VERTICES,
|
||||
"Faces", TK_C_FACES,
|
||||
"Vertex", TK_C_VERTEX,
|
||||
"list", TK_LIST,
|
||||
"Face", TK_C_FACE,
|
||||
|
||||
"Hexen", TK_C_HEXEN,
|
||||
"Triangles", TK_C_TRIANGLES,
|
||||
"Version", TK_C_VERSION,
|
||||
"faces", TK_FACES,
|
||||
"face", TK_FACE,
|
||||
"origin", TK_ORIGIN,
|
||||
|
||||
"DK_clusters", TK_CLUSTERS,
|
||||
"DK_cluster_ncvs", TK_NUM_CLUSTER_VERTICES,
|
||||
"name", TK_NAME,
|
||||
"DK_cluster_name", TK_CLUSTER_NAME,
|
||||
"DK_cluster_state", TK_CLUSTER_STATE,
|
||||
|
||||
"actor_data", TK_ACTOR_DATA,
|
||||
"uvTexture", TK_UVTEXTURE,
|
||||
|
||||
NULL, -1
|
||||
};
|
||||
|
||||
static char *TokenNames[] =
|
||||
{
|
||||
"<nothing>",
|
||||
"<unknown_char>",
|
||||
"<EOF>",
|
||||
"<identifier>",
|
||||
"<string>",
|
||||
"<int_number>",
|
||||
"<float_number>",
|
||||
"(",
|
||||
")",
|
||||
"{",
|
||||
"}",
|
||||
"[",
|
||||
"]",
|
||||
":",
|
||||
"mesh",
|
||||
"model",
|
||||
"nodes",
|
||||
"rotation",
|
||||
"scaling",
|
||||
"translation",
|
||||
"polygons",
|
||||
"position",
|
||||
"vertex",
|
||||
"vertices",
|
||||
"HRCH",
|
||||
"Softimage"
|
||||
};
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// TK_Init
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void TK_Init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; i < 256; i++)
|
||||
{
|
||||
ASCIIToChrCode[i] = CHR_SPECIAL;
|
||||
}
|
||||
for(i = '0'; i <= '9'; i++)
|
||||
{
|
||||
ASCIIToChrCode[i] = CHR_NUMBER;
|
||||
}
|
||||
for(i = 'A'; i <= 'Z'; i++)
|
||||
{
|
||||
ASCIIToChrCode[i] = CHR_LETTER;
|
||||
}
|
||||
for(i = 'a'; i <= 'z'; i++)
|
||||
{
|
||||
ASCIIToChrCode[i] = CHR_LETTER;
|
||||
}
|
||||
ASCIIToChrCode[ASCII_QUOTE] = CHR_QUOTE;
|
||||
ASCIIToChrCode[ASCII_UNDERSCORE] = CHR_LETTER;
|
||||
ASCIIToChrCode[EOF_CHARACTER] = CHR_EOF;
|
||||
tk_String = TokenStringBuffer;
|
||||
IncLineNumber = FALSE;
|
||||
SourceOpen = FALSE;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// TK_OpenSource
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void TK_OpenSource(char *fileName)
|
||||
{
|
||||
int size;
|
||||
|
||||
TK_CloseSource();
|
||||
size = LoadFile(fileName, (void **)&FileStart);
|
||||
strcpy(tk_SourceName, fileName);
|
||||
SourceOpen = TRUE;
|
||||
FileEnd = FileStart+size;
|
||||
FilePtr = FileStart;
|
||||
tk_Line = 1;
|
||||
tk_Token = TK_NONE;
|
||||
NextChr();
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// TK_CloseSource
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void TK_CloseSource(void)
|
||||
{
|
||||
if(SourceOpen)
|
||||
{
|
||||
free(FileStart);
|
||||
SourceOpen = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// TK_Fetch
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
tokenType_t TK_Fetch(void)
|
||||
{
|
||||
while(Chr == ASCII_SPACE)
|
||||
{
|
||||
NextChr();
|
||||
}
|
||||
if(Chr == '-')
|
||||
{
|
||||
ProcessNumberToken();
|
||||
}
|
||||
else switch(ASCIIToChrCode[(byte)Chr])
|
||||
{
|
||||
case CHR_EOF:
|
||||
tk_Token = TK_EOF;
|
||||
break;
|
||||
case CHR_LETTER:
|
||||
ProcessLetterToken();
|
||||
break;
|
||||
case CHR_NUMBER:
|
||||
ProcessNumberToken();
|
||||
break;
|
||||
case CHR_QUOTE:
|
||||
ProcessQuoteToken();
|
||||
break;
|
||||
default:
|
||||
ProcessSpecialToken();
|
||||
break;
|
||||
}
|
||||
return tk_Token;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// TK_Require
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
void TK_Require(tokenType_t tokType)
|
||||
{
|
||||
if(tokType == TK_FLOATNUMBER && tk_Token == TK_INTNUMBER)
|
||||
{
|
||||
tk_FloatNumber = (float)tk_IntNumber;
|
||||
tk_Token = TK_FLOATNUMBER;
|
||||
return;
|
||||
}
|
||||
if(tk_Token != tokType)
|
||||
{
|
||||
Error("File '%s', line %d:\nExpected '%s', found '%s'.\n",
|
||||
tk_SourceName, tk_Line, TokenNames[tokType],
|
||||
TokenNames[tk_Token]);
|
||||
}
|
||||
}
|
||||
|
||||
void TK_FetchRequire(tokenType_t tokType)
|
||||
{
|
||||
TK_Fetch();
|
||||
TK_Require(tokType);
|
||||
}
|
||||
|
||||
tokenType_t TK_RequireFetch(tokenType_t tokType)
|
||||
{
|
||||
TK_Require(tokType);
|
||||
return TK_Fetch();
|
||||
}
|
||||
|
||||
tokenType_t TK_FetchRequireFetch(tokenType_t tokType)
|
||||
{
|
||||
TK_Fetch();
|
||||
TK_Require(tokType);
|
||||
return TK_Fetch();
|
||||
}
|
||||
|
||||
tokenType_t TK_Beyond(tokenType_t tokType)
|
||||
{
|
||||
while(tk_Token != tokType)
|
||||
{
|
||||
if(TK_Fetch() == TK_EOF)
|
||||
{
|
||||
Error("File '%s':\nCould not find token '%s'.\n", // FIXME: TokenNames table not big enuff
|
||||
tk_SourceName, TokenNames[tokType]);
|
||||
}
|
||||
}
|
||||
return TK_Fetch();
|
||||
}
|
||||
|
||||
void TK_BeyondRequire(tokenType_t bTok, tokenType_t rTok)
|
||||
{
|
||||
TK_Beyond(bTok);
|
||||
TK_Require(rTok);
|
||||
}
|
||||
|
||||
tokenType_t TK_Search(tokenType_t tokType)
|
||||
{
|
||||
while(tk_Token != tokType)
|
||||
{
|
||||
if(TK_Fetch() == TK_EOF)
|
||||
{
|
||||
return TK_EOF;
|
||||
}
|
||||
}
|
||||
return TK_Fetch();
|
||||
}
|
||||
|
||||
tokenType_t TK_Get(tokenType_t tokType)
|
||||
{
|
||||
while(tk_Token != tokType)
|
||||
{
|
||||
if(TK_Fetch() == TK_EOF)
|
||||
{
|
||||
Error("File '%s':\nCould not find token '%s'.\n",
|
||||
tk_SourceName, TokenNames[tokType]);
|
||||
}
|
||||
}
|
||||
return tk_Token;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ProcessLetterToken
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ProcessLetterToken(void)
|
||||
{
|
||||
int i;
|
||||
char *text;
|
||||
|
||||
i = 0;
|
||||
text = TokenStringBuffer;
|
||||
while(ASCIIToChrCode[(byte)Chr] == CHR_LETTER
|
||||
|| ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
|
||||
{
|
||||
if(++i == MAX_IDENTIFIER_LENGTH)
|
||||
{
|
||||
Error("File '%s', line %d:\nIdentifier too long.\n",
|
||||
tk_SourceName, tk_Line);
|
||||
}
|
||||
*text++ = Chr;
|
||||
NextChr();
|
||||
}
|
||||
*text = 0;
|
||||
if(CheckForKeyword() == FALSE)
|
||||
{
|
||||
tk_Token = TK_IDENTIFIER;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// CheckForKeyword
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static qboolean CheckForKeyword(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i = 0; Keywords[i].name != NULL; i++)
|
||||
{
|
||||
if(strcmp(tk_String, Keywords[i].name) == 0)
|
||||
{
|
||||
tk_Token = Keywords[i].token;
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ProcessNumberToken
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ProcessNumberToken(void)
|
||||
{
|
||||
char *buffer;
|
||||
|
||||
buffer = TempBuffer;
|
||||
*buffer++ = Chr;
|
||||
NextChr();
|
||||
while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
|
||||
{
|
||||
*buffer++ = Chr;
|
||||
NextChr();
|
||||
}
|
||||
if(Chr == '.')
|
||||
{ // Float
|
||||
*buffer++ = Chr;
|
||||
NextChr(); // Skip period
|
||||
while(ASCIIToChrCode[(byte)Chr] == CHR_NUMBER)
|
||||
{
|
||||
*buffer++ = Chr;
|
||||
NextChr();
|
||||
}
|
||||
*buffer = 0;
|
||||
tk_FloatNumber = (float)atof(TempBuffer);
|
||||
tk_Token = TK_FLOATNUMBER;
|
||||
return;
|
||||
}
|
||||
|
||||
// Integer
|
||||
*buffer = 0;
|
||||
tk_IntNumber = atoi(TempBuffer);
|
||||
tk_Token = TK_INTNUMBER;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ProcessQuoteToken
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ProcessQuoteToken(void)
|
||||
{
|
||||
int i;
|
||||
char *text;
|
||||
|
||||
i = 0;
|
||||
text = TokenStringBuffer;
|
||||
NextChr();
|
||||
while(Chr != ASCII_QUOTE)
|
||||
{
|
||||
if(Chr == EOF_CHARACTER)
|
||||
{
|
||||
Error("File '%s', line %d:\n<EOF> inside string.\n",
|
||||
tk_SourceName, tk_Line);
|
||||
}
|
||||
if(++i > MAX_QUOTED_LENGTH-1)
|
||||
{
|
||||
Error("File '%s', line %d:\nString literal too long.\n",
|
||||
tk_SourceName, tk_Line);
|
||||
}
|
||||
*text++ = Chr;
|
||||
NextChr();
|
||||
}
|
||||
*text = 0;
|
||||
NextChr();
|
||||
tk_Token = TK_STRING;
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// ProcessSpecialToken
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void ProcessSpecialToken(void)
|
||||
{
|
||||
char c;
|
||||
|
||||
c = Chr;
|
||||
NextChr();
|
||||
switch(c)
|
||||
{
|
||||
case '(':
|
||||
tk_Token = TK_LPAREN;
|
||||
break;
|
||||
case ')':
|
||||
tk_Token = TK_RPAREN;
|
||||
break;
|
||||
case '{':
|
||||
tk_Token = TK_LBRACE;
|
||||
break;
|
||||
case '}':
|
||||
tk_Token = TK_RBRACE;
|
||||
break;
|
||||
case '[':
|
||||
tk_Token = TK_LBRACKET;
|
||||
break;
|
||||
case ']':
|
||||
tk_Token = TK_RBRACKET;
|
||||
break;
|
||||
case ':':
|
||||
tk_Token = TK_COLON;
|
||||
break;
|
||||
default:
|
||||
tk_Token = TK_UNKNOWNCHAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
// NextChr
|
||||
//
|
||||
//==========================================================================
|
||||
|
||||
static void NextChr(void)
|
||||
{
|
||||
if(FilePtr >= FileEnd)
|
||||
{
|
||||
Chr = EOF_CHARACTER;
|
||||
return;
|
||||
}
|
||||
if(IncLineNumber == TRUE)
|
||||
{
|
||||
tk_Line++;
|
||||
IncLineNumber = FALSE;
|
||||
}
|
||||
Chr = *FilePtr++;
|
||||
if(Chr < ASCII_SPACE)
|
||||
{
|
||||
if(Chr == '\n')
|
||||
{
|
||||
IncLineNumber = TRUE;
|
||||
}
|
||||
Chr = ASCII_SPACE;
|
||||
}
|
||||
}
|
||||
132
tools/quake2/qdata_heretic2/common/token.h
Normal file
132
tools/quake2/qdata_heretic2/common/token.h
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
//**
|
||||
//** token.h
|
||||
//**
|
||||
//**************************************************************************
|
||||
|
||||
#ifndef __TOKEN_H__
|
||||
#define __TOKEN_H__
|
||||
|
||||
#include "cmdlib.h"
|
||||
|
||||
#ifndef TRUE
|
||||
#define TRUE 1
|
||||
#endif
|
||||
#ifndef FALSE
|
||||
#define FALSE 0
|
||||
#endif
|
||||
#ifndef YES
|
||||
#define YES 1
|
||||
#endif
|
||||
#ifndef NO
|
||||
#define NO 0
|
||||
#endif
|
||||
#define ASCII_SPACE 32
|
||||
#define ASCII_QUOTE 34
|
||||
#define ASCII_UNDERSCORE 95
|
||||
#define EOF_CHARACTER 127
|
||||
#define MAX_IDENTIFIER_LENGTH 64
|
||||
#define MAX_QUOTED_LENGTH 1024
|
||||
#define MAX_FILE_NAME_LENGTH 1024
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TK_NONE,
|
||||
TK_UNKNOWNCHAR,
|
||||
TK_EOF,
|
||||
TK_IDENTIFIER, // VALUE: (char *) tk_String
|
||||
TK_STRING, // VALUE: (char *) tk_String
|
||||
TK_INTNUMBER, // VALUE: (int) tk_IntNumber
|
||||
TK_FLOATNUMBER, // VALUE: (float) tk_FloatNumber
|
||||
TK_LPAREN,
|
||||
TK_RPAREN,
|
||||
TK_LBRACE,
|
||||
TK_RBRACE, // 10
|
||||
TK_LBRACKET,
|
||||
TK_RBRACKET,
|
||||
TK_COLON,
|
||||
TK_MESH,
|
||||
TK_MODEL, // 15
|
||||
TK_NODES,
|
||||
TK_ROTATION,
|
||||
TK_SCALING,
|
||||
TK_TRANSLATION,
|
||||
TK_POLYGONS, // 20
|
||||
TK_POSITION,
|
||||
TK_VERTEX,
|
||||
TK_VERTICES,
|
||||
TK_EDGES,
|
||||
TK_HRCH, // 25
|
||||
TK_SOFTIMAGE,
|
||||
TK_MATERIAL,
|
||||
TK_SPLINE, // 28
|
||||
|
||||
TK_C_NAMED,
|
||||
TK_OBJECT, // 30
|
||||
TK_C_TRI,
|
||||
TK_C_VERTICES,
|
||||
TK_C_FACES,
|
||||
TK_C_VERTEX,
|
||||
TK_LIST, // 35
|
||||
TK_C_FACE,
|
||||
|
||||
TK_C_HEXEN,
|
||||
TK_C_TRIANGLES,
|
||||
TK_C_VERSION,
|
||||
TK_FACES, // 40
|
||||
TK_FACE,
|
||||
TK_ORIGIN,
|
||||
|
||||
TK_CLUSTERS,
|
||||
TK_NUM_CLUSTER_VERTICES,
|
||||
TK_NAME, // 45
|
||||
TK_CLUSTER_NAME,
|
||||
TK_CLUSTER_STATE,
|
||||
|
||||
TK_ACTOR_DATA,
|
||||
TK_UVTEXTURE,
|
||||
} tokenType_t;
|
||||
|
||||
void TK_Init(void);
|
||||
void TK_OpenSource(char *fileName);
|
||||
void TK_CloseSource(void);
|
||||
tokenType_t TK_Fetch(void);
|
||||
void TK_Require(tokenType_t tokType);
|
||||
void TK_FetchRequire(tokenType_t tokType);
|
||||
tokenType_t TK_RequireFetch(tokenType_t tokType);
|
||||
tokenType_t TK_FetchRequireFetch(tokenType_t tokType);
|
||||
tokenType_t TK_Beyond(tokenType_t tokType);
|
||||
void TK_BeyondRequire(tokenType_t bTok, tokenType_t rTok);
|
||||
tokenType_t TK_Search(tokenType_t tokType);
|
||||
tokenType_t TK_Get(tokenType_t tokType);
|
||||
|
||||
extern tokenType_t tk_Token;
|
||||
extern int tk_Line;
|
||||
extern int tk_IntNumber;
|
||||
extern float tk_FloatNumber;
|
||||
extern char *tk_String;
|
||||
extern char tk_SourceName[MAX_FILE_NAME_LENGTH];
|
||||
|
||||
#endif
|
||||
1077
tools/quake2/qdata_heretic2/common/trilib.c
Normal file
1077
tools/quake2/qdata_heretic2/common/trilib.c
Normal file
File diff suppressed because it is too large
Load Diff
56
tools/quake2/qdata_heretic2/common/trilib.h
Normal file
56
tools/quake2/qdata_heretic2/common/trilib.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright (C) 1999-2006 Id Software, Inc. and contributors.
|
||||
For a list of contributors, see the accompanying CONTRIBUTORS file.
|
||||
|
||||
This file is part of GtkRadiant.
|
||||
|
||||
GtkRadiant 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.
|
||||
|
||||
GtkRadiant 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 GtkRadiant; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
//
|
||||
// trilib.h: header file for loading triangles from an Alias triangle file
|
||||
//
|
||||
|
||||
#include "fmodel.h"
|
||||
|
||||
#define MAXTRIANGLES MAX_FM_TRIANGLES
|
||||
|
||||
typedef struct
|
||||
{
|
||||
vec3_t verts[3];
|
||||
#if 1
|
||||
int indicies[3];
|
||||
float uv[3][2];
|
||||
qboolean HasUV;
|
||||
#endif
|
||||
} triangle_t;
|
||||
|
||||
#define NUM_CLUSTERS 8
|
||||
|
||||
typedef struct
|
||||
{
|
||||
char name[64];
|
||||
byte tris[MAXTRIANGLES>>3];
|
||||
byte verts[MAX_FM_VERTS>>3];
|
||||
int start_glcmds, num_glcmds;
|
||||
|
||||
int *clusters[NUM_CLUSTERS];
|
||||
struct IntListNode_s *vertLists[NUM_CLUSTERS];
|
||||
int num_verts[NUM_CLUSTERS + 1];
|
||||
int new_num_verts[NUM_CLUSTERS + 1];
|
||||
qboolean clustered;
|
||||
} mesh_node_t;
|
||||
|
||||
void LoadTriangleList (char *filename, triangle_t **pptri, int *numtriangles, mesh_node_t **ppmnodes, int *num_mesh_nodes);
|
||||
Reference in New Issue
Block a user