BSP2 support. patch kindly provided by Eric Wasylishen (see the patch

tracker entry #11 at http://sourceforge.net/p/quakespasm/patches/11/)

git-svn-id: svn://svn.code.sf.net/p/quakespasm/code/trunk/quakespasm@881 af15c1b1-3010-417e-b628-4374ebc0bcbd
This commit is contained in:
Ozkan Sezer 2013-12-25 09:10:28 +00:00
parent 7b9e1335d8
commit 1eb360205b
3 changed files with 538 additions and 110 deletions

View file

@ -34,7 +34,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define MAX_MAP_PLANES 32767 #define MAX_MAP_PLANES 32767
#define MAX_MAP_NODES 32767 // because negative shorts are contents #define MAX_MAP_NODES 32767 // because negative shorts are contents
#define MAX_MAP_CLIPNODES 32767 #define MAX_MAP_CLIPNODES 32767
#define MAX_MAP_LEAFS 32767 //johnfitz -- was 8192 #define MAX_MAP_LEAFS 65535 //johnfitz -- was 8192
#define MAX_MAP_VERTS 65535 #define MAX_MAP_VERTS 65535
#define MAX_MAP_FACES 65535 #define MAX_MAP_FACES 65535
#define MAX_MAP_MARKSURFACES 65535 #define MAX_MAP_MARKSURFACES 65535
@ -57,6 +57,14 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define BSPVERSION 29 #define BSPVERSION 29
/* RMQ support (2PSB). 32bits instead of shorts for all but bbox sizes (which
* still use shorts) */
#define BSP2VERSION_2PSB (('B' << 24) | ('S' << 16) | ('P' << 8) | '2')
/* BSP2 support. 32bits instead of shorts for everything (bboxes use floats) */
#define BSP2VERSION_BSP2 (('B' << 0) | ('S' << 8) | ('P' << 16) | ('2'<<24))
#define TOOLVERSION 2 #define TOOLVERSION 2
typedef struct typedef struct
@ -136,7 +144,6 @@ typedef struct
} dplane_t; } dplane_t;
#define CONTENTS_EMPTY -1 #define CONTENTS_EMPTY -1
#define CONTENTS_SOLID -2 #define CONTENTS_SOLID -2
#define CONTENTS_WATER -3 #define CONTENTS_WATER -3
@ -163,13 +170,39 @@ typedef struct
short maxs[3]; short maxs[3];
unsigned short firstface; unsigned short firstface;
unsigned short numfaces; // counting both sides unsigned short numfaces; // counting both sides
} dnode_t; } dsnode_t;
typedef struct
{
int planenum;
int children[2]; // negative numbers are -(leafs+1), not nodes
short mins[3]; // for sphere culling
short maxs[3];
unsigned int firstface;
unsigned int numfaces; // counting both sides
} dl1node_t;
typedef struct
{
int planenum;
int children[2]; // negative numbers are -(leafs+1), not nodes
float mins[3]; // for sphere culling
float maxs[3];
unsigned int firstface;
unsigned int numfaces; // counting both sides
} dl2node_t;
typedef struct typedef struct
{ {
int planenum; int planenum;
short children[2]; // negative numbers are contents short children[2]; // negative numbers are contents
} dclipnode_t; } dsclipnode_t;
typedef struct
{
int planenum;
int children[2]; // negative numbers are contents
} dlclipnode_t;
typedef struct texinfo_s typedef struct texinfo_s
@ -186,7 +219,12 @@ typedef struct texinfo_s
typedef struct typedef struct
{ {
unsigned short v[2]; // vertex numbers unsigned short v[2]; // vertex numbers
} dedge_t; } dsedge_t;
typedef struct
{
unsigned int v[2]; // vertex numbers
} dledge_t;
#define MAXLIGHTMAPS 4 #define MAXLIGHTMAPS 4
typedef struct typedef struct
@ -201,9 +239,21 @@ typedef struct
// lighting info // lighting info
byte styles[MAXLIGHTMAPS]; byte styles[MAXLIGHTMAPS];
int lightofs; // start of [numstyles*surfsize] samples int lightofs; // start of [numstyles*surfsize] samples
} dface_t; } dsface_t;
typedef struct
{
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
} dlface_t;
#define AMBIENT_WATER 0 #define AMBIENT_WATER 0
#define AMBIENT_SKY 1 #define AMBIENT_SKY 1
@ -226,7 +276,35 @@ typedef struct
unsigned short nummarksurfaces; unsigned short nummarksurfaces;
byte ambient_level[NUM_AMBIENTS]; byte ambient_level[NUM_AMBIENTS];
} dleaf_t; } dsleaf_t;
typedef struct
{
int contents;
int visofs; // -1 = no visibility info
short mins[3]; // for frustum culling
short maxs[3];
unsigned int firstmarksurface;
unsigned int nummarksurfaces;
byte ambient_level[NUM_AMBIENTS];
} dl1leaf_t;
typedef struct
{
int contents;
int visofs; // -1 = no visibility info
float mins[3]; // for frustum culling
float maxs[3];
unsigned int firstmarksurface;
unsigned int nummarksurfaces;
byte ambient_level[NUM_AMBIENTS];
} dl2leaf_t;
//============================================================================ //============================================================================

View file

@ -795,25 +795,48 @@ void Mod_LoadVertexes (lump_t *l)
Mod_LoadEdges Mod_LoadEdges
================= =================
*/ */
void Mod_LoadEdges (lump_t *l) void Mod_LoadEdges (lump_t *l, int bsp2)
{ {
dedge_t *in;
medge_t *out; medge_t *out;
int i, count; int i, count;
in = (dedge_t *)(mod_base + l->fileofs); if (bsp2)
if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (medge_t *) Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);
loadmodel->edges = out;
loadmodel->numedges = count;
for ( i=0 ; i<count ; i++, in++, out++)
{ {
out->v[0] = (unsigned short)LittleShort(in->v[0]); dledge_t *in = (dledge_t *)(mod_base + l->fileofs);
out->v[1] = (unsigned short)LittleShort(in->v[1]);
if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (medge_t *) Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);
loadmodel->edges = out;
loadmodel->numedges = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
out->v[0] = LittleLong(in->v[0]);
out->v[1] = LittleLong(in->v[1]);
}
}
else
{
dsedge_t *in = (dsedge_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (medge_t *) Hunk_AllocName ( (count + 1) * sizeof(*out), loadname);
loadmodel->edges = out;
loadmodel->numedges = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
out->v[0] = (unsigned short)LittleShort(in->v[0]);
out->v[1] = (unsigned short)LittleShort(in->v[1]);
}
} }
} }
@ -1033,54 +1056,85 @@ void Mod_CalcSurfaceBounds (msurface_t *s)
Mod_LoadFaces Mod_LoadFaces
================= =================
*/ */
void Mod_LoadFaces (lump_t *l) void Mod_LoadFaces (lump_t *l, qboolean bsp2)
{ {
dface_t *in; dsface_t *ins;
dlface_t *inl;
msurface_t *out; msurface_t *out;
int i, count, surfnum; int i, count, surfnum, lofs;
int planenum, side; int planenum, side, texinfon;
in = (dface_t *)(mod_base + l->fileofs); if (bsp2)
if (l->filelen % sizeof(*in)) {
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); ins = NULL;
count = l->filelen / sizeof(*in); inl = (dlface_t *)(mod_base + l->fileofs);
out = (msurface_t *) Hunk_AllocName ( count*sizeof(*out), loadname); if (l->filelen % sizeof(*inl))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*inl);
}
else
{
ins = (dsface_t *)(mod_base + l->fileofs);
inl = NULL;
if (l->filelen % sizeof(*ins))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*ins);
}
out = (msurface_t *)Hunk_AllocName ( count*sizeof(*out), loadname);
//johnfitz -- warn mappers about exceeding old limits //johnfitz -- warn mappers about exceeding old limits
if (count > 32767) if (count > 32767 && !bsp2)
Con_Warning ("%i faces exceeds standard limit of 32767.\n", count); Con_Warning ("%i faces exceeds standard limit of 32767.\n", count);
//johnfitz //johnfitz
loadmodel->surfaces = out; loadmodel->surfaces = out;
loadmodel->numsurfaces = count; loadmodel->numsurfaces = count;
for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++) for ( surfnum=0 ; surfnum<count ; surfnum++, out++)
{ {
out->firstedge = LittleLong(in->firstedge); if (bsp2)
out->numedges = LittleShort(in->numedges); {
out->firstedge = LittleLong(inl->firstedge);
out->numedges = LittleLong(inl->numedges);
planenum = LittleLong(inl->planenum);
side = LittleLong(inl->side);
texinfon = LittleLong (inl->texinfo);
for (i=0 ; i<MAXLIGHTMAPS ; i++)
out->styles[i] = inl->styles[i];
lofs = LittleLong(inl->lightofs);
inl++;
}
else
{
out->firstedge = LittleLong(ins->firstedge);
out->numedges = LittleShort(ins->numedges);
planenum = LittleShort(ins->planenum);
side = LittleShort(ins->side);
texinfon = LittleShort (ins->texinfo);
for (i=0 ; i<MAXLIGHTMAPS ; i++)
out->styles[i] = ins->styles[i];
lofs = LittleLong(ins->lightofs);
ins++;
}
out->flags = 0; out->flags = 0;
planenum = LittleShort(in->planenum);
side = LittleShort(in->side);
if (side) if (side)
out->flags |= SURF_PLANEBACK; out->flags |= SURF_PLANEBACK;
out->plane = loadmodel->planes + planenum; out->plane = loadmodel->planes + planenum;
out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); out->texinfo = loadmodel->texinfo + texinfon;
CalcSurfaceExtents (out); CalcSurfaceExtents (out);
Mod_CalcSurfaceBounds (out); //johnfitz -- for per-surface frustum culling Mod_CalcSurfaceBounds (out); //johnfitz -- for per-surface frustum culling
// lighting info // lighting info
for (i=0 ; i<MAXLIGHTMAPS ; i++) if (lofs == -1)
out->styles[i] = in->styles[i];
i = LittleLong(in->lightofs);
if (i == -1)
out->samples = NULL; out->samples = NULL;
else else
out->samples = loadmodel->lightdata + (i * 3); //johnfitz -- lit support via lordhavoc (was "+ i") out->samples = loadmodel->lightdata + (lofs * 3); //johnfitz -- lit support via lordhavoc (was "+ i")
//johnfitz -- this section rewritten //johnfitz -- this section rewritten
if (!q_strncasecmp(out->texinfo->texture->name,"sky",3)) // sky surface //also note -- was Q_strncmp, changed to match qbsp if (!q_strncasecmp(out->texinfo->texture->name,"sky",3)) // sky surface //also note -- was Q_strncmp, changed to match qbsp
@ -1130,13 +1184,13 @@ void Mod_SetParent (mnode_t *node, mnode_t *parent)
Mod_LoadNodes Mod_LoadNodes
================= =================
*/ */
void Mod_LoadNodes (lump_t *l) void Mod_LoadNodes_S (lump_t *l)
{ {
int i, j, count, p; int i, j, count, p;
dnode_t *in; dsnode_t *in;
mnode_t *out; mnode_t *out;
in = (dnode_t *)(mod_base + l->fileofs); in = (dsnode_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in)) if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in); count = l->filelen / sizeof(*in);
@ -1184,25 +1238,132 @@ void Mod_LoadNodes (lump_t *l)
//johnfitz //johnfitz
} }
} }
}
void Mod_LoadNodes_L1 (lump_t *l)
{
int i, j, count, p;
dl1node_t *in;
mnode_t *out;
in = (dl1node_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Sys_Error ("Mod_LoadNodes: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mnode_t *)Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->nodes = out;
loadmodel->numnodes = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->minmaxs[j] = LittleShort (in->mins[j]);
out->minmaxs[3+j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->planenum);
out->plane = loadmodel->planes + p;
out->firstsurface = LittleLong (in->firstface); //johnfitz -- explicit cast as unsigned short
out->numsurfaces = LittleLong (in->numfaces); //johnfitz -- explicit cast as unsigned short
for (j=0 ; j<2 ; j++)
{
//johnfitz -- hack to handle nodes > 32k, adapted from darkplaces
p = LittleLong(in->children[j]);
if (p >= 0 && p < count)
out->children[j] = loadmodel->nodes + p;
else
{
p = 0xffffffff - p; //note this uses 65535 intentionally, -1 is leaf 0
if (p >= 0 && p < loadmodel->numleafs)
out->children[j] = (mnode_t *)(loadmodel->leafs + p);
else
{
Con_Printf("Mod_LoadNodes: invalid leaf index %i (file has only %i leafs)\n", p, loadmodel->numleafs);
out->children[j] = (mnode_t *)(loadmodel->leafs); //map it to the solid leaf
}
}
//johnfitz
}
}
}
void Mod_LoadNodes_L2 (lump_t *l)
{
int i, j, count, p;
dl2node_t *in;
mnode_t *out;
in = (dl2node_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Sys_Error ("Mod_LoadNodes: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (mnode_t *)Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->nodes = out;
loadmodel->numnodes = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->minmaxs[j] = LittleFloat (in->mins[j]);
out->minmaxs[3+j] = LittleFloat (in->maxs[j]);
}
p = LittleLong(in->planenum);
out->plane = loadmodel->planes + p;
out->firstsurface = LittleLong (in->firstface); //johnfitz -- explicit cast as unsigned short
out->numsurfaces = LittleLong (in->numfaces); //johnfitz -- explicit cast as unsigned short
for (j=0 ; j<2 ; j++)
{
//johnfitz -- hack to handle nodes > 32k, adapted from darkplaces
p = LittleLong(in->children[j]);
if (p > 0 && p < count)
out->children[j] = loadmodel->nodes + p;
else
{
p = 0xffffffff - p; //note this uses 65535 intentionally, -1 is leaf 0
if (p >= 0 && p < loadmodel->numleafs)
out->children[j] = (mnode_t *)(loadmodel->leafs + p);
else
{
Con_Printf("Mod_LoadNodes: invalid leaf index %i (file has only %i leafs)\n", p, loadmodel->numleafs);
out->children[j] = (mnode_t *)(loadmodel->leafs); //map it to the solid leaf
}
}
//johnfitz
}
}
}
void Mod_LoadNodes (lump_t *l, int bsp2)
{
if (bsp2 == 2)
Mod_LoadNodes_L2(l);
else if (bsp2)
Mod_LoadNodes_L1(l);
else
Mod_LoadNodes_S(l);
Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs Mod_SetParent (loadmodel->nodes, NULL); // sets nodes and leafs
} }
/* void Mod_ProcessLeafs_S (dsleaf_t *in, int filelen)
=================
Mod_LoadLeafs
=================
*/
void Mod_LoadLeafs (lump_t *l)
{ {
dleaf_t *in; mleaf_t *out;
mleaf_t *out;
int i, j, count, p; int i, j, count, p;
in = (dleaf_t *)(mod_base + l->fileofs); if (filelen % sizeof(*in))
if (l->filelen % sizeof(*in)) Sys_Error ("Mod_ProcessLeafs: funny lump size in %s", loadmodel->name);
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); count = filelen / sizeof(*in);
count = l->filelen / sizeof(*in);
out = (mleaf_t *) Hunk_AllocName ( count*sizeof(*out), loadname); out = (mleaf_t *) Hunk_AllocName ( count*sizeof(*out), loadname);
//johnfitz //johnfitz
@ -1241,26 +1402,153 @@ void Mod_LoadLeafs (lump_t *l)
} }
} }
void Mod_ProcessLeafs_L1 (dl1leaf_t *in, int filelen)
{
mleaf_t *out;
int i, j, count, p;
if (filelen % sizeof(*in))
Sys_Error ("Mod_ProcessLeafs: funny lump size in %s", loadmodel->name);
count = filelen / sizeof(*in);
out = (mleaf_t *) Hunk_AllocName (count * sizeof(*out), loadname);
if (count > MAX_MAP_LEAFS)
Host_Error ("Mod_LoadLeafs: %i leafs exceeds limit of %i.\n", count, MAX_MAP_LEAFS);
loadmodel->leafs = out;
loadmodel->numleafs = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->minmaxs[j] = LittleShort (in->mins[j]);
out->minmaxs[3+j] = LittleShort (in->maxs[j]);
}
p = LittleLong(in->contents);
out->contents = p;
out->firstmarksurface = loadmodel->marksurfaces + LittleLong(in->firstmarksurface); //johnfitz -- unsigned short
out->nummarksurfaces = LittleLong(in->nummarksurfaces); //johnfitz -- unsigned short
p = LittleLong(in->visofs);
if (p == -1)
out->compressed_vis = NULL;
else
out->compressed_vis = loadmodel->visdata + p;
out->efrags = NULL;
for (j=0 ; j<4 ; j++)
out->ambient_sound_level[j] = in->ambient_level[j];
//johnfitz -- removed code to mark surfaces as SURF_UNDERWATER
}
}
void Mod_ProcessLeafs_L2 (dl2leaf_t *in, int filelen)
{
mleaf_t *out;
int i, j, count, p;
if (filelen % sizeof(*in))
Sys_Error ("Mod_ProcessLeafs: funny lump size in %s", loadmodel->name);
count = filelen / sizeof(*in);
out = (mleaf_t *) Hunk_AllocName (count * sizeof(*out), loadname);
if (count > MAX_MAP_LEAFS)
Host_Error ("Mod_LoadLeafs: %i leafs exceeds limit of %i.\n", count, MAX_MAP_LEAFS);
loadmodel->leafs = out;
loadmodel->numleafs = count;
for ( i=0 ; i<count ; i++, in++, out++)
{
for (j=0 ; j<3 ; j++)
{
out->minmaxs[j] = LittleFloat (in->mins[j]);
out->minmaxs[3+j] = LittleFloat (in->maxs[j]);
}
p = LittleLong(in->contents);
out->contents = p;
out->firstmarksurface = loadmodel->marksurfaces + LittleLong(in->firstmarksurface); //johnfitz -- unsigned short
out->nummarksurfaces = LittleLong(in->nummarksurfaces); //johnfitz -- unsigned short
p = LittleLong(in->visofs);
if (p == -1)
out->compressed_vis = NULL;
else
out->compressed_vis = loadmodel->visdata + p;
out->efrags = NULL;
for (j=0 ; j<4 ; j++)
out->ambient_sound_level[j] = in->ambient_level[j];
//johnfitz -- removed code to mark surfaces as SURF_UNDERWATER
}
}
/*
=================
Mod_LoadLeafs
=================
*/
void Mod_LoadLeafs (lump_t *l, int bsp2)
{
void *in = (void *)(mod_base + l->fileofs);
if (bsp2 == 2)
Mod_ProcessLeafs_L2 (in, l->filelen);
else if (bsp2)
Mod_ProcessLeafs_L1 (in, l->filelen);
else
Mod_ProcessLeafs_S (in, l->filelen);
}
/* /*
================= =================
Mod_LoadClipnodes Mod_LoadClipnodes
================= =================
*/ */
void Mod_LoadClipnodes (lump_t *l) void Mod_LoadClipnodes (lump_t *l, qboolean bsp2)
{ {
dclipnode_t *in; dsclipnode_t *ins;
dlclipnode_t *inl;
mclipnode_t *out; //johnfitz -- was dclipnode_t mclipnode_t *out; //johnfitz -- was dclipnode_t
int i, count; int i, count;
hull_t *hull; hull_t *hull;
in = (dclipnode_t *)(mod_base + l->fileofs); if (bsp2)
if (l->filelen % sizeof(*in)) {
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name); ins = NULL;
count = l->filelen / sizeof(*in); inl = (dlclipnode_t *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*inl))
Sys_Error ("Mod_LoadClipnodes: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*inl);
}
else
{
ins = (dsclipnode_t *)(mod_base + l->fileofs);
inl = NULL;
if (l->filelen % sizeof(*ins))
Sys_Error ("Mod_LoadClipnodes: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*ins);
}
out = (mclipnode_t *) Hunk_AllocName ( count*sizeof(*out), loadname); out = (mclipnode_t *) Hunk_AllocName ( count*sizeof(*out), loadname);
//johnfitz -- warn about exceeding old limits //johnfitz -- warn about exceeding old limits
if (count > 32767) if (count > 32767 && !bsp2)
Con_Warning ("%i clipnodes exceeds standard limit of 32767.\n", count); Con_Warning ("%i clipnodes exceeds standard limit of 32767.\n", count);
//johnfitz //johnfitz
@ -1291,23 +1579,43 @@ void Mod_LoadClipnodes (lump_t *l)
hull->clip_maxs[1] = 32; hull->clip_maxs[1] = 32;
hull->clip_maxs[2] = 64; hull->clip_maxs[2] = 64;
for (i=0 ; i<count ; i++, out++, in++) if (bsp2)
{ {
out->planenum = LittleLong(in->planenum); for (i=0 ; i<count ; i++, out++, inl++)
{
out->planenum = LittleLong(inl->planenum);
//johnfitz -- bounds check
if (out->planenum < 0 || out->planenum >= loadmodel->numplanes)
Host_Error ("Mod_LoadClipnodes: planenum out of bounds");
//johnfitz
out->children[0] = LittleLong(inl->children[0]);
out->children[1] = LittleLong(inl->children[1]);
//Spike: FIXME: bounds check
}
}
else
{
for (i=0 ; i<count ; i++, out++, ins++)
{
out->planenum = LittleLong(ins->planenum);
//johnfitz -- bounds check //johnfitz -- bounds check
if (out->planenum < 0 || out->planenum >= loadmodel->numplanes) if (out->planenum < 0 || out->planenum >= loadmodel->numplanes)
Host_Error ("Mod_LoadClipnodes: planenum out of bounds"); Host_Error ("Mod_LoadClipnodes: planenum out of bounds");
//johnfitz //johnfitz
//johnfitz -- support clipnodes > 32k //johnfitz -- support clipnodes > 32k
out->children[0] = (unsigned short)LittleShort(in->children[0]); out->children[0] = (unsigned short)LittleShort(ins->children[0]);
out->children[1] = (unsigned short)LittleShort(in->children[1]); out->children[1] = (unsigned short)LittleShort(ins->children[1]);
if (out->children[0] >= count)
out->children[0] -= 65536; if (out->children[0] >= count)
if (out->children[1] >= count) out->children[0] -= 65536;
out->children[1] -= 65536; if (out->children[1] >= count)
//johnfitz out->children[1] -= 65536;
//johnfitz
}
} }
} }
@ -1355,32 +1663,57 @@ void Mod_MakeHull0 (void)
Mod_LoadMarksurfaces Mod_LoadMarksurfaces
================= =================
*/ */
void Mod_LoadMarksurfaces (lump_t *l) void Mod_LoadMarksurfaces (lump_t *l, int bsp2)
{ {
int i, j, count; int i, j, count;
short *in;
msurface_t **out; msurface_t **out;
if (bsp2)
in = (short *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Sys_Error ("MOD_LoadBmodel: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (msurface_t **) Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->marksurfaces = out;
loadmodel->nummarksurfaces = count;
//johnfitz -- warn mappers about exceeding old limits
if (count > 32767)
Con_Warning ("%i marksurfaces exceeds standard limit of 32767.\n", count);
//johnfitz
for ( i=0 ; i<count ; i++)
{ {
j = (unsigned short)LittleShort(in[i]); //johnfitz -- explicit cast as unsigned short unsigned int *in = (unsigned int *)(mod_base + l->fileofs);
if (j >= loadmodel->numsurfaces)
Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); if (l->filelen % sizeof(*in))
out[i] = loadmodel->surfaces + j; Host_Error ("Mod_LoadMarksurfaces: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (msurface_t **)Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->marksurfaces = out;
loadmodel->nummarksurfaces = count;
for ( i=0 ; i<count ; i++)
{
j = LittleLong(in[i]);
if (j >= loadmodel->numsurfaces)
Host_Error ("Mod_LoadMarksurfaces: bad surface number");
out[i] = loadmodel->surfaces + j;
}
}
else
{
short *in = (short *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
Host_Error ("Mod_LoadMarksurfaces: funny lump size in %s",loadmodel->name);
count = l->filelen / sizeof(*in);
out = (msurface_t **)Hunk_AllocName ( count*sizeof(*out), loadname);
loadmodel->marksurfaces = out;
loadmodel->nummarksurfaces = count;
//johnfitz -- warn mappers about exceeding old limits
if (count > 32767)
Con_Warning ("%i marksurfaces exceeds standard limit of 32767.\n", count);
//johnfitz
for ( i=0 ; i<count ; i++)
{
j = (unsigned short)LittleShort(in[i]); //johnfitz -- explicit cast as unsigned short
if (j >= loadmodel->numsurfaces)
Sys_Error ("Mod_LoadMarksurfaces: bad surface number");
out[i] = loadmodel->surfaces + j;
}
} }
} }
@ -1570,6 +1903,7 @@ Mod_LoadBrushModel
void Mod_LoadBrushModel (qmodel_t *mod, void *buffer) void Mod_LoadBrushModel (qmodel_t *mod, void *buffer)
{ {
int i, j; int i, j;
int bsp2;
dheader_t *header; dheader_t *header;
dmodel_t *bm; dmodel_t *bm;
float radius; //johnfitz float radius; //johnfitz
@ -1578,9 +1912,23 @@ void Mod_LoadBrushModel (qmodel_t *mod, void *buffer)
header = (dheader_t *)buffer; header = (dheader_t *)buffer;
i = LittleLong (header->version); mod->bspversion = LittleLong (header->version);
if (i != BSPVERSION)
Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, i, BSPVERSION); switch(mod->bspversion)
{
case BSPVERSION:
bsp2 = false;
break;
case BSP2VERSION_2PSB:
bsp2 = 1; //first iteration
break;
case BSP2VERSION_BSP2:
bsp2 = 2; //sanitised revision
break;
default:
Sys_Error ("Mod_LoadBrushModel: %s has wrong version number (%i should be %i)", mod->name, mod->bspversion, BSPVERSION);
break;
}
// swap all the lumps // swap all the lumps
mod_base = (byte *)header; mod_base = (byte *)header;
@ -1591,18 +1939,18 @@ void Mod_LoadBrushModel (qmodel_t *mod, void *buffer)
// load into heap // load into heap
Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]); Mod_LoadVertexes (&header->lumps[LUMP_VERTEXES]);
Mod_LoadEdges (&header->lumps[LUMP_EDGES]); Mod_LoadEdges (&header->lumps[LUMP_EDGES], bsp2);
Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]); Mod_LoadSurfedges (&header->lumps[LUMP_SURFEDGES]);
Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]); Mod_LoadTextures (&header->lumps[LUMP_TEXTURES]);
Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]); Mod_LoadLighting (&header->lumps[LUMP_LIGHTING]);
Mod_LoadPlanes (&header->lumps[LUMP_PLANES]); Mod_LoadPlanes (&header->lumps[LUMP_PLANES]);
Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]); Mod_LoadTexinfo (&header->lumps[LUMP_TEXINFO]);
Mod_LoadFaces (&header->lumps[LUMP_FACES]); Mod_LoadFaces (&header->lumps[LUMP_FACES], bsp2);
Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES]); Mod_LoadMarksurfaces (&header->lumps[LUMP_MARKSURFACES], bsp2);
Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]); Mod_LoadVisibility (&header->lumps[LUMP_VISIBILITY]);
Mod_LoadLeafs (&header->lumps[LUMP_LEAFS]); Mod_LoadLeafs (&header->lumps[LUMP_LEAFS], bsp2);
Mod_LoadNodes (&header->lumps[LUMP_NODES]); Mod_LoadNodes (&header->lumps[LUMP_NODES], bsp2);
Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES]); Mod_LoadClipnodes (&header->lumps[LUMP_CLIPNODES], bsp2);
Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]); Mod_LoadEntities (&header->lumps[LUMP_ENTITIES]);
Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]); Mod_LoadSubmodels (&header->lumps[LUMP_MODELS]);

View file

@ -103,7 +103,7 @@ typedef struct texture_s
// !!! if this is changed, it must be changed in asm_draw.h too !!! // !!! if this is changed, it must be changed in asm_draw.h too !!!
typedef struct typedef struct
{ {
unsigned short v[2]; unsigned int v[2];
unsigned int cachededgeoffset; unsigned int cachededgeoffset;
} medge_t; } medge_t;
@ -174,8 +174,8 @@ typedef struct mnode_s
mplane_t *plane; mplane_t *plane;
struct mnode_s *children[2]; struct mnode_s *children[2];
unsigned short firstsurface; unsigned int firstsurface;
unsigned short numsurfaces; unsigned int numsurfaces;
} mnode_t; } mnode_t;
@ -436,6 +436,8 @@ typedef struct qmodel_s
byte *lightdata; byte *lightdata;
char *entities; char *entities;
int bspversion;
// //
// additional model data // additional model data
// //