// cmodel.c -- model loading #include <u.h>#include <libc.h>#include <stdio.h>#include "dat.h"#include "fns.h" typedef struct{ cplane_t *plane; int children[2]; // negative numbers are leafs} cnode_t; typedef struct{ cplane_t *plane; mapsurface_t *surface;} cbrushside_t; typedef struct{ int contents; int cluster; int area; unsigned short firstleafbrush; unsigned short numleafbrushes;} cleaf_t; typedef struct{ int contents; int numsides; int firstbrushside; int checkcount; // to avoid repeated testings} cbrush_t; typedef struct{ int numareaportals; int firstareaportal; int floodnum; // if two areas have equal floodnums, they are connected int floodvalid;} carea_t; int checkcount; char map_name[MAX_QPATH]; int numbrushsides;cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES]; int numtexinfo;mapsurface_t map_surfaces[MAX_MAP_TEXINFO]; int numplanes;cplane_t map_planes[MAX_MAP_PLANES+6]; // extra for box hull int numnodes;cnode_t map_nodes[MAX_MAP_NODES+6]; // extra for box hull int numleafs = 1; // allow leaf funcs to be called without a mapcleaf_t map_leafs[MAX_MAP_LEAFS];int emptyleaf, solidleaf; int numleafbrushes;unsigned short map_leafbrushes[MAX_MAP_LEAFBRUSHES]; int numcmodels;cmodel_t map_cmodels[MAX_MAP_MODELS]; int numbrushes;cbrush_t map_brushes[MAX_MAP_BRUSHES]; int numvisibility;byte map_visibility[MAX_MAP_VISIBILITY];dvis_t *map_vis = (dvis_t *)map_visibility; int numentitychars;char map_entitystring[MAX_MAP_ENTSTRING]; int numareas = 1;carea_t map_areas[MAX_MAP_AREAS]; int numareaportals;dareaportal_t map_areaportals[MAX_MAP_AREAPORTALS]; int numclusters = 1; mapsurface_t nullsurface; int floodvalid; qboolean portalopen[MAX_MAP_AREAPORTALS]; cvar_t *map_noareas; void CM_InitBoxHull (void);void FloodAreaConnections (void); int c_pointcontents;int c_traces, c_brush_traces; /*=============================================================================== MAP LOADING ===============================================================================*/ byte *cmod_base; /*=================CMod_LoadSubmodels=================*/void CMod_LoadSubmodels (lump_t *l){ dmodel_t *in; cmodel_t *out; int i, j, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no models"); if (count > MAX_MAP_MODELS) Com_Error (ERR_DROP, "Map has too many models"); numcmodels = count; for ( i=0 ; i<count ; i++, in++) { out = &map_cmodels[i]; for (j=0 ; j<3 ; j++) { // spread the mins / maxs by a pixel out->mins[j] = LittleFloat (in->mins[j]) - 1; out->maxs[j] = LittleFloat (in->maxs[j]) + 1; out->origin[j] = LittleFloat (in->origin[j]); } out->headnode = LittleLong (in->headnode); }} /*=================CMod_LoadSurfaces=================*/void CMod_LoadSurfaces (lump_t *l){ texinfo_t *in; mapsurface_t *out; int i, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no surfaces"); if (count > MAX_MAP_TEXINFO) Com_Error (ERR_DROP, "Map has too many surfaces"); numtexinfo = count; out = map_surfaces; for ( i=0 ; i<count ; i++, in++, out++) { strncpy (out->c.name, in->texture, sizeof(out->c.name)-1); strncpy (out->rname, in->texture, sizeof(out->rname)-1); out->c.flags = LittleLong (in->flags); out->c.value = LittleLong (in->value); }} /*=================CMod_LoadNodes =================*/void CMod_LoadNodes (lump_t *l){ dnode_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, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map has no nodes"); if (count > MAX_MAP_NODES) Com_Error (ERR_DROP, "Map has too many nodes"); 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; } } } /*=================CMod_LoadBrushes =================*/void CMod_LoadBrushes (lump_t *l){ dbrush_t *in; cbrush_t *out; int i, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count > MAX_MAP_BRUSHES) Com_Error (ERR_DROP, "Map has too many brushes"); out = map_brushes; numbrushes = count; for (i=0 ; i<count ; i++, out++, in++) { out->firstbrushside = LittleLong(in->firstside); out->numsides = LittleLong(in->numsides); out->contents = LittleLong(in->contents); } } /*=================CMod_LoadLeafs=================*/void CMod_LoadLeafs (lump_t *l){ int i; cleaf_t *out; dleaf_t *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no leafs"); // need to save space for box planes if (count > MAX_MAP_PLANES) Com_Error (ERR_DROP, "Map has too many planes"); out = map_leafs; numleafs = count; numclusters = 0; for ( i=0 ; i<count ; i++, in++, out++) { out->contents = LittleLong (in->contents); out->cluster = LittleShort (in->cluster); out->area = LittleShort (in->area); out->firstleafbrush = LittleShort (in->firstleafbrush); out->numleafbrushes = LittleShort (in->numleafbrushes); if (out->cluster >= numclusters) numclusters = out->cluster + 1; } if (map_leafs[0].contents != CONTENTS_SOLID) Com_Error (ERR_DROP, "Map leaf 0 is not CONTENTS_SOLID"); 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, "Map does not have an empty leaf");} /*=================CMod_LoadPlanes=================*/void CMod_LoadPlanes (lump_t *l){ int i, j; cplane_t *out; dplane_t *in; int count; int bits; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no planes"); // need to save space for box planes if (count > MAX_MAP_PLANES) Com_Error (ERR_DROP, "Map has too many planes"); out = map_planes; numplanes = count; for ( i=0 ; i<count ; i++, in++, out++) { bits = 0; for (j=0 ; j<3 ; j++) { out->normal[j] = LittleFloat (in->normal[j]); if (out->normal[j] < 0) bits |= 1<<j; } out->dist = LittleFloat (in->dist); out->type = LittleLong (in->type); out->signbits = bits; }} /*=================CMod_LoadLeafBrushes=================*/void CMod_LoadLeafBrushes (lump_t *l){ int i; unsigned short *out; unsigned short *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no planes"); // need to save space for box planes if (count > MAX_MAP_LEAFBRUSHES) Com_Error (ERR_DROP, "Map has too many leafbrushes"); out = map_leafbrushes; numleafbrushes = count; for ( i=0 ; i<count ; i++, in++, out++) *out = LittleShort (*in);} /*=================CMod_LoadBrushSides=================*/void CMod_LoadBrushSides (lump_t *l){ int i, j; cbrushside_t *out; dbrushside_t *in; int count; int num; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); // need to save space for box planes if (count > MAX_MAP_BRUSHSIDES) Com_Error (ERR_DROP, "Map has too many planes"); out = map_brushsides; numbrushsides = count; for ( i=0 ; i<count ; i++, in++, out++) { num = LittleShort (in->planenum); out->plane = &map_planes[num]; j = LittleShort (in->texinfo); if (j >= numtexinfo) Com_Error (ERR_DROP, "Bad brushside texinfo"); out->surface = &map_surfaces[j]; }} /*=================CMod_LoadAreas=================*/void CMod_LoadAreas (lump_t *l){ int i; carea_t *out; darea_t *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count > MAX_MAP_AREAS) Com_Error (ERR_DROP, "Map has too many areas"); out = map_areas; numareas = count; for ( i=0 ; i<count ; i++, in++, out++) { out->numareaportals = LittleLong (in->numareaportals); out->firstareaportal = LittleLong (in->firstareaportal); out->floodvalid = 0; out->floodnum = 0; }} /*=================CMod_LoadAreaPortals=================*/void CMod_LoadAreaPortals (lump_t *l){ int i; dareaportal_t *out; dareaportal_t *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count > MAX_MAP_AREAS) Com_Error (ERR_DROP, "Map has too many areas"); out = map_areaportals; numareaportals = count; for ( i=0 ; i<count ; i++, in++, out++) { out->portalnum = LittleLong (in->portalnum); out->otherarea = LittleLong (in->otherarea); }} /*=================CMod_LoadVisibility=================*/void CMod_LoadVisibility (lump_t *l){ int i; numvisibility = l->filelen; if (l->filelen > MAX_MAP_VISIBILITY) Com_Error (ERR_DROP, "Map has too large visibility lump"); memcpy (map_visibility, cmod_base + l->fileofs, l->filelen); Lines 1–500 of 1750. Load more
// cmodel.c -- model loading #include <u.h> #include <libc.h> #include <stdio.h> #include "dat.h" #include "fns.h" typedef struct { cplane_t *plane; int children[2]; // negative numbers are leafs } cnode_t; typedef struct { cplane_t *plane; mapsurface_t *surface; } cbrushside_t; typedef struct { int contents; int cluster; int area; unsigned short firstleafbrush; unsigned short numleafbrushes; } cleaf_t; typedef struct { int contents; int numsides; int firstbrushside; int checkcount; // to avoid repeated testings } cbrush_t; typedef struct { int numareaportals; int firstareaportal; int floodnum; // if two areas have equal floodnums, they are connected int floodvalid; } carea_t; int checkcount; char map_name[MAX_QPATH]; int numbrushsides; cbrushside_t map_brushsides[MAX_MAP_BRUSHSIDES]; int numtexinfo; mapsurface_t map_surfaces[MAX_MAP_TEXINFO]; int numplanes; cplane_t map_planes[MAX_MAP_PLANES+6]; // extra for box hull int numnodes; cnode_t map_nodes[MAX_MAP_NODES+6]; // extra for box hull int numleafs = 1; // allow leaf funcs to be called without a map cleaf_t map_leafs[MAX_MAP_LEAFS]; int emptyleaf, solidleaf; int numleafbrushes; unsigned short map_leafbrushes[MAX_MAP_LEAFBRUSHES]; int numcmodels; cmodel_t map_cmodels[MAX_MAP_MODELS]; int numbrushes; cbrush_t map_brushes[MAX_MAP_BRUSHES]; int numvisibility; byte map_visibility[MAX_MAP_VISIBILITY]; dvis_t *map_vis = (dvis_t *)map_visibility; int numentitychars; char map_entitystring[MAX_MAP_ENTSTRING]; int numareas = 1; carea_t map_areas[MAX_MAP_AREAS]; int numareaportals; dareaportal_t map_areaportals[MAX_MAP_AREAPORTALS]; int numclusters = 1; mapsurface_t nullsurface; int floodvalid; qboolean portalopen[MAX_MAP_AREAPORTALS]; cvar_t *map_noareas; void CM_InitBoxHull (void); void FloodAreaConnections (void); int c_pointcontents; int c_traces, c_brush_traces; /* =============================================================================== MAP LOADING =============================================================================== */ byte *cmod_base; /* ================= CMod_LoadSubmodels ================= */ void CMod_LoadSubmodels (lump_t *l) { dmodel_t *in; cmodel_t *out; int i, j, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no models"); if (count > MAX_MAP_MODELS) Com_Error (ERR_DROP, "Map has too many models"); numcmodels = count; for ( i=0 ; i<count ; i++, in++) { out = &map_cmodels[i]; for (j=0 ; j<3 ; j++) { // spread the mins / maxs by a pixel out->mins[j] = LittleFloat (in->mins[j]) - 1; out->maxs[j] = LittleFloat (in->maxs[j]) + 1; out->origin[j] = LittleFloat (in->origin[j]); } out->headnode = LittleLong (in->headnode); } } /* ================= CMod_LoadSurfaces ================= */ void CMod_LoadSurfaces (lump_t *l) { texinfo_t *in; mapsurface_t *out; int i, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no surfaces"); if (count > MAX_MAP_TEXINFO) Com_Error (ERR_DROP, "Map has too many surfaces"); numtexinfo = count; out = map_surfaces; for ( i=0 ; i<count ; i++, in++, out++) { strncpy (out->c.name, in->texture, sizeof(out->c.name)-1); strncpy (out->rname, in->texture, sizeof(out->rname)-1); out->c.flags = LittleLong (in->flags); out->c.value = LittleLong (in->value); } } /* ================= CMod_LoadNodes ================= */ void CMod_LoadNodes (lump_t *l) { dnode_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, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map has no nodes"); if (count > MAX_MAP_NODES) Com_Error (ERR_DROP, "Map has too many nodes"); 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; } } } /* ================= CMod_LoadBrushes ================= */ void CMod_LoadBrushes (lump_t *l) { dbrush_t *in; cbrush_t *out; int i, count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count > MAX_MAP_BRUSHES) Com_Error (ERR_DROP, "Map has too many brushes"); out = map_brushes; numbrushes = count; for (i=0 ; i<count ; i++, out++, in++) { out->firstbrushside = LittleLong(in->firstside); out->numsides = LittleLong(in->numsides); out->contents = LittleLong(in->contents); } } /* ================= CMod_LoadLeafs ================= */ void CMod_LoadLeafs (lump_t *l) { int i; cleaf_t *out; dleaf_t *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no leafs"); // need to save space for box planes if (count > MAX_MAP_PLANES) Com_Error (ERR_DROP, "Map has too many planes"); out = map_leafs; numleafs = count; numclusters = 0; for ( i=0 ; i<count ; i++, in++, out++) { out->contents = LittleLong (in->contents); out->cluster = LittleShort (in->cluster); out->area = LittleShort (in->area); out->firstleafbrush = LittleShort (in->firstleafbrush); out->numleafbrushes = LittleShort (in->numleafbrushes); if (out->cluster >= numclusters) numclusters = out->cluster + 1; } if (map_leafs[0].contents != CONTENTS_SOLID) Com_Error (ERR_DROP, "Map leaf 0 is not CONTENTS_SOLID"); 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, "Map does not have an empty leaf"); } /* ================= CMod_LoadPlanes ================= */ void CMod_LoadPlanes (lump_t *l) { int i, j; cplane_t *out; dplane_t *in; int count; int bits; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no planes"); // need to save space for box planes if (count > MAX_MAP_PLANES) Com_Error (ERR_DROP, "Map has too many planes"); out = map_planes; numplanes = count; for ( i=0 ; i<count ; i++, in++, out++) { bits = 0; for (j=0 ; j<3 ; j++) { out->normal[j] = LittleFloat (in->normal[j]); if (out->normal[j] < 0) bits |= 1<<j; } out->dist = LittleFloat (in->dist); out->type = LittleLong (in->type); out->signbits = bits; } } /* ================= CMod_LoadLeafBrushes ================= */ void CMod_LoadLeafBrushes (lump_t *l) { int i; unsigned short *out; unsigned short *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count < 1) Com_Error (ERR_DROP, "Map with no planes"); // need to save space for box planes if (count > MAX_MAP_LEAFBRUSHES) Com_Error (ERR_DROP, "Map has too many leafbrushes"); out = map_leafbrushes; numleafbrushes = count; for ( i=0 ; i<count ; i++, in++, out++) *out = LittleShort (*in); } /* ================= CMod_LoadBrushSides ================= */ void CMod_LoadBrushSides (lump_t *l) { int i, j; cbrushside_t *out; dbrushside_t *in; int count; int num; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); // need to save space for box planes if (count > MAX_MAP_BRUSHSIDES) Com_Error (ERR_DROP, "Map has too many planes"); out = map_brushsides; numbrushsides = count; for ( i=0 ; i<count ; i++, in++, out++) { num = LittleShort (in->planenum); out->plane = &map_planes[num]; j = LittleShort (in->texinfo); if (j >= numtexinfo) Com_Error (ERR_DROP, "Bad brushside texinfo"); out->surface = &map_surfaces[j]; } } /* ================= CMod_LoadAreas ================= */ void CMod_LoadAreas (lump_t *l) { int i; carea_t *out; darea_t *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count > MAX_MAP_AREAS) Com_Error (ERR_DROP, "Map has too many areas"); out = map_areas; numareas = count; for ( i=0 ; i<count ; i++, in++, out++) { out->numareaportals = LittleLong (in->numareaportals); out->firstareaportal = LittleLong (in->firstareaportal); out->floodvalid = 0; out->floodnum = 0; } } /* ================= CMod_LoadAreaPortals ================= */ void CMod_LoadAreaPortals (lump_t *l) { int i; dareaportal_t *out; dareaportal_t *in; int count; in = (void *)(cmod_base + l->fileofs); if (l->filelen % sizeof(*in)) Com_Error (ERR_DROP, "MOD_LoadBmodel: funny lump size"); count = l->filelen / sizeof(*in); if (count > MAX_MAP_AREAS) Com_Error (ERR_DROP, "Map has too many areas"); out = map_areaportals; numareaportals = count; for ( i=0 ; i<count ; i++, in++, out++) { out->portalnum = LittleLong (in->portalnum); out->otherarea = LittleLong (in->otherarea); } } /* ================= CMod_LoadVisibility ================= */ void CMod_LoadVisibility (lump_t *l) { int i; numvisibility = l->filelen; if (l->filelen > MAX_MAP_VISIBILITY) Com_Error (ERR_DROP, "Map has too large visibility lump"); memcpy (map_visibility, cmod_base + l->fileofs, l->filelen);