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/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); } diff --git a/libs/models/brush/model_brush.c b/libs/models/brush/model_brush.c index af919f581..3b0bffbf4 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,23 +587,26 @@ 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]); - if (p < count) { + p = in->children[j]; + // this check is for extended bsp 29 files + 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 { @@ -638,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", @@ -649,18 +643,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 +723,12 @@ 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] = 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) @@ -791,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; @@ -807,7 +801,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 +823,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 +843,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; } } 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); } diff --git a/libs/util/bspfile.c b/libs/util/bspfile.c index f5807f71b..01635d848 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] = (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); + } + + // 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] = (uint16_t) LittleShort (clipnode2->children[0]); + clipnode29->children[1] = (uint16_t) 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] = (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); + } + + // 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] = (uint16_t) LittleShort (clipnode29->children[0]); + clipnode2->children[1] = (uint16_t) 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,13 +525,13 @@ 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->firstface = LittleShort (node->firstface); - node->numfaces = LittleShort (node->numfaces); + node->children[0] = LittleLong (node->children[0]); + node->children[1] = LittleLong (node->children[1]); + node->firstface = LittleLong (node->firstface); + node->numfaces = LittleLong (node->numfaces); } // leafs @@ -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,26 +583,14 @@ 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]); } } -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; - - 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); - #undef SET_LUMP #define SET_LUMP(l,n) \ do { \ @@ -246,8 +637,107 @@ do { \ SET_LUMP (LUMP_VISIBILITY, visdata); SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); +} - swap_bsp (bsp, 0, cb, cbdata); +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 { + 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; } @@ -264,19 +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; + 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); @@ -290,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); @@ -330,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) @@ -349,10 +838,133 @@ do { \ SET_LUMP (LUMP_ENTITIES, entdata); SET_LUMP (LUMP_TEXTURES, texdata); - swap_bsp (&tbsp, 1, 0, 0); + *_size = size - sizeof (*tbsp); + 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 - sizeof (*tbsp); + 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 * 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; } } diff --git a/libs/video/renderer/glsl/glsl_bsp.c b/libs/video/renderer/glsl/glsl_bsp.c index ecffcef56..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,23 +1328,25 @@ 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 - static const char *sky_suffix[] = { "ft", "bk", "rt", "lf", "up", "dn"}; + // 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 {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 +1382,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 +1405,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/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 (); 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 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))); 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/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/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/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 6ca02c954..dcf5e82e1 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++) { @@ -457,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)) @@ -510,6 +519,7 @@ LoadMapFile (const char *filename) Qclose (file); map_script = Script_New (); + map_script->single = ""; Script_Start (map_script, filename, buf); num_entities = 0; @@ -543,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); } diff --git a/tools/qfbsp/source/outside.c b/tools/qfbsp/source/outside.c index 930a5a0eb..0f17ec728 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 < n1->winding->numpoints; i++) + VectorAdd (p1, n1->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 < n2->winding->numpoints; i++) + VectorAdd (p2, n2->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); } 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;