collision: check string entity hash before load

https://github.com/yquake2/yquake2remaster/issues/4#issuecomment-1741814349
This commit is contained in:
Denis Pauk 2024-07-29 14:29:40 +03:00
parent 180050b9a3
commit c92664c01d
16 changed files with 184 additions and 156 deletions

View file

@ -53,8 +53,8 @@ typedef struct
typedef struct typedef struct
{ {
int contents; int contents;
int numsides; unsigned int numsides;
int firstbrushside; unsigned int firstbrushside;
int checkcount; /* to avoid repeated testings */ int checkcount; /* to avoid repeated testings */
} cbrush_t; } cbrush_t;
@ -66,57 +66,57 @@ typedef struct
int floodvalid; int floodvalid;
} carea_t; } carea_t;
byte *cmod_base; static byte *cmod_base;
byte map_visibility[MAX_MAP_VISIBILITY]; static byte map_visibility[MAX_MAP_VISIBILITY];
// DG: is casted to int32_t* in SV_FatPVS() so align accordingly // DG: is casted to int32_t* in SV_FatPVS() so align accordingly
static YQ2_ALIGNAS_TYPE(int32_t) byte pvsrow[MAX_MAP_LEAFS / 8]; static YQ2_ALIGNAS_TYPE(int32_t) byte pvsrow[MAX_MAP_LEAFS / 8];
byte phsrow[MAX_MAP_LEAFS / 8]; static byte phsrow[MAX_MAP_LEAFS / 8];
carea_t map_areas[MAX_MAP_AREAS]; static carea_t map_areas[MAX_MAP_AREAS];
cbrush_t map_brushes[MAX_MAP_BRUSHES]; static cbrush_t map_brushes[MAX_MAP_BRUSHES];
cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES]; static cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES];
char map_name[MAX_QPATH]; static char map_name[MAX_QPATH];
char map_entitystring[MAX_MAP_ENTSTRING]; static char map_entitystring[MAX_MAP_ENTSTRING];
cbrush_t *box_brush; static cbrush_t *box_brush;
cleaf_t *box_leaf; static cleaf_t *box_leaf;
cleaf_t map_leafs[MAX_MAP_LEAFS]; static cleaf_t map_leafs[MAX_MAP_LEAFS];
cmodel_t map_cmodels[MAX_MAP_MODELS]; static cmodel_t map_cmodels[MAX_MAP_MODELS];
cnode_t map_nodes[MAX_MAP_NODES+6]; /* extra for box hull */ static cnode_t map_nodes[MAX_MAP_NODES+6]; /* extra for box hull */
cplane_t *box_planes; static cplane_t *box_planes;
cplane_t map_planes[MAX_MAP_PLANES+6]; /* extra for box hull */ static cplane_t map_planes[MAX_MAP_PLANES+6]; /* extra for box hull */
cvar_t *map_noareas; static cvar_t *map_noareas;
dareaportal_t map_areaportals[MAX_MAP_AREAPORTALS]; static dareaportal_t map_areaportals[MAX_MAP_AREAPORTALS];
dvis_t *map_vis = (dvis_t *)map_visibility; static dvis_t *map_vis = (dvis_t *)map_visibility;
int box_headnode; static int box_headnode;
int checkcount; static int checkcount;
int emptyleaf, solidleaf; static int emptyleaf, solidleaf;
int floodvalid; static int floodvalid;
float *leaf_mins, *leaf_maxs; static float *leaf_mins, *leaf_maxs;
int leaf_count, leaf_maxcount; static int leaf_count, leaf_maxcount;
int *leaf_list; static int *leaf_list;
int leaf_topnode; static int leaf_topnode;
int numareaportals; static int numareaportals;
int numareas = 1; static int numareas = 1;
int numbrushes; static int numbrushes;
int numbrushsides; static int numbrushsides;
int numclusters = 1; static int numclusters = 1;
int numcmodels; static int numcmodels;
int numentitychars; static int numentitychars;
int numleafbrushes; static int numleafbrushes;
int numleafs = 1; /* allow leaf funcs to be called without a map */ static int numleafs = 1; /* allow leaf funcs to be called without a map */
int numnodes; static int numnodes;
int numplanes; static int numplanes;
int numtexinfo; int numtexinfo;
int numvisibility; static int numvisibility;
int trace_contents; static int trace_contents;
mapsurface_t map_surfaces[MAX_MAP_TEXINFO]; mapsurface_t map_surfaces[MAX_MAP_TEXINFO];
mapsurface_t nullsurface; static mapsurface_t nullsurface;
qboolean portalopen[MAX_MAP_AREAPORTALS]; static qboolean portalopen[MAX_MAP_AREAPORTALS];
qboolean trace_ispoint; /* optimized case */ static qboolean trace_ispoint; /* optimized case */
trace_t trace_trace; static trace_t trace_trace;
unsigned short map_leafbrushes[MAX_MAP_LEAFBRUSHES]; static unsigned short map_leafbrushes[MAX_MAP_LEAFBRUSHES];
vec3_t trace_start, trace_end; static vec3_t trace_start, trace_end;
vec3_t trace_mins, trace_maxs; static vec3_t trace_mins, trace_maxs;
vec3_t trace_extents; static vec3_t trace_extents;
#ifndef DEDICATED_ONLY #ifndef DEDICATED_ONLY
int c_pointcontents; int c_pointcontents;
@ -126,11 +126,11 @@ int c_traces, c_brush_traces;
/* 1/32 epsilon to keep floating point happy */ /* 1/32 epsilon to keep floating point happy */
#define DIST_EPSILON (0.03125f) #define DIST_EPSILON (0.03125f)
void static void
FloodArea_r(carea_t *area, int floodnum) FloodArea_r(carea_t *area, int floodnum)
{ {
int i; int i;
dareaportal_t *p; const dareaportal_t *p;
if (area->floodvalid == floodvalid) if (area->floodvalid == floodvalid)
{ {
@ -139,7 +139,7 @@ FloodArea_r(carea_t *area, int floodnum)
return; return;
} }
Com_Error(ERR_DROP, "FloodArea_r: reflooded"); Com_Error(ERR_DROP, "%s: reflooded", __func__);
} }
area->floodnum = floodnum; area->floodnum = floodnum;
@ -155,12 +155,10 @@ FloodArea_r(carea_t *area, int floodnum)
} }
} }
void static void
FloodAreaConnections(void) FloodAreaConnections(void)
{ {
int i; int i, floodnum;
carea_t *area;
int floodnum;
/* all current floods are now invalid */ /* all current floods are now invalid */
floodvalid++; floodvalid++;
@ -169,6 +167,8 @@ FloodAreaConnections(void)
/* area 0 is not used */ /* area 0 is not used */
for (i = 1; i < numareas; i++) for (i = 1; i < numareas; i++)
{ {
carea_t *area;
area = &map_areas[i]; area = &map_areas[i];
if (area->floodvalid == floodvalid) if (area->floodvalid == floodvalid)
@ -223,8 +223,6 @@ CM_AreasConnected(int area1, int area2)
int int
CM_WriteAreaBits(byte *buffer, int area) CM_WriteAreaBits(byte *buffer, int area)
{ {
int i;
int floodnum;
int bytes; int bytes;
bytes = (numareas + 7) >> 3; bytes = (numareas + 7) >> 3;
@ -237,6 +235,8 @@ CM_WriteAreaBits(byte *buffer, int area)
else else
{ {
int floodnum, i;
memset(buffer, 0, bytes); memset(buffer, 0, bytes);
floodnum = map_areas[area].floodnum; floodnum = map_areas[area].floodnum;
@ -280,12 +280,13 @@ CM_ReadPortalState(fileHandle_t f)
qboolean qboolean
CM_HeadnodeVisible(int nodenum, byte *visbits) CM_HeadnodeVisible(int nodenum, byte *visbits)
{ {
int leafnum1; const cnode_t *node;
int cluster;
cnode_t *node;
if (nodenum < 0) if (nodenum < 0)
{ {
int leafnum1;
int cluster;
leafnum1 = -1 - nodenum; leafnum1 = -1 - nodenum;
cluster = map_leafs[leafnum1].cluster; cluster = map_leafs[leafnum1].cluster;
@ -316,14 +317,11 @@ CM_HeadnodeVisible(int nodenum, byte *visbits)
* Set up the planes and nodes so that the six floats of a bounding box * 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. * can just be stored out and get a proper clipping hull structure.
*/ */
void static void
CM_InitBoxHull(void) CM_InitBoxHull(void)
{ {
int i;
int side;
cnode_t *c;
cplane_t *p; cplane_t *p;
cbrushside_t *s; int i;
box_headnode = numnodes; box_headnode = numnodes;
box_planes = &map_planes[numplanes]; box_planes = &map_planes[numplanes];
@ -351,6 +349,10 @@ CM_InitBoxHull(void)
for (i = 0; i < 6; i++) for (i = 0; i < 6; i++)
{ {
cbrushside_t *s;
cnode_t *c;
int side;
side = i & 1; side = i & 1;
/* brush sides */ /* brush sides */
@ -411,7 +413,7 @@ CM_HeadnodeForBox(vec3_t mins, vec3_t maxs)
return box_headnode; return box_headnode;
} }
int static int
CM_PointLeafnum_r(vec3_t p, int num) CM_PointLeafnum_r(vec3_t p, int num)
{ {
float d; float d;
@ -465,16 +467,15 @@ CM_PointLeafnum(vec3_t p)
/* /*
* Fills in a list of all the leafs touched * Fills in a list of all the leafs touched
*/ */
static void
void
CM_BoxLeafnums_r(int nodenum) CM_BoxLeafnums_r(int nodenum)
{ {
while (1)
{
cplane_t *plane; cplane_t *plane;
cnode_t *node; cnode_t *node;
int s; int s;
while (1)
{
if (nodenum < 0) if (nodenum < 0)
{ {
if (leaf_count >= leaf_maxcount) if (leaf_count >= leaf_maxcount)
@ -514,7 +515,7 @@ CM_BoxLeafnums_r(int nodenum)
} }
} }
int static int
CM_BoxLeafnums_headnode(vec3_t mins, vec3_t maxs, int *list, CM_BoxLeafnums_headnode(vec3_t mins, vec3_t maxs, int *list,
int listsize, int headnode, int *topnode) int listsize, int headnode, int *topnode)
{ {
@ -591,7 +592,7 @@ CM_TransformedPointContents(vec3_t p, int headnode,
return map_leafs[l].contents; return map_leafs[l].contents;
} }
void static void
CM_ClipBoxToBrush(vec3_t mins, vec3_t maxs, vec3_t p1, CM_ClipBoxToBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
vec3_t p2, trace_t *trace, cbrush_t *brush) vec3_t p2, trace_t *trace, cbrush_t *brush)
{ {
@ -729,7 +730,7 @@ CM_ClipBoxToBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
if (clipplane == NULL) if (clipplane == NULL)
{ {
Com_Error(ERR_FATAL, "clipplane was NULL!\n"); Com_Error(ERR_FATAL, "%s: clipplane was NULL!\n", __func__);
} }
trace->fraction = enterfrac; trace->fraction = enterfrac;
@ -740,15 +741,13 @@ 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, CM_TestBoxInBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
trace_t *trace, cbrush_t *brush) trace_t *trace, const cbrush_t *brush)
{ {
int i, j; int i, j;
cplane_t *plane; cplane_t *plane;
float dist;
vec3_t ofs; vec3_t ofs;
float d1;
cbrushside_t *side; cbrushside_t *side;
if (!brush->numsides) if (!brush->numsides)
@ -758,6 +757,8 @@ CM_TestBoxInBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
for (i = 0; i < brush->numsides; i++) for (i = 0; i < brush->numsides; i++)
{ {
float d1, dist;
side = &map_brushsides[brush->firstbrushside + i]; side = &map_brushsides[brush->firstbrushside + i];
plane = side->plane; plane = side->plane;
@ -795,13 +796,11 @@ CM_TestBoxInBrush(vec3_t mins, vec3_t maxs, vec3_t p1,
trace->contents = brush->contents; trace->contents = brush->contents;
} }
void static void
CM_TraceToLeaf(int leafnum) CM_TraceToLeaf(int leafnum)
{ {
const cleaf_t *leaf;
int k; int k;
int brushnum;
cleaf_t *leaf;
cbrush_t *b;
leaf = &map_leafs[leafnum]; leaf = &map_leafs[leafnum];
@ -813,6 +812,9 @@ CM_TraceToLeaf(int leafnum)
/* trace line against all brushes in the leaf */ /* trace line against all brushes in the leaf */
for (k = 0; k < leaf->numleafbrushes; k++) for (k = 0; k < leaf->numleafbrushes; k++)
{ {
int brushnum;
cbrush_t *b;
brushnum = map_leafbrushes[leaf->firstleafbrush + k]; brushnum = map_leafbrushes[leaf->firstleafbrush + k];
b = &map_brushes[brushnum]; b = &map_brushes[brushnum];
@ -838,13 +840,11 @@ CM_TraceToLeaf(int leafnum)
} }
} }
void static void
CM_TestInLeaf(int leafnum) CM_TestInLeaf(int leafnum)
{ {
const cleaf_t *leaf;
int k; int k;
int brushnum;
cleaf_t *leaf;
cbrush_t *b;
leaf = &map_leafs[leafnum]; leaf = &map_leafs[leafnum];
@ -856,6 +856,9 @@ CM_TestInLeaf(int leafnum)
/* trace line against all brushes in the leaf */ /* trace line against all brushes in the leaf */
for (k = 0; k < leaf->numleafbrushes; k++) for (k = 0; k < leaf->numleafbrushes; k++)
{ {
int brushnum;
cbrush_t *b;
brushnum = map_leafbrushes[leaf->firstleafbrush + k]; brushnum = map_leafbrushes[leaf->firstleafbrush + k];
b = &map_brushes[brushnum]; b = &map_brushes[brushnum];
@ -880,7 +883,7 @@ CM_TestInLeaf(int leafnum)
} }
} }
void static void
CM_RecursiveHullCheck(int num, float p1f, float p2f, vec3_t p1, vec3_t p2) CM_RecursiveHullCheck(int num, float p1f, float p2f, vec3_t p1, vec3_t p2)
{ {
cnode_t *node; cnode_t *node;
@ -1017,8 +1020,6 @@ trace_t
CM_BoxTrace(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, CM_BoxTrace(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs,
int headnode, int brushmask) int headnode, int brushmask)
{ {
int i;
checkcount++; /* for multi-check avoidance */ checkcount++; /* for multi-check avoidance */
#ifndef DEDICATED_ONLY #ifndef DEDICATED_ONLY
@ -1101,6 +1102,8 @@ CM_BoxTrace(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs,
else else
{ {
int i;
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
trace_trace.endpos[i] = start[i] + trace_trace.fraction * trace_trace.endpos[i] = start[i] + trace_trace.fraction *
@ -1119,12 +1122,11 @@ trace_t
CM_TransformedBoxTrace(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, CM_TransformedBoxTrace(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs,
int headnode, int brushmask, vec3_t origin, vec3_t angles) int headnode, int brushmask, vec3_t origin, vec3_t angles)
{ {
trace_t trace;
vec3_t start_l, end_l;
vec3_t a;
vec3_t forward, right, up; vec3_t forward, right, up;
vec3_t temp; vec3_t start_l, end_l;
qboolean rotated; qboolean rotated;
trace_t trace;
vec3_t temp;
/* subtract origin offset */ /* subtract origin offset */
VectorSubtract(start, origin, start_l); VectorSubtract(start, origin, start_l);
@ -1162,6 +1164,8 @@ CM_TransformedBoxTrace(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs,
if (rotated && (trace.fraction != 1.0)) if (rotated && (trace.fraction != 1.0))
{ {
vec3_t a;
VectorNegate(angles, a); VectorNegate(angles, a);
AngleVectors(a, forward, right, up); AngleVectors(a, forward, right, up);
@ -1178,8 +1182,8 @@ CM_TransformedBoxTrace(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs,
return trace; return trace;
} }
void static void
CMod_LoadSubmodels(lump_t *l) CMod_LoadSubmodels(const char *name, lump_t *l)
{ {
dmodel_t *in; dmodel_t *in;
cmodel_t *out; cmodel_t *out;
@ -1189,19 +1193,19 @@ CMod_LoadSubmodels(lump_t *l)
if (l->filelen % sizeof(*in)) if (l->filelen % sizeof(*in))
{ {
Com_Error(ERR_DROP, "Mod_LoadSubmodels: funny lump size"); Com_Error(ERR_DROP, "%s: Map %s has funny lump size", __func__, name);
} }
count = l->filelen / sizeof(*in); count = l->filelen / sizeof(*in);
if (count < 1) if (count < 1)
{ {
Com_Error(ERR_DROP, "Map with no models"); Com_Error(ERR_DROP, "%s: Map %s with no models", __func__, name);
} }
if (count > MAX_MAP_MODELS) if (count > MAX_MAP_MODELS)
{ {
Com_Error(ERR_DROP, "Map has too many models"); Com_Error(ERR_DROP, "%s: Map %s has too many models", __func__, name);
} }
numcmodels = count; numcmodels = count;
@ -1222,7 +1226,7 @@ CMod_LoadSubmodels(lump_t *l)
} }
} }
void static void
CMod_LoadSurfaces(lump_t *l) CMod_LoadSurfaces(lump_t *l)
{ {
texinfo_t *in; texinfo_t *in;
@ -1233,14 +1237,14 @@ CMod_LoadSurfaces(lump_t *l)
if (l->filelen % sizeof(*in)) 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); count = l->filelen / sizeof(*in);
if (count < 1) 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) if (count > MAX_MAP_TEXINFO)
@ -1260,8 +1264,8 @@ CMod_LoadSurfaces(lump_t *l)
} }
} }
void static void
CMod_LoadNodes(lump_t *l) CMod_LoadNodes(const char *name, lump_t *l)
{ {
dnode_t *in; dnode_t *in;
int child; int child;
@ -1272,14 +1276,15 @@ CMod_LoadNodes(lump_t *l)
if (l->filelen % sizeof(*in)) if (l->filelen % sizeof(*in))
{ {
Com_Error(ERR_DROP, "Mod_LoadNodes: funny lump size"); Com_Error(ERR_DROP, "%s: Map %s funny lump size " YQ2_COM_PRIdS,
__func__, name, sizeof(*in));
} }
count = l->filelen / sizeof(*in); count = l->filelen / sizeof(*in);
if (count < 1) if (count < 1)
{ {
Com_Error(ERR_DROP, "Map has no nodes"); Com_Error(ERR_DROP, "%s: Map %s with no nodes", __func__, name);
} }
if (count > MAX_MAP_NODES) if (count > MAX_MAP_NODES)
@ -1303,8 +1308,8 @@ CMod_LoadNodes(lump_t *l)
} }
} }
void static void
CMod_LoadBrushes(lump_t *l) CMod_LoadBrushes(const char *name, lump_t *l)
{ {
dbrush_t *in; dbrush_t *in;
cbrush_t *out; cbrush_t *out;
@ -1314,7 +1319,7 @@ CMod_LoadBrushes(lump_t *l)
if (l->filelen % sizeof(*in)) if (l->filelen % sizeof(*in))
{ {
Com_Error(ERR_DROP, "Mod_LoadBrushes: funny lump size"); Com_Error(ERR_DROP, "%s: Map %s funny lump size", __func__, name);
} }
count = l->filelen / sizeof(*in); count = l->filelen / sizeof(*in);
@ -1336,7 +1341,7 @@ CMod_LoadBrushes(lump_t *l)
} }
} }
void static void
CMod_LoadLeafs(lump_t *l) CMod_LoadLeafs(lump_t *l)
{ {
int i; int i;
@ -1348,14 +1353,14 @@ CMod_LoadLeafs(lump_t *l)
if (l->filelen % sizeof(*in)) 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); count = l->filelen / sizeof(*in);
if (count < 1) 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 */ /* need to save space for box planes */
@ -1405,14 +1410,13 @@ CMod_LoadLeafs(lump_t *l)
} }
} }
void static void
CMod_LoadPlanes(lump_t *l) CMod_LoadPlanes(lump_t *l)
{ {
int i, j; int i, j;
cplane_t *out; cplane_t *out;
dplane_t *in; dplane_t *in;
int count; int count;
int bits;
in = (void *)(cmod_base + l->fileofs); in = (void *)(cmod_base + l->fileofs);
@ -1439,6 +1443,8 @@ CMod_LoadPlanes(lump_t *l)
for (i = 0; i < count; i++, in++, out++) for (i = 0; i < count; i++, in++, out++)
{ {
int bits;
bits = 0; bits = 0;
for (j = 0; j < 3; j++) for (j = 0; j < 3; j++)
@ -1457,8 +1463,8 @@ CMod_LoadPlanes(lump_t *l)
} }
} }
void static void
CMod_LoadLeafBrushes(lump_t *l) CMod_LoadLeafBrushes(const char *name, lump_t *l)
{ {
int i; int i;
unsigned short *out; unsigned short *out;
@ -1469,7 +1475,7 @@ CMod_LoadLeafBrushes(lump_t *l)
if (l->filelen % sizeof(*in)) if (l->filelen % sizeof(*in))
{ {
Com_Error(ERR_DROP, "Mod_LoadLeafBrushes: funny lump size"); Com_Error(ERR_DROP, "%s: Map %s funny lump size", __func__, name);
} }
count = l->filelen / sizeof(*in); count = l->filelen / sizeof(*in);
@ -1536,7 +1542,7 @@ CMod_LoadBrushSides(lump_t *l)
} }
} }
void static void
CMod_LoadAreas(lump_t *l) CMod_LoadAreas(lump_t *l)
{ {
int i; int i;
@ -1570,7 +1576,7 @@ CMod_LoadAreas(lump_t *l)
} }
} }
void static void
CMod_LoadAreaPortals(lump_t *l) CMod_LoadAreaPortals(lump_t *l)
{ {
dareaportal_t *out; dareaportal_t *out;
@ -1597,7 +1603,7 @@ CMod_LoadAreaPortals(lump_t *l)
memcpy(out, in, sizeof(dareaportal_t) * count); memcpy(out, in, sizeof(dareaportal_t) * count);
} }
void static void
CMod_LoadVisibility(lump_t *l) CMod_LoadVisibility(lump_t *l)
{ {
numvisibility = l->filelen; numvisibility = l->filelen;
@ -1612,54 +1618,76 @@ CMod_LoadVisibility(lump_t *l)
map_vis->numclusters = LittleLong(map_vis->numclusters); map_vis->numclusters = LittleLong(map_vis->numclusters);
} }
void static void
CMod_LoadEntityString(lump_t *l, char *name) CMod_LoadEntityString(const lump_t *l, const char *name)
{ {
if (sv_entfile->value) if (sv_entfile->value)
{ {
char s[MAX_QPATH]; char *buffer = NULL, entname[256];
char *buffer = NULL; int nameLen, bufLen = -1;
int nameLen, bufLen;
nameLen = strlen(name); nameLen = strlen(name);
strcpy(s, name); if (strcmp(name + nameLen - 4, ".bsp") || nameLen > (MAX_QPATH - 1))
s[nameLen-3] = 'e'; s[nameLen-2] = 'n'; s[nameLen-1] = 't';
bufLen = FS_LoadFile(s, (void **)&buffer);
if (buffer != NULL && bufLen > 1)
{ {
if (bufLen + 1 > sizeof(map_entitystring)) Com_Printf("%s: unsupported map format '%s'\n", __func__, name);
{
Com_Printf("CMod_LoadEntityString: .ent file %s too large: %i > %lu.\n", s, bufLen, (unsigned long)sizeof(map_entitystring));
FS_FreeFile(buffer);
} }
else else
{ {
Com_Printf ("CMod_LoadEntityString: .ent file %s loaded.\n", s); char namewe[MAX_QPATH];
numentitychars = bufLen;
memcpy(map_entitystring, buffer, bufLen); int crc = 0;
map_entitystring[bufLen] = 0; /* jit entity bug - null terminate the entity string! */
FS_FreeFile(buffer); if (l->filelen > 0) {
return; crc = CRC_Block(cmod_base + l->fileofs, l->filelen - 1);
} }
memset(namewe, 0, sizeof(namewe));
memcpy(namewe, name, nameLen - 4);
snprintf(entname, sizeof(entname) -1, "%s@%04x.ent", namewe, crc);
bufLen = FS_LoadFile(entname, (void **)&buffer);
if (buffer == NULL)
{
Com_Printf("No fixes found for '%s'\n", entname);
}
}
if (buffer != NULL && bufLen > 1 && bufLen < sizeof(map_entitystring) - 1)
{
numentitychars = bufLen;
memcpy(map_entitystring, buffer, bufLen);
/* jit entity bug - null terminate the entity string! */
map_entitystring[bufLen] = 0;
FS_FreeFile(buffer);
Com_Printf (".ent file %s loaded.\n", entname);
return;
} }
else if (bufLen != -1) else if (bufLen != -1)
{ {
/* If the .ent file is too small, don't load. */ /* If the .ent file is too small, don't load. */
Com_Printf("CMod_LoadEntityString: .ent file %s too small.\n", s); Com_Printf("%s: .ent file %s too small.\n", __func__, entname);
FS_FreeFile(buffer); FS_FreeFile(buffer);
} }
} }
numentitychars = l->filelen; numentitychars = l->filelen;
if (l->filelen + 1 > sizeof(map_entitystring)) if (l->filelen < 0)
{ {
Com_Error(ERR_DROP, "Map has too large entity lump"); Com_Error(ERR_DROP, "%s: Map has too small entity lump", __func__);
} }
memcpy(map_entitystring, cmod_base + l->fileofs, l->filelen); if (l->filelen >= sizeof(map_entitystring))
map_entitystring[l->filelen] = 0; {
Com_Error(ERR_DROP, "%s: Map has too big entity lump", __func__);
}
memcpy(map_entitystring, (const char *)cmod_base + l->fileofs, numentitychars);
/* jit entity bug - null terminate the entity string! */
map_entitystring[numentitychars] = 0;
} }
/* /*
@ -1738,12 +1766,12 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
/* load into heap */ /* load into heap */
CMod_LoadSurfaces(&header.lumps[LUMP_TEXINFO]); CMod_LoadSurfaces(&header.lumps[LUMP_TEXINFO]);
CMod_LoadLeafs(&header.lumps[LUMP_LEAFS]); CMod_LoadLeafs(&header.lumps[LUMP_LEAFS]);
CMod_LoadLeafBrushes(&header.lumps[LUMP_LEAFBRUSHES]); CMod_LoadLeafBrushes(name, &header.lumps[LUMP_LEAFBRUSHES]);
CMod_LoadPlanes(&header.lumps[LUMP_PLANES]); CMod_LoadPlanes(&header.lumps[LUMP_PLANES]);
CMod_LoadBrushes(&header.lumps[LUMP_BRUSHES]); CMod_LoadBrushes(name, &header.lumps[LUMP_BRUSHES]);
CMod_LoadBrushSides(&header.lumps[LUMP_BRUSHSIDES]); CMod_LoadBrushSides(&header.lumps[LUMP_BRUSHSIDES]);
CMod_LoadSubmodels(&header.lumps[LUMP_MODELS]); CMod_LoadSubmodels(name, &header.lumps[LUMP_MODELS]);
CMod_LoadNodes(&header.lumps[LUMP_NODES]); CMod_LoadNodes(name, &header.lumps[LUMP_NODES]);
CMod_LoadAreas(&header.lumps[LUMP_AREAS]); CMod_LoadAreas(&header.lumps[LUMP_AREAS]);
CMod_LoadAreaPortals(&header.lumps[LUMP_AREAPORTALS]); CMod_LoadAreaPortals(&header.lumps[LUMP_AREAPORTALS]);
CMod_LoadVisibility(&header.lumps[LUMP_VISIBILITY]); CMod_LoadVisibility(&header.lumps[LUMP_VISIBILITY]);
@ -1763,20 +1791,20 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
} }
cmodel_t * cmodel_t *
CM_InlineModel(char *name) CM_InlineModel(const char *name)
{ {
int num; int num;
if (!name || (name[0] != '*')) 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); num = (int)strtol(name + 1, (char **)NULL, 10);
if ((num < 1) || (num >= numcmodels)) 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]; return &map_cmodels[num];

View file

@ -616,7 +616,7 @@ qboolean Netchan_CanReliable(netchan_t *chan);
#include "files.h" #include "files.h"
cmodel_t *CM_LoadMap(char *name, qboolean clientload, unsigned *checksum); cmodel_t *CM_LoadMap(char *name, qboolean clientload, unsigned *checksum);
cmodel_t *CM_InlineModel(char *name); /* *1, *2, etc */ cmodel_t *CM_InlineModel(const char *name); /* *1, *2, etc */
int CM_NumClusters(void); int CM_NumClusters(void);
int CM_NumInlineModels(void); int CM_NumInlineModels(void);