Merge branch 'master' into mapedit

This commit is contained in:
Bill Currie 2012-09-17 07:52:42 +09:00
commit 45fd312133
23 changed files with 945 additions and 259 deletions

View file

@ -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;

View file

@ -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 {

View file

@ -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 !!!

View file

@ -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);
}

View file

@ -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;
}
}

View file

@ -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);
}

View file

@ -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 ; i<bsp29->nummodels ; i++) {
d = &bsp29->models[i];
for (j=0 ; j<MAX_MAP_HULLS ; j++)
d->headnode[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 ; i<bsp29->numvertexes ; i++) {
dvertex_t *vertex = &bsp29->vertexes[i];
for (j=0 ; j<3 ; j++)
vertex->point[j] = LittleFloat (vertex->point[j]);
}
// planes
for (i=0 ; i<bsp29->numplanes ; 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 ; i<bsp29->numtexinfo ; 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 ; i<bsp29->numfaces ; 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 ; i<bsp29->numnodes ; 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 ; i<bsp29->numleafs ; 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 ; i<bsp29->numclipnodes ; 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 ; i<c ; i++)
mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
}
// marksurfaces
for (i=0 ; i<bsp29->nummarksurfaces ; i++) {
const uint32_t *marksurface2 = &bsp2->marksurfaces[i];
uint16_t *marksurface29 = (uint16_t *) &bsp29->marksurfaces[i];
*marksurface29 = LittleShort (*marksurface2);
}
// surfedges
for (i=0 ; i<bsp29->numsurfedges ; i++) {
int32_t *surfedge = &bsp29->surfedges[i];
*surfedge = LittleLong (*surfedge);
}
// edges
for (i=0 ; i<bsp29->numedges ; 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 ; i<bsp2->nummodels ; i++) {
d = &bsp2->models[i];
for (j=0 ; j<MAX_MAP_HULLS ; j++)
d->headnode[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 ; i<bsp2->numvertexes ; i++) {
dvertex_t *vertex = &bsp2->vertexes[i];
for (j=0 ; j<3 ; j++)
vertex->point[j] = LittleFloat (vertex->point[j]);
}
// planes
for (i=0 ; i<bsp2->numplanes ; 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 ; i<bsp2->numtexinfo ; 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 ; i<bsp2->numfaces ; 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 ; i<bsp2->numnodes ; 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 ; i<bsp2->numleafs ; 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 ; i<bsp2->numclipnodes ; 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 ; i<c ; i++)
mtl->dataofs[i] = LittleLong(mtl->dataofs[i]);
}
// marksurfaces
for (i=0 ; i<bsp2->nummarksurfaces ; i++) {
uint32_t *marksurface2 = &bsp2->marksurfaces[i];
const uint16_t *marksurface29 = &bsp29->marksurfaces[i];
*marksurface2 = LittleShort (*marksurface29);
}
// surfedges
for (i=0 ; i<bsp2->numsurfedges ; i++) {
int32_t *surfedge = &bsp2->surfedges[i];
*surfedge = LittleLong (*surfedge);
}
// edges
for (i=0 ; i<bsp2->numedges ; 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 ; i<bsp->numfaces ; 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 ; i<bsp->numclipnodes ; 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 ; i<bsp->nummarksurfaces ; 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 ; i<bsp->numedges ; 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 *

View file

@ -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}
}
};

View file

@ -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;
}
}

View file

@ -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,

View file

@ -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 ();

View file

@ -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

View file

@ -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)));

View file

@ -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;

View file

@ -336,6 +336,7 @@ readMapFile
dat[size] = 0;
script = Script_New ();
script->single = "";
Script_Start (script, [fname fileSystemRepresentation], dat);
do {

View file

@ -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++) {

View file

@ -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.

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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++) {

View file

@ -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");

View file

@ -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);
}

View file

@ -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;