Use hunk allocation for CMod_LoadAreas

This commit is contained in:
Denis Pauk 2023-10-08 15:19:33 +03:00
parent 703d281391
commit a89ff8c0a0
6 changed files with 130 additions and 50 deletions

View file

@ -936,6 +936,7 @@ CLIENT_OBJS_ := \
src/common/argproc.o \ src/common/argproc.o \
src/common/clientserver.o \ src/common/clientserver.o \
src/common/collision.o \ src/common/collision.o \
src/common/cmodels.o \
src/common/crc.o \ src/common/crc.o \
src/common/cmdparser.o \ src/common/cmdparser.o \
src/common/cvar.o \ src/common/cvar.o \
@ -1006,6 +1007,7 @@ REFGL1_OBJS_ := \
src/client/refresh/files/pvs.o \ src/client/refresh/files/pvs.o \
src/common/shared/shared.o \ src/common/shared/shared.o \
src/common/shared/utils.o \ src/common/shared/utils.o \
src/common/cmodels.o \
src/common/md4.o src/common/md4.o
ifeq ($(YQ2_OSTYPE), Windows) ifeq ($(YQ2_OSTYPE), Windows)
@ -1040,6 +1042,7 @@ REFGL3_OBJS_ := \
src/client/refresh/files/pvs.o \ src/client/refresh/files/pvs.o \
src/common/shared/shared.o \ src/common/shared/shared.o \
src/common/shared/utils.o \ src/common/shared/utils.o \
src/common/cmodels.o \
src/common/md4.o src/common/md4.o
REFGL3_OBJS_GLADE_ := \ REFGL3_OBJS_GLADE_ := \
@ -1079,6 +1082,7 @@ REFGL4_OBJS_ := \
src/client/refresh/files/wal.o \ src/client/refresh/files/wal.o \
src/client/refresh/files/pvs.o \ src/client/refresh/files/pvs.o \
src/common/shared/shared.o \ src/common/shared/shared.o \
src/common/cmodels.o \
src/common/md4.o src/common/md4.o
REFGL4_OBJS_GLADE_ := \ REFGL4_OBJS_GLADE_ := \
@ -1121,6 +1125,7 @@ REFSOFT_OBJS_ := \
src/client/refresh/files/pvs.o \ src/client/refresh/files/pvs.o \
src/common/shared/shared.o \ src/common/shared/shared.o \
src/common/shared/utils.o \ src/common/shared/utils.o \
src/common/cmodels.o \
src/common/md4.o src/common/md4.o
ifeq ($(YQ2_OSTYPE), Windows) ifeq ($(YQ2_OSTYPE), Windows)
@ -1163,6 +1168,7 @@ REFVK_OBJS_ := \
src/client/refresh/files/pvs.o \ src/client/refresh/files/pvs.o \
src/common/shared/shared.o \ src/common/shared/shared.o \
src/common/shared/utils.o \ src/common/shared/utils.o \
src/common/cmodels.o \
src/common/md4.o src/common/md4.o
ifeq ($(YQ2_OSTYPE), Windows) ifeq ($(YQ2_OSTYPE), Windows)
@ -1181,6 +1187,7 @@ SERVER_OBJS_ := \
src/common/argproc.o \ src/common/argproc.o \
src/common/clientserver.o \ src/common/clientserver.o \
src/common/collision.o \ src/common/collision.o \
src/common/cmodels.o \
src/common/crc.o \ src/common/crc.o \
src/common/cmdparser.o \ src/common/cmdparser.o \
src/common/cvar.o \ src/common/cvar.o \

View file

@ -2016,34 +2016,6 @@ Mod_LoadSurfedges(const char *name, int **surfedges, int *numsurfedges,
out[i] = LittleLong (in[i]); out[i] = LittleLong (in[i]);
} }
/*
=================
Mod_LoadSurfedges
calculate the size that Hunk_Alloc(), called by Mod_Load*() from Mod_LoadBrushModel(),
will use (=> includes its padding), so we'll know how big the hunk needs to be
extra is used for skybox, which adds 6 surfaces
=================
*/
int
Mod_CalcLumpHunkSize(const lump_t *l, int inSize, int outSize, int extra)
{
if (l->filelen % inSize)
{
// Mod_Load*() will error out on this because of "funny size"
// don't error out here because in Mod_Load*() it can print the functionname
// (=> tells us what kind of lump) before shutting down the game
return 0;
}
int count = l->filelen / inSize + extra;
int size = count * outSize;
// round to cacheline, like Hunk_Alloc() does
size = (size + 31) & ~31;
return size;
}
/* /*
=============== ===============
Mod_PointInLeaf Mod_PointInLeaf

View file

@ -28,6 +28,7 @@
#define SRC_CLIENT_REFRESH_REF_SHARED_H_ #define SRC_CLIENT_REFRESH_REF_SHARED_H_
#include "../vid/header/ref.h" #include "../vid/header/ref.h"
#include "../../common/header/cmodel.h"
#ifdef _MSC_VER #ifdef _MSC_VER
@ -353,7 +354,6 @@ extern void Mod_LoadPlanes(const char *name, cplane_t **planes, int *numplanes,
const byte *mod_base, const lump_t *l, int extra); const byte *mod_base, const lump_t *l, int extra);
extern void Mod_LoadSurfedges(const char *name, int **surfedges, int *numsurfedges, extern void Mod_LoadSurfedges(const char *name, int **surfedges, int *numsurfedges,
const byte *mod_base, const lump_t *l, int extra); const byte *mod_base, const lump_t *l, int extra);
extern int Mod_CalcLumpHunkSize(const lump_t *l, int inSize, int outSize, int extra);
extern mleaf_t *Mod_PointInLeaf(const vec3_t p, mnode_t *node); extern mleaf_t *Mod_PointInLeaf(const vec3_t p, mnode_t *node);
extern const void *Mod_LoadBSPXFindLump(const bspx_header_t *bspx_header, extern const void *Mod_LoadBSPXFindLump(const bspx_header_t *bspx_header,
const char *lumpname, int *plumpsize, const byte *mod_base); const char *lumpname, int *plumpsize, const byte *mod_base);

55
src/common/cmodels.c Normal file
View file

@ -0,0 +1,55 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*
* =======================================================================
*
* The models file format
*
* =======================================================================
*/
#include "header/common.h"
/*
=================
Mod_LoadSurfedges
calculate the size that Hunk_Alloc(), called by Mod_Load*() from Mod_LoadBrushModel(),
will use (=> includes its padding), so we'll know how big the hunk needs to be
extra is used for skybox, which adds 6 surfaces
=================
*/
int
Mod_CalcLumpHunkSize(const lump_t *l, int inSize, int outSize, int extra)
{
if (l->filelen % inSize)
{
// Mod_Load*() will error out on this because of "funny size"
// don't error out here because in Mod_Load*() it can print the functionname
// (=> tells us what kind of lump) before shutting down the game
return 0;
}
int count = l->filelen / inSize + extra;
int size = count * outSize;
// round to cacheline, like Hunk_Alloc() does
size = (size + 31) & ~31;
return size;
}

View file

@ -28,6 +28,7 @@
#include <stdint.h> #include <stdint.h>
#include "header/common.h" #include "header/common.h"
#include "header/cmodel.h"
typedef struct typedef struct
{ {
@ -70,6 +71,9 @@ typedef struct
{ {
char name[MAX_QPATH]; char name[MAX_QPATH];
carea_t *map_areas;
int numareas;
dareaportal_t *map_areaportals; dareaportal_t *map_areaportals;
int numareaportals; int numareaportals;
@ -88,7 +92,6 @@ static model_t cmod = {0};
// 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];
static byte phsrow[MAX_MAP_LEAFS / 8]; static byte phsrow[MAX_MAP_LEAFS / 8];
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 cbrush_t *box_brush; static cbrush_t *box_brush;
@ -107,7 +110,6 @@ static float *leaf_mins, *leaf_maxs;
static int leaf_count, leaf_maxcount; static int leaf_count, leaf_maxcount;
static int *leaf_list; static int *leaf_list;
static int leaf_topnode; static int leaf_topnode;
static int numareas = 1;
static int numbrushes; static int numbrushes;
static int numbrushsides; static int numbrushsides;
static int numcmodels; static int numcmodels;
@ -160,7 +162,7 @@ FloodArea_r(carea_t *area, int floodnum)
{ {
if (portalopen[LittleLong(p->portalnum)]) if (portalopen[LittleLong(p->portalnum)])
{ {
FloodArea_r(&map_areas[LittleLong(p->otherarea)], floodnum); FloodArea_r(&cmod.map_areas[LittleLong(p->otherarea)], floodnum);
} }
} }
} }
@ -177,9 +179,9 @@ FloodAreaConnections(void)
floodnum = 0; floodnum = 0;
/* area 0 is not used */ /* area 0 is not used */
for (i = 1; i < numareas; i++) for (i = 1; i < cmod.numareas; i++)
{ {
area = &map_areas[i]; area = &cmod.map_areas[i];
if (area->floodvalid == floodvalid) if (area->floodvalid == floodvalid)
{ {
@ -211,12 +213,12 @@ CM_AreasConnected(int area1, int area2)
return true; return true;
} }
if ((area1 > numareas) || (area2 > numareas)) if ((area1 > cmod.numareas) || (area2 > cmod.numareas))
{ {
Com_Error(ERR_DROP, "%s: area > numareas", __func__); Com_Error(ERR_DROP, "%s: area > numareas", __func__);
} }
if (map_areas[area1].floodnum == map_areas[area2].floodnum) if (cmod.map_areas[area1].floodnum == cmod.map_areas[area2].floodnum)
{ {
return true; return true;
} }
@ -237,7 +239,7 @@ CM_WriteAreaBits(byte *buffer, int area)
int floodnum; int floodnum;
int bytes; int bytes;
bytes = (numareas + 7) >> 3; bytes = (cmod.numareas + 7) >> 3;
if (map_noareas->value) if (map_noareas->value)
{ {
@ -249,11 +251,11 @@ CM_WriteAreaBits(byte *buffer, int area)
{ {
memset(buffer, 0, bytes); memset(buffer, 0, bytes);
floodnum = map_areas[area].floodnum; floodnum = cmod.map_areas[area].floodnum;
for (i = 0; i < numareas; i++) for (i = 0; i < cmod.numareas; i++)
{ {
if ((map_areas[i].floodnum == floodnum) || !area) if ((cmod.map_areas[i].floodnum == floodnum) || !area)
{ {
buffer[i >> 3] |= 1 << (i & 7); buffer[i >> 3] |= 1 << (i & 7);
} }
@ -1741,7 +1743,8 @@ CMod_LoadQBrushSides(const byte *cmod_base, const lump_t *l)
} }
static void static void
CMod_LoadAreas(const byte *cmod_base, const lump_t *l) CMod_LoadAreas(const char *name, carea_t **map_areas, int *numareas,
const byte *cmod_base, const lump_t *l)
{ {
int i; int i;
carea_t *out; carea_t *out;
@ -1752,18 +1755,20 @@ CMod_LoadAreas(const byte *cmod_base, const lump_t *l)
if (l->filelen % sizeof(*in)) if (l->filelen % sizeof(*in))
{ {
Com_Error(ERR_DROP, "%s: funny lump size", __func__); Com_Error(ERR_DROP, "%s: Map %s funny lump size",
__func__, name);
} }
count = l->filelen / sizeof(*in); count = l->filelen / sizeof(*in);
if (count > MAX_MAP_AREAS) if (count <= 0)
{ {
Com_Error(ERR_DROP, "%s: Map has too many areas", __func__); Com_Error(ERR_DROP, "%s: Map %s has too small areas",
__func__, name);
} }
out = map_areas; out = *map_areas = Hunk_Alloc(sizeof(*out) * count);
numareas = count; *numareas = count;
for (i = 0; i < count; i++, in++, out++) for (i = 0; i < count; i++, in++, out++)
{ {
@ -1902,10 +1907,15 @@ CM_ModFree(model_t *cmod)
cmod->extradata = NULL; cmod->extradata = NULL;
cmod->extradatasize = 0; cmod->extradatasize = 0;
} }
cmod->map_areas = NULL;
cmod->numareas = 1;
cmod->map_vis = NULL; cmod->map_vis = NULL;
cmod->numclusters = 1; cmod->numclusters = 1;
cmod->map_entitystring = NULL;
cmod->numvisibility = 0; cmod->numvisibility = 0;
cmod->map_entitystring = NULL;
cmod->name[0] = 0; cmod->name[0] = 0;
} }
@ -1956,7 +1966,6 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
if (!name[0]) if (!name[0])
{ {
numleafs = 1; numleafs = 1;
numareas = 1;
*checksum = 0; *checksum = 0;
return &map_cmodels[0]; /* cinematic servers won't have anything at all */ return &map_cmodels[0]; /* cinematic servers won't have anything at all */
} }
@ -2025,17 +2034,22 @@ CM_LoadMap(char *name, qboolean clientload, unsigned *checksum)
{ {
CMod_LoadQNodes(cmod_base, &header.lumps[LUMP_NODES]); CMod_LoadQNodes(cmod_base, &header.lumps[LUMP_NODES]);
} }
CMod_LoadAreas(cmod_base, &header.lumps[LUMP_AREAS]);
strcpy(cmod.name, name); strcpy(cmod.name, name);
int hunkSize = 0; int hunkSize = 0;
hunkSize += header.lumps[LUMP_AREAPORTALS].filelen;
hunkSize += Mod_CalcLumpHunkSize(&header.lumps[LUMP_AREAS],
sizeof(darea_t), sizeof(carea_t), 0);
hunkSize += Mod_CalcLumpHunkSize(&header.lumps[LUMP_AREAPORTALS],
sizeof(dareaportal_t), sizeof(dareaportal_t), 0);
hunkSize += header.lumps[LUMP_VISIBILITY].filelen; hunkSize += header.lumps[LUMP_VISIBILITY].filelen;
hunkSize += header.lumps[LUMP_ENTITIES].filelen + MAX_MAP_ENTSTRING; hunkSize += header.lumps[LUMP_ENTITIES].filelen + MAX_MAP_ENTSTRING;
cmod.extradata = Hunk_Begin(hunkSize); cmod.extradata = Hunk_Begin(hunkSize);
CMod_LoadAreas(cmod.name, &cmod.map_areas, &cmod.numareas, cmod_base,
&header.lumps[LUMP_AREAS]);
CMod_LoadAreaPortals(cmod.name, &cmod.map_areaportals, &cmod.numareaportals, CMod_LoadAreaPortals(cmod.name, &cmod.map_areaportals, &cmod.numareaportals,
cmod_base, &header.lumps[LUMP_AREAPORTALS]); cmod_base, &header.lumps[LUMP_AREAPORTALS]);
CMod_LoadVisibility(cmod.name, &cmod.map_vis, CMod_LoadVisibility(cmod.name, &cmod.map_vis,

View file

@ -0,0 +1,32 @@
/*
* Copyright (C) 1997-2001 Id Software, Inc.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*
* See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
* USA.
*
* =======================================================================
*
* Shared model load code
*
* =======================================================================
*/
#ifndef COMMON_CMODEL_H
#define COMMON_CMODEL_H
extern int Mod_CalcLumpHunkSize(const lump_t *l, int inSize, int outSize, int extra);
#endif