Clean up bsp limits.

Delete all bogus bsp limits, fixing the code that depended on them.
Document those limits that are dictated by the format.
This commit is contained in:
Bill Currie 2010-12-07 15:41:57 +09:00
parent 0bd960d6cc
commit a0828ddd06
9 changed files with 98 additions and 94 deletions

View file

@ -33,35 +33,15 @@
// upper design bounds
#define MAX_MAP_HULLS 4
#define MAX_MAP_MODELS 256
#define MAX_MAP_BRUSHES 4096
#define MAX_MAP_ENTITIES 1024
#define MAX_MAP_ENTSTRING 65536
#define MAX_MAP_PLANES 32767
#define MAX_MAP_NODES 32767 // because negative shorts are contents
#define MAX_MAP_CLIPNODES 32767 //
#define MAX_MAP_LEAFS 32767 //
#define MAX_MAP_VERTS 65535
#define MAX_MAP_FACES 65535
#define MAX_MAP_MARKSURFACES 65535
#define MAX_MAP_TEXINFO 4096
#define MAX_MAP_EDGES 256000
#define MAX_MAP_SURFEDGES 512000
#define MAX_MAP_TEXTURES 512
#define MAX_MAP_MIPTEX 0x200000
#define MAX_MAP_LIGHTING 0x100000
#define MAX_MAP_VISIBILITY 0x100000
#define MAX_MAP_PORTALS 65536
// key / value pair sizes
#define MAX_KEY 32
#define MAX_VALUE 1024
#define MAX_MAP_HULLS 4 // format limit (array)
#define MAX_MAP_PLANES 32767 // format limit (s16) FIXME u16 ok?
#define MAX_MAP_NODES 65520 // because negative shorts are contents
#define MAX_MAP_CLIPNODES 65520 // but contents "max" is -15, so
#define MAX_MAP_LEAFS 65520 // -32768 to -17 are available
#define MAX_MAP_VERTS 65535 // format limit (u16)
#define MAX_MAP_FACES 65535 // format limit (u16)
#define MAX_MAP_MARKSURFACES 65535 // format limit (u16)
//=============================================================================
@ -109,9 +89,10 @@ typedef struct dmiptexlump_s {
int32_t dataofs[4]; // [nummiptex]
} dmiptexlump_t;
#define MIPTEXNAME 16
#define MIPLEVELS 4
typedef struct miptex_s {
char name[16];
char name[MIPTEXNAME];
uint32_t width, height;
uint32_t offsets[MIPLEVELS]; // four mip maps stored
} miptex_t;

View file

@ -57,18 +57,15 @@ typedef struct {
epair_t *epairs; ///< Nul terminated list of key=value pairs.
} entity_t;
extern int nummapbrushes;
extern mbrush_t mapbrushes[MAX_MAP_BRUSHES];
extern int num_entities;
extern entity_t entities[MAX_MAP_ENTITIES];
extern entity_t *entities;
extern int nummiptex;
extern char miptex[MAX_MAP_TEXINFO][16];
extern int nummiptexnames;
extern const char **miptexnames;
/** Load and parse the map script.
Fills in the ::mapbrushes, ::entities and ::miptex arrays.
Fills in the ::entities and ::miptexnames arrays.
\param filename Path of the map script to parse.
*/

View file

@ -34,9 +34,13 @@ struct visfacet_s;
struct node_s;
struct surface_s;
typedef struct edgeface_s {
struct visfacet_s *f[2];
} edgeface_t;
extern int c_cornerverts;
extern int c_tryedges;
extern struct visfacet_s *edgefaces[MAX_MAP_EDGES][2];
extern edgeface_t *edgefaces;
extern int firstmodeledge;
extern int firstmodelface;

View file

@ -694,7 +694,7 @@ LoadBrush (const mbrush_t *mb, int hullnum)
return NULL;
contents = CONTENTS_EMPTY;
} else {
name = miptex[bsp->texinfo[mb->faces->texinfo].miptex];
name = miptexnames[bsp->texinfo[mb->faces->texinfo].miptex];
if (!strcasecmp (name, "clip") && hullnum == 0)
return NULL; // "clip" brushes don't show up in the draw hull

View file

@ -35,6 +35,7 @@ static __attribute__ ((used)) const char rcsid[] =
#include <ctype.h>
#include "QF/dstring.h"
#include "QF/hash.h"
#include "QF/quakefs.h"
#include "QF/script.h"
#include "QF/sys.h"
@ -50,13 +51,17 @@ static __attribute__ ((used)) const char rcsid[] =
int nummapbrushfaces;
int nummapbrushes;
mbrush_t mapbrushes[MAX_MAP_BRUSHES];
#define ENTITIES_CHUNK 16
int num_entities;
entity_t entities[MAX_MAP_ENTITIES];
int max_entities;
entity_t *entities;
int nummiptex;
char miptex[MAX_MAP_TEXINFO][16];
#define MIPTEXNAME_CHUNK 16
int nummiptexnames;
int maxmiptexnames;
const char **miptexnames;
hashtab_t *miptex_hash;
int numdetailbrushes;
@ -75,24 +80,41 @@ map_error (const char *fmt, ...)
exit (1);
}
static const char *
miptex_getkey (void *key, void *unused)
{
intptr_t index = (intptr_t) key;
return miptexnames[index - 1];
}
int
FindMiptex (const char *name)
{
int i;
intptr_t index;
char mpname[MIPTEXNAME];
strncpy (mpname, name, MIPTEXNAME - 1);
mpname[MIPTEXNAME - 1] = 0;
if (strcmp (name, "hint") == 0)
return TEX_HINT;
if (strcmp (name, "skip") == 0)
return TEX_SKIP;
for (i = 0; i < nummiptex; i++) {
if (!strcmp (name, miptex[i]))
return i;
if (!miptex_hash)
miptex_hash = Hash_NewTable (1023, miptex_getkey, 0, 0);
if (miptexnames) {
index = (intptr_t) Hash_Find (miptex_hash, mpname);
if (index)
return index - 1;
}
if (nummiptex == MAX_MAP_TEXINFO)
map_error ("nummiptex == MAX_MAP_TEXINFO");
strcpy (miptex[i], name);
nummiptex++;
return i;
if (nummiptexnames == maxmiptexnames) {
maxmiptexnames += MIPTEXNAME_CHUNK;
miptexnames = realloc (miptexnames,
maxmiptexnames * sizeof (const char *));
}
index = nummiptexnames++;
miptexnames[index] = strdup (mpname);
Hash_Add (miptex_hash, (void *) (index + 1));
return index;
}
/*
@ -110,8 +132,8 @@ FindTexinfo (texinfo_t *t)
return t->miptex; // it's HINT or SKIP
// set the special flag
if (miptex[t->miptex][0] == '*'
|| !strncasecmp (miptex[t->miptex], "sky", 3))
if (miptexnames[t->miptex][0] == '*'
|| !strncasecmp (miptexnames[t->miptex], "sky", 3))
t->flags |= TEX_SPECIAL;
tex = bsp->texinfo;
@ -222,8 +244,8 @@ ParseBrush (void)
vec3_t t1, t2, *verts = 0;
vec_t d, vecs[2][4];
b = &mapbrushes[nummapbrushes];
nummapbrushes++;
b = calloc (1, sizeof (mbrush_t));
b->next = mapent->brushes;
mapent->brushes = b;
@ -430,11 +452,14 @@ ParseEntity (void)
if (strcmp (map_script->token->str, "{"))
map_error ("ParseEntity: { not found");
if (num_entities == MAX_MAP_ENTITIES)
map_error ("num_entities == MAX_MAP_ENTITIES");
if (num_entities == max_entities) {
max_entities += ENTITIES_CHUNK;
entities = realloc (entities, max_entities * sizeof (entity_t));
}
mapent = &entities[num_entities];
num_entities++;
memset (mapent, 0, sizeof (entity_t));
do {
if (!Script_GetToken (map_script, true))
@ -512,7 +537,7 @@ LoadMapFile (const char *filename)
qprintf ("%5i faces\n", nummapbrushfaces);
qprintf ("%5i brushes (%i detail)\n", nummapbrushes, numdetailbrushes);
qprintf ("%5i entities\n", num_entities);
qprintf ("%5i textures\n", nummiptex);
qprintf ("%5i textures\n", nummiptexnames);
qprintf ("%5i texinfo\n", bsp->numtexinfo);
}

View file

@ -352,20 +352,20 @@ static byte default_palette[] = {
static const char *
unique_name (wad_t *wad, const char *name)
{
char uname[16];
char uname[MIPTEXNAME];
int i = 0;
const char *tag;
if (!wad_find_lump (wad, name))
return name;
do {
strncpy (uname, name, 16);
uname[15] = 0;
strncpy (uname, name, MIPTEXNAME);
uname[(MIPTEXNAME - 1)] = 0;
tag = va ("~%x", i++);
if (strlen (uname) + strlen (tag) <= 15)
if (strlen (uname) + strlen (tag) <= (MIPTEXNAME - 1))
strcat (uname, tag);
else
strcpy (uname + 15 - strlen (tag), tag);
strcpy (uname + (MIPTEXNAME - 1) - strlen (tag), tag);
} while (wad_find_lump (wad, uname));
return va ("%s", uname); // just to make a safe returnable that doesn't
// need to be freed

View file

@ -139,33 +139,30 @@ RecursiveGrowRegion (dface_t *r, face_t *f)
// add edges
for (i = 0; i < f->points->numpoints; i++) {
e = f->edges[i];
if (!edgefaces[abs (e)][0])
if (!edgefaces[abs (e)].f[0])
continue; // edge has allready been removed
if (e > 0)
f2 = edgefaces[e][1];
f2 = edgefaces[e].f[1];
else
f2 = edgefaces[-e][0];
f2 = edgefaces[-e].f[0];
if (f2 && f2->outputnumber == bsp->numfaces) {
edgefaces[abs (e)][0] = NULL;
edgefaces[abs (e)][1] = NULL;
edgefaces[abs (e)].f[0] = NULL;
edgefaces[abs (e)].f[1] = NULL;
continue; // allready merged
}
if (f2 && CanJoinFaces (f, f2)) { // remove the edge and merge the
// faces
edgefaces[abs (e)][0] = NULL;
edgefaces[abs (e)][1] = NULL;
edgefaces[abs (e)].f[0] = NULL;
edgefaces[abs (e)].f[1] = NULL;
RecursiveGrowRegion (r, f2);
} else {
// emit a surfedge
if (bsp->numsurfedges == MAX_MAP_SURFEDGES)
Sys_Error ("numsurfedges == MAX_MAP_SURFEDGES");
BSP_AddSurfEdge (bsp, e);
}
}
}
*/
int edgemapping[MAX_MAP_EDGES];
typedef struct {
int numedges;
@ -188,7 +185,7 @@ CountRealNumbers (void)
c = 0;
for (i = firstmodeledge; i < bsp->numedges; i++)
if (edgefaces[i][0])
if (edgefaces[i].f[0])
c++; // not removed
qprintf ("%5i real edges\n", c);
@ -233,8 +230,6 @@ GrowNodeRegion_r (node_t * node)
#endif
r.firstedge = firstedge = bsp->numsurfedges;
for (i = 0; i < f->points->numpoints; i++) {
if (bsp->numsurfedges == MAX_MAP_SURFEDGES)
Sys_Error ("numsurfedges == MAX_MAP_SURFEDGES");
BSP_AddSurfEdge (bsp, f->edges[i]);
}

View file

@ -205,7 +205,9 @@ int c_cornerverts;
hashvert_t hvertex[MAX_MAP_VERTS];
hashvert_t *hvert_p;
face_t *edgefaces[MAX_MAP_EDGES][2];
#define EDGEFACE_CHUNK 4096
int numedgefaces = 0;
edgeface_t *edgefaces = 0;
int firstmodeledge = 1;
int firstmodelface;
@ -360,20 +362,23 @@ GetEdge (const vec3_t p1, const vec3_t p2, face_t *f)
// but does not yet have a second face.
for (i = firstmodeledge; i < bsp->numedges; i++) {
if (v1 == bsp->edges[i].v[1] && v2 == bsp->edges[i].v[0]
&& !edgefaces[i][1]
&& edgefaces[i][0]->contents[0] == f->contents[0]) {
edgefaces[i][1] = f;
&& !edgefaces[i].f[1]
&& edgefaces[i].f[0]->contents[0] == f->contents[0]) {
edgefaces[i].f[1] = f;
return -i;
}
}
// Create a new edge.
if (bsp->numedges == MAX_MAP_EDGES)
Sys_Error ("numedges == MAX_MAP_EDGES");
while (bsp->numedges >= numedgefaces) {
numedgefaces += EDGEFACE_CHUNK;
edgefaces = realloc (edgefaces, numedgefaces * sizeof (edgeface_t));
}
edge.v[0] = v1;
edge.v[1] = v2;
BSP_AddEdge (bsp, &edge);
edgefaces[i][0] = f;
edgefaces[i].f[0] = f;
edgefaces[i].f[1] = 0;
return i;
}

View file

@ -250,9 +250,6 @@ WriteDrawNodes (const node_t *headnode)
#endif
// emit a model
if (bsp->nummodels == MAX_MAP_MODELS)
Sys_Error ("nummodels == MAX_MAP_MODELS");
bm.headnode[0] = bsp->numnodes;
for (i = 1; i < MAX_MAP_HULLS; i++)
bm.headnode[i] = 0;
@ -382,14 +379,14 @@ AddAnimatingTextures (void)
char name[32];
wadlist_t *wl;
base = nummiptex;
base = nummiptexnames;
name[sizeof (name) - 1] = 0;
for (i = 0; i < base; i++) {
if (miptex[i][0] != '+')
if (miptexnames[i][0] != '+')
continue;
strncpy (name, miptex[i], sizeof (name) - 1);
strncpy (name, miptexnames[i], sizeof (name) - 1);
for (j = 0; j < 20; j++) {
if (j < 10)
@ -407,8 +404,8 @@ AddAnimatingTextures (void)
}
}
if (nummiptex - base)
printf ("added %i texture frames\n", nummiptex - base);
if (nummiptexnames - base)
printf ("added %i texture frames\n", nummiptexnames - base);
}
/** Write the miptex data to the bsp file.
@ -480,14 +477,14 @@ WriteMiptex (void)
dstring_adjust (data);
l = (dmiptexlump_t *) data->str;
l->nummiptex = nummiptex;
data->size = (char *) &l->dataofs[nummiptex] - data->str;
l->nummiptex = nummiptexnames;
data->size = (char *) &l->dataofs[nummiptexnames] - data->str;
dstring_adjust (data);
for (i = 0; i < nummiptex; i++) {
for (i = 0; i < nummiptexnames; i++) {
l = (dmiptexlump_t *) data->str;
l->dataofs[i] = data->size;
len = LoadLump (miptex[i], data);
len = LoadLump (miptexnames[i], data);
l = (dmiptexlump_t *) data->str;
if (!len)
l->dataofs[i] = -1; // didn't find the texture