mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-23 04:42:32 +00:00
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:
parent
0bd960d6cc
commit
a0828ddd06
9 changed files with 98 additions and 94 deletions
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
*/
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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]);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue