Initial server model load code with hunk alloc

This commit is contained in:
Denis Pauk 2023-10-08 00:47:53 +03:00
parent f3b2a9c4bf
commit b56df03b76
6 changed files with 119 additions and 83 deletions

View file

@ -66,7 +66,18 @@ typedef struct
int floodvalid; int floodvalid;
} carea_t; } carea_t;
static byte *cmod_base; typedef struct
{
char name[MAX_QPATH];
char *map_entitystring;
int extradatasize;
void *extradata;
} model_t;
static model_t cmod = {0};
static 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];
@ -74,8 +85,6 @@ static byte phsrow[MAX_MAP_LEAFS / 8];
static carea_t map_areas[MAX_MAP_AREAS]; static carea_t map_areas[MAX_MAP_AREAS];
static cbrush_t map_brushes[MAX_MAP_BRUSHES]; static cbrush_t map_brushes[MAX_MAP_BRUSHES];
static cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES]; 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 cbrush_t *box_brush;
static cleaf_t *box_leaf; static cleaf_t *box_leaf;
static cleaf_t map_leafs[MAX_MAP_LEAFS]; static cleaf_t map_leafs[MAX_MAP_LEAFS];
@ -112,8 +121,8 @@ mapsurface_t map_surfaces[MAX_MAP_TEXINFO];
static mapsurface_t nullsurface; static mapsurface_t nullsurface;
static qboolean portalopen[MAX_MAP_AREAPORTALS]; static qboolean portalopen[MAX_MAP_AREAPORTALS];
static qboolean trace_ispoint; /* optimized case */ static qboolean trace_ispoint; /* optimized case */
static trace_t trace_trace;
static unsigned int map_leafbrushes[MAX_MAP_LEAFBRUSHES]; static unsigned int map_leafbrushes[MAX_MAP_LEAFBRUSHES];
static trace_t trace_trace;
static vec3_t trace_start, trace_end; static vec3_t trace_start, trace_end;
static vec3_t trace_mins, trace_maxs; static vec3_t trace_mins, trace_maxs;
static vec3_t trace_extents; static vec3_t trace_extents;
@ -1183,7 +1192,7 @@ CM_TransformedBoxTrace(vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs,
} }
static void static void
CMod_LoadSubmodels(lump_t *l) CMod_LoadSubmodels(const byte *cmod_base, const lump_t *l)
{ {
dmodel_t *in; dmodel_t *in;
cmodel_t *out; cmodel_t *out;
@ -1227,7 +1236,7 @@ CMod_LoadSubmodels(lump_t *l)
} }
static void static void
CMod_LoadSurfaces(lump_t *l) CMod_LoadSurfaces(const byte *cmod_base, const lump_t *l)
{ {
texinfo_t *in; texinfo_t *in;
mapsurface_t *out; mapsurface_t *out;
@ -1265,7 +1274,7 @@ CMod_LoadSurfaces(lump_t *l)
} }
static void static void
CMod_LoadNodes(lump_t *l) CMod_LoadNodes(const byte *cmod_base, const lump_t *l)
{ {
dnode_t *in; dnode_t *in;
int child; int child;
@ -1308,7 +1317,7 @@ CMod_LoadNodes(lump_t *l)
} }
static void static void
CMod_LoadQNodes(lump_t *l) CMod_LoadQNodes(const byte *cmod_base, const lump_t *l)
{ {
dqnode_t *in; dqnode_t *in;
int child; int child;
@ -1351,7 +1360,7 @@ CMod_LoadQNodes(lump_t *l)
} }
static void static void
CMod_LoadBrushes(lump_t *l) CMod_LoadBrushes(const byte *cmod_base, const lump_t *l)
{ {
dbrush_t *in; dbrush_t *in;
cbrush_t *out; cbrush_t *out;
@ -1384,7 +1393,7 @@ CMod_LoadBrushes(lump_t *l)
} }
static void static void
CMod_LoadLeafs(lump_t *l) CMod_LoadLeafs(const byte *cmod_base, const lump_t *l)
{ {
int i; int i;
cleaf_t *out; cleaf_t *out;
@ -1453,7 +1462,7 @@ CMod_LoadLeafs(lump_t *l)
} }
static void static void
CMod_LoadQLeafs(lump_t *l) CMod_LoadQLeafs(const byte *cmod_base, const lump_t *l)
{ {
int i; int i;
cleaf_t *out; cleaf_t *out;
@ -1522,7 +1531,7 @@ CMod_LoadQLeafs(lump_t *l)
} }
static void static void
CMod_LoadPlanes(lump_t *l) CMod_LoadPlanes(const byte *cmod_base, const lump_t *l)
{ {
int i, j; int i, j;
cplane_t *out; cplane_t *out;
@ -1574,7 +1583,7 @@ CMod_LoadPlanes(lump_t *l)
} }
static void static void
CMod_LoadLeafBrushes(lump_t *l) CMod_LoadLeafBrushes(const byte *cmod_base, const lump_t *l)
{ {
int i; int i;
unsigned int *out; unsigned int *out;
@ -1611,7 +1620,7 @@ CMod_LoadLeafBrushes(lump_t *l)
} }
static void static void
CMod_LoadQLeafBrushes(lump_t *l) CMod_LoadQLeafBrushes(const byte *cmod_base, const lump_t *l)
{ {
int i; int i;
unsigned int *out; unsigned int *out;
@ -1648,7 +1657,7 @@ CMod_LoadQLeafBrushes(lump_t *l)
} }
static void static void
CMod_LoadBrushSides(lump_t *l) CMod_LoadBrushSides(const byte *cmod_base, const lump_t *l)
{ {
int i, j; int i, j;
cbrushside_t *out; cbrushside_t *out;
@ -1689,7 +1698,7 @@ CMod_LoadBrushSides(lump_t *l)
} }
} }
static void static void
CMod_LoadQBrushSides(lump_t *l) CMod_LoadQBrushSides(const byte *cmod_base, const lump_t *l)
{ {
int i, j; int i, j;
cbrushside_t *out; cbrushside_t *out;
@ -1731,7 +1740,7 @@ CMod_LoadQBrushSides(lump_t *l)
} }
static void static void
CMod_LoadAreas(lump_t *l) CMod_LoadAreas(const byte *cmod_base, const lump_t *l)
{ {
int i; int i;
carea_t *out; carea_t *out;
@ -1765,7 +1774,7 @@ CMod_LoadAreas(lump_t *l)
} }
static void static void
CMod_LoadAreaPortals(lump_t *l) CMod_LoadAreaPortals(const byte *cmod_base, const lump_t *l)
{ {
dareaportal_t *out; dareaportal_t *out;
dareaportal_t *in; dareaportal_t *in;
@ -1792,7 +1801,7 @@ CMod_LoadAreaPortals(lump_t *l)
} }
static void static void
CMod_LoadVisibility(lump_t *l) CMod_LoadVisibility(const byte *cmod_base, const lump_t *l)
{ {
numvisibility = l->filelen; numvisibility = l->filelen;
@ -1807,7 +1816,7 @@ CMod_LoadVisibility(lump_t *l)
} }
static void static void
CMod_LoadEntityString(lump_t *l, char *name) CMod_LoadEntityString(const char *name, char **map_entitystring, const byte *cmod_base, const lump_t *l)
{ {
if (sv_entfile->value) if (sv_entfile->value)
{ {
@ -1842,23 +1851,17 @@ CMod_LoadEntityString(lump_t *l, char *name)
} }
if (buffer != NULL && bufLen > 1) if (buffer != NULL && bufLen > 1)
{
if (bufLen + 1 > sizeof(map_entitystring))
{
Com_Printf("%s: .ent file %s too large: %i > %lu.\n",
__func__, entname, bufLen, (unsigned long)sizeof(map_entitystring));
FS_FreeFile(buffer);
}
else
{ {
Com_Printf ("%s: .ent file %s loaded.\n", __func__, entname); Com_Printf ("%s: .ent file %s loaded.\n", __func__, entname);
numentitychars = bufLen; numentitychars = bufLen;
memcpy(map_entitystring, buffer, bufLen);
map_entitystring[bufLen] = 0; /* jit entity bug - null terminate the entity string! */ *map_entitystring = Hunk_Alloc(bufLen + 1);
memcpy(*map_entitystring, buffer, bufLen);
(*map_entitystring)[bufLen] = 0; /* jit entity bug - null terminate the entity string! */
FS_FreeFile(buffer); FS_FreeFile(buffer);
return; 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. */
@ -1869,13 +1872,32 @@ CMod_LoadEntityString(lump_t *l, char *name)
numentitychars = l->filelen; numentitychars = l->filelen;
if (l->filelen + 1 > sizeof(map_entitystring)) if (l->filelen < 0)
{ {
Com_Error(ERR_DROP, "%s: Map has too large entity lump", __func__); Com_Error(ERR_DROP, "%s: Map has too small entity lump", __func__);
} }
memcpy(map_entitystring, cmod_base + l->fileofs, l->filelen); *map_entitystring = Hunk_Alloc(l->filelen + 1);
map_entitystring[l->filelen] = 0; memcpy(*map_entitystring, cmod_base + l->fileofs, l->filelen);
(*map_entitystring)[l->filelen] = 0;
}
const void
CM_ModFree(model_t *cmod)
{
if (cmod->extradata && cmod->extradatasize)
{
Hunk_Free(cmod->extradata);
cmod->extradata = NULL;
cmod->extradatasize = 0;
}
}
void
CM_ModFreeAll(void)
{
CM_ModFree(&cmod);
Com_Printf("Server models free up\n");
} }
/* /*
@ -1889,10 +1911,11 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
dheader_t header; dheader_t header;
int length; int length;
static unsigned last_checksum; static unsigned last_checksum;
byte *cmod_base;
map_noareas = Cvar_Get("map_noareas", "0", 0); map_noareas = Cvar_Get("map_noareas", "0", 0);
if (strcmp(map_name, name) == 0 if (strcmp(cmod.name, name) == 0
&& (clientload || !Cvar_VariableValue("flushmap"))) && (clientload || !Cvar_VariableValue("flushmap")))
{ {
*checksum = last_checksum; *checksum = last_checksum;
@ -1913,8 +1936,8 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
numcmodels = 0; numcmodels = 0;
numvisibility = 0; numvisibility = 0;
numentitychars = 0; numentitychars = 0;
map_entitystring[0] = 0; cmod.map_entitystring = NULL;
map_name[0] = 0; cmod.name[0] = 0;
if (!name[0]) if (!name[0])
{ {
@ -1958,41 +1981,53 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
cmod_base = (byte *)buf; cmod_base = (byte *)buf;
/* load into heap */ /* load into heap */
CMod_LoadSurfaces(&header.lumps[LUMP_TEXINFO]); CMod_LoadSurfaces(cmod_base, &header.lumps[LUMP_TEXINFO]);
if (header.ident == IDBSPHEADER) if (header.ident == IDBSPHEADER)
{ {
CMod_LoadLeafs(&header.lumps[LUMP_LEAFS]); CMod_LoadLeafs(cmod_base, &header.lumps[LUMP_LEAFS]);
CMod_LoadLeafBrushes(&header.lumps[LUMP_LEAFBRUSHES]); CMod_LoadLeafBrushes(cmod_base, &header.lumps[LUMP_LEAFBRUSHES]);
} }
else else
{ {
CMod_LoadQLeafs(&header.lumps[LUMP_LEAFS]); CMod_LoadQLeafs(cmod_base, &header.lumps[LUMP_LEAFS]);
CMod_LoadQLeafBrushes(&header.lumps[LUMP_LEAFBRUSHES]); CMod_LoadQLeafBrushes(cmod_base, &header.lumps[LUMP_LEAFBRUSHES]);
} }
CMod_LoadPlanes(&header.lumps[LUMP_PLANES]); CMod_LoadPlanes(cmod_base, &header.lumps[LUMP_PLANES]);
CMod_LoadBrushes(&header.lumps[LUMP_BRUSHES]); CMod_LoadBrushes(cmod_base, &header.lumps[LUMP_BRUSHES]);
if (header.ident == IDBSPHEADER) if (header.ident == IDBSPHEADER)
{ {
CMod_LoadBrushSides(&header.lumps[LUMP_BRUSHSIDES]); CMod_LoadBrushSides(cmod_base, &header.lumps[LUMP_BRUSHSIDES]);
} }
else else
{ {
CMod_LoadQBrushSides(&header.lumps[LUMP_BRUSHSIDES]); CMod_LoadQBrushSides(cmod_base, &header.lumps[LUMP_BRUSHSIDES]);
} }
CMod_LoadSubmodels(&header.lumps[LUMP_MODELS]);
CMod_LoadSubmodels(cmod_base, &header.lumps[LUMP_MODELS]);
if (header.ident == IDBSPHEADER) if (header.ident == IDBSPHEADER)
{ {
CMod_LoadNodes(&header.lumps[LUMP_NODES]); CMod_LoadNodes(cmod_base, &header.lumps[LUMP_NODES]);
} }
else else
{ {
CMod_LoadQNodes(&header.lumps[LUMP_NODES]); CMod_LoadQNodes(cmod_base, &header.lumps[LUMP_NODES]);
} }
CMod_LoadAreas(&header.lumps[LUMP_AREAS]); CMod_LoadAreas(cmod_base, &header.lumps[LUMP_AREAS]);
CMod_LoadAreaPortals(&header.lumps[LUMP_AREAPORTALS]); CMod_LoadAreaPortals(cmod_base, &header.lumps[LUMP_AREAPORTALS]);
CMod_LoadVisibility(&header.lumps[LUMP_VISIBILITY]); CMod_LoadVisibility(cmod_base, &header.lumps[LUMP_VISIBILITY]);
strcpy(cmod.name, name);
CM_ModFree(&cmod);
int hunkSize = 0;
hunkSize += header.lumps[LUMP_ENTITIES].filelen + MAX_MAP_ENTSTRING;
cmod.extradata = Hunk_Begin(hunkSize);
/* From kmquake2: adding an extra parameter for .ent support. */ /* From kmquake2: adding an extra parameter for .ent support. */
CMod_LoadEntityString(&header.lumps[LUMP_ENTITIES], name); CMod_LoadEntityString(cmod.name, &cmod.map_entitystring, cmod_base, &header.lumps[LUMP_ENTITIES]);
cmod.extradatasize = Hunk_End();
FS_FreeFile(buf); FS_FreeFile(buf);
@ -2001,8 +2036,6 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
memset(portalopen, 0, sizeof(portalopen)); memset(portalopen, 0, sizeof(portalopen));
FloodAreaConnections(); FloodAreaConnections();
strcpy(map_name, name);
return &map_cmodels[0]; return &map_cmodels[0];
} }
@ -2041,7 +2074,7 @@ CM_NumInlineModels(void)
char * char *
CM_EntityString(void) CM_EntityString(void)
{ {
return map_entitystring; return cmod.map_entitystring;
} }
int int

View file

@ -139,7 +139,7 @@ CRC_Init(unsigned short *crcvalue)
} }
unsigned short unsigned short
CRC_Block(byte *start, int count) CRC_Block(const byte *start, int count)
{ {
unsigned short crc; unsigned short crc;
@ -154,7 +154,7 @@ CRC_Block(byte *start, int count)
} }
byte byte
COM_BlockSequenceCRCByte(byte *base, int length, int sequence) COM_BlockSequenceCRCByte(const byte *base, int length, int sequence)
{ {
int n; int n;
int x; int x;

View file

@ -617,6 +617,7 @@ qboolean Netchan_CanReliable(netchan_t *chan);
cmodel_t *CM_LoadMap(char *name, qboolean clientload, unsigned *checksum); cmodel_t *CM_LoadMap(char *name, qboolean clientload, unsigned *checksum);
cmodel_t *CM_InlineModel(const char *name); /* *1, *2, etc */ cmodel_t *CM_InlineModel(const char *name); /* *1, *2, etc */
void CM_ModFreeAll(void);
int CM_NumClusters(void); int CM_NumClusters(void);
int CM_NumInlineModels(void); int CM_NumInlineModels(void);
@ -770,8 +771,8 @@ YQ2_ATTR_NORETURN void Com_Quit(void);
int Com_ServerState(void); /* this should have just been a cvar... */ int Com_ServerState(void); /* this should have just been a cvar... */
void Com_SetServerState(int state); void Com_SetServerState(int state);
unsigned Com_BlockChecksum(void *buffer, int length); unsigned Com_BlockChecksum(const void *buffer, int length);
byte COM_BlockSequenceCRCByte(byte *base, int length, int sequence); byte COM_BlockSequenceCRCByte(const byte *base, int length, int sequence);
extern cvar_t *developer; extern cvar_t *developer;
extern cvar_t *modder; extern cvar_t *modder;

View file

@ -28,6 +28,6 @@
#define CO_CRC_H #define CO_CRC_H
void CRC_Init(unsigned short *crcvalue); void CRC_Init(unsigned short *crcvalue);
unsigned short CRC_Block(byte *start, int count); unsigned short CRC_Block(const byte *start, int count);
#endif #endif

View file

@ -210,7 +210,7 @@ PerformMD4(const unsigned char *buf, int length, unsigned char *digest)
} }
unsigned unsigned
Com_BlockChecksum(void *buffer, int length) Com_BlockChecksum(const void *buffer, int length)
{ {
uint32_t digest[4]; uint32_t digest[4];
unsigned val; unsigned val;

View file

@ -707,5 +707,7 @@ SV_Shutdown(char *finalmsg, qboolean reconnect)
} }
memset(&svs, 0, sizeof(svs)); memset(&svs, 0, sizeof(svs));
CM_ModFreeAll();
} }