ref_gl1: Load IBSQ map format

This commit is contained in:
Denis Pauk 2023-09-03 13:56:19 +03:00
parent 10e791471e
commit 85ebca9979
5 changed files with 886 additions and 146 deletions

View file

@ -447,6 +447,93 @@ Mod_LoadNodes(const char *name, cplane_t *planes, int numplanes, mleaf_t *leafs,
Mod_NumberLeafs (leafs, *nodes, r_leaftovis, r_vistoleaf, &numvisleafs);
}
/*
=================
Mod_LoadQNodes
=================
*/
void
Mod_LoadQNodes(const char *name, cplane_t *planes, int numplanes, mleaf_t *leafs,
int numleafs, mnode_t **nodes, int *numnodes, const byte *mod_base,
const lump_t *l)
{
int r_leaftovis[MAX_MAP_LEAFS], r_vistoleaf[MAX_MAP_LEAFS];
int i, count, numvisleafs;
dqnode_t *in;
mnode_t *out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
ri.Sys_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc(count * sizeof(*out));
*nodes = out;
*numnodes = count;
for (i = 0; i < count; i++, in++, out++)
{
int j, planenum;
for (j = 0; j < 3; j++)
{
out->minmaxs[j] = LittleFloat(in->mins[j]);
out->minmaxs[3 + j] = LittleFloat(in->maxs[j]);
}
planenum = LittleLong(in->planenum);
if (planenum < 0 || planenum >= numplanes)
{
ri.Sys_Error(ERR_DROP, "%s: Incorrect %d < %d planenum.",
__func__, planenum, numplanes);
}
out->plane = planes + planenum;
out->firstsurface = LittleLong(in->firstface);
out->numsurfaces = LittleLong(in->numfaces);
out->contents = CONTENTS_NODE; /* differentiate from leafs */
for (j = 0; j < 2; j++)
{
int leafnum;
leafnum = LittleLong(in->children[j]);
if (leafnum >= 0)
{
if (leafnum < 0 || leafnum >= *numnodes)
{
ri.Sys_Error(ERR_DROP, "%s: Incorrect %d nodenum as leaf.",
__func__, leafnum);
}
out->children[j] = *nodes + leafnum;
}
else
{
leafnum = -1 - leafnum;
if (leafnum < 0 || leafnum >= numleafs)
{
ri.Sys_Error(ERR_DROP, "%s: Incorrect %d leafnum.",
__func__, leafnum);
}
out->children[j] = (mnode_t *)(leafs + leafnum);
}
}
}
Mod_SetParent(*nodes, NULL); /* sets nodes and leafs */
numvisleafs = 0;
Mod_NumberLeafs (leafs, *nodes, r_leaftovis, r_vistoleaf, &numvisleafs);
}
/*
=================
Mod_LoadVisibility
@ -657,6 +744,41 @@ Mod_LoadEdges(const char *name, medge_t **edges, int *numedges,
}
}
/*
=================
Mod_LoadQEdges
extra is used for skybox, which adds 6 surfaces
=================
*/
void
Mod_LoadQEdges(const char *name, medge_t **edges, int *numedges,
const byte *mod_base, const lump_t *l, int extra)
{
dqedge_t *in;
medge_t *out;
int i, count;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
ri.Sys_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc((count + extra) * sizeof(*out));
*edges = out;
*numedges = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
out->v[0] = (unsigned int)LittleLong(in->v[0]);
out->v[1] = (unsigned int)LittleLong(in->v[1]);
}
}
/*
=================
Mod_LoadPlanes

View file

@ -237,6 +237,8 @@ Mod_ForName (char *name, model_t *parent_model, qboolean crash)
break;
case IDBSPHEADER:
/* fall through */
case QDBSPHEADER:
Mod_LoadBrushModel(mod, buf, modfilelen);
break;
@ -371,7 +373,8 @@ Mod_CalcSurfaceExtents(model_t *loadmodel, msurface_t *s)
}
}
static int calcTexinfoAndFacesSize(byte *mod_base, const lump_t *fl, const lump_t *tl)
static int
calcTexinfoAndFacesSize(byte *mod_base, const lump_t *fl, const lump_t *tl)
{
dface_t* face_in = (void *)(mod_base + fl->fileofs);
texinfo_t* texinfo_in = (void *)(mod_base + tl->fileofs);
@ -446,7 +449,83 @@ static int calcTexinfoAndFacesSize(byte *mod_base, const lump_t *fl, const lump_
return ret;
}
// Extension to support lightmaps that aren't tied to texture scale.
static int
calcTexinfoAndQFacesSize(byte *mod_base, const lump_t *fl, const lump_t *tl)
{
dqface_t* face_in = (void *)(mod_base + fl->fileofs);
texinfo_t* texinfo_in = (void *)(mod_base + tl->fileofs);
if (fl->filelen % sizeof(*face_in) || tl->filelen % sizeof(*texinfo_in))
{
// will error out when actually loading it
return 0;
}
int ret = 0;
int face_count = fl->filelen / sizeof(*face_in);
int texinfo_count = tl->filelen / sizeof(*texinfo_in);
{
// out = Hunk_Alloc(count * sizeof(*out));
int baseSize = face_count * sizeof(msurface_t);
baseSize = (baseSize + 31) & ~31;
ret += baseSize;
int ti_size = texinfo_count * sizeof(mtexinfo_t);
ti_size = (ti_size + 31) & ~31;
ret += ti_size;
}
int numWarpFaces = 0;
for (int surfnum = 0; surfnum < face_count; surfnum++, face_in++)
{
int numverts = LittleLong(face_in->numedges);
int ti = LittleLong(face_in->texinfo);
if ((ti < 0) || (ti >= texinfo_count))
{
return 0; // will error out
}
int texFlags = LittleLong(texinfo_in[ti].flags);
/* set the drawing flags */
if (texFlags & SURF_WARP)
{
if (numverts > 60)
return 0; // will error out in R_SubdividePolygon()
// GL3_SubdivideSurface(out, loadmodel); /* cut up polygon for warps */
// for each (pot. recursive) call to R_SubdividePolygon():
// sizeof(glpoly_t) + ((numverts - 4) + 2) * sizeof(gl3_3D_vtx_t)
// this is tricky, how much is allocated depends on the size of the surface
// which we don't know (we'd need the vertices etc to know, but we can't load
// those without allocating...)
// so we just count warped faces and use a generous estimate below
++numWarpFaces;
}
else
{
// LM_BuildPolygonFromSurface(out);
// => poly = Hunk_Alloc(sizeof(glpoly_t) + (numverts - 4) * VERTEXSIZE * sizeof(float));
int polySize = sizeof(glpoly_t) + (numverts - 4) * VERTEXSIZE * sizeof(float);
polySize = (polySize + 31) & ~31;
ret += polySize;
}
}
// yeah, this is a bit hacky, but it looks like for each warped face
// 256-55000 bytes are allocated (usually on the lower end),
// so just assume 48k per face to be safe
ret += numWarpFaces * 49152;
ret += 5000000; // and 5MB extra just in case
return ret;
}
/* Extension to support lightmaps that aren't tied to texture scale. */
static int
Mod_LoadBSPXDecoupledLM(const dlminfo_t* lminfos, int surfnum, msurface_t *out)
{
@ -632,6 +711,129 @@ Mod_LoadFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
LM_EndBuildingLightmaps();
}
static void
Mod_LoadQFaces(model_t *loadmodel, const byte *mod_base, const lump_t *l,
const bspx_header_t *bspx_header)
{
int i, count, surfnum, lminfosize, lightofs;
const dlminfo_t *lminfos;
msurface_t *out;
dqface_t *in;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
ri.Sys_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, loadmodel->name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc(count * sizeof(*out));
loadmodel->surfaces = out;
loadmodel->numsurfaces = count;
lminfos = Mod_LoadBSPXFindLump(bspx_header, "DECOUPLED_LM", &lminfosize, mod_base);
if (lminfos != NULL && lminfosize / sizeof(dlminfo_t) != loadmodel->numsurfaces) {
R_Printf(PRINT_ALL, "%s: [%s] decoupled_lm size %ld does not match surface count %d\n",
__func__, loadmodel->name, lminfosize / sizeof(dlminfo_t), loadmodel->numsurfaces);
lminfos = NULL;
}
LM_BeginBuildingLightmaps(loadmodel);
for (surfnum = 0; surfnum < count; surfnum++, in++, out++)
{
int side, ti, planenum;
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleLong(in->numedges);
if (out->numedges < 3)
{
ri.Sys_Error(ERR_DROP, "%s: Surface with %d edges",
__func__, out->numedges);
}
out->flags = 0;
out->polys = NULL;
planenum = LittleLong(in->planenum);
side = LittleLong(in->side);
if (side)
{
out->flags |= SURF_PLANEBACK;
}
if (planenum < 0 || planenum >= loadmodel->numplanes)
{
ri.Sys_Error(ERR_DROP, "%s: Incorrect %d planenum.",
__func__, planenum);
}
out->plane = loadmodel->planes + planenum;
ti = LittleLong(in->texinfo);
if ((ti < 0) || (ti >= loadmodel->numtexinfo))
{
ri.Sys_Error(ERR_DROP, "%s: bad texinfo number",
__func__);
}
out->texinfo = loadmodel->texinfo + ti;
lightofs = Mod_LoadBSPXDecoupledLM(lminfos, surfnum, out);
if (lightofs < 0) {
memcpy(out->lmvecs, out->texinfo->vecs, sizeof(out->lmvecs));
out->lmshift = DEFAULT_LMSHIFT;
out->lmvlen[0] = 1.0f;
out->lmvlen[1] = 1.0f;
Mod_CalcSurfaceExtents(loadmodel, out);
lightofs = in->lightofs;
}
SetSurfaceLighting(loadmodel, out, in->styles, lightofs);
/* set the drawing flags */
if (out->texinfo->flags & SURF_WARP)
{
out->flags |= SURF_DRAWTURB;
for (i = 0; i < 2; i++)
{
out->extents[i] = 16384;
out->texturemins[i] = -8192;
}
R_SubdivideSurface(loadmodel, out); /* cut up polygon for warps */
}
if (r_fixsurfsky->value)
{
if (out->texinfo->flags & SURF_SKY)
{
out->flags |= SURF_DRAWSKY;
}
}
/* create lightmaps and polygons */
if (!(out->texinfo->flags & (SURF_SKY | SURF_TRANS33 | SURF_TRANS66 | SURF_WARP)))
{
LM_CreateSurfaceLightmap(out);
}
if (!(out->texinfo->flags & SURF_WARP))
{
LM_BuildPolygonFromSurface(loadmodel, out);
}
}
LM_EndBuildingLightmaps();
}
static void
Mod_LoadLeafs(model_t *loadmodel, const byte *mod_base, const lump_t *l)
{
@ -680,6 +882,54 @@ Mod_LoadLeafs(model_t *loadmodel, const byte *mod_base, const lump_t *l)
}
}
static void
Mod_LoadQLeafs(model_t *loadmodel, const byte *mod_base, const lump_t *l)
{
dqleaf_t *in;
mleaf_t *out;
int i, j, count;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
ri.Sys_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, loadmodel->name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc(count * sizeof(*out));
loadmodel->leafs = out;
loadmodel->numleafs = count;
for (i = 0; i < count; i++, in++, out++)
{
unsigned firstleafface;
for (j = 0; j < 3; j++)
{
out->minmaxs[j] = LittleFloat(in->mins[j]);
out->minmaxs[3 + j] = LittleFloat(in->maxs[j]);
}
out->contents = LittleLong(in->contents);
out->cluster = LittleLong(in->cluster);
out->area = LittleLong(in->area);
// make unsigned long from signed short
firstleafface = LittleLong(in->firstleafface) & 0xFFFF;
out->nummarksurfaces = LittleLong(in->numleaffaces) & 0xFFFF;
out->firstmarksurface = loadmodel->marksurfaces + firstleafface;
if ((firstleafface + out->nummarksurfaces) > loadmodel->nummarksurfaces)
{
ri.Sys_Error(ERR_DROP, "%s: wrong marksurfaces position in %s",
__func__, loadmodel->name);
}
}
}
static void
Mod_LoadMarksurfaces(model_t *loadmodel, const byte *mod_base, const lump_t *l)
{
@ -715,6 +965,42 @@ Mod_LoadMarksurfaces(model_t *loadmodel, const byte *mod_base, const lump_t *l)
}
}
static void
Mod_LoadQMarksurfaces(model_t *loadmodel, const byte *mod_base, const lump_t *l)
{
int i, count;
int *in;
msurface_t **out;
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
ri.Sys_Error(ERR_DROP, "%s: funny lump size in %s",
__func__, loadmodel->name);
}
count = l->filelen / sizeof(*in);
out = Hunk_Alloc(count * sizeof(*out));
loadmodel->marksurfaces = out;
loadmodel->nummarksurfaces = count;
for (i = 0; i < count; i++)
{
int j;
j = LittleLong(in[i]);
if ((j < 0) || (j >= loadmodel->numsurfaces))
{
ri.Sys_Error(ERR_DROP, "%s: bad surface number",
__func__);
}
out[i] = loadmodel->surfaces + j;
}
}
static void
Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
{
@ -730,6 +1016,14 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
header = (dheader_t *)buffer;
i = LittleLong(header->ident);
if (i != IDBSPHEADER && i != QDBSPHEADER)
{
ri.Sys_Error(ERR_DROP, "%s: %s has wrong ident (%i should be %i)",
__func__, mod->name, i, IDBSPHEADER);
}
i = LittleLong(header->version);
if (i != BSPVERSION)
@ -749,18 +1043,41 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
// calculate the needed hunksize from the lumps
int hunkSize = 0;
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_VERTEXES], sizeof(dvertex_t), sizeof(mvertex_t), 0);
if (header->ident == IDBSPHEADER)
{
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_EDGES], sizeof(dedge_t), sizeof(medge_t), 0);
}
else
{
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_EDGES], sizeof(dqedge_t), sizeof(medge_t), 0);
}
hunkSize += sizeof(medge_t) + 31; // for count+1 in Mod_LoadEdges()
int surfEdgeCount = (header->lumps[LUMP_SURFEDGES].filelen+sizeof(int)-1)/sizeof(int);
if(surfEdgeCount < MAX_MAP_SURFEDGES) // else it errors out later anyway
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_SURFEDGES], sizeof(int), sizeof(int), 0);
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_LIGHTING], 1, 1, 0);
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_PLANES], sizeof(dplane_t), sizeof(cplane_t)*2, 0);
if (header->ident == IDBSPHEADER)
{
hunkSize += calcTexinfoAndFacesSize(mod_base, &header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]);
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_LEAFFACES], sizeof(short), sizeof(msurface_t *), 0); // yes, out is indeed a pointer!
}
else
{
hunkSize += calcTexinfoAndQFacesSize(mod_base, &header->lumps[LUMP_FACES], &header->lumps[LUMP_TEXINFO]);
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_LEAFFACES], sizeof(int), sizeof(msurface_t *), 0); // yes, out is indeed a pointer!
}
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_VISIBILITY], 1, 1, 0);
if (header->ident == IDBSPHEADER)
{
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_LEAFS], sizeof(dleaf_t), sizeof(mleaf_t), 0);
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_NODES], sizeof(dnode_t), sizeof(mnode_t), 0);
}
else
{
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_LEAFS], sizeof(dqleaf_t), sizeof(mleaf_t), 0);
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_NODES], sizeof(dqnode_t), sizeof(mnode_t), 0);
}
hunkSize += Mod_CalcLumpHunkSize(&header->lumps[LUMP_MODELS], sizeof(dmodel_t), sizeof(model_t), 0);
mod->extradata = Hunk_Begin(hunkSize);
@ -773,8 +1090,16 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
/* load into heap */
Mod_LoadVertexes(mod->name, &mod->vertexes, &mod->numvertexes, mod_base,
&header->lumps[LUMP_VERTEXES], 0);
if (header->ident == IDBSPHEADER)
{
Mod_LoadEdges(mod->name, &mod->edges, &mod->numedges,
mod_base, &header->lumps[LUMP_EDGES], 1);
}
else
{
Mod_LoadQEdges(mod->name, &mod->edges, &mod->numedges,
mod_base, &header->lumps[LUMP_EDGES], 1);
}
Mod_LoadSurfedges(mod->name, &mod->surfedges, &mod->numsurfedges,
mod_base, &header->lumps[LUMP_SURFEDGES], 0);
Mod_LoadLighting(&mod->lightdata, mod_base, &header->lumps[LUMP_LIGHTING]);
@ -783,13 +1108,31 @@ Mod_LoadBrushModel(model_t *mod, const void *buffer, int modfilelen)
Mod_LoadTexinfo(mod->name, &mod->texinfo, &mod->numtexinfo,
mod_base, &header->lumps[LUMP_TEXINFO], (findimage_t)R_FindImage,
r_notexture, 0);
if (header->ident == IDBSPHEADER)
{
Mod_LoadFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
Mod_LoadMarksurfaces(mod, mod_base, &header->lumps[LUMP_LEAFFACES]);
}
else
{
Mod_LoadQFaces(mod, mod_base, &header->lumps[LUMP_FACES], bspx_header);
Mod_LoadQMarksurfaces(mod, mod_base, &header->lumps[LUMP_LEAFFACES]);
}
Mod_LoadVisibility(&mod->vis, mod_base, &header->lumps[LUMP_VISIBILITY]);
if (header->ident == IDBSPHEADER)
{
Mod_LoadLeafs(mod, mod_base, &header->lumps[LUMP_LEAFS]);
Mod_LoadNodes(mod->name, mod->planes, mod->numplanes, mod->leafs,
mod->numleafs, &mod->nodes, &mod->numnodes, mod_base,
&header->lumps[LUMP_NODES]);
}
else
{
Mod_LoadQLeafs(mod, mod_base, &header->lumps[LUMP_LEAFS]);
Mod_LoadQNodes(mod->name, mod->planes, mod->numplanes, mod->leafs,
mod->numleafs, &mod->nodes, &mod->numnodes, mod_base,
&header->lumps[LUMP_NODES]);
}
Mod_LoadSubmodels (mod, mod_base, &header->lumps[LUMP_MODELS]);
mod->numframes = 2; /* regular and alternate animation */
}

View file

@ -125,7 +125,7 @@ typedef struct mvertex_s
typedef struct medge_s
{
unsigned short v[2];
unsigned int v[2];
unsigned int cachededgeoffset;
} medge_t;
@ -153,8 +153,8 @@ typedef struct mnode_s
cplane_t *plane;
struct mnode_s *children[2];
unsigned short firstsurface;
unsigned short numsurfaces;
unsigned int firstsurface;
unsigned int numsurfaces;
} mnode_t;
typedef struct mleaf_s
@ -194,6 +194,9 @@ extern struct image_s* R_LoadImage(const char *name, const char* namewe, const c
extern void Mod_LoadNodes(const char *name, cplane_t *planes, int numplanes,
mleaf_t *leafs, int numleafs, mnode_t **nodes, int *numnodes,
const byte *mod_base, const lump_t *l);
extern void Mod_LoadQNodes(const char *name, cplane_t *planes, int numplanes,
mleaf_t *leafs, int numleafs, mnode_t **nodes, int *numnodes,
const byte *mod_base, const lump_t *l);
extern void Mod_LoadVertexes(const char *name, mvertex_t **vertexes, int *numvertexes,
const byte *mod_base, const lump_t *l, int extra);
extern void Mod_LoadVisibility(dvis_t **vis, const byte *mod_base, const lump_t *l);
@ -203,6 +206,8 @@ extern void Mod_LoadTexinfo(const char *name, mtexinfo_t **texinfo, int *numtexi
struct image_s *notexture, int extra);
extern void Mod_LoadEdges(const char *name, medge_t **edges, int *numedges,
const byte *mod_base, const lump_t *l, int extra);
extern void Mod_LoadQEdges(const char *name, medge_t **edges, int *numedges,
const byte *mod_base, const lump_t *l, int extra);
extern void Mod_LoadPlanes (const char *name, cplane_t **planes, int *numplanes,
const byte *mod_base, const lump_t *l, int extra);
extern void Mod_LoadSurfedges (const char *name, int **surfedges, int *numsurfedges,

View file

@ -46,8 +46,8 @@ typedef struct
int contents;
int cluster;
int area;
unsigned short firstleafbrush;
unsigned short numleafbrushes;
unsigned int firstleafbrush;
unsigned int numleafbrushes;
} cleaf_t;
typedef struct
@ -66,57 +66,57 @@ typedef struct
int floodvalid;
} carea_t;
byte *cmod_base;
byte map_visibility[MAX_MAP_VISIBILITY];
static byte *cmod_base;
static byte map_visibility[MAX_MAP_VISIBILITY];
// DG: is casted to int32_t* in SV_FatPVS() so align accordingly
static YQ2_ALIGNAS_TYPE(int32_t) byte pvsrow[MAX_MAP_LEAFS / 8];
byte phsrow[MAX_MAP_LEAFS / 8];
carea_t map_areas[MAX_MAP_AREAS];
cbrush_t map_brushes[MAX_MAP_BRUSHES];
cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES];
char map_name[MAX_QPATH];
char map_entitystring[MAX_MAP_ENTSTRING];
cbrush_t *box_brush;
cleaf_t *box_leaf;
cleaf_t map_leafs[MAX_MAP_LEAFS];
cmodel_t map_cmodels[MAX_MAP_MODELS];
cnode_t map_nodes[MAX_MAP_NODES+6]; /* extra for box hull */
cplane_t *box_planes;
cplane_t map_planes[MAX_MAP_PLANES+6]; /* extra for box hull */
cvar_t *map_noareas;
dareaportal_t map_areaportals[MAX_MAP_AREAPORTALS];
dvis_t *map_vis = (dvis_t *)map_visibility;
int box_headnode;
int checkcount;
int emptyleaf, solidleaf;
int floodvalid;
float *leaf_mins, *leaf_maxs;
int leaf_count, leaf_maxcount;
int *leaf_list;
int leaf_topnode;
int numareaportals;
int numareas = 1;
int numbrushes;
int numbrushsides;
int numclusters = 1;
int numcmodels;
int numentitychars;
int numleafbrushes;
int numleafs = 1; /* allow leaf funcs to be called without a map */
int numnodes;
int numplanes;
static byte phsrow[MAX_MAP_LEAFS / 8];
static carea_t map_areas[MAX_MAP_AREAS];
static cbrush_t map_brushes[MAX_MAP_BRUSHES];
static cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES];
static char map_name[MAX_QPATH];
static char map_entitystring[MAX_MAP_ENTSTRING];
static cbrush_t *box_brush;
static cleaf_t *box_leaf;
static cleaf_t map_leafs[MAX_MAP_LEAFS];
static cmodel_t map_cmodels[MAX_MAP_MODELS];
static cnode_t map_nodes[MAX_MAP_NODES+6]; /* extra for box hull */
static cplane_t *box_planes;
static cplane_t map_planes[MAX_MAP_PLANES+6]; /* extra for box hull */
static cvar_t *map_noareas;
static dareaportal_t map_areaportals[MAX_MAP_AREAPORTALS];
static dvis_t *map_vis = (dvis_t *)map_visibility;
static int box_headnode;
static int checkcount;
static int emptyleaf, solidleaf;
static int floodvalid;
static float *leaf_mins, *leaf_maxs;
static int leaf_count, leaf_maxcount;
static int *leaf_list;
static int leaf_topnode;
static int numareaportals;
static int numareas = 1;
static int numbrushes;
static int numbrushsides;
static int numclusters = 1;
static int numcmodels;
static int numentitychars;
static int numleafbrushes;
static int numleafs = 1; /* allow leaf funcs to be called without a map */
static int numnodes;
static int numplanes;
int numtexinfo;
int numvisibility;
int trace_contents;
static int numvisibility;
static int trace_contents;
mapsurface_t map_surfaces[MAX_MAP_TEXINFO];
mapsurface_t nullsurface;
qboolean portalopen[MAX_MAP_AREAPORTALS];
qboolean trace_ispoint; /* optimized case */
trace_t trace_trace;
unsigned short map_leafbrushes[MAX_MAP_LEAFBRUSHES];
vec3_t trace_start, trace_end;
vec3_t trace_mins, trace_maxs;
vec3_t trace_extents;
static mapsurface_t nullsurface;
static qboolean portalopen[MAX_MAP_AREAPORTALS];
static qboolean trace_ispoint; /* optimized case */
static trace_t trace_trace;
static unsigned int map_leafbrushes[MAX_MAP_LEAFBRUSHES];
static vec3_t trace_start, trace_end;
static vec3_t trace_mins, trace_maxs;
static vec3_t trace_extents;
#ifndef DEDICATED_ONLY
int c_pointcontents;
@ -126,7 +126,7 @@ int c_traces, c_brush_traces;
/* 1/32 epsilon to keep floating point happy */
#define DIST_EPSILON (0.03125f)
void
static void
FloodArea_r(carea_t *area, int floodnum)
{
int i;
@ -139,7 +139,7 @@ FloodArea_r(carea_t *area, int floodnum)
return;
}
Com_Error(ERR_DROP, "FloodArea_r: reflooded");
Com_Error(ERR_DROP, "%s: reflooded", __func__);
}
area->floodnum = floodnum;
@ -155,7 +155,7 @@ FloodArea_r(carea_t *area, int floodnum)
}
}
void
static void
FloodAreaConnections(void)
{
int i;
@ -186,7 +186,7 @@ CM_SetAreaPortalState(int portalnum, qboolean open)
{
if (portalnum > numareaportals)
{
Com_Error(ERR_DROP, "areaportal > numareaportals");
Com_Error(ERR_DROP, "%s: areaportal > numareaportals", __func__);
}
portalopen[portalnum] = open;
@ -203,7 +203,7 @@ CM_AreasConnected(int area1, int area2)
if ((area1 > numareas) || (area2 > numareas))
{
Com_Error(ERR_DROP, "area > numareas");
Com_Error(ERR_DROP, "%s: area > numareas", __func__);
}
if (map_areas[area1].floodnum == map_areas[area2].floodnum)
@ -316,7 +316,7 @@ CM_HeadnodeVisible(int nodenum, byte *visbits)
* Set up the planes and nodes so that the six floats of a bounding box
* can just be stored out and get a proper clipping hull structure.
*/
void
static void
CM_InitBoxHull(void)
{
int i;
@ -334,7 +334,7 @@ CM_InitBoxHull(void)
(numbrushsides + 6 > MAX_MAP_BRUSHSIDES) ||
(numplanes + 12 > MAX_MAP_PLANES))
{
Com_Error(ERR_DROP, "Not enough room for box tree");
Com_Error(ERR_DROP, "%s: Not enough room for box tree", __func__);
}
box_brush = &map_brushes[numbrushes];
@ -411,7 +411,7 @@ CM_HeadnodeForBox(vec3_t mins, vec3_t maxs)
return box_headnode;
}
int
static int
CM_PointLeafnum_r(vec3_t p, int num)
{
float d;
@ -465,8 +465,7 @@ CM_PointLeafnum(vec3_t p)
/*
* Fills in a list of all the leafs touched
*/
void
static void
CM_BoxLeafnums_r(int nodenum)
{
cplane_t *plane;
@ -514,7 +513,7 @@ CM_BoxLeafnums_r(int nodenum)
}
}
int
static int
CM_BoxLeafnums_headnode(vec3_t mins, vec3_t maxs, int *list,
int listsize, int headnode, int *topnode)
{
@ -591,7 +590,7 @@ CM_TransformedPointContents(vec3_t p, int headnode,
return map_leafs[l].contents;
}
void
static void
CM_ClipBoxToBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
vec3_t p2, trace_t *trace, cbrush_t *brush)
{
@ -729,7 +728,7 @@ CM_ClipBoxToBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
if (clipplane == NULL)
{
Com_Error(ERR_FATAL, "clipplane was NULL!\n");
Com_Error(ERR_FATAL, "%s: clipplane was NULL!\n", __func__);
}
trace->fraction = enterfrac;
@ -740,7 +739,7 @@ CM_ClipBoxToBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
}
}
void
static void
CM_TestBoxInBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
trace_t *trace, cbrush_t *brush)
{
@ -795,7 +794,7 @@ CM_TestBoxInBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
trace->contents = brush->contents;
}
void
static void
CM_TraceToLeaf(int leafnum)
{
int k;
@ -838,7 +837,7 @@ CM_TraceToLeaf(int leafnum)
}
}
void
static void
CM_TestInLeaf(int leafnum)
{
int k;
@ -880,7 +879,7 @@ CM_TestInLeaf(int leafnum)
}
}
void
static void
CM_RecursiveHullCheck(int num, float p1f, float p2f, vec3_t p1, vec3_t p2)
{
cnode_t *node;
@ -1178,7 +1177,7 @@ CM_TransformedBoxTrace(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs,
return trace;
}
void
static void
CMod_LoadSubmodels(lump_t *l)
{
dmodel_t *in;
@ -1189,19 +1188,19 @@ CMod_LoadSubmodels(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadSubmodels: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count < 1)
{
Com_Error(ERR_DROP, "Map with no models");
Com_Error(ERR_DROP, "%s: Map with no models", __func__);
}
if (count > MAX_MAP_MODELS)
{
Com_Error(ERR_DROP, "Map has too many models");
Com_Error(ERR_DROP, "%s: Map has too many models", __func__);
}
numcmodels = count;
@ -1222,7 +1221,7 @@ CMod_LoadSubmodels(lump_t *l)
}
}
void
static void
CMod_LoadSurfaces(lump_t *l)
{
texinfo_t *in;
@ -1233,19 +1232,19 @@ CMod_LoadSurfaces(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadSurfaces: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count < 1)
{
Com_Error(ERR_DROP, "Map with no surfaces");
Com_Error(ERR_DROP, "%s: Map with no surfaces", __func__);
}
if (count > MAX_MAP_TEXINFO)
{
Com_Error(ERR_DROP, "Map has too many surfaces");
Com_Error(ERR_DROP, "%s: Map has too many surfaces", __func__);
}
numtexinfo = count;
@ -1260,7 +1259,7 @@ CMod_LoadSurfaces(lump_t *l)
}
}
void
static void
CMod_LoadNodes(lump_t *l)
{
dnode_t *in;
@ -1272,19 +1271,19 @@ CMod_LoadNodes(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadNodes: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size %ld", __func__, sizeof(*in));
}
count = l->filelen / sizeof(*in);
if (count < 1)
{
Com_Error(ERR_DROP, "Map has no nodes");
Com_Error(ERR_DROP, "%s: Map has no nodes", __func__);
}
if (count > MAX_MAP_NODES)
{
Com_Error(ERR_DROP, "Map has too many nodes");
Com_Error(ERR_DROP, "%s: Map has too many nodes", __func__);
}
out = map_nodes;
@ -1303,7 +1302,50 @@ CMod_LoadNodes(lump_t *l)
}
}
void
static void
CMod_LoadQNodes(lump_t *l)
{
dqnode_t *in;
int child;
cnode_t *out;
int i, j, count;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size %ld", __func__, sizeof(*in));
}
count = l->filelen / sizeof(*in);
if (count < 1)
{
Com_Error(ERR_DROP, "%s: Map has no nodes", __func__);
}
if (count > MAX_MAP_NODES)
{
Com_Error(ERR_DROP, "%s: Map has too many nodes", __func__);
}
out = map_nodes;
numnodes = count;
for (i = 0; i < count; i++, out++, in++)
{
out->plane = map_planes + LittleLong(in->planenum);
for (j = 0; j < 2; j++)
{
child = LittleLong(in->children[j]);
out->children[j] = child;
}
}
}
static void
CMod_LoadBrushes(lump_t *l)
{
dbrush_t *in;
@ -1314,14 +1356,14 @@ CMod_LoadBrushes(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadBrushes: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count > MAX_MAP_BRUSHES)
{
Com_Error(ERR_DROP, "Map has too many brushes");
Com_Error(ERR_DROP, "%s: Map has too many brushes", __func__);
}
out = map_brushes;
@ -1336,7 +1378,7 @@ CMod_LoadBrushes(lump_t *l)
}
}
void
static void
CMod_LoadLeafs(lump_t *l)
{
int i;
@ -1348,20 +1390,20 @@ CMod_LoadLeafs(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadLeafs: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count < 1)
{
Com_Error(ERR_DROP, "Map with no leafs");
Com_Error(ERR_DROP, "%s: Map with no leafs", __func__);
}
/* need to save space for box planes */
if (count > MAX_MAP_PLANES)
{
Com_Error(ERR_DROP, "Map has too many planes");
Com_Error(ERR_DROP, "%s: Map has too many planes", __func__);
}
out = map_leafs;
@ -1384,7 +1426,7 @@ CMod_LoadLeafs(lump_t *l)
if (map_leafs[0].contents != CONTENTS_SOLID)
{
Com_Error(ERR_DROP, "Map leaf 0 is not CONTENTS_SOLID");
Com_Error(ERR_DROP, "%s: Map leaf 0 is not CONTENTS_SOLID", __func__);
}
solidleaf = 0;
@ -1401,11 +1443,80 @@ CMod_LoadLeafs(lump_t *l)
if (emptyleaf == -1)
{
Com_Error(ERR_DROP, "Map does not have an empty leaf");
Com_Error(ERR_DROP, "%s: Map does not have an empty leaf", __func__);
}
}
void
static void
CMod_LoadQLeafs(lump_t *l)
{
int i;
cleaf_t *out;
dqleaf_t *in;
int count;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count < 1)
{
Com_Error(ERR_DROP, "%s: Map with no leafs", __func__);
}
/* need to save space for box planes */
if (count > MAX_MAP_PLANES)
{
Com_Error(ERR_DROP, "%s: Map has too many planes", __func__);
}
out = map_leafs;
numleafs = count;
numclusters = 0;
for (i = 0; i < count; i++, in++, out++)
{
out->contents = LittleLong(in->contents);
out->cluster = LittleLong(in->cluster);
out->area = LittleLong(in->area);
out->firstleafbrush = LittleFloat(in->firstleafbrush);
out->numleafbrushes = LittleFloat(in->numleafbrushes);
if (out->cluster >= numclusters)
{
numclusters = out->cluster + 1;
}
}
if (map_leafs[0].contents != CONTENTS_SOLID)
{
Com_Error(ERR_DROP, "%s: Map leaf 0 is not CONTENTS_SOLID", __func__);
}
solidleaf = 0;
emptyleaf = -1;
for (i = 1; i < numleafs; i++)
{
if (!map_leafs[i].contents)
{
emptyleaf = i;
break;
}
}
if (emptyleaf == -1)
{
Com_Error(ERR_DROP, "%s: Map does not have an empty leaf", __func__);
}
}
static void
CMod_LoadPlanes(lump_t *l)
{
int i, j;
@ -1418,20 +1529,20 @@ CMod_LoadPlanes(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadPlanes: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count < 1)
{
Com_Error(ERR_DROP, "Map with no planes");
Com_Error(ERR_DROP, "%s: Map with no planes", __func__);
}
/* need to save space for box planes */
if (count > MAX_MAP_PLANES)
{
Com_Error(ERR_DROP, "Map has too many planes");
Com_Error(ERR_DROP, "%s: Map has too many planes", __func__);
}
out = map_planes;
@ -1457,11 +1568,11 @@ CMod_LoadPlanes(lump_t *l)
}
}
void
static void
CMod_LoadLeafBrushes(lump_t *l)
{
int i;
unsigned short *out;
unsigned int *out;
unsigned short *in;
int count;
@ -1469,20 +1580,20 @@ CMod_LoadLeafBrushes(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadLeafBrushes: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count < 1)
{
Com_Error(ERR_DROP, "Map with no planes");
Com_Error(ERR_DROP, "%s: Map with no planes", __func__);
}
/* need to save space for box planes */
if (count > MAX_MAP_LEAFBRUSHES)
{
Com_Error(ERR_DROP, "Map has too many leafbrushes");
Com_Error(ERR_DROP, "%s: Map has too many leafbrushes", __func__);
}
out = map_leafbrushes;
@ -1494,7 +1605,44 @@ CMod_LoadLeafBrushes(lump_t *l)
}
}
void
static void
CMod_LoadQLeafBrushes(lump_t *l)
{
int i;
unsigned int *out;
unsigned int *in;
int count;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count < 1)
{
Com_Error(ERR_DROP, "%s: Map with no planes", __func__);
}
/* need to save space for box planes */
if (count > MAX_MAP_LEAFBRUSHES)
{
Com_Error(ERR_DROP, "%s: Map has too many leafbrushes", __func__);
}
out = map_leafbrushes;
numleafbrushes = count;
for (i = 0; i < count; i++, in++, out++)
{
*out = LittleLong(*in);
}
}
static void
CMod_LoadBrushSides(lump_t *l)
{
int i, j;
@ -1507,7 +1655,7 @@ CMod_LoadBrushSides(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadBrushSides: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
@ -1515,7 +1663,7 @@ CMod_LoadBrushSides(lump_t *l)
/* need to save space for box planes */
if (count > MAX_MAP_BRUSHSIDES)
{
Com_Error(ERR_DROP, "Map has too many planes");
Com_Error(ERR_DROP, "%s: Map has too many planes", __func__);
}
out = map_brushsides;
@ -1529,14 +1677,55 @@ CMod_LoadBrushSides(lump_t *l)
if (j >= numtexinfo)
{
Com_Error(ERR_DROP, "Bad brushside texinfo");
Com_Error(ERR_DROP, "%s: Bad brushside texinfo", __func__);
}
out->surface = (j >= 0) ? &map_surfaces[j] : &nullsurface;
}
}
static void
CMod_LoadQBrushSides(lump_t *l)
{
int i, j;
cbrushside_t *out;
dqbrushside_t *in;
int count;
int num;
in = (void *)(cmod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
/* need to save space for box planes */
if (count > MAX_MAP_BRUSHSIDES)
{
Com_Error(ERR_DROP, "%s: Map has too many planes", __func__);
}
out = map_brushsides;
numbrushsides = count;
for (i = 0; i < count; i++, in++, out++)
{
num = LittleLong(in->planenum);
out->plane = &map_planes[num];
j = LittleLong(in->texinfo);
if (j >= numtexinfo)
{
Com_Error(ERR_DROP, "%s: Bad brushside texinfo", __func__);
}
out->surface = (j >= 0) ? &map_surfaces[j] : &nullsurface;
}
}
void
static void
CMod_LoadAreas(lump_t *l)
{
int i;
@ -1548,14 +1737,14 @@ CMod_LoadAreas(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadAreas: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count > MAX_MAP_AREAS)
{
Com_Error(ERR_DROP, "Map has too many areas");
Com_Error(ERR_DROP, "%s: Map has too many areas", __func__);
}
out = map_areas;
@ -1570,7 +1759,7 @@ CMod_LoadAreas(lump_t *l)
}
}
void
static void
CMod_LoadAreaPortals(lump_t *l)
{
dareaportal_t *out;
@ -1581,14 +1770,14 @@ CMod_LoadAreaPortals(lump_t *l)
if (l->filelen % sizeof(*in))
{
Com_Error(ERR_DROP, "Mod_LoadAreaPortals: funny lump size");
Com_Error(ERR_DROP, "%s: funny lump size", __func__);
}
count = l->filelen / sizeof(*in);
if (count > MAX_MAP_AREAS)
{
Com_Error(ERR_DROP, "Map has too many areas");
Com_Error(ERR_DROP, "%s: Map has too many areas", __func__);
}
out = map_areaportals;
@ -1597,14 +1786,14 @@ CMod_LoadAreaPortals(lump_t *l)
memcpy(out, in, sizeof(dareaportal_t) * count);
}
void
static void
CMod_LoadVisibility(lump_t *l)
{
numvisibility = l->filelen;
if (l->filelen > MAX_MAP_VISIBILITY)
{
Com_Error(ERR_DROP, "Map has too large visibility lump");
Com_Error(ERR_DROP, "%s: Map has too large visibility lump", __func__);
}
memcpy(map_visibility, cmod_base + l->fileofs, l->filelen);
@ -1612,7 +1801,7 @@ CMod_LoadVisibility(lump_t *l)
map_vis->numclusters = LittleLong(map_vis->numclusters);
}
void
static void
CMod_LoadEntityString(lump_t *l, char *name)
{
if (sv_entfile->value)
@ -1655,7 +1844,7 @@ CMod_LoadEntityString(lump_t *l, char *name)
if (l->filelen + 1 > sizeof(map_entitystring))
{
Com_Error(ERR_DROP, "Map has too large entity lump");
Com_Error(ERR_DROP, "%s: Map has too large entity lump", __func__);
}
memcpy(map_entitystring, cmod_base + l->fileofs, l->filelen);
@ -1713,7 +1902,7 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
if (!buf)
{
Com_Error(ERR_DROP, "Couldn't load %s", name);
Com_Error(ERR_DROP, "%s: Couldn't load %s", name, __func__);
}
last_checksum = LittleLong(Com_BlockChecksum(buf, length));
@ -1726,24 +1915,52 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
((int *)&header)[i] = LittleLong(((int *)&header)[i]);
}
if (header.ident != IDBSPHEADER && header.ident != QDBSPHEADER)
{
Com_Error(ERR_DROP, "%s: %s has wrong ident (%i should be %i)",
__func__, name, header.ident, IDBSPHEADER);
}
if (header.version != BSPVERSION)
{
Com_Error(ERR_DROP,
"CMod_LoadBrushModel: %s has wrong version number (%i should be %i)",
name, header.version, BSPVERSION);
"%s: %s has wrong version number (%i should be %i)",
__func__, name, header.version, BSPVERSION);
}
cmod_base = (byte *)buf;
/* load into heap */
CMod_LoadSurfaces(&header.lumps[LUMP_TEXINFO]);
if (header.ident == IDBSPHEADER)
{
CMod_LoadLeafs(&header.lumps[LUMP_LEAFS]);
CMod_LoadLeafBrushes(&header.lumps[LUMP_LEAFBRUSHES]);
}
else
{
CMod_LoadQLeafs(&header.lumps[LUMP_LEAFS]);
CMod_LoadQLeafBrushes(&header.lumps[LUMP_LEAFBRUSHES]);
}
CMod_LoadPlanes(&header.lumps[LUMP_PLANES]);
CMod_LoadBrushes(&header.lumps[LUMP_BRUSHES]);
if (header.ident == IDBSPHEADER)
{
CMod_LoadBrushSides(&header.lumps[LUMP_BRUSHSIDES]);
}
else
{
CMod_LoadQBrushSides(&header.lumps[LUMP_BRUSHSIDES]);
}
CMod_LoadSubmodels(&header.lumps[LUMP_MODELS]);
if (header.ident == IDBSPHEADER)
{
CMod_LoadNodes(&header.lumps[LUMP_NODES]);
}
else
{
CMod_LoadQNodes(&header.lumps[LUMP_NODES]);
}
CMod_LoadAreas(&header.lumps[LUMP_AREAS]);
CMod_LoadAreaPortals(&header.lumps[LUMP_AREAPORTALS]);
CMod_LoadVisibility(&header.lumps[LUMP_VISIBILITY]);
@ -1769,14 +1986,14 @@ CM_InlineModel(char *name)
if (!name || (name[0] != '*'))
{
Com_Error(ERR_DROP, "CM_InlineModel: bad name");
Com_Error(ERR_DROP, "%s: bad name", __func__);
}
num = (int)strtol(name + 1, (char **)NULL, 10);
if ((num < 1) || (num >= numcmodels))
{
Com_Error(ERR_DROP, "CM_InlineModel: bad number");
Com_Error(ERR_DROP, "%s: bad number", __func__);
}
return &map_cmodels[num];
@ -1805,7 +2022,7 @@ CM_LeafContents(int leafnum)
{
if ((leafnum < 0) || (leafnum >= numleafs))
{
Com_Error(ERR_DROP, "CM_LeafContents: bad number");
Com_Error(ERR_DROP, "%s: bad number", __func__);
}
return map_leafs[leafnum].contents;
@ -1816,7 +2033,7 @@ CM_LeafCluster(int leafnum)
{
if ((leafnum < 0) || (leafnum >= numleafs))
{
Com_Error(ERR_DROP, "CM_LeafCluster: bad number");
Com_Error(ERR_DROP, "%s: bad number", __func__);
}
return map_leafs[leafnum].cluster;
@ -1827,13 +2044,13 @@ CM_LeafArea(int leafnum)
{
if ((leafnum < 0) || (leafnum >= numleafs))
{
Com_Error(ERR_DROP, "CM_LeafArea: bad number");
Com_Error(ERR_DROP, "%s: bad number", __func__);
}
return map_leafs[leafnum].area;
}
void
static void
CM_DecompressVis(byte *in, byte *out)
{
int c;

View file

@ -232,22 +232,23 @@ typedef struct m32tex_s
/* .BSP file format */
#define IDBSPHEADER (('P' << 24) + ('S' << 16) + ('B' << 8) + 'I') /* little-endian "IBSP" */
#define QDBSPHEADER (('P' << 24) + ('S' << 16) + ('B' << 8) + 'Q') /* little-endian "IBSQ" */
#define BSPXHEADER (('X' << 24) + ('P' << 16) + ('S' << 8) + 'B') /* little-endian "BSPX" */
#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_BRUSHES 16384
#define MAX_MAP_ENTITIES 2048
#define MAX_MAP_ENTSTRING 0x40000
#define MAX_MAP_TEXINFO 8192
#define MAX_MAP_TEXINFO 32768
#define MAX_MAP_AREAS 256
#define MAX_MAP_AREAPORTALS 1024
#define MAX_MAP_PLANES 65536
#define MAX_MAP_PLANES 131072
#define MAX_MAP_NODES 65536
#define MAX_MAP_BRUSHSIDES 65536
#define MAX_MAP_BRUSHSIDES 131072
#define MAX_MAP_LEAFS 65536
#define MAX_MAP_VERTS 65536
#define MAX_MAP_FACES 65536
@ -257,7 +258,7 @@ typedef struct m32tex_s
#define MAX_MAP_EDGES 128000
#define MAX_MAP_SURFEDGES 256000
#define MAX_MAP_LIGHTING 0x200000
#define MAX_MAP_VISIBILITY 0x100000
#define MAX_MAP_VISIBILITY 0x200000
/* key / value pair sizes */
@ -400,6 +401,16 @@ typedef struct
unsigned short numfaces; /* counting both sides */
} dnode_t;
typedef struct
{
int planenum;
int children[2]; /* negative numbers are -(leafs+1), not nodes */
float mins[3]; /* for frustom culling */
float maxs[3];
unsigned int firstface;
unsigned int numfaces; /* counting both sides */
} dqnode_t;
typedef struct texinfo_s
{
float vecs[2][4]; /* [s/t][xyz offset] */
@ -417,6 +428,11 @@ typedef struct
unsigned short v[2]; /* vertex numbers */
} dedge_t;
typedef struct
{
unsigned int v[2]; /* vertex numbers */
} dqedge_t;
#define MAXLIGHTMAPS 4
typedef struct
{
@ -432,6 +448,20 @@ typedef struct
int lightofs; /* start of [numstyles*surfsize] samples */
} dface_t;
typedef struct
{
unsigned int planenum;
int side;
int firstedge; /* we must support > 64k edges */
int numedges;
int texinfo;
/* lighting info */
byte styles[MAXLIGHTMAPS];
int lightofs; /* start of [numstyles*surfsize] samples */
} dqface_t;
typedef struct {
unsigned short lmwidth;
unsigned short lmheight;
@ -456,12 +486,35 @@ typedef struct
unsigned short numleafbrushes;
} dleaf_t;
typedef struct
{
int contents; /* OR of all brushes (not needed?) */
int cluster;
int area;
float mins[3]; /* for frustum culling */
float maxs[3];
unsigned int firstleafface;
unsigned int numleaffaces;
unsigned int firstleafbrush;
unsigned int numleafbrushes;
} dqleaf_t;
typedef struct
{
unsigned short planenum; /* facing out of the leaf */
short texinfo;
} dbrushside_t;
typedef struct
{
unsigned int planenum; /* facing out of the leaf */
int texinfo;
} dqbrushside_t;
typedef struct
{
int firstside;