From 88514bda4f8e26c937d013657a1b1dcc09beca27 Mon Sep 17 00:00:00 2001 From: Shpoike Date: Sun, 13 Aug 2023 01:24:38 +0100 Subject: [PATCH] Add support for the 'qbsim' variant of q2bsp. --- engine/common/bspfile.h | 27 ++- engine/common/gl_q2bsp.c | 384 +++++++++++++++++++++++++-------------- engine/common/q1bsp.c | 10 +- engine/gl/gl_model.c | 18 +- 4 files changed, 288 insertions(+), 151 deletions(-) diff --git a/engine/common/bspfile.h b/engine/common/bspfile.h index 96c84f7ee..87f417e78 100644 --- a/engine/common/bspfile.h +++ b/engine/common/bspfile.h @@ -693,7 +693,7 @@ typedef struct short maxs[3]; unsigned short firstface; unsigned short numfaces; // counting both sides -} q2dnode_t; +} q2dsnode_t; typedef struct { @@ -730,7 +730,23 @@ typedef struct unsigned short firstleafbrush; unsigned short numleafbrushes; -} q2dleaf_t; +} q2dsleaf_t; +typedef struct +{ + int contents; // OR of all brushes (not needed?) + + int cluster; + int area; + + float mins[3]; // for frustum culling + float maxs[3]; + + unsigned int firstleafface; + unsigned int numleaffaces; + + unsigned int firstleafbrush; + unsigned int numleafbrushes; +} q2dlleaf_t; typedef struct { @@ -749,7 +765,12 @@ typedef struct { unsigned short planenum; // facing out of the leaf short texinfo; -} q2dbrushside_t; +} q2dsbrushside_t; +typedef struct +{ + unsigned int planenum; // facing out of the leaf + int texinfo; +} q2dlbrushside_t; typedef struct { diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 412e34411..0f0697dfe 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -51,8 +51,8 @@ extern cvar_t r_shadow_bumpscale_basetexture; //these are in model.c (or gl_model.c) qboolean Mod_LoadVertexes (model_t *loadmodel, qbyte *mod_base, lump_t *l); qboolean Mod_LoadVertexNormals (model_t *loadmodel, bspx_header_t *bspx, qbyte *mod_base, lump_t *l); -qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm); -qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm); +qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, subbsp_t lm); +qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, subbsp_t lm); qboolean Mod_LoadSurfedges (model_t *loadmodel, qbyte *mod_base, lump_t *l); void Mod_LoadEntities (model_t *loadmodel, qbyte *mod_base, lump_t *l); @@ -1659,9 +1659,10 @@ Mod_LoadFaces ================= */ #ifdef HAVE_CLIENT -static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, lump_t *lightlump, qboolean lightofsisdouble, bspx_header_t *bspx) +static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, lump_t *lightlump, qboolean lightofsisdouble, bspx_header_t *bspx, qboolean isbig) { - dsface_t *in; + dsface_t *ins = NULL; + dlface_t *inl = NULL; msurface_t *out; int i, count, surfnum; int planenum, side; @@ -1676,13 +1677,16 @@ static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, lump lightmapoverrides_t overrides = {0}; overrides.defaultshift = LMSHIFT_DEFAULT; - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) + if (!isbig && !(l->filelen % sizeof(*ins))) + ins = (void *)(mod_base + l->fileofs); + else if (isbig && !(l->filelen % sizeof(*inl))) + inl = (void *)(mod_base + l->fileofs); + else { Con_Printf ("MOD_LoadBmodel: funny lump size in %s\n",mod->name); return false; } - count = l->filelen / sizeof(*in); + count = l->filelen / (isbig?sizeof(*inl):sizeof(*ins)); out = ZG_Malloc(&mod->memgroup, (count+6)*sizeof(*out)); //spare for skybox mod->surfaces = out; @@ -1709,20 +1713,50 @@ static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, lump else decoupledlm = NULL; //wrong size somehow... discard it. - for ( surfnum=0 ; surfnumfirstedge = LittleLong(in->firstedge); - out->numedges = (unsigned short)LittleShort(in->numedges); + if (isbig) + { + out->firstedge = LittleLong(inl->firstedge); + out->numedges = (unsigned int)LittleLong(inl->numedges); + planenum = (unsigned int)LittleLong(inl->planenum); + side = (unsigned int)LittleLong(inl->side); + ti = (unsigned int)LittleLong (inl->texinfo); + lofs = LittleLong(inl->lightofs); + for (i=0 ; i<4 ; i++) + { + style = inl->styles[i]; + if (style == 0xff) + style = INVALID_LIGHTSTYLE; + else if (mod->lightmaps.maxstyle < style) + mod->lightmaps.maxstyle = style; + out->styles[i] = style; + } + inl++; + } + else + { + out->firstedge = LittleLong(ins->firstedge); + out->numedges = (unsigned short)LittleShort(ins->numedges); + planenum = (unsigned short)LittleShort(ins->planenum); + side = (unsigned short)LittleShort(ins->side); + ti = (unsigned short)LittleShort (ins->texinfo); + lofs = LittleLong(ins->lightofs); + for (i=0 ; i<4 ; i++) + { + style = ins->styles[i]; + if (style == 0xff) + style = INVALID_LIGHTSTYLE; + else if (mod->lightmaps.maxstyle < style) + mod->lightmaps.maxstyle = style; + out->styles[i] = style; + } + ins++; + } + out->plane = mod->planes + planenum; out->flags = 0; - - planenum = (unsigned short)LittleShort(in->planenum); - side = (unsigned short)LittleShort(in->side); if (side) out->flags |= SURF_PLANEBACK; - - out->plane = mod->planes + planenum; - - ti = (unsigned short)LittleShort (in->texinfo); if (ti < 0 || ti >= mod->numtexinfo) { Con_Printf (CON_ERROR "MOD_LoadBmodel: bad texinfo number\n"); @@ -1770,8 +1804,6 @@ static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, lump { if (overrides.offsets) lofs = overrides.offsets[surfnum]; - else - lofs = LittleLong(in->lightofs); CalcSurfaceExtents (mod, out); if (overrides.extents) @@ -1806,18 +1838,6 @@ static qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, lump out->styles[i] = style; } } - else - { - for (i=0 ; i<4 ; i++) - { - style = in->styles[i]; - if (style == 0xff) - style = INVALID_LIGHTSTYLE; - else if (mod->lightmaps.maxstyle < style) - mod->lightmaps.maxstyle = style; - out->styles[i] = style; - } - } for ( ; istyles[i] = INVALID_LIGHTSTYLE; if (lofs == ~0u) @@ -1850,20 +1870,20 @@ CMod_LoadNodes ================= */ -static qboolean CModQ2_LoadNodes (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadNodes (model_t *mod, qbyte *mod_base, lump_t *l, qboolean isbig) { - q2dnode_t *in; + q2dsnode_t *ins; + dl2node_t *inl; int child; mnode_t *out; int i, j, count; - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) + if (l->filelen % (isbig?sizeof(*inl):sizeof(*ins))) { Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size\n"); return false; } - count = l->filelen / sizeof(*in); + count = l->filelen / (isbig?sizeof(*inl):sizeof(*ins)); if (count < 1) { @@ -1881,30 +1901,60 @@ static qboolean CModQ2_LoadNodes (model_t *mod, qbyte *mod_base, lump_t *l) mod->nodes = out; mod->numnodes = count; - for (i=0 ; ifileofs); + for (i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); + for (j=0 ; j<3 ; j++) + { + out->minmaxs[j] = LittleFloat (inl->mins[j]); + out->minmaxs[3+j] = LittleFloat (inl->maxs[j]); + } + + out->plane = mod->planes + LittleLong(inl->planenum); + + out->firstsurface = (unsigned int)LittleLong (inl->firstface); + out->numsurfaces = (unsigned int)LittleLong (inl->numfaces); + out->contents = -1; // differentiate from leafs + + for (j=0 ; j<2 ; j++) + { + child = LittleLong (inl->children[j]); + out->childnum[j] = child; + if (child < 0) + out->children[j] = (mnode_t *)(mod->leafs + -1-child); + else + out->children[j] = mod->nodes + child; + } } - - out->plane = mod->planes + LittleLong(in->planenum); - - out->firstsurface = (unsigned short)LittleShort (in->firstface); - out->numsurfaces = (unsigned short)LittleShort (in->numfaces); - out->contents = -1; // differentiate from leafs - - for (j=0 ; j<2 ; j++) + } + else + { + ins = (void *)(mod_base + l->fileofs); + for (i=0 ; ichildren[j]); - out->childnum[j] = child; - if (child < 0) - out->children[j] = (mnode_t *)(mod->leafs + -1-child); - else - out->children[j] = mod->nodes + child; + for (j=0 ; j<3 ; j++) + { + out->minmaxs[j] = LittleShort (ins->mins[j]); + out->minmaxs[3+j] = LittleShort (ins->maxs[j]); + } + + out->plane = mod->planes + LittleLong(ins->planenum); + + out->firstsurface = (unsigned short)LittleShort (ins->firstface); + out->numsurfaces = (unsigned short)LittleShort (ins->numfaces); + out->contents = -1; // differentiate from leafs + + for (j=0 ; j<2 ; j++) + { + child = LittleLong (ins->children[j]); + out->childnum[j] = child; + if (child < 0) + out->children[j] = (mnode_t *)(mod->leafs + -1-child); + else + out->children[j] = mod->nodes + child; + } } } @@ -1963,20 +2013,20 @@ static qboolean CModQ2_LoadBrushes (model_t *mod, qbyte *mod_base, lump_t *l) CMod_LoadLeafs ================= */ -static qboolean CModQ2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l, qboolean isbig) { int i, j; mleaf_t *out; - q2dleaf_t *in; + q2dsleaf_t *ins; + q2dlleaf_t *inl; int count; - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) + if (l->filelen % (isbig?sizeof(*inl):sizeof(*ins))) { Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size\n"); return false; } - count = l->filelen / sizeof(*in); + count = l->filelen / (isbig?sizeof(*inl):sizeof(*ins)); if (count < 1) { @@ -1996,31 +2046,62 @@ static qboolean CModQ2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l) mod->leafs = out; mod->numleafs = count; - for ( i=0 ; ifileofs); + for ( i=0 ; iminmaxs[j] = LittleShort (in->mins[j]); - out->minmaxs[3+j] = LittleShort (in->maxs[j]); + for (j=0 ; j<3 ; j++) + { + out->minmaxs[j] = LittleFloat (inl->mins[j]); + out->minmaxs[3+j] = LittleFloat (inl->maxs[j]); + } + + out->contents = LittleLong (inl->contents); + out->cluster = (unsigned int)LittleLong (inl->cluster); + if (out->cluster == 0xffffffff) + out->cluster = -1; + + out->area = (unsigned int)LittleLong (inl->area); + out->firstleafbrush = (unsigned int)LittleLong (inl->firstleafbrush); + out->numleafbrushes = (unsigned int)LittleLong (inl->numleafbrushes); + + out->firstmarksurface = mod->marksurfaces + + (unsigned int)LittleLong(inl->firstleafface); + out->nummarksurfaces = (unsigned int)LittleLong(inl->numleaffaces); + + if (out->cluster >= mod->numclusters) + mod->numclusters = out->cluster + 1; } + } + else + { + ins = (void *)(mod_base + l->fileofs); + for ( i=0 ; iminmaxs[j] = LittleShort (ins->mins[j]); + out->minmaxs[3+j] = LittleShort (ins->maxs[j]); + } - out->contents = LittleLong (in->contents); - out->cluster = (unsigned short)LittleShort (in->cluster); - if (out->cluster == 0xffff) - out->cluster = -1; + out->contents = LittleLong (ins->contents); + out->cluster = (unsigned short)LittleShort (ins->cluster); + if (out->cluster == 0xffff) + out->cluster = -1; - out->area = (unsigned short)LittleShort (in->area); - out->firstleafbrush = (unsigned short)LittleShort (in->firstleafbrush); - out->numleafbrushes = (unsigned short)LittleShort (in->numleafbrushes); + out->area = (unsigned short)LittleShort (ins->area); + out->firstleafbrush = (unsigned short)LittleShort (ins->firstleafbrush); + out->numleafbrushes = (unsigned short)LittleShort (ins->numleafbrushes); - out->firstmarksurface = mod->marksurfaces + - (unsigned short)LittleShort(in->firstleafface); - out->nummarksurfaces = (unsigned short)LittleShort(in->numleaffaces); + out->firstmarksurface = mod->marksurfaces + + (unsigned short)LittleShort(ins->firstleafface); + out->nummarksurfaces = (unsigned short)LittleShort(ins->numleaffaces); - if (out->cluster >= mod->numclusters) - mod->numclusters = out->cluster + 1; + if (out->cluster >= mod->numclusters) + mod->numclusters = out->cluster + 1; + } } out = mod->leafs; mod->pvsbytes = ((mod->numclusters + 31)>>3)&~3; @@ -2093,21 +2174,21 @@ static qboolean CModQ2_LoadPlanes (model_t *mod, qbyte *mod_base, lump_t *l) CMod_LoadLeafBrushes ================= */ -static qboolean CModQ2_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l, qboolean isbig) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; int i; q2cbrush_t **out; - unsigned short *in; + unsigned short *ins; + unsigned int *inl; int count; - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) + if (l->filelen % (isbig?sizeof(*inl):sizeof(*ins))) { Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size\n"); return false; } - count = l->filelen / sizeof(*in); + count = l->filelen / (isbig?sizeof(*inl):sizeof(*ins)); if (count < 1) { @@ -2125,8 +2206,18 @@ static qboolean CModQ2_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l out = prv->leafbrushes = ZG_Malloc(&mod->memgroup, sizeof(*out) * (count+prv->numbrushes)); prv->numleafbrushes = count; - for ( i=0 ; ibrushes + (unsigned short)(short)LittleShort (*in); + if (isbig) + { + inl = (void *)(mod_base + l->fileofs); + for ( i=0 ; ibrushes + (unsigned int)LittleLong (*inl); + } + else + { + ins = (void *)(mod_base + l->fileofs); + for ( i=0 ; ibrushes + (unsigned short)(short)LittleShort (*ins); + } return true; } @@ -2136,22 +2227,22 @@ static qboolean CModQ2_LoadLeafBrushes (model_t *mod, qbyte *mod_base, lump_t *l CMod_LoadBrushSides ================= */ -static qboolean CModQ2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) +static qboolean CModQ2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l, qboolean isbig) { cminfo_t *prv = (cminfo_t*)mod->meshinfo; unsigned int i, j; q2cbrushside_t *out; - q2dbrushside_t *in; + q2dsbrushside_t *ins; + q2dlbrushside_t *inl; int count; int num; - in = (void *)(mod_base + l->fileofs); - if (l->filelen % sizeof(*in)) + if (l->filelen % (isbig?sizeof(*inl):sizeof(*ins))) { Con_Printf (CON_ERROR "MOD_LoadBmodel: funny lump size\n"); return false; } - count = l->filelen / sizeof(*in); + count = l->filelen / (isbig?sizeof(*inl):sizeof(*ins)); // need to save space for box planes if (count > SANITY_MAX_MAP_BRUSHSIDES) @@ -2163,15 +2254,33 @@ static qboolean CModQ2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l) out = prv->brushsides = ZG_Malloc(&mod->memgroup, sizeof(*out) * count); prv->numbrushsides = count; - for ( i=0 ; iplanenum); - out->plane = &mod->planes[num]; - j = (unsigned short)LittleShort (in->texinfo); - if (j >= mod->numtexinfo) - out->surface = &nullsurface; - else - out->surface = &prv->surfaces[j]; + inl = (void *)(mod_base + l->fileofs); + for ( i=0 ; iplanenum); + out->plane = &mod->planes[num]; + j = (unsigned int)LittleLong (inl->texinfo); + if (j >= mod->numtexinfo) + out->surface = &nullsurface; + else + out->surface = &prv->surfaces[j]; + } + } + else + { + ins = (void *)(mod_base + l->fileofs); + for ( i=0 ; iplanenum); + out->plane = &mod->planes[num]; + j = (unsigned short)LittleShort (ins->texinfo); + if (j >= mod->numtexinfo) + out->surface = &nullsurface; + else + out->surface = &prv->surfaces[j]; + } } return true; @@ -2204,7 +2313,7 @@ static qboolean CModQ2_LoadAreas (model_t *mod, qbyte *mod_base, lump_t *l) return false; } - out = prv->q2areas = ZG_Malloc(&mod->memgroup, sizeof(*out) * count);; + out = prv->q2areas = ZG_Malloc(&mod->memgroup, sizeof(*out) * count); prv->numareas = count; for ( i=0 ; iname, loadname, sizeof(loadname)); @@ -4942,6 +5052,8 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole #ifdef Q2BSPS case BSPVERSION_Q2: case BSPVERSION_Q2W: + isbig = *mod_base == 'Q'; //'qbism' + mod->lightmaps.width = LMBLOCK_SIZE_MAX; mod->lightmaps.height = LMBLOCK_SIZE_MAX; @@ -4995,11 +5107,11 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole noerrors = noerrors && CModQ2_LoadSurfaces (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO]); noerrors = noerrors && CModQ2_LoadPlanes (mod, mod_base, &header.lumps[Q2LUMP_PLANES]); noerrors = noerrors && CModQ2_LoadVisibility (mod, mod_base, &header.lumps[Q2LUMP_VISIBILITY]); - noerrors = noerrors && CModQ2_LoadBrushSides (mod, mod_base, &header.lumps[Q2LUMP_BRUSHSIDES]); + noerrors = noerrors && CModQ2_LoadBrushSides (mod, mod_base, &header.lumps[Q2LUMP_BRUSHSIDES], isbig); noerrors = noerrors && CModQ2_LoadBrushes (mod, mod_base, &header.lumps[Q2LUMP_BRUSHES]); - noerrors = noerrors && CModQ2_LoadLeafBrushes (mod, mod_base, &header.lumps[Q2LUMP_LEAFBRUSHES]); - noerrors = noerrors && CModQ2_LoadLeafs (mod, mod_base, &header.lumps[Q2LUMP_LEAFS]); - noerrors = noerrors && CModQ2_LoadNodes (mod, mod_base, &header.lumps[Q2LUMP_NODES]); + noerrors = noerrors && CModQ2_LoadLeafBrushes (mod, mod_base, &header.lumps[Q2LUMP_LEAFBRUSHES], isbig); + noerrors = noerrors && CModQ2_LoadLeafs (mod, mod_base, &header.lumps[Q2LUMP_LEAFS], isbig); + noerrors = noerrors && CModQ2_LoadNodes (mod, mod_base, &header.lumps[Q2LUMP_NODES], isbig); noerrors = noerrors && CModQ2_LoadSubmodels (mod, mod_base, &header.lumps[Q2LUMP_MODELS]); noerrors = noerrors && CModQ2_LoadAreas (mod, mod_base, &header.lumps[Q2LUMP_AREAS]); noerrors = noerrors && CModQ2_LoadAreaPortals (mod, mod_base, &header.lumps[Q2LUMP_AREAPORTALS]); @@ -5008,41 +5120,39 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole break; #ifdef HAVE_CLIENT default: - { - // load into heap - noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[Q2LUMP_VERTEXES]); - noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header.lumps[Q2LUMP_EDGES], false); - noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[Q2LUMP_SURFEDGES]); - noerrors = noerrors && CModQ2_LoadSurfaces (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO]); - noerrors = noerrors && CModQ2_LoadPlanes (mod, mod_base, &header.lumps[Q2LUMP_PLANES]); - noerrors = noerrors && CModQ2_LoadTexInfo (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO], loadname); - if (noerrors) - Mod_LoadEntities (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]); - noerrors = noerrors && CModQ2_LoadFaces (mod, mod_base, &header.lumps[Q2LUMP_FACES], &header.lumps[Q2LUMP_LIGHTING], header.version == BSPVERSION_Q2W, bspx); - Mod_LoadVertexNormals(mod, bspx, mod_base, (header.version == BSPVERSION_Q2W)?&header.lumps[19]:NULL); - noerrors = noerrors && Mod_LoadMarksurfaces (mod, mod_base, &header.lumps[Q2LUMP_LEAFFACES], false); - noerrors = noerrors && CModQ2_LoadVisibility (mod, mod_base, &header.lumps[Q2LUMP_VISIBILITY]); - noerrors = noerrors && CModQ2_LoadBrushSides (mod, mod_base, &header.lumps[Q2LUMP_BRUSHSIDES]); - noerrors = noerrors && CModQ2_LoadBrushes (mod, mod_base, &header.lumps[Q2LUMP_BRUSHES]); - noerrors = noerrors && CModQ2_LoadLeafBrushes (mod, mod_base, &header.lumps[Q2LUMP_LEAFBRUSHES]); - noerrors = noerrors && CModQ2_LoadLeafs (mod, mod_base, &header.lumps[Q2LUMP_LEAFS]); - noerrors = noerrors && CModQ2_LoadNodes (mod, mod_base, &header.lumps[Q2LUMP_NODES]); - noerrors = noerrors && CModQ2_LoadSubmodels (mod, mod_base, &header.lumps[Q2LUMP_MODELS]); - noerrors = noerrors && CModQ2_LoadAreas (mod, mod_base, &header.lumps[Q2LUMP_AREAS]); - noerrors = noerrors && CModQ2_LoadAreaPortals (mod, mod_base, &header.lumps[Q2LUMP_AREAPORTALS]); + // load into heap + noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[Q2LUMP_VERTEXES]); + noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header.lumps[Q2LUMP_EDGES], isbig?sb_long2:sb_none); + noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[Q2LUMP_SURFEDGES]); + noerrors = noerrors && CModQ2_LoadSurfaces (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO]); + noerrors = noerrors && CModQ2_LoadPlanes (mod, mod_base, &header.lumps[Q2LUMP_PLANES]); + noerrors = noerrors && CModQ2_LoadTexInfo (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO], loadname); + if (noerrors) + Mod_LoadEntities (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]); + noerrors = noerrors && CModQ2_LoadFaces (mod, mod_base, &header.lumps[Q2LUMP_FACES], &header.lumps[Q2LUMP_LIGHTING], header.version == BSPVERSION_Q2W, bspx, isbig); + Mod_LoadVertexNormals(mod, bspx, mod_base, (header.version == BSPVERSION_Q2W)?&header.lumps[19]:NULL); + noerrors = noerrors && Mod_LoadMarksurfaces (mod, mod_base, &header.lumps[Q2LUMP_LEAFFACES], isbig?sb_long2:sb_none); + noerrors = noerrors && CModQ2_LoadVisibility (mod, mod_base, &header.lumps[Q2LUMP_VISIBILITY]); + noerrors = noerrors && CModQ2_LoadBrushSides (mod, mod_base, &header.lumps[Q2LUMP_BRUSHSIDES], isbig); + noerrors = noerrors && CModQ2_LoadBrushes (mod, mod_base, &header.lumps[Q2LUMP_BRUSHES]); + noerrors = noerrors && CModQ2_LoadLeafBrushes (mod, mod_base, &header.lumps[Q2LUMP_LEAFBRUSHES], isbig); + noerrors = noerrors && CModQ2_LoadLeafs (mod, mod_base, &header.lumps[Q2LUMP_LEAFS], isbig); + noerrors = noerrors && CModQ2_LoadNodes (mod, mod_base, &header.lumps[Q2LUMP_NODES], isbig); + noerrors = noerrors && CModQ2_LoadSubmodels (mod, mod_base, &header.lumps[Q2LUMP_MODELS]); + noerrors = noerrors && CModQ2_LoadAreas (mod, mod_base, &header.lumps[Q2LUMP_AREAS]); + noerrors = noerrors && CModQ2_LoadAreaPortals (mod, mod_base, &header.lumps[Q2LUMP_AREAPORTALS]); - if (!noerrors) - { - return NULL; - } - mod->funcs.LightPointValues = GLQ2BSP_LightPointValues; - mod->funcs.StainNode = GLR_Q2BSP_StainNode; - mod->funcs.MarkLights = Q2BSP_MarkLights; - mod->funcs.PrepareFrame = CM_PrepareFrame; -#ifdef RTLIGHTS - mod->funcs.GenerateShadowMesh = Q2BSP_GenerateShadowMesh; -#endif + if (!noerrors) + { + return NULL; } + mod->funcs.LightPointValues = GLQ2BSP_LightPointValues; + mod->funcs.StainNode = GLR_Q2BSP_StainNode; + mod->funcs.MarkLights = Q2BSP_MarkLights; + mod->funcs.PrepareFrame = CM_PrepareFrame; +#ifdef RTLIGHTS + mod->funcs.GenerateShadowMesh = Q2BSP_GenerateShadowMesh; +#endif break; #endif } diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 98381f978..79b803f3f 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -2944,7 +2944,10 @@ qboolean Mod_BSPXRW_Read(struct bspxrw *ctx, const char *fname) ctx->lumps = 0; ctx->totallumps = 0; - i = LittleLong(*(int*)ctx->origfile); + if (ctx->origsize < 4) + i = 0; + else + i = LittleLong(*(int*)ctx->origfile); switch(i) { case 29: @@ -2977,6 +2980,7 @@ qboolean Mod_BSPXRW_Read(struct bspxrw *ctx, const char *fname) #endif default: Mod_BSPXRW_Free(ctx); + Con_Printf(CON_ERROR"%s: Unknown 'IBSP' revision\n", fname); return false; } break; @@ -2987,19 +2991,21 @@ qboolean Mod_BSPXRW_Read(struct bspxrw *ctx, const char *fname) ctx->lumpofs = 8; switch(i) { - case BSPVERSION_RBSP: + case BSPVERSION_RBSP: //both rbsp+fbsp are version 1, with the only difference being lightmap sizes. ctx->fg = fg_quake3; ctx->corelumps = 18; corelumpnames = q3corelumpnames; break; default: Mod_BSPXRW_Free(ctx); + Con_Printf(CON_ERROR"%s: Unknown 'RBSP'/'FBSP' revision\n", fname); return false; } break; #endif default: Mod_BSPXRW_Free(ctx); + Con_Printf(CON_ERROR"%s: Unknown file magic\n", fname); return false; } diff --git a/engine/gl/gl_model.c b/engine/gl/gl_model.c index a1cb66887..1cb896c58 100644 --- a/engine/gl/gl_model.c +++ b/engine/gl/gl_model.c @@ -708,18 +708,18 @@ void Mod_Init (qboolean initial) #endif //q2/q3bsps -#if defined(Q2BSPS) || defined(Q3BSPS) -#ifndef Q2BSPS - Mod_RegisterModelFormatMagic(NULL, "Quake3 Map (bsp)", IDBSPHEADER, Mod_LoadQ2BrushModel); -#elif !defined(Q3BSPS) - Mod_RegisterModelFormatMagic(NULL, "Quake2 Map (bsp)", IDBSPHEADER, Mod_LoadQ2BrushModel); -#else - Mod_RegisterModelFormatMagic(NULL, "Quake2/Quake3 Map (bsp)", IDBSPHEADER, Mod_LoadQ2BrushModel); +#ifdef Q3BSPS + Mod_RegisterModelFormatMagic(NULL, "RTCW Map (bsp)", "IBSP\57\0\0\0",8, Mod_LoadQ2BrushModel); + Mod_RegisterModelFormatMagic(NULL, "Quake3 Map (bsp)", "IBSP\56\0\0\0",8, Mod_LoadQ2BrushModel); #endif +#ifdef Q2BSPS + Mod_RegisterModelFormatMagic(NULL, "Quake2 Map (bsp)", "IBSP\46\0\0\0",8, Mod_LoadQ2BrushModel); + Mod_RegisterModelFormatMagic(NULL, "Quake2World Map (bsp)", "IBSP\105\0\0\0",8, Mod_LoadQ2BrushModel); + Mod_RegisterModelFormatMagic(NULL, "Qbism (Quake2) Map (bsp)", "QBSP\46\0\0\0",8, Mod_LoadQ2BrushModel); #endif #ifdef RFBSPS - Mod_RegisterModelFormatMagic(NULL, "Raven Map (bsp)", "RBSP",4, Mod_LoadQ2BrushModel); - Mod_RegisterModelFormatMagic(NULL, "QFusion Map (bsp)", "FBSP",4, Mod_LoadQ2BrushModel); + Mod_RegisterModelFormatMagic(NULL, "Raven Map (bsp)", "RBSP\1\0\0\0",8, Mod_LoadQ2BrushModel); + Mod_RegisterModelFormatMagic(NULL, "QFusion Map (bsp)", "FBSP\1\0\0\0",8, Mod_LoadQ2BrushModel); #endif //doom maps