From 6ba6959205151cb07ce4ed85b0faa344e457fdbe Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 5 Sep 2012 14:02:44 +0900 Subject: [PATCH 01/18] Allow any NxN or 2NxN sky texture for glsl. Maps that specify a skybox often use a fake sky texture, sometimes 16x16. Having a hardcoded requiredment of 256x128 is a tad inappropriate. --- libs/models/brush/glsl_model_brush.c | 48 +++++++++++++++++++++------- 1 file changed, 36 insertions(+), 12 deletions(-) diff --git a/libs/models/brush/glsl_model_brush.c b/libs/models/brush/glsl_model_brush.c index c5388336d..8de370981 100644 --- a/libs/models/brush/glsl_model_brush.c +++ b/libs/models/brush/glsl_model_brush.c @@ -66,6 +66,8 @@ glsl_brush_clear (model_t *m) // NOTE: some maps (eg e1m2) have empty texture slots if (m->textures[i] && m->textures[i]->gl_texturenum) { GLSL_ReleaseTexture (m->textures[i]->gl_texturenum); + GLSL_ReleaseTexture (m->textures[i]->sky_tex[0]); + GLSL_ReleaseTexture (m->textures[i]->sky_tex[1]); m->textures[i]->gl_texturenum = 0; } } @@ -77,6 +79,18 @@ glsl_brush_clear (model_t *m) } } +static int +load_skytex (texture_t *tx, byte *data) +{ + int tex; + + tex = GLSL_LoadQuakeTexture (tx->name, tx->height, tx->height, data); + // GLSL_LoadQuakeTexture () leaves the texture bound + qfeglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + qfeglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + return tex; +} + void glsl_Mod_ProcessTexture (texture_t *tx) { @@ -85,22 +99,32 @@ glsl_Mod_ProcessTexture (texture_t *tx) // wrapping on both sky layers. byte *data; byte *tx_data; + int tx_w, tx_h; int i, j; - if (tx->width != 256 || tx->height != 128) - Sys_Error ("Mod_ProcessTexture: invalid sky texture: %dx%d\n", - tx->width, tx->height); - data = alloca (128 * 128); + tx_w = tx->width; + tx_h = tx->height; tx_data = (byte *)tx + tx->offsets[0]; - for (i = 0; i < 2; i++) { - for (j = 0; j < 128; j++) - memcpy (&data[j * 128], &tx_data[j * 256 + i * 128], 128); - tx->sky_tex[i] = GLSL_LoadQuakeTexture (tx->name, 128, 128, data); - // GLSL_LoadQuakeTexture () leaves the texture bound - qfeglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); - qfeglTexParameteri (GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + if (tx_w == tx_h) { + // a square sky texture probably means it's black, but just in + // case some other magic is being done, duplicate the square to + // both sky layers. + tx->sky_tex[0] = load_skytex (tx, tx_data); + tx->sky_tex[1] = tx->sky_tex[0]; + } else if (tx_w == 2 * tx_h) { + data = alloca (tx_h * tx_h); + for (i = 0; i < 2; i++) { + for (j = 0; j < tx_h; j++) + memcpy (&data[j * tx_h], &tx_data[j * tx_w + i * tx_h], + tx_h); + tx->sky_tex[i] = load_skytex (tx, data); + } + tx->gl_texturenum = 0; + } else { + Sys_Error ("Mod_ProcessTexture: invalid sky texture: %dx%d\n", + tx_w, tx_h); } - tx->gl_texturenum = 0; } else { tx->gl_texturenum = GLSL_LoadQuakeMipTex (tx); } From 69fb78278f6caa6f7612a336bc21121c46532b9b Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 7 Sep 2012 15:45:59 +0900 Subject: [PATCH 02/18] Remove the redundant endian conversions from bsp loading. It's obvious that it's been a very long time since anybody's tried playing QF on a big-endian machine: double converting data isn't good :/ --- libs/models/brush/model_brush.c | 94 +++++++++++++++------------------ 1 file changed, 43 insertions(+), 51 deletions(-) diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index af919f581..d8e0ee43f 100644 --- a/libs/models/brush/model_brush.c +++ b/libs/models/brush/model_brush.c @@ -168,14 +168,11 @@ Mod_LoadTextures (bsp_t *bsp) } m = (dmiptexlump_t *) bsp->texdata; - m->nummiptex = LittleLong (m->nummiptex); - loadmodel->numtextures = m->nummiptex; loadmodel->textures = Hunk_AllocName (m->nummiptex * sizeof (*loadmodel->textures), loadname); for (i = 0; i < m->nummiptex; i++) { - m->dataofs[i] = LittleLong (m->dataofs[i]); if (m->dataofs[i] == -1) continue; mt = (miptex_t *) ((byte *) m + m->dataofs[i]); @@ -323,11 +320,8 @@ Mod_LoadVertexes (bsp_t *bsp) loadmodel->vertexes = out; loadmodel->numvertexes = count; - for (i = 0; i < count; i++, in++, out++) { - out->position[0] = LittleFloat (in->point[0]); - out->position[1] = LittleFloat (in->point[1]); - out->position[2] = LittleFloat (in->point[2]); - } + for (i = 0; i < count; i++, in++, out++) + VectorCopy (in->point, out->position); } static void @@ -344,16 +338,16 @@ Mod_LoadSubmodels (bsp_t *bsp) loadmodel->numsubmodels = count; for (i = 0; i < count; i++, in++, out++) { - 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]); - } + static vec3_t offset = {1, 1, 1}; + // spread the mins / maxs by a pixel + VectorSubtract (in->mins, offset, out->mins); + VectorAdd (in->maxs, offset, out->maxs); + VectorCopy (in->origin, out->origin); for (j = 0; j < MAX_MAP_HULLS; j++) - out->headnode[j] = LittleLong (in->headnode[j]); - out->visleafs = LittleLong (in->visleafs); - out->firstface = LittleLong (in->firstface); - out->numfaces = LittleLong (in->numfaces); + out->headnode[j] = in->headnode[j]; + out->visleafs = in->visleafs; + out->firstface = in->firstface; + out->numfaces = in->numfaces; } out = loadmodel->submodels; @@ -384,8 +378,8 @@ Mod_LoadEdges (bsp_t *bsp) 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]); + out->v[0] = in->v[0]; + out->v[1] = in->v[1]; } } @@ -406,8 +400,8 @@ Mod_LoadTexinfo (bsp_t *bsp) for (i = 0; i < count; i++, in++, out++) { for (j = 0; j < 4; j++) { - out->vecs[0][j] = LittleFloat (in->vecs[0][j]); - out->vecs[1][j] = LittleFloat (in->vecs[1][j]); + out->vecs[0][j] = in->vecs[0][j]; + out->vecs[1][j] = in->vecs[1][j]; } len1 = VectorLength (out->vecs[0]); len2 = VectorLength (out->vecs[1]); @@ -422,8 +416,8 @@ Mod_LoadTexinfo (bsp_t *bsp) else out->mipadjust = 1; - miptex = LittleLong (in->miptex); - out->flags = LittleLong (in->flags); + miptex = in->miptex; + out->flags = in->flags; if (!loadmodel->textures) { out->texture = r_notexture_mip; // checkerboard texture @@ -510,18 +504,18 @@ Mod_LoadFaces (bsp_t *bsp) loadmodel->numsurfaces = count; for (surfnum = 0; surfnum < count; surfnum++, in++, out++) { - out->firstedge = LittleLong (in->firstedge); - out->numedges = LittleShort (in->numedges); + out->firstedge = in->firstedge; + out->numedges = in->numedges; out->flags = 0; - planenum = LittleShort (in->planenum); - side = LittleShort (in->side); + planenum = in->planenum; + side = in->side; if (side) out->flags |= SURF_PLANEBACK; out->plane = loadmodel->planes + planenum; - out->texinfo = loadmodel->texinfo + LittleShort (in->texinfo); + out->texinfo = loadmodel->texinfo + in->texinfo; CalcSurfaceExtents (out); @@ -529,7 +523,7 @@ Mod_LoadFaces (bsp_t *bsp) for (i = 0; i < MAXLIGHTMAPS; i++) out->styles[i] = in->styles[i]; - i = LittleLong (in->lightofs); + i = in->lightofs; if (i == -1) out->samples = NULL; else @@ -593,19 +587,18 @@ Mod_LoadNodes (bsp_t *bsp) 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]); + out->minmaxs[j] = in->mins[j]; + out->minmaxs[3 + j] = in->maxs[j]; } - p = LittleLong (in->planenum); + p = in->planenum; out->plane = loadmodel->planes + p; - out->firstsurface = LittleShort (in->firstface); - out->numsurfaces = LittleShort (in->numfaces); + out->firstsurface = in->firstface; + out->numsurfaces = in->numfaces; for (j = 0; j < 2; j++) { - // handle > 32k nodes. From darkplaces via fitzquake - p = (unsigned short) LittleShort (in->children[j]); + p = (uint16_t) in->children[j]; if (p < count) { out->children[j] = loadmodel->nodes + p; } else { @@ -649,18 +642,17 @@ Mod_LoadLeafs (bsp_t *bsp) isnotmap = false; for (i = 0; i < count; i++, in++, out++) { for (j = 0; j < 3; j++) { - out->mins[j] = LittleShort (in->mins[j]); - out->maxs[j] = LittleShort (in->maxs[j]); + out->mins[j] = in->mins[j]; + out->maxs[j] = in->maxs[j]; } - p = LittleLong (in->contents); + p = in->contents; out->contents = p; - out->firstmarksurface = loadmodel->marksurfaces + - (uint16_t) LittleShort (in->firstmarksurface); - out->nummarksurfaces = (uint16_t) LittleShort (in->nummarksurfaces); + out->firstmarksurface = loadmodel->marksurfaces + in->firstmarksurface; + out->nummarksurfaces = in->nummarksurfaces; - p = LittleLong (in->visofs); + p = in->visofs; if (p == -1) out->compressed_vis = NULL; else @@ -730,11 +722,11 @@ Mod_LoadClipnodes (bsp_t *bsp) hull->clip_maxs[2] = 64; for (i = 0; i < count; i++, out++, in++) { - out->planenum = LittleLong (in->planenum); + out->planenum = in->planenum; if (out->planenum < 0 || out->planenum >= loadmodel->numplanes) Sys_Error ("Mod_LoadClipnodes: planenum out of bounds"); - out->children[0] = (uint16_t) LittleShort (in->children[0]); - out->children[1] = (uint16_t) LittleShort (in->children[1]); + out->children[0] = (uint16_t) in->children[0]; + out->children[1] = (uint16_t) in->children[1]; if (out->children[0] >= count) out->children[0] -= 65536; if (out->children[1] >= count) @@ -807,7 +799,7 @@ Mod_LoadMarksurfaces (bsp_t *bsp) loadmodel->nummarksurfaces = count; for (i = 0; i < count; i++) { - j = (uint16_t) LittleShort (in[i]); + j = in[i]; if (j >= loadmodel->numsurfaces) Sys_Error ("Mod_ParseMarksurfaces: bad surface number"); out[i] = loadmodel->surfaces + j; @@ -829,7 +821,7 @@ Mod_LoadSurfedges (bsp_t *bsp) loadmodel->numsurfedges = count; for (i = 0; i < count; i++) - out[i] = LittleLong (in[i]); + out[i] = in[i]; } static void @@ -849,13 +841,13 @@ Mod_LoadPlanes (bsp_t *bsp) for (i = 0; i < count; i++, in++, out++) { bits = 0; for (j = 0; j < 3; j++) { - out->normal[j] = LittleFloat (in->normal[j]); + out->normal[j] = in->normal[j]; if (out->normal[j] < 0) bits |= 1 << j; } - out->dist = LittleFloat (in->dist); - out->type = LittleLong (in->type); + out->dist = in->dist; + out->type = in->type; out->signbits = bits; } } From a37c5465e12166e9302f285d637f955afa310fef Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 7 Sep 2012 16:09:24 +0900 Subject: [PATCH 03/18] First step for BSP2 support. DOES NOT WORK! All of the nastiness is hidden in bspfile.c (including the old bsp29 specific data types). However, the conversions between bsp29 and bsp2 are implemented but not yet hooked up properly. This commit just gets the data structures in place and the obvious changes necessary to the rest of the engine to get it to compile, plus a few obvious "make it work" changes. --- include/QF/bspfile.h | 39 +-- include/QF/model.h | 6 +- include/asm_draw.h | 4 +- libs/models/brush/model_brush.c | 10 +- libs/util/bspfile.c | 458 ++++++++++++++++++++++++++++++-- libs/video/renderer/r_light.c | 5 +- tools/qfbsp/source/readbsp.c | 8 +- tools/qfbsp/source/surfaces.c | 3 +- tools/qflight/source/vis.c | 7 +- tools/qfvis/source/soundphs.c | 3 +- 10 files changed, 485 insertions(+), 58 deletions(-) diff --git a/include/QF/bspfile.h b/include/QF/bspfile.h index 9dd47d26d..b7683849f 100644 --- a/include/QF/bspfile.h +++ b/include/QF/bspfile.h @@ -45,6 +45,7 @@ //============================================================================= #define BSPVERSION 29 +#define BSP2VERSION "BSP2" // use memcmp with 4 bytes #define Q2BSPVERSION 38 #define TOOLVERSION 2 @@ -133,19 +134,20 @@ typedef struct dplane_s { #define CONTENTS_CURRENT_UP -13 #define CONTENTS_CURRENT_DOWN -14 - +//BSP2 version (bsp 29 version is in bspfile.c) typedef struct dnode_s { int32_t planenum; - int16_t children[2]; // negative numbers are -(leafs+1), not nodes - int16_t mins[3]; // for sphere culling - int16_t maxs[3]; - uint16_t firstface; - uint16_t numfaces; // counting both sides + int32_t children[2]; // negative numbers are -(leafs+1), not nodes + float mins[3]; // for sphere culling + float maxs[3]; + uint32_t firstface; + uint32_t numfaces; // counting both sides } dnode_t; +//BSP2 version (bsp 29 version is in bspfile.c) typedef struct dclipnode_s { int32_t planenum; - int16_t children[2]; // negative numbers are contents + int32_t children[2]; // negative numbers are contents } dclipnode_t; @@ -159,18 +161,20 @@ typedef struct texinfo_s { // note that edge 0 is never used, because negative edge nums are used for // counterclockwise use of the edge in a face +//BSP2 version (bsp 29 version is in bspfile.c) typedef struct dedge_s { - uint16_t v[2]; // vertex numbers + uint32_t v[2]; // vertex numbers } dedge_t; #define MAXLIGHTMAPS 4 +//BSP2 version (bsp 29 version is in bspfile.c) typedef struct dface_s { - int16_t planenum; - int16_t side; + int32_t planenum; + int32_t side; int32_t firstedge; // we must support > 64k edges - int16_t numedges; - int16_t texinfo; + int32_t numedges; + int32_t texinfo; // lighting info byte styles[MAXLIGHTMAPS]; @@ -187,15 +191,16 @@ typedef struct dface_s { // leaf 0 is the generic CONTENTS_SOLID leaf, used for all solid areas // all other leafs need visibility info +//BSP2 version (bsp 29 version is in bspfile.c) typedef struct dleaf_s { int32_t contents; int32_t visofs; // -1 = no visibility info - int16_t mins[3]; // for frustum culling - int16_t maxs[3]; + float mins[3]; // for frustum culling + float maxs[3]; - uint16_t firstmarksurface; - uint16_t nummarksurfaces; + uint32_t firstmarksurface; + uint32_t nummarksurfaces; byte ambient_level[NUM_AMBIENTS]; } dleaf_t; @@ -260,7 +265,7 @@ typedef struct bsp_s { int own_marksurfaces; int nummarksurfaces; - uint16_t *marksurfaces; + uint32_t *marksurfaces; int own_surfedges; int numsurfedges; diff --git a/include/QF/model.h b/include/QF/model.h index a241fd922..f60664fab 100644 --- a/include/QF/model.h +++ b/include/QF/model.h @@ -121,7 +121,7 @@ typedef struct texture_s { // !!! if this is changed, it must be changed in asm_draw.h too !!! typedef struct { - unsigned short v[2]; + unsigned int v[2]; unsigned int cachededgeoffset; } medge_t; @@ -192,8 +192,8 @@ typedef struct mnode_s { plane_t *plane; struct mnode_s *children[2]; - unsigned short firstsurface; - unsigned short numsurfaces; + unsigned int firstsurface; + unsigned int numsurfaces; } mnode_t; typedef struct mleaf_s { diff --git a/include/asm_draw.h b/include/asm_draw.h index bc9efd06c..ec6d99283 100644 --- a/include/asm_draw.h +++ b/include/asm_draw.h @@ -108,8 +108,8 @@ // medge_t structure // !!! if this is changed, it must be changed in model.h too !!! #define me_v 0 -#define me_cachededgeoffset 4 -#define me_size 8 +#define me_cachededgeoffset 8 +#define me_size 12 // mvertex_t structure // !!! if this is changed, it must be changed in model.h too !!! diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index d8e0ee43f..50b627597 100644 --- a/libs/models/brush/model_brush.c +++ b/libs/models/brush/model_brush.c @@ -598,7 +598,8 @@ Mod_LoadNodes (bsp_t *bsp) out->numsurfaces = in->numfaces; for (j = 0; j < 2; j++) { - p = (uint16_t) in->children[j]; + p = in->children[j]; + // this check is for extended bsp 29 files if (p < count) { out->children[j] = loadmodel->nodes + p; } else { @@ -725,8 +726,9 @@ Mod_LoadClipnodes (bsp_t *bsp) out->planenum = in->planenum; if (out->planenum < 0 || out->planenum >= loadmodel->numplanes) Sys_Error ("Mod_LoadClipnodes: planenum out of bounds"); - out->children[0] = (uint16_t) in->children[0]; - out->children[1] = (uint16_t) in->children[1]; + out->children[0] = in->children[0]; + out->children[1] = in->children[1]; + // these checks are for extended bsp 29 files if (out->children[0] >= count) out->children[0] -= 65536; if (out->children[1] >= count) @@ -783,7 +785,7 @@ Mod_LoadMarksurfaces (bsp_t *bsp) { int count, i, j; msurface_t **out; - uint16_t *in; + uint32_t *in; in = bsp->marksurfaces; count = bsp->nummarksurfaces; diff --git a/libs/util/bspfile.c b/libs/util/bspfile.c index f5807f71b..7c1986a17 100644 --- a/libs/util/bspfile.c +++ b/libs/util/bspfile.c @@ -43,6 +43,409 @@ #include "QF/quakefs.h" #include "QF/sys.h" +typedef struct dnode29_s { + int32_t planenum; + int16_t children[2]; // negative numbers are -(leafs+1), not nodes + int16_t mins[3]; // for sphere culling + int16_t maxs[3]; + uint16_t firstface; + uint16_t numfaces; // counting both sides +} dnode29_t; + +typedef struct dclipnode29_s { + int32_t planenum; + int16_t children[2]; // negative numbers are contents +} dclipnode29_t; + +typedef struct dedge29_s { + uint16_t v[2]; // vertex numbers +} dedge29_t; + +typedef struct dface29_s { + int16_t planenum; + int16_t side; + + int32_t firstedge; // we must support > 64k edges + int16_t numedges; + int16_t texinfo; + +// lighting info + byte styles[MAXLIGHTMAPS]; + int32_t lightofs; // start of [numstyles*surfsize] samples +} dface29_t; + +typedef struct dleaf29_s { + int32_t contents; + int32_t visofs; // -1 = no visibility info + + int16_t mins[3]; // for frustum culling + int16_t maxs[3]; + + uint16_t firstmarksurface; + uint16_t nummarksurfaces; + + byte ambient_level[NUM_AMBIENTS]; +} dleaf29_t; + +typedef struct bsp29_s { + int own_header; + dheader_t *header; + + int own_models; + int nummodels; + dmodel_t *models; + + int own_visdata; + size_t visdatasize; + byte *visdata; + + int own_lightdata; + size_t lightdatasize; + byte *lightdata; + + int own_texdata; + size_t texdatasize; + byte *texdata; // (dmiptexlump_t) + + int own_entdata; + size_t entdatasize; + char *entdata; + + int own_leafs; + int numleafs; + dleaf29_t *leafs; + + int own_planes; + int numplanes; + dplane_t *planes; + + int own_vertexes; + int numvertexes; + dvertex_t *vertexes; + + int own_nodes; + int numnodes; + dnode29_t *nodes; + + int own_texinfo; + int numtexinfo; + texinfo_t *texinfo; + + int own_faces; + int numfaces; + dface29_t *faces; + + int own_clipnodes; + int numclipnodes; + dclipnode29_t *clipnodes; + + int own_edges; + int numedges; + dedge29_t *edges; + + int own_marksurfaces; + int nummarksurfaces; + uint16_t *marksurfaces; + + int own_surfedges; + int numsurfedges; + int32_t *surfedges; +} bsp29_t; + +static void +swap_to_bsp29 (bsp29_t *bsp29, const bsp_t *bsp2) +{ + int c, i, j; + dmiptexlump_t *mtl; + dmodel_t *d; + + if (bsp2->header && bsp29->header) { + bsp29->header->version = LittleLong (bsp2->header->version); + for (i = 0; i < HEADER_LUMPS; i++) { + bsp29->header->lumps[i].fileofs = + LittleLong (bsp2->header->lumps[i].fileofs); + bsp29->header->lumps[i].filelen = + LittleLong (bsp2->header->lumps[i].filelen); + } + } + + // models + for (i=0 ; inummodels ; i++) { + d = &bsp29->models[i]; + + for (j=0 ; jheadnode[j] = LittleLong (d->headnode[j]); + + d->visleafs = LittleLong (d->visleafs); + d->firstface = LittleLong (d->firstface); + d->numfaces = LittleLong (d->numfaces); + + for (j=0 ; j<3 ; j++) { + d->mins[j] = LittleFloat(d->mins[j]); + d->maxs[j] = LittleFloat(d->maxs[j]); + d->origin[j] = LittleFloat(d->origin[j]); + } + } + + // vertexes + for (i=0 ; inumvertexes ; i++) { + dvertex_t *vertex = &bsp29->vertexes[i]; + for (j=0 ; j<3 ; j++) + vertex->point[j] = LittleFloat (vertex->point[j]); + } + + // planes + for (i=0 ; inumplanes ; i++) { + dplane_t *plane = &bsp29->planes[i]; + for (j=0 ; j<3 ; j++) + plane->normal[j] = LittleFloat (plane->normal[j]); + plane->dist = LittleFloat (plane->dist); + plane->type = LittleLong (plane->type); + } + + // texinfos + for (i=0 ; inumtexinfo ; i++) { + texinfo_t *texinfo = &bsp29->texinfo[i]; + for (j=0 ; j<8 ; j++) + texinfo->vecs[0][j] = LittleFloat (texinfo->vecs[0][j]); + texinfo->miptex = LittleLong (texinfo->miptex); + texinfo->flags = LittleLong (texinfo->flags); + } + + // faces + for (i=0 ; inumfaces ; i++) { + const dface_t *face2 = &bsp2->faces[i]; + dface29_t *face29 = &bsp29->faces[i]; + face29->planenum = LittleShort (face2->planenum); + face29->side = LittleShort (face2->side); + face29->firstedge = LittleLong (face2->firstedge); + face29->numedges = LittleShort (face2->numedges); + face29->texinfo = LittleShort (face2->texinfo); + memcpy (face29->styles, face2->styles, sizeof(face29->styles)); + face29->lightofs = LittleLong (face2->lightofs); + } + + // nodes + for (i=0 ; inumnodes ; i++) { + const dnode_t *node2 = &bsp2->nodes[i]; + dnode29_t *node29 = &bsp29->nodes[i]; + node29->planenum = LittleLong (node2->planenum); + for (j=0 ; j<3 ; j++) { + node29->mins[j] = LittleShort (node2->mins[j]); + node29->maxs[j] = LittleShort (node2->maxs[j]); + } + node29->children[0] = LittleShort (node2->children[0]); + node29->children[1] = LittleShort (node2->children[1]); + node29->firstface = LittleShort (node2->firstface); + node29->numfaces = LittleShort (node2->numfaces); + } + + // leafs + for (i=0 ; inumleafs ; i++) { + const dleaf_t *leaf2 = &bsp2->leafs[i]; + dleaf29_t *leaf29 = &bsp29->leafs[i]; + leaf29->contents = LittleLong (leaf2->contents); + for (j=0 ; j<3 ; j++) { + leaf29->mins[j] = LittleShort (leaf2->mins[j]); + leaf29->maxs[j] = LittleShort (leaf2->maxs[j]); + } + + leaf29->firstmarksurface = LittleShort (leaf2->firstmarksurface); + leaf29->nummarksurfaces = LittleShort (leaf2->nummarksurfaces); + leaf29->visofs = LittleLong (leaf2->visofs); + memcpy (leaf29->ambient_level, leaf2->ambient_level, + sizeof(leaf29->ambient_level)); + } + + // clipnodes + for (i=0 ; inumclipnodes ; i++) { + const dclipnode_t *clipnode2 = &bsp2->clipnodes[i]; + dclipnode29_t *clipnode29 = (dclipnode29_t *) &bsp29->clipnodes[i]; + clipnode29->planenum = LittleLong (clipnode2->planenum); + clipnode29->children[0] = LittleShort (clipnode2->children[0]); + clipnode29->children[1] = LittleShort (clipnode2->children[1]); + } + + // miptex + if (bsp29->texdatasize) { + mtl = (dmiptexlump_t *)bsp29->texdata; + //miptexlumps have not yet been swapped + c = mtl->nummiptex; + mtl->nummiptex = LittleLong (mtl->nummiptex); + for (i=0 ; idataofs[i] = LittleLong(mtl->dataofs[i]); + } + + // marksurfaces + for (i=0 ; inummarksurfaces ; i++) { + const uint32_t *marksurface2 = &bsp2->marksurfaces[i]; + uint16_t *marksurface29 = (uint16_t *) &bsp29->marksurfaces[i]; + *marksurface29 = LittleShort (*marksurface2); + } + + // surfedges + for (i=0 ; inumsurfedges ; i++) { + int32_t *surfedge = &bsp29->surfedges[i]; + *surfedge = LittleLong (*surfedge); + } + + // edges + for (i=0 ; inumedges ; i++) { + const dedge_t *edge2 = &bsp2->edges[i]; + dedge29_t *edge29 = (dedge29_t *) &bsp29->edges[i]; + edge29->v[0] = LittleShort (edge2->v[0]); + edge29->v[1] = LittleShort (edge2->v[1]); + } +} + +static void +swap_from_bsp29 (bsp_t *bsp2, const bsp29_t *bsp29, + void (*cb) (const bsp_t *, void *), void *cbdata) +{ + int c, i, j; + dmiptexlump_t *mtl; + dmodel_t *d; + + if (bsp2->header) { + bsp2->header->version = LittleLong (bsp2->header->version); + for (i = 0; i < HEADER_LUMPS; i++) { + bsp2->header->lumps[i].fileofs = + LittleLong (bsp2->header->lumps[i].fileofs); + bsp2->header->lumps[i].filelen = + LittleLong (bsp2->header->lumps[i].filelen); + } + if (cb) + cb (bsp2, cbdata); + } + + // models + for (i=0 ; inummodels ; i++) { + d = &bsp2->models[i]; + + for (j=0 ; jheadnode[j] = LittleLong (d->headnode[j]); + + d->visleafs = LittleLong (d->visleafs); + d->firstface = LittleLong (d->firstface); + d->numfaces = LittleLong (d->numfaces); + + for (j=0 ; j<3 ; j++) { + d->mins[j] = LittleFloat(d->mins[j]); + d->maxs[j] = LittleFloat(d->maxs[j]); + d->origin[j] = LittleFloat(d->origin[j]); + } + } + + // vertexes + for (i=0 ; inumvertexes ; i++) { + dvertex_t *vertex = &bsp2->vertexes[i]; + for (j=0 ; j<3 ; j++) + vertex->point[j] = LittleFloat (vertex->point[j]); + } + + // planes + for (i=0 ; inumplanes ; i++) { + dplane_t *plane = &bsp2->planes[i]; + for (j=0 ; j<3 ; j++) + plane->normal[j] = LittleFloat (plane->normal[j]); + plane->dist = LittleFloat (plane->dist); + plane->type = LittleLong (plane->type); + } + + // texinfos + for (i=0 ; inumtexinfo ; i++) { + texinfo_t *texinfo = &bsp2->texinfo[i]; + for (j=0 ; j<8 ; j++) + texinfo->vecs[0][j] = LittleFloat (texinfo->vecs[0][j]); + texinfo->miptex = LittleLong (texinfo->miptex); + texinfo->flags = LittleLong (texinfo->flags); + } + + // faces + for (i=0 ; inumfaces ; i++) { + dface_t *face2 = &bsp2->faces[i]; + const dface29_t *face29 = &bsp29->faces[i]; + face2->planenum = LittleShort (face29->planenum); + face2->side = LittleShort (face29->side); + face2->firstedge = LittleLong (face29->firstedge); + face2->numedges = LittleShort (face29->numedges); + face2->texinfo = LittleShort (face29->texinfo); + memcpy (face2->styles, face29->styles, sizeof(face2->styles)); + face2->lightofs = LittleLong (face29->lightofs); + } + + // nodes + for (i=0 ; inumnodes ; i++) { + dnode_t *node2 = &bsp2->nodes[i]; + const dnode29_t *node29 = &bsp29->nodes[i]; + node2->planenum = LittleLong (node29->planenum); + for (j=0 ; j<3 ; j++) { + node2->mins[j] = LittleShort (node29->mins[j]); + node2->maxs[j] = LittleShort (node29->maxs[j]); + } + node2->children[0] = LittleShort (node29->children[0]); + node2->children[1] = LittleShort (node29->children[1]); + node2->firstface = LittleShort (node29->firstface); + node2->numfaces = LittleShort (node29->numfaces); + } + + // leafs + for (i=0 ; inumleafs ; i++) { + dleaf_t *leaf2 = &bsp2->leafs[i]; + const dleaf29_t *leaf29 = &bsp29->leafs[i]; + leaf2->contents = LittleLong (leaf29->contents); + for (j=0 ; j<3 ; j++) { + leaf2->mins[j] = LittleShort (leaf29->mins[j]); + leaf2->maxs[j] = LittleShort (leaf29->maxs[j]); + } + + leaf2->firstmarksurface = LittleShort (leaf29->firstmarksurface); + leaf2->nummarksurfaces = LittleShort (leaf29->nummarksurfaces); + leaf2->visofs = LittleLong (leaf29->visofs); + memcpy (leaf2->ambient_level, leaf29->ambient_level, + sizeof(leaf2->ambient_level)); + } + + // clipnodes + for (i=0 ; inumclipnodes ; i++) { + dclipnode_t *clipnode2 = &bsp2->clipnodes[i]; + const dclipnode29_t *clipnode29 = &bsp29->clipnodes[i]; + clipnode2->planenum = LittleLong (clipnode29->planenum); + clipnode2->children[0] = LittleShort (clipnode29->children[0]); + clipnode2->children[1] = LittleShort (clipnode29->children[1]); + } + + // miptex + if (bsp2->texdatasize) { + mtl = (dmiptexlump_t *)bsp2->texdata; + c = LittleLong(mtl->nummiptex); + mtl->nummiptex = LittleLong (mtl->nummiptex); + for (i=0 ; idataofs[i] = LittleLong(mtl->dataofs[i]); + } + + // marksurfaces + for (i=0 ; inummarksurfaces ; i++) { + uint32_t *marksurface2 = &bsp2->marksurfaces[i]; + const uint16_t *marksurface29 = &bsp29->marksurfaces[i]; + *marksurface2 = LittleShort (*marksurface29); + } + + // surfedges + for (i=0 ; inumsurfedges ; i++) { + int32_t *surfedge = &bsp2->surfedges[i]; + *surfedge = LittleLong (*surfedge); + } + + // edges + for (i=0 ; inumedges ; i++) { + dedge_t *edge2 = &bsp2->edges[i]; + const dedge29_t *edge29 = &bsp29->edges[i]; + edge2->v[0] = LittleShort (edge29->v[0]); + edge2->v[1] = LittleShort (edge29->v[1]); + } +} + static void swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), void *cbdata) @@ -109,12 +512,12 @@ swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), // faces for (i=0 ; inumfaces ; i++) { dface_t *face = &bsp->faces[i]; - face->texinfo = LittleShort (face->texinfo); - face->planenum = LittleShort (face->planenum); - face->side = LittleShort (face->side); + face->texinfo = LittleLong (face->texinfo); + face->planenum = LittleLong (face->planenum); + face->side = LittleLong (face->side); face->lightofs = LittleLong (face->lightofs); face->firstedge = LittleLong (face->firstedge); - face->numedges = LittleShort (face->numedges); + face->numedges = LittleLong (face->numedges); } // nodes @@ -122,11 +525,11 @@ swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), dnode_t *node = &bsp->nodes[i]; node->planenum = LittleLong (node->planenum); for (j=0 ; j<3 ; j++) { - node->mins[j] = LittleShort (node->mins[j]); - node->maxs[j] = LittleShort (node->maxs[j]); + node->mins[j] = LittleFloat (node->mins[j]); + node->maxs[j] = LittleFloat (node->maxs[j]); } - node->children[0] = LittleShort (node->children[0]); - node->children[1] = LittleShort (node->children[1]); + node->children[0] = LittleLong (node->children[0]); + node->children[1] = LittleLong (node->children[1]); node->firstface = LittleShort (node->firstface); node->numfaces = LittleShort (node->numfaces); } @@ -136,12 +539,12 @@ swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), dleaf_t *leaf = &bsp->leafs[i]; leaf->contents = LittleLong (leaf->contents); for (j=0 ; j<3 ; j++) { - leaf->mins[j] = LittleShort (leaf->mins[j]); - leaf->maxs[j] = LittleShort (leaf->maxs[j]); + leaf->mins[j] = LittleFloat (leaf->mins[j]); + leaf->maxs[j] = LittleFloat (leaf->maxs[j]); } - leaf->firstmarksurface = LittleShort (leaf->firstmarksurface); - leaf->nummarksurfaces = LittleShort (leaf->nummarksurfaces); + leaf->firstmarksurface = LittleLong (leaf->firstmarksurface); + leaf->nummarksurfaces = LittleLong (leaf->nummarksurfaces); leaf->visofs = LittleLong (leaf->visofs); } @@ -149,8 +552,8 @@ swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), for (i=0 ; inumclipnodes ; i++) { dclipnode_t *clipnode = &bsp->clipnodes[i]; clipnode->planenum = LittleLong (clipnode->planenum); - clipnode->children[0] = LittleShort (clipnode->children[0]); - clipnode->children[1] = LittleShort (clipnode->children[1]); + clipnode->children[0] = LittleLong (clipnode->children[0]); + clipnode->children[1] = LittleLong (clipnode->children[1]); } // miptex @@ -167,8 +570,8 @@ swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), // marksurfaces for (i=0 ; inummarksurfaces ; i++) { - uint16_t *marksurface = &bsp->marksurfaces[i]; - *marksurface = LittleShort (*marksurface); + uint32_t *marksurface = &bsp->marksurfaces[i]; + *marksurface = LittleLong (*marksurface); } // surfedges @@ -180,8 +583,8 @@ swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), // edges for (i=0 ; inumedges ; i++) { dedge_t *edge = &bsp->edges[i]; - edge->v[0] = LittleShort (edge->v[0]); - edge->v[1] = LittleShort (edge->v[1]); + edge->v[0] = LittleLong (edge->v[0]); + edge->v[1] = LittleLong (edge->v[1]); } } @@ -191,14 +594,18 @@ LoadBSPMem (void *mem, size_t mem_size, void (*cb) (const bsp_t *, void *), { bsp_t *bsp; int version; + qboolean bsp2 = false; bsp = calloc (sizeof (bsp_t), 1); bsp->header = mem; version = LittleLong (bsp->header->version); - if (version != BSPVERSION) - Sys_Error ("version %i, not %i", version, BSPVERSION); + if (!memcmp (&bsp->header->version, BSP2VERSION, 4)) { + bsp2 = true; + } else if (version != BSPVERSION) + Sys_Error ("version %i, neither %i nor %s", version, BSPVERSION, + BSP2VERSION); #undef SET_LUMP #define SET_LUMP(l,n) \ @@ -247,7 +654,10 @@ do { \ SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); - swap_bsp (bsp, 0, cb, cbdata); + if (bsp2) + swap_bsp (bsp, 0, cb, cbdata); + else + swap_from_bsp29 (bsp, 0, cb, cbdata);//FIXME return bsp; } @@ -273,6 +683,7 @@ WriteBSPFile (const bsp_t *bsp, QFile *file) size_t size; byte *data; bsp_t tbsp; + qboolean bsp2 = false; #define ROUND(x) (((x) + 3) & ~3) @@ -349,7 +760,10 @@ do { \ SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); - swap_bsp (&tbsp, 1, 0, 0); + if (bsp2) + swap_bsp (&tbsp, 1, 0, 0); + else + swap_to_bsp29 (0, &tbsp); //FIXME Qwrite (file, tbsp.header, size); free (tbsp.header); diff --git a/libs/video/renderer/r_light.c b/libs/video/renderer/r_light.c index db9ff436f..6faad5e1e 100644 --- a/libs/video/renderer/r_light.c +++ b/libs/video/renderer/r_light.c @@ -204,7 +204,7 @@ void R_RecursiveMarkLights (const vec3_t lightorigin, dlight_t *light, int lightnum, mnode_t *node) { - int i; + unsigned i; float ndist, maxdist; plane_t *splitplane; msurface_t *surf; @@ -400,7 +400,8 @@ calc_lighting_3 (msurface_t *surf, int ds, int dt) static int RecursiveLightPoint (mnode_t *node, const vec3_t start, const vec3_t end) { - int i, r, s, t, ds, dt, side; + unsigned i; + int r, s, t, ds, dt, side; float front, back, frac; plane_t *plane; msurface_t *surf; diff --git a/tools/qfbsp/source/readbsp.c b/tools/qfbsp/source/readbsp.c index 3a7df973c..4168a2ae5 100644 --- a/tools/qfbsp/source/readbsp.c +++ b/tools/qfbsp/source/readbsp.c @@ -66,7 +66,7 @@ texinfo_t *texinfo; dvertex_t *vertices; dedge_t *edges; int *surfedges; -unsigned short *marksurfaces; +uint32_t *marksurfaces; static brushset_t bs; static void @@ -161,7 +161,8 @@ static void load_leafs (void) { const dleaf_t *l; - int i, j; + int i; + unsigned j; leafs = calloc (bsp->numleafs, sizeof (node_t)); for (i = 0; i < bsp->numleafs; i++) { @@ -184,7 +185,8 @@ load_nodes (void) { const dnode_t *n; face_t *f; - int i, j; + int i; + unsigned j; nodes = calloc (bsp->numnodes, sizeof (node_t)); for (i = 0; i < bsp->numnodes; i++) { diff --git a/tools/qfbsp/source/surfaces.c b/tools/qfbsp/source/surfaces.c index 1c704925a..9c467c0e1 100644 --- a/tools/qfbsp/source/surfaces.c +++ b/tools/qfbsp/source/surfaces.c @@ -344,7 +344,8 @@ static int GetEdge (const vec3_t p1, const vec3_t p2, face_t *f) { dedge_t edge; - int v1, v2, i; + unsigned v1, v2; + int i; if (!f->contents[0]) Sys_Error ("GetEdge: 0 contents"); diff --git a/tools/qflight/source/vis.c b/tools/qflight/source/vis.c index 855fac463..cba4cd971 100644 --- a/tools/qflight/source/vis.c +++ b/tools/qflight/source/vis.c @@ -143,8 +143,9 @@ VisEntity (int ent_index) entity_t *entity = entities + ent_index; dleaf_t *leaf; int ignorevis = false; - int i, j; - unsigned short *mark; + int i; + unsigned j; + uint32_t *mark; byte *vis, *surfacehit; int vis_size; @@ -202,7 +203,7 @@ VisEntity (int ent_index) } } for (i = 1; i < bsp->nummodels; i++) { - for (j = 0; j < bsp->models[i].numfaces; j++) { + for (j = 0; (int) j < bsp->models[i].numfaces; j++) { //FIXME vis mark_face (bsp->models[i].firstface + j, surfacehit, entity); } diff --git a/tools/qfvis/source/soundphs.c b/tools/qfvis/source/soundphs.c index c7cd0642d..086e453cc 100644 --- a/tools/qfvis/source/soundphs.c +++ b/tools/qfvis/source/soundphs.c @@ -94,7 +94,8 @@ void CalcAmbientSounds (void) { byte *vis; - int ambient_type, ofs, i, j, k, l; + int ambient_type, ofs, i, j, l; + unsigned k; float maxd, vol, d; float dists[NUM_AMBIENTS]; dface_t *surf; From 3df85a6abe54d9453877af84142b2a4ecdd8b2a4 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 7 Sep 2012 17:37:46 +0900 Subject: [PATCH 04/18] Fix reading bsp29 files. --- libs/util/bspfile.c | 138 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 109 insertions(+), 29 deletions(-) diff --git a/libs/util/bspfile.c b/libs/util/bspfile.c index 7c1986a17..a0030b05f 100644 --- a/libs/util/bspfile.c +++ b/libs/util/bspfile.c @@ -234,8 +234,8 @@ swap_to_bsp29 (bsp29_t *bsp29, const bsp_t *bsp2) node29->mins[j] = LittleShort (node2->mins[j]); node29->maxs[j] = LittleShort (node2->maxs[j]); } - node29->children[0] = LittleShort (node2->children[0]); - node29->children[1] = LittleShort (node2->children[1]); + node29->children[0] = (uint16_t) LittleShort (node2->children[0]); + node29->children[1] = (uint16_t) LittleShort (node2->children[1]); node29->firstface = LittleShort (node2->firstface); node29->numfaces = LittleShort (node2->numfaces); } @@ -262,8 +262,8 @@ swap_to_bsp29 (bsp29_t *bsp29, const bsp_t *bsp2) const dclipnode_t *clipnode2 = &bsp2->clipnodes[i]; dclipnode29_t *clipnode29 = (dclipnode29_t *) &bsp29->clipnodes[i]; clipnode29->planenum = LittleLong (clipnode2->planenum); - clipnode29->children[0] = LittleShort (clipnode2->children[0]); - clipnode29->children[1] = LittleShort (clipnode2->children[1]); + clipnode29->children[0] = (uint16_t) LittleShort (clipnode2->children[0]); + clipnode29->children[1] = (uint16_t) LittleShort (clipnode2->children[1]); } // miptex @@ -383,8 +383,8 @@ swap_from_bsp29 (bsp_t *bsp2, const bsp29_t *bsp29, node2->mins[j] = LittleShort (node29->mins[j]); node2->maxs[j] = LittleShort (node29->maxs[j]); } - node2->children[0] = LittleShort (node29->children[0]); - node2->children[1] = LittleShort (node29->children[1]); + node2->children[0] = (uint16_t) LittleShort (node29->children[0]); + node2->children[1] = (uint16_t) LittleShort (node29->children[1]); node2->firstface = LittleShort (node29->firstface); node2->numfaces = LittleShort (node29->numfaces); } @@ -411,8 +411,8 @@ swap_from_bsp29 (bsp_t *bsp2, const bsp29_t *bsp29, dclipnode_t *clipnode2 = &bsp2->clipnodes[i]; const dclipnode29_t *clipnode29 = &bsp29->clipnodes[i]; clipnode2->planenum = LittleLong (clipnode29->planenum); - clipnode2->children[0] = LittleShort (clipnode29->children[0]); - clipnode2->children[1] = LittleShort (clipnode29->children[1]); + clipnode2->children[0] = (uint16_t) LittleShort (clipnode29->children[0]); + clipnode2->children[1] = (uint16_t) LittleShort (clipnode29->children[1]); } // miptex @@ -588,25 +588,9 @@ swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), } } -bsp_t * -LoadBSPMem (void *mem, size_t mem_size, void (*cb) (const bsp_t *, void *), - void *cbdata) +static void +set_bsp2_read (void *mem, size_t mem_size, bsp_t *bsp) { - bsp_t *bsp; - int version; - qboolean bsp2 = false; - - bsp = calloc (sizeof (bsp_t), 1); - - bsp->header = mem; - - version = LittleLong (bsp->header->version); - if (!memcmp (&bsp->header->version, BSP2VERSION, 4)) { - bsp2 = true; - } else if (version != BSPVERSION) - Sys_Error ("version %i, neither %i nor %s", version, BSPVERSION, - BSP2VERSION); - #undef SET_LUMP #define SET_LUMP(l,n) \ do { \ @@ -653,11 +637,107 @@ do { \ SET_LUMP (LUMP_VISIBILITY, visdata); SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); +} - if (bsp2) +static void +set_bsp29_read (void *mem, size_t mem_size, bsp29_t *bsp29) +{ +#undef SET_LUMP +#define SET_LUMP(l,n) \ +do { \ + size_t size = LittleLong (bsp29->header->lumps[l].filelen); \ + size_t offs = LittleLong (bsp29->header->lumps[l].fileofs); \ + void *data = (byte *) mem + offs; \ + if (offs >= mem_size || (offs + size) > mem_size) \ + Sys_Error ("invalid lump"); \ + if (size % sizeof (bsp29->n[0])) \ + Sys_Error ("funny lump size"); \ + bsp29->n = 0; \ + if (size) \ + bsp29->n = (void *) data; \ + bsp29->num##n = size / sizeof (bsp29->n[0]); \ +} while (0) + + SET_LUMP (LUMP_PLANES, planes); + SET_LUMP (LUMP_LEAFS, leafs); + SET_LUMP (LUMP_VERTEXES, vertexes); + SET_LUMP (LUMP_NODES, nodes); + SET_LUMP (LUMP_TEXINFO, texinfo); + SET_LUMP (LUMP_FACES, faces); + SET_LUMP (LUMP_CLIPNODES, clipnodes); + SET_LUMP (LUMP_MARKSURFACES, marksurfaces); + SET_LUMP (LUMP_SURFEDGES, surfedges); + SET_LUMP (LUMP_EDGES, edges); + SET_LUMP (LUMP_MODELS, models); + +#undef SET_LUMP +#define SET_LUMP(l,n) \ +do { \ + size_t size = LittleLong (bsp29->header->lumps[l].filelen); \ + size_t offs = LittleLong (bsp29->header->lumps[l].fileofs); \ + void *data = (byte *) mem + offs; \ + if (offs >= mem_size || (offs + size) > mem_size) \ + Sys_Error ("invalid lump"); \ + bsp29->n = 0; \ + if (size) \ + bsp29->n = (void *) data; \ + bsp29->n##size = size; \ +} while (0) + + SET_LUMP (LUMP_LIGHTING, lightdata); + SET_LUMP (LUMP_VISIBILITY, visdata); + SET_LUMP (LUMP_ENTITIES, entdata); + SET_LUMP (LUMP_TEXTURES, texdata); +} + +bsp_t * +LoadBSPMem (void *mem, size_t mem_size, void (*cb) (const bsp_t *, void *), + void *cbdata) +{ + bsp_t *bsp; + int version; + qboolean bsp2 = false; + + bsp = calloc (sizeof (bsp_t), 1); + + bsp->header = mem; + + version = LittleLong (bsp->header->version); + if (!memcmp (&bsp->header->version, BSP2VERSION, 4)) { + bsp2 = true; + } else if (version != BSPVERSION) + Sys_Error ("version %i, neither %i nor %s", version, BSPVERSION, + BSP2VERSION); + + if (bsp2) { + set_bsp2_read (mem, mem_size, bsp); swap_bsp (bsp, 0, cb, cbdata); - else - swap_from_bsp29 (bsp, 0, cb, cbdata);//FIXME + } else { + bsp29_t bsp29; + + if (sizeof (bsp29) != sizeof (*bsp)) + Sys_Error ("taniwha's being lazy about bsp29 support"); + memcpy (&bsp29, bsp, sizeof (bsp29)); + set_bsp29_read (mem, mem_size, &bsp29); + memcpy (bsp, &bsp29, sizeof (bsp29)); + +#undef SET_LUMP +#define SET_LUMP(n) \ +do { \ + if (bsp->num##n) {\ + bsp->n = (void *) malloc (bsp->num##n * sizeof (bsp->n[0])); \ + bsp->own_##n = 1; \ + } \ +} while (0) + + SET_LUMP (nodes); + SET_LUMP (clipnodes); + SET_LUMP (edges); + SET_LUMP (faces); + SET_LUMP (leafs); + SET_LUMP (marksurfaces); + swap_from_bsp29 (bsp, &bsp29, cb, cbdata); + } return bsp; } From 2d30cddc6604fdd02c653dcdbf888534b7fd75f9 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 7 Sep 2012 18:27:20 +0900 Subject: [PATCH 05/18] Implement bsp2/bsp29 writing. It's ugly, inefficient, and untested, but it should work. --- libs/util/bspfile.c | 198 +++++++++++++++++++++++++++++++++++--------- 1 file changed, 158 insertions(+), 40 deletions(-) diff --git a/libs/util/bspfile.c b/libs/util/bspfile.c index a0030b05f..9ac610e86 100644 --- a/libs/util/bspfile.c +++ b/libs/util/bspfile.c @@ -754,20 +754,17 @@ LoadBSPFile (QFile *file, size_t size) return bsp; } -/* - WriteBSPFile -*/ -VISIBLE void -WriteBSPFile (const bsp_t *bsp, QFile *file) +#define ROUND(x) (((x) + 3) & ~3) + +static bsp_t * +set_bsp2_write (const bsp_t *bsp, size_t *_size) { size_t size; byte *data; - bsp_t tbsp; - qboolean bsp2 = false; + bsp_t *tbsp; -#define ROUND(x) (((x) + 3) & ~3) - - size = ROUND (sizeof (dheader_t)); + size = sizeof (*tbsp); + size += ROUND (sizeof (dheader_t)); size += ROUND (bsp->nummodels * sizeof (dmodel_t)); size += ROUND (bsp->visdatasize); size += ROUND (bsp->lightdatasize); @@ -781,31 +778,32 @@ WriteBSPFile (const bsp_t *bsp, QFile *file) size += ROUND (bsp->numfaces * sizeof (dface_t)); size += ROUND (bsp->numclipnodes * sizeof (dclipnode_t)); size += ROUND (bsp->numedges * sizeof (dedge_t)); - size += ROUND (bsp->nummarksurfaces * sizeof (uint16_t)); + size += ROUND (bsp->nummarksurfaces * sizeof (uint32_t)); size += ROUND (bsp->numsurfedges * sizeof (uint32_t)); - tbsp.header = calloc (size, 1); + tbsp = calloc (size, 1); + tbsp->header = (dheader_t *) &tbsp[1]; #undef SET_LUMP #define SET_LUMP(l,n) \ do { \ - tbsp.num##n = bsp->num##n; \ - if (tbsp.num##n) {\ - tbsp.n = (void *) data; \ - tbsp.header->lumps[l].fileofs = data - (byte *) tbsp.header; \ - tbsp.header->lumps[l].filelen = tbsp.num##n * sizeof (bsp->n[0]); \ - memcpy (data, bsp->n, tbsp.header->lumps[l].filelen); \ - data += ROUND (tbsp.header->lumps[l].filelen); \ + tbsp->num##n = bsp->num##n; \ + if (tbsp->num##n) {\ + tbsp->n = (void *) data; \ + tbsp->header->lumps[l].fileofs = data - (byte *) tbsp->header; \ + tbsp->header->lumps[l].filelen = tbsp->num##n * sizeof (tbsp->n[0]); \ + memcpy (data, bsp->n, tbsp->header->lumps[l].filelen); \ + data += ROUND (tbsp->header->lumps[l].filelen); \ } else {\ - tbsp.n = 0; \ - tbsp.header->lumps[l].fileofs = 0; \ - tbsp.header->lumps[l].filelen = 0; \ + tbsp->n = 0; \ + tbsp->header->lumps[l].fileofs = 0; \ + tbsp->header->lumps[l].filelen = 0; \ } \ } while (0) - tbsp.header->version = BSPVERSION; + tbsp->header->version = BSPVERSION; - data = (byte *) &tbsp.header[1]; + data = (byte *) &tbsp->header[1]; SET_LUMP (LUMP_PLANES, planes); SET_LUMP (LUMP_LEAFS, leafs); SET_LUMP (LUMP_VERTEXES, vertexes); @@ -821,17 +819,17 @@ do { \ #undef SET_LUMP #define SET_LUMP(l,n) \ do { \ - tbsp.n##size = bsp->n##size; \ - if (tbsp.n##size) { \ - tbsp.n = (void *) data; \ - tbsp.header->lumps[l].fileofs = data - (byte *) tbsp.header; \ - tbsp.header->lumps[l].filelen = tbsp.n##size; \ - memcpy (data, bsp->n, bsp->n##size); \ - data += ROUND (tbsp.header->lumps[l].filelen); \ + tbsp->n##size = bsp->n##size; \ + if (tbsp->n##size) { \ + tbsp->n = (void *) data; \ + tbsp->header->lumps[l].fileofs = data - (byte *) tbsp->header; \ + tbsp->header->lumps[l].filelen = tbsp->n##size; \ + memcpy (data, bsp->n, tbsp->n##size); \ + data += ROUND (tbsp->header->lumps[l].filelen); \ } else {\ - tbsp.n = 0; \ - tbsp.header->lumps[l].fileofs = 0; \ - tbsp.header->lumps[l].filelen = 0; \ + tbsp->n = 0; \ + tbsp->header->lumps[l].fileofs = 0; \ + tbsp->header->lumps[l].filelen = 0; \ } \ } while (0) @@ -840,13 +838,133 @@ do { \ SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); - if (bsp2) - swap_bsp (&tbsp, 1, 0, 0); - else - swap_to_bsp29 (0, &tbsp); //FIXME + *_size = size; + return tbsp; +} - Qwrite (file, tbsp.header, size); - free (tbsp.header); +static bsp29_t * +set_bsp29_write (const bsp_t *bsp, size_t *_size) +{ + size_t size; + byte *data; + bsp29_t *tbsp; + + size = sizeof (*tbsp); + size += ROUND (sizeof (dheader_t)); + size += ROUND (bsp->nummodels * sizeof (dmodel_t)); + size += ROUND (bsp->visdatasize); + size += ROUND (bsp->lightdatasize); + size += ROUND (bsp->texdatasize); + size += ROUND (bsp->entdatasize); + size += ROUND (bsp->numleafs * sizeof (dleaf29_t)); + size += ROUND (bsp->numplanes * sizeof (dplane_t)); + size += ROUND (bsp->numvertexes * sizeof (dvertex_t)); + size += ROUND (bsp->numnodes * sizeof (dnode29_t)); + size += ROUND (bsp->numtexinfo * sizeof (texinfo_t)); + size += ROUND (bsp->numfaces * sizeof (dface29_t)); + size += ROUND (bsp->numclipnodes * sizeof (dclipnode29_t)); + size += ROUND (bsp->numedges * sizeof (dedge29_t)); + size += ROUND (bsp->nummarksurfaces * sizeof (uint16_t)); + size += ROUND (bsp->numsurfedges * sizeof (uint32_t)); + + tbsp = calloc (size, 1); + tbsp->header = (dheader_t *) &tbsp[1]; + +#undef SET_LUMP +#define SET_LUMP(l,n) \ +do { \ + tbsp->num##n = bsp->num##n; \ + if (tbsp->num##n) {\ + tbsp->n = (void *) data; \ + tbsp->header->lumps[l].fileofs = data - (byte *) tbsp->header; \ + tbsp->header->lumps[l].filelen = tbsp->num##n * sizeof (tbsp->n[0]); \ + memcpy (data, bsp->n, tbsp->header->lumps[l].filelen); \ + data += ROUND (tbsp->header->lumps[l].filelen); \ + } else {\ + tbsp->n = 0; \ + tbsp->header->lumps[l].fileofs = 0; \ + tbsp->header->lumps[l].filelen = 0; \ + } \ +} while (0) + + tbsp->header->version = BSPVERSION; + + data = (byte *) &tbsp->header[1]; + SET_LUMP (LUMP_PLANES, planes); + SET_LUMP (LUMP_LEAFS, leafs); + SET_LUMP (LUMP_VERTEXES, vertexes); + SET_LUMP (LUMP_NODES, nodes); + SET_LUMP (LUMP_TEXINFO, texinfo); + SET_LUMP (LUMP_FACES, faces); + SET_LUMP (LUMP_CLIPNODES, clipnodes); + SET_LUMP (LUMP_MARKSURFACES, marksurfaces); + SET_LUMP (LUMP_SURFEDGES, surfedges); + SET_LUMP (LUMP_EDGES, edges); + SET_LUMP (LUMP_MODELS, models); + +#undef SET_LUMP +#define SET_LUMP(l,n) \ +do { \ + tbsp->n##size = bsp->n##size; \ + if (tbsp->n##size) { \ + tbsp->n = (void *) data; \ + tbsp->header->lumps[l].fileofs = data - (byte *) tbsp->header; \ + tbsp->header->lumps[l].filelen = tbsp->n##size; \ + memcpy (data, bsp->n, tbsp->n##size); \ + data += ROUND (tbsp->header->lumps[l].filelen); \ + } else {\ + tbsp->n = 0; \ + tbsp->header->lumps[l].fileofs = 0; \ + tbsp->header->lumps[l].filelen = 0; \ + } \ +} while (0) + + SET_LUMP (LUMP_LIGHTING, lightdata); + SET_LUMP (LUMP_VISIBILITY, visdata); + SET_LUMP (LUMP_ENTITIES, entdata); + SET_LUMP (LUMP_TEXTURES, texdata); + + *_size = size; + return tbsp; +} + +/* + WriteBSPFile +*/ +VISIBLE void +WriteBSPFile (const bsp_t *bsp, QFile *file) +{ + qboolean bsp2 = ( bsp->models[0].mins[0] < -32768.0f + || bsp->models[0].mins[1] < -32768.0f + || bsp->models[0].mins[2] < -32768.0f + || bsp->models[0].mins[0] >= 32768.0f + || bsp->models[0].mins[0] >= 32768.0f + || bsp->models[0].mins[0] >= 32768.0f + || bsp->nummarksurfaces >= 32768 + || bsp->numvertexes >= 32768 + || bsp->numnodes >= 32768 + || bsp->numleafs >= 32768 + || bsp->numplanes >= 32768 + || bsp->numtexinfo >= 32768 + || bsp->numclipnodes >= 32768); + + if (bsp2) { + bsp_t *tbsp; + size_t size; + + tbsp = set_bsp2_write (bsp, &size); + swap_bsp (tbsp, 1, 0, 0); + Qwrite (file, tbsp->header, size); + free (tbsp); + } else { + bsp29_t *tbsp; + size_t size; + + tbsp = set_bsp29_write (bsp, &size); + swap_to_bsp29 (tbsp, bsp); + Qwrite (file, tbsp->header, size); + free (tbsp); + } } VISIBLE bsp_t * From 0ce32a793e08c612ff5290e87f92af88133ddc1c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Fri, 7 Sep 2012 20:40:58 +0900 Subject: [PATCH 06/18] Return the correct size for set_bsp*_write(). Need to subtract the size of the bsp_t/bsp29_t struct. Now old and new qfbsp produce identical bsps (so long as they're both unoptimized, or (probably) both optimized). --- libs/util/bspfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/util/bspfile.c b/libs/util/bspfile.c index 9ac610e86..82911b113 100644 --- a/libs/util/bspfile.c +++ b/libs/util/bspfile.c @@ -838,7 +838,7 @@ do { \ SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); - *_size = size; + *_size = size - sizeof (*tbsp); return tbsp; } @@ -924,7 +924,7 @@ do { \ SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); - *_size = size; + *_size = size - sizeof (*tbsp); return tbsp; } From beb0b9e0fc32f883871f88020a88b468c0faf8bd Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 8 Sep 2012 09:37:48 +0900 Subject: [PATCH 07/18] Fix a segfault when no interfaces are available. --- libs/net/nm/net_udp.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/net/nm/net_udp.c b/libs/net/nm/net_udp.c index 7b4a2bebb..c2268026f 100644 --- a/libs/net/nm/net_udp.c +++ b/libs/net/nm/net_udp.c @@ -590,7 +590,8 @@ UDP_GetSocketAddr (int socket, netadr_t *na) SockadrToNetadr (&addr, na); memcpy (&a, na->ip, ADDR_SIZE); if (a == 0 || a == inet_addr ("127.0.0.1")) { - memcpy (na->ip, default_iface, ADDR_SIZE); + if (default_iface) + memcpy (na->ip, default_iface, ADDR_SIZE); if (last_iface) memcpy (na->ip, last_iface, ADDR_SIZE); } From cfb856b9cf03de8226acfcbb96bff6efcff8f04c Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 8 Sep 2012 09:38:22 +0900 Subject: [PATCH 08/18] Fix byteswapping of a node's firstface/numfaces. I'd forgotten to fix this. --- libs/util/bspfile.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libs/util/bspfile.c b/libs/util/bspfile.c index 82911b113..01635d848 100644 --- a/libs/util/bspfile.c +++ b/libs/util/bspfile.c @@ -530,8 +530,8 @@ swap_bsp (bsp_t *bsp, int todisk, void (*cb) (const bsp_t *, void *), } node->children[0] = LittleLong (node->children[0]); node->children[1] = LittleLong (node->children[1]); - node->firstface = LittleShort (node->firstface); - node->numfaces = LittleShort (node->numfaces); + node->firstface = LittleLong (node->firstface); + node->numfaces = LittleLong (node->numfaces); } // leafs From 45c48a621531aa1333becdcddb79c3905f9f227e Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sat, 8 Sep 2012 09:41:00 +0900 Subject: [PATCH 09/18] Fix bsp2 loading. Just some problems with the handling of extended bsp29 files. I'm not quite happy with the code, but it will do for now. --- libs/models/brush/model_brush.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index 50b627597..3b0bffbf4 100644 --- a/libs/models/brush/model_brush.c +++ b/libs/models/brush/model_brush.c @@ -600,10 +600,13 @@ Mod_LoadNodes (bsp_t *bsp) for (j = 0; j < 2; j++) { p = in->children[j]; // this check is for extended bsp 29 files - if (p < count) { + if (p >= 0 && p < count) { out->children[j] = loadmodel->nodes + p; } else { - p = 65535 - p; //NOTE this uses 65535 intentionally, -1 is leaf + if (p >= count) + p = 65535 - p; //NOTE 65535 is intentional, -1 is leaf + else + p = ~p; if (p < loadmodel->numleafs) { out->children[j] = (mnode_t *) (loadmodel->leafs + p); } else { @@ -632,9 +635,6 @@ Mod_LoadLeafs (bsp_t *bsp) count = bsp->numleafs; out = Hunk_AllocName (count * sizeof (*out), loadname); - if (count > 32767) - Sys_Error ("%i leafs exceeds limit of 32767.\n", count); - loadmodel->leafs = out; loadmodel->numleafs = count; // snprintf(s, sizeof (s), "maps/%s.bsp", From ea541b325dd44515e1ba8b06db78623683d519b5 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 9 Sep 2012 17:23:55 +0900 Subject: [PATCH 10/18] Set the map parser scripts to not lex single chars. qbsp treats {foo as one token, not two. --- tools/Forge/Bundles/MapEdit/Map.m | 1 + tools/qfbsp/source/map.c | 1 + 2 files changed, 2 insertions(+) diff --git a/tools/Forge/Bundles/MapEdit/Map.m b/tools/Forge/Bundles/MapEdit/Map.m index 71ad276b7..8fa1ed0e5 100644 --- a/tools/Forge/Bundles/MapEdit/Map.m +++ b/tools/Forge/Bundles/MapEdit/Map.m @@ -336,6 +336,7 @@ readMapFile dat[size] = 0; script = Script_New (); + script->single = ""; Script_Start (script, [fname fileSystemRepresentation], dat); do { diff --git a/tools/qfbsp/source/map.c b/tools/qfbsp/source/map.c index 6ca02c954..196e2cdd8 100644 --- a/tools/qfbsp/source/map.c +++ b/tools/qfbsp/source/map.c @@ -510,6 +510,7 @@ LoadMapFile (const char *filename) Qclose (file); map_script = Script_New (); + map_script->single = ""; Script_Start (map_script, filename, buf); num_entities = 0; From db25d5597d2b92b496625892e8191f74c9878ddc Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 12 Sep 2012 08:24:17 +0900 Subject: [PATCH 11/18] Handle quest format brushes. Bah, I forgot I needed to fix the vertex count parsing when I did the script lexing change. --- tools/Forge/Bundles/MapEdit/SetBrush.m | 14 +++++++++++--- tools/qfbsp/source/map.c | 14 +++++++++++--- 2 files changed, 22 insertions(+), 6 deletions(-) diff --git a/tools/Forge/Bundles/MapEdit/SetBrush.m b/tools/Forge/Bundles/MapEdit/SetBrush.m index 6e5ea03a7..7711d9e7f 100644 --- a/tools/Forge/Bundles/MapEdit/SetBrush.m +++ b/tools/Forge/Bundles/MapEdit/SetBrush.m @@ -643,11 +643,19 @@ ParseVerts (script_t *script, int *n_verts) { vec3_t *verts; int i; + const char *token; - if (strcmp (Script_Token (script), ":")) + token = Script_Token (script); + if (token[0] != ':') Sys_Error ("parsing map file"); - Script_GetToken (script, false); - *n_verts = atoi (Script_Token (script)); + // It's normally ":count", but somebody might have done ": count" + if (!token[1]) { + Script_GetToken (script, false); + token = Script_Token (script); + } else { + token++; + } + *n_verts = atoi (token); verts = malloc (sizeof (vec3_t) * *n_verts); for (i = 0; i < *n_verts; i++) { diff --git a/tools/qfbsp/source/map.c b/tools/qfbsp/source/map.c index 196e2cdd8..3ee844f10 100644 --- a/tools/qfbsp/source/map.c +++ b/tools/qfbsp/source/map.c @@ -207,11 +207,19 @@ ParseVerts (int *n_verts) { vec3_t *verts; int i; + const char *token; - if (map_script->token->str[0] != ':') + token = Script_Token (map_script); + if (token[0] != ':') map_error ("parsing brush"); - Script_GetToken (map_script, false); - *n_verts = atoi (map_script->token->str); + // It's normally ":count", but somebody might have done ": count" + if (!token[1]) { + Script_GetToken (map_script, false); + token = Script_Token (map_script); + } else { + token++; + } + *n_verts = atoi (token); verts = malloc (sizeof (vec3_t) * *n_verts); for (i = 0; i < *n_verts; i++) { From bcda96a4452b8a6a10482318fefac94b1e76d27f Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 12 Sep 2012 08:33:44 +0900 Subject: [PATCH 12/18] Report the source line of the entity in messages. For now, just when PrintEntity is used to print the message, but having the first line of the entity sure makes life easier. --- tools/qfbsp/include/map.h | 1 + tools/qfbsp/source/map.c | 2 ++ 2 files changed, 3 insertions(+) diff --git a/tools/qfbsp/include/map.h b/tools/qfbsp/include/map.h index f95691a7e..1e6c18f29 100644 --- a/tools/qfbsp/include/map.h +++ b/tools/qfbsp/include/map.h @@ -51,6 +51,7 @@ typedef struct epair_s { /** In-memory representation of an entity as parsed from the map script. */ typedef struct { + int line; ///< Map line of entity start (for messages) vec3_t origin; ///< Location of this entity in world-space. mbrush_t *brushes; ///< Nul terminated list of brushes. epair_t *epairs; ///< Nul terminated list of key=value pairs. diff --git a/tools/qfbsp/source/map.c b/tools/qfbsp/source/map.c index 3ee844f10..dcf5e82e1 100644 --- a/tools/qfbsp/source/map.c +++ b/tools/qfbsp/source/map.c @@ -465,6 +465,7 @@ ParseEntity (void) mapent = &entities[num_entities]; num_entities++; memset (mapent, 0, sizeof (entity_t)); + mapent->line = map_script->line; do { if (!Script_GetToken (map_script, true)) @@ -552,6 +553,7 @@ PrintEntity (const entity_t *ent) { const epair_t *ep; + printf ("%20s : %d\n", "map source line", ent->line); for (ep = ent->epairs; ep; ep = ep->next) printf ("%20s : %s\n", ep->key, ep->value); } From 433d9d138bd7e1c95aa4bcb2e405f4d5d666f839 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 12 Sep 2012 09:54:24 +0900 Subject: [PATCH 13/18] Hook up the pointfile loader in glsl. I was always wondering what that was for (never bothered looking at the command registration, I guess :P). --- libs/video/renderer/glsl/glsl_main.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libs/video/renderer/glsl/glsl_main.c b/libs/video/renderer/glsl/glsl_main.c index b55f8ad0c..f83594409 100644 --- a/libs/video/renderer/glsl/glsl_main.c +++ b/libs/video/renderer/glsl/glsl_main.c @@ -41,6 +41,7 @@ # include "strings.h" #endif +#include "QF/cmd.h" #include "QF/cvar.h" #include "QF/image.h" #include "QF/render.h" @@ -245,6 +246,8 @@ glsl_R_RenderView (void) void glsl_R_Init (void) { + Cmd_AddCommand ("pointfile", glsl_R_ReadPointFile_f, + "Load a pointfile to determine map leaks"); R_Init_Cvars (); glsl_R_Particles_Init_Cvars (); Draw_Init (); From 536ee48a9793da20bfb6a90cae41bc079297c7de Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 12 Sep 2012 15:19:20 +0900 Subject: [PATCH 14/18] Some minor skybox improvements suggested by mh. Rearrange the sky_suffix and sky_coords arrays and remove the sky_target array such that the faces can be loaded using GL_TEXTURE_CUBE_MAP_POSITIVE_X + i (apparently certain drivers break if the faces aren't loaded in the correct order). Also, the nomalization of the direction vector in the fragment isn't necessary. --- libs/video/renderer/glsl/glsl_bsp.c | 18 +++++------------- libs/video/renderer/glsl/quakeskb.frag | 2 -- 2 files changed, 5 insertions(+), 15 deletions(-) diff --git a/libs/video/renderer/glsl/glsl_bsp.c b/libs/video/renderer/glsl/glsl_bsp.c index ecffcef56..06e2db6e7 100644 --- a/libs/video/renderer/glsl/glsl_bsp.c +++ b/libs/video/renderer/glsl/glsl_bsp.c @@ -1326,22 +1326,14 @@ glsl_R_LoadSkys (const char *sky) // NOTE: quake's world and GL's world are rotated relative to each other // quake has x right, y in, z up. gl has x right, y up, z out // However, skymaps have lf and rt swapped :/ lf rt - static const char *sky_suffix[] = { "ft", "bk", "rt", "lf", "up", "dn"}; + static const char *sky_suffix[] = { "ft", "bk", "up", "dn", "rt", "lf"}; static int sky_coords[][2] = { {2, 0}, // front {0, 0}, // back - {2, 1}, // left - {1, 0}, // right {1, 1}, // up {0, 1}, // down - }; - static int sky_target[] = { - GL_TEXTURE_CUBE_MAP_POSITIVE_X, // front - GL_TEXTURE_CUBE_MAP_NEGATIVE_X, // back - GL_TEXTURE_CUBE_MAP_POSITIVE_Z, // left (normally -ve Z, see shader) - GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, // right (normally +ve Z, see shader) - GL_TEXTURE_CUBE_MAP_POSITIVE_Y, // up - GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, // down + {2, 1}, // left + {1, 0}, // right }; if (!sky || !*sky) @@ -1377,7 +1369,7 @@ glsl_R_LoadSkys (const char *sky) x = sky_coords[i][0] * size; y = sky_coords[i][1] * size; copy_sub_tex (tex, x, y, sub); - qfeglTexImage2D (sky_target[i], 0, + qfeglTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, sub->format == 3 ? GL_RGB : GL_RGBA, sub->width, sub->height, 0, sub->format == 3 ? GL_RGB : GL_RGBA, @@ -1400,7 +1392,7 @@ glsl_R_LoadSkys (const char *sky) } } Sys_MaskPrintf (SYS_GLSL, "Loaded %s\n", name); - qfeglTexImage2D (sky_target[i], 0, + qfeglTexImage2D (GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, tex->format == 3 ? GL_RGB : GL_RGBA, tex->width, tex->height, 0, tex->format == 3 ? GL_RGB : GL_RGBA, diff --git a/libs/video/renderer/glsl/quakeskb.frag b/libs/video/renderer/glsl/quakeskb.frag index 17420b04b..3ffacd398 100644 --- a/libs/video/renderer/glsl/quakeskb.frag +++ b/libs/video/renderer/glsl/quakeskb.frag @@ -24,8 +24,6 @@ main (void) { vec3 dir = direction; - dir *= inversesqrt (dot (dir, dir)); - // NOTE: quake's world and GL's world are rotated relative to each other // quake has x right, y in, z up. gl has x right, y up, z out // The textures are loaded with GL's z (quake's y) already negated, so From 14f089d08ea880d4315ffd85837d54fd85a465d1 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Wed, 12 Sep 2012 19:06:07 +0900 Subject: [PATCH 15/18] Correct the orientation of the skybox (for glsl). It turns out the expected orientation of the sky cube is exactly that of Blender's default cube looked at from the front view (num-1) and the front face being the nearest face. This put's Marcher's sun nicely in the view when exiting the cave. --- libs/video/renderer/glsl/glsl_bsp.c | 17 +++++++++++++++-- libs/video/renderer/glsl/quakeski.frag | 7 ++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/libs/video/renderer/glsl/glsl_bsp.c b/libs/video/renderer/glsl/glsl_bsp.c index 06e2db6e7..a5c11f9af 100644 --- a/libs/video/renderer/glsl/glsl_bsp.c +++ b/libs/video/renderer/glsl/glsl_bsp.c @@ -98,6 +98,7 @@ static GLuint skybox_tex; static qboolean skybox_loaded; static quat_t sky_rotation[2]; static quat_t sky_velocity; +static quat_t sky_fix; static double sky_time; static quat_t default_color = { 1, 1, 1, 1 }; @@ -522,8 +523,9 @@ glsl_R_BuildDisplayLists (model_t **models, int num_models) msurface_t *surf; dstring_t *vertices; + QuatSet (sqrt(0.5), 0, 0, sqrt(0.5), sky_fix); // proper skies QuatSet (1, 0, 0, 0, sky_rotation[0]); - QuatSet (1, 0, 0, 0, sky_rotation[1]); + QuatCopy (sky_rotation[0], sky_rotation[1]); QuatSet (0, 0, 0, 0, sky_velocity); QuatExp (sky_velocity, sky_velocity); sky_time = vr_data.realtime; @@ -948,6 +950,7 @@ spin (mat4_t mat) blend = bound (0, (vr_data.realtime - sky_time), 1); QuatBlend (sky_rotation[0], sky_rotation[1], blend, q); + QuatMult (sky_fix, q, q); Mat4Identity (mat); VectorNegate (r_origin, mat + 12); QuatToMatrix (q, m, 1, 1); @@ -1325,7 +1328,17 @@ glsl_R_LoadSkys (const char *sky) tex_t *tex; // NOTE: quake's world and GL's world are rotated relative to each other // quake has x right, y in, z up. gl has x right, y up, z out - // However, skymaps have lf and rt swapped :/ lf rt + // quake order: +x -x +z -z +y -y + // gl order: +x -x +y -y +z -z + // fizquake orger: -y +y +z -z +x -x + // to get from quake order to fitzquake order, all that's needed is + // a -90 degree rotation on the (quake) z-axis. This is taken care of in + // the sky_matrix setup code. + // However, from the player's perspective, skymaps have lf and rt + // swapped, but everythink makes sense if looking at the cube from outside + // along the positive y axis, with the front of the cube being the nearest + // face. This matches nicely with Blender's default cube in front (num-1) + // view. static const char *sky_suffix[] = { "ft", "bk", "up", "dn", "rt", "lf"}; static int sky_coords[][2] = { {2, 0}, // front diff --git a/libs/video/renderer/glsl/quakeski.frag b/libs/video/renderer/glsl/quakeski.frag index e5a7b30d3..5c2bbb96c 100644 --- a/libs/video/renderer/glsl/quakeski.frag +++ b/libs/video/renderer/glsl/quakeski.frag @@ -30,17 +30,18 @@ main (void) float len; float pix; vec2 flow = vec2 (1.0, 1.0); - vec2 st; + vec2 st, base; vec3 dir = direction; dir.z *= 3.0; len = dot (dir, dir); len = SCALE * inversesqrt (len); - st = direction.xy * len + flow * realtime / 8.0; + base = direction.yx * vec2(1.0, -1.0) * len; + st = base + flow * realtime / 8.0; pix = texture2D (trans, st).r; if (pix == 0.0) { - st = direction.xy * len + flow * realtime / 16.0; + st = base + flow * realtime / 16.0; pix = texture2D (solid, st).r; } gl_FragColor = fogBlend (texture2D (palette, vec2 (pix, 0.0))); From 709da6e7d77321176a191d3f9b5d5583ebc7a5f6 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Thu, 13 Sep 2012 08:36:28 +0900 Subject: [PATCH 16/18] Rotate the skybox -90 degrees on the z axis (gl) Now gl and glsl match again, and quake's skies are now "correct" (assuming fitzquake is the standard). --- libs/video/renderer/gl/gl_sky.c | 59 +++++++++++++++------------- libs/video/renderer/gl/gl_sky_clip.c | 11 +++--- 2 files changed, 37 insertions(+), 33 deletions(-) diff --git a/libs/video/renderer/gl/gl_sky.c b/libs/video/renderer/gl/gl_sky.c index 210e4ef25..a4d325f09 100644 --- a/libs/video/renderer/gl/gl_sky.c +++ b/libs/video/renderer/gl/gl_sky.c @@ -55,6 +55,9 @@ #include "compat.h" #include "r_internal.h" +// Note that the cube face names are from the perspective of looking at the +// cube from the outside on the -ve y axis with +x to the right, +y going in, +// +z up, and front is the nearest face. static const char *suf[6] = { "rt", "bk", "lf", "ft", "up", "dn" }; int gl_solidskytexture; int gl_alphaskytexture; @@ -65,46 +68,46 @@ qboolean gl_skyloaded = false; vec5_t gl_skyvec[6][4] = { { - // right +y - {1, 0, 1024, 1024, 1024}, - {1, 1, 1024, 1024, -1024}, - {0, 1, -1024, 1024, -1024}, - {0, 0, -1024, 1024, 1024} + // right +x + {0, 0, 1024, 1024, 1024}, + {0, 1, 1024, 1024, -1024}, + {1, 1, 1024, -1024, -1024}, + {1, 0, 1024, -1024, 1024} }, { - // back -x - {1, 0, -1024, 1024, 1024}, - {1, 1, -1024, 1024, -1024}, + // back +y + {0, 0, -1024, 1024, 1024}, + {0, 1, -1024, 1024, -1024}, + {1, 1, 1024, 1024, -1024}, + {1, 0, 1024, 1024, 1024} + }, + { + // left -x + {0, 0, -1024, -1024, 1024}, {0, 1, -1024, -1024, -1024}, - {0, 0, -1024, -1024, 1024} + {1, 1, -1024, 1024, -1024}, + {1, 0, -1024, 1024, 1024} }, { - // left -y - {1, 0, -1024, -1024, 1024}, + // front -y + {0, 0, 1024, -1024, 1024}, + {0, 1, 1024, -1024, -1024}, {1, 1, -1024, -1024, -1024}, - {0, 1, 1024, -1024, -1024}, - {0, 0, 1024, -1024, 1024} - }, - { - // front +x - {1, 0, 1024, -1024, 1024}, - {1, 1, 1024, -1024, -1024}, - {0, 1, 1024, 1024, -1024}, - {0, 0, 1024, 1024, 1024} + {1, 0, -1024, -1024, 1024} }, { // up +z - {1, 0, 1024, -1024, 1024}, - {1, 1, 1024, 1024, 1024}, - {0, 1, -1024, 1024, 1024}, - {0, 0, -1024, -1024, 1024} + {0, 0, -1024, 1024, 1024}, + {0, 1, 1024, 1024, 1024}, + {1, 1, 1024, -1024, 1024}, + {1, 0, -1024, -1024, 1024} }, { // down -z - {1, 0, 1024, 1024, -1024}, - {1, 1, 1024, -1024, -1024}, - {0, 1, -1024, -1024, -1024}, - {0, 0, -1024, 1024, -1024} + {0, 0, 1024, 1024, -1024}, + {0, 1, -1024, 1024, -1024}, + {1, 1, -1024, -1024, -1024}, + {1, 0, 1024, -1024, -1024} } }; diff --git a/libs/video/renderer/gl/gl_sky_clip.c b/libs/video/renderer/gl/gl_sky_clip.c index 3ab792c2b..755a00e8d 100644 --- a/libs/video/renderer/gl/gl_sky_clip.c +++ b/libs/video/renderer/gl/gl_sky_clip.c @@ -64,7 +64,8 @@ #define BOX_WIDTH 2056 /* cube face to sky texture offset conversion */ -static const int skytex_offs[] = { 3, 0, 4, 1, 2, 5 }; +// see gl_sky.c for naming: rt bk up lf ft dn +static const int skytex_offs[] = { 0, 1, 4, 2, 3, 5 }; /* convert axis and face distance into face */ static const int faces_table[3][6] = { @@ -238,8 +239,8 @@ set_vertex (struct box_def *box, int face, int ind, const vec3_t v) box->face[face].poly.verts[ind][4] = (1024 - v[2] + 4) / BOX_WIDTH; break; case 2: - box->face[face].poly.verts[ind][3] = (1024 + v[0] + 4) / BOX_WIDTH; - box->face[face].poly.verts[ind][4] = (1024 + v[1] + 4) / BOX_WIDTH; + box->face[face].poly.verts[ind][3] = (1024 - v[1] + 4) / BOX_WIDTH; + box->face[face].poly.verts[ind][4] = (1024 + v[0] + 4) / BOX_WIDTH; break; case 3: box->face[face].poly.verts[ind][3] = (1024 + v[1] + 4) / BOX_WIDTH; @@ -250,8 +251,8 @@ set_vertex (struct box_def *box, int face, int ind, const vec3_t v) box->face[face].poly.verts[ind][4] = (1024 - v[2] + 4) / BOX_WIDTH; break; case 5: - box->face[face].poly.verts[ind][3] = (1024 + v[0] + 4) / BOX_WIDTH; - box->face[face].poly.verts[ind][4] = (1024 - v[1] + 4) / BOX_WIDTH; + box->face[face].poly.verts[ind][3] = (1024 - v[1] + 4) / BOX_WIDTH; + box->face[face].poly.verts[ind][4] = (1024 - v[0] + 4) / BOX_WIDTH; break; } } From d6476d4f93d03e6b79f0a2a219de25b208b29fa0 Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 16 Sep 2012 12:38:55 +0900 Subject: [PATCH 17/18] Make some improvements to the leak files. smart leak files now produce many points, not just one per portal. Normal leak files now center the trail on the portal (instead of some weird weighted average). --- tools/qfbsp/source/outside.c | 66 +++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/tools/qfbsp/source/outside.c b/tools/qfbsp/source/outside.c index 930a5a0eb..83cf9655a 100644 --- a/tools/qfbsp/source/outside.c +++ b/tools/qfbsp/source/outside.c @@ -111,6 +111,25 @@ PlaceOccupant (int num, const vec3_t point, node_t *headnode) const portal_t *prevleaknode; FILE *leakfile; +static void +write_points (const vec3_t p1, const vec3_t p2) +{ + vec3_t p, dir; + float len; + + VectorSubtract (p2, p1, dir); + len = VectorLength (dir); + _VectorNormalize (dir); + + VectorCopy (p1, p); + + while (len > 2) { + fprintf (leakfile, "%f %f %f\n", p[0], p[1], p[2]); + VectorMultAdd(p, 2, dir, p); + len -= 2; + } +} + /** Write the coords for points joining two portals to the point file. \param n2 The second portal. @@ -119,10 +138,9 @@ FILE *leakfile; static void MarkLeakTrail (const portal_t *n2) { - float len; - int i, j; + int i; const portal_t *n1; - vec3_t p1, p2, dir; + vec3_t p1, p2; n1 = prevleaknode; prevleaknode = n2; @@ -130,33 +148,22 @@ MarkLeakTrail (const portal_t *n2) if (!n1) return; - VectorCopy (n2->winding->points[0], p1); - for (i = 1; i < n2->winding->numpoints; i++) { - for (j = 0; j < 3; j++) - p1[j] = (p1[j] + n2->winding->points[i][j]) / 2; - } + VectorZero (p1); + for (i = 0; i < n2->winding->numpoints; i++) + VectorAdd (p1, n2->winding->points[i], p1); + VectorScale (p1, 1.0 / i, p1); - VectorCopy (n1->winding->points[0], p2); - for (i = 1; i < n1->winding->numpoints; i++) { - for (j = 0; j < 3; j++) - p2[j] = (p2[j] + n1->winding->points[i][j]) / 2; - } - - VectorSubtract (p2, p1, dir); - len = VectorLength (dir); - _VectorNormalize (dir); + VectorZero (p2); + for (i = 0; i < n1->winding->numpoints; i++) + VectorAdd (p2, n1->winding->points[i], p2); + VectorScale (p2, 1.0 / i, p2); if (!leakfile) leakfile = fopen (options.pointfile, "w"); if (!leakfile) Sys_Error ("Couldn't open %s\n", options.pointfile); - while (len > 2) { - fprintf (leakfile, "%f %f %f\n", p1[0], p1[1], p1[2]); - for (i = 0; i < 3; i++) - p1[i] += dir[i] * 2; - len -= 2; - } + write_points (p1, p2); } /** Mark the trail from outside to the entity. @@ -166,11 +173,11 @@ MarkLeakTrail (const portal_t *n2) static void MarkLeakTrail2 (void) { - int i; + int i, first; int next, side; const node_t *n, *nextnode; const portal_t *p, *p2; - vec3_t wc; + vec3_t wc, pwc; const vec_t *v; leakfile = fopen (options.pointfile, "w"); @@ -180,6 +187,7 @@ MarkLeakTrail2 (void) n = &outside_node; next = -1; + first = 1; while ((n->o_dist > 1) || (next == -1)) { nextnode = 0; p2 = 0; @@ -201,10 +209,14 @@ MarkLeakTrail2 (void) for (i = 0; i < p2->winding->numpoints; i++) VectorAdd (wc, p2->winding->points[i], wc); VectorScale (wc, 1.0 / i, wc); - fprintf (leakfile, "%g %g %g", wc[0], wc[1], wc[2]); + if (first) { + first = 0; + write_points(pwc, wc); + } + VectorCopy(wc, pwc); } v = entities[n->occupied].origin; - fprintf (leakfile, "%g %g %g\n", v[0], v[1], v[2]); + write_points(wc, v); fclose (leakfile); } From 156f3382a5c589f243711cbdeca5436a0469c0cb Mon Sep 17 00:00:00 2001 From: Bill Currie Date: Sun, 16 Sep 2012 13:50:54 +0900 Subject: [PATCH 18/18] Emit the points in the expected order. Associating p1 with n2 and p2 with n1 was a bit confusing. Makes for a more-sensible points output file, too. --- tools/qfbsp/source/outside.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tools/qfbsp/source/outside.c b/tools/qfbsp/source/outside.c index 83cf9655a..0f17ec728 100644 --- a/tools/qfbsp/source/outside.c +++ b/tools/qfbsp/source/outside.c @@ -149,13 +149,13 @@ MarkLeakTrail (const portal_t *n2) return; VectorZero (p1); - for (i = 0; i < n2->winding->numpoints; i++) - VectorAdd (p1, n2->winding->points[i], p1); + for (i = 0; i < n1->winding->numpoints; i++) + VectorAdd (p1, n1->winding->points[i], p1); VectorScale (p1, 1.0 / i, p1); VectorZero (p2); - for (i = 0; i < n1->winding->numpoints; i++) - VectorAdd (p2, n1->winding->points[i], p2); + for (i = 0; i < n2->winding->numpoints; i++) + VectorAdd (p2, n2->winding->points[i], p2); VectorScale (p2, 1.0 / i, p2); if (!leakfile)